| @@ -39,6 +39,50 @@ directory to route session and turn operations for a thread, so callers name a t · 38 unmodified lines |
| 39 | Adding a driver means writing the driver plus adapter and adding it to `BUILT_IN_DRIVERS`. No | 39 | Adding a driver means writing the driver plus adapter and adding it to `BUILT_IN_DRIVERS`. No |
| 40 | orchestration, contract, or client change is required for the common case. | 40 | orchestration, contract, or client change is required for the common case. |
| 41 | | 41 | |
| | 42 | ## OpenCode server ownership and catalog |
| | 43 | |
| | 44 | Each OpenCode provider instance owns one lazy local server for catalog discovery and |
| | 45 | text-generation helpers through [`OpenCodeServerOwner.ts`][opencode-server-owner]. Concurrent |
| | 46 | borrowers share startup. The server closes 30 seconds after the last borrower releases it, or |
| | 47 | when the provider instance closes. A failed or exited process can be started again on the next |
| | 48 | use. An externally configured OpenCode server remains externally owned. |
| | 49 | |
| | 50 | The local server and its SDK clients use one resolved password. An explicit provider password |
| | 51 | overrides `OPENCODE_SERVER_PASSWORD` in the spawned environment. Without an explicit password, |
| | 52 | the client uses the password from the environment that the process inherits. External servers use |
| | 53 | only their explicit provider password and never inherit the host's local password. |
| | 54 | |
| | 55 | Every server connection must pass the authenticated `/global/health` check before inventory or |
| | 56 | session operations start. The response must contain a valid version at or above 1.14.19. Local |
| | 57 | owners cache this result for the lifetime of the spawned process. External actions check once when |
| | 58 | they create their server connection, not for each model or SDK request. |
| | 59 | |
| | 60 | Chat adapters keep their own server per thread. They register a thread-specific `t3-code` MCP |
| | 61 | connection, while OpenCode stores MCP connections by directory. Sharing these chat servers |
| | 62 | without changing MCP routing would let two threads in one directory replace each other's |
| | 63 | connection. |
| | 64 | |
| | 65 | OpenCode loads its catalog through the HTTP API when an enabled provider instance starts. The |
| | 66 | provider registry keeps the snapshot in memory and persists it in the existing per-instance cache. |
| | 67 | Each `subscribeServerConfig` connection refreshes all providers, so a client reconnect reloads the |
| | 68 | OpenCode catalog from the current helper. The `serverRefreshProviders` request also refreshes it. |
| | 69 | Periodic OpenCode probes remain disabled. OpenCode reads credentials for each inventory request, |
| | 70 | but its native configuration files can remain cached for the lifetime of the helper process. The |
| | 71 | helper closes 30 seconds after its last inventory or text-generation borrower releases it. A |
| | 72 | refresh after that idle period starts a new helper and reads file changes. Repeated refreshes and |
| | 73 | active text-generation work can extend process reuse. Changes to the provider configuration or |
| | 74 | environment replace the instance and start a new discovery. Changes to unrelated settings only |
| | 75 | update snapshot enrichment. Other providers retain their existing refresh policy. |
| | 76 | |
| | 77 | T3 Code does not own an external OpenCode process. Native configuration changes there can require |
| | 78 | an external reload or restart before T3 Code's next refresh sees them. |
| | 79 | |
| | 80 | The shared server's idle shutdown does not clear the catalog. Failed discovery keeps the last |
| | 81 | known models, slash commands, and skills through the registry's existing merge rules. A successful |
| | 82 | empty inventory is authoritative. Existing threads keep their explicit model identifier and |
| | 83 | options when catalog metadata is missing; the catalog is not permission to choose a different |
| | 84 | model for a thread. |
| | 85 | |
| 42 | ## Model manifest | 86 | ## Model manifest |
| 43 | | 87 | |
| 44 | The model picker's legacy section is driven by `apps/server/src/provider/model-manifest.json`, which | 88 | The model picker's legacy section is driven by `apps/server/src/provider/model-manifest.json`, which |
| @@ -121,6 +165,7 @@ when a request opens (approval) or user input is requested, via · 76 unmodified lines |
| 121 | [cursor]: ../../apps/server/src/provider/Drivers/CursorDriver.ts | 165 | [cursor]: ../../apps/server/src/provider/Drivers/CursorDriver.ts |
| 122 | [grok]: ../../apps/server/src/provider/Drivers/GrokDriver.ts | 166 | [grok]: ../../apps/server/src/provider/Drivers/GrokDriver.ts |
| 123 | [opencode]: ../../apps/server/src/provider/Drivers/OpenCodeDriver.ts | 167 | [opencode]: ../../apps/server/src/provider/Drivers/OpenCodeDriver.ts |
| | 168 | [opencode-server-owner]: ../../apps/server/src/provider/OpenCodeServerOwner.ts |
| 124 | [adapter]: ../../apps/server/src/provider/Services/ProviderAdapter.ts | 169 | [adapter]: ../../apps/server/src/provider/Services/ProviderAdapter.ts |
| 125 | [instances]: ../../apps/server/src/provider/Services/ProviderInstanceRegistry.ts | 170 | [instances]: ../../apps/server/src/provider/Services/ProviderInstanceRegistry.ts |
| 126 | [registry]: ../../apps/server/src/provider/Services/ProviderAdapterRegistry.ts | 171 | [registry]: ../../apps/server/src/provider/Services/ProviderAdapterRegistry.ts |