(
options: TextOptions<OpencodeTextProviderOptions>,
)
| 119 | } |
| 120 | |
| 121 | async *chatStream( |
| 122 | options: TextOptions<OpencodeTextProviderOptions>, |
| 123 | ): AsyncIterable<StreamChunk> { |
| 124 | const { logger } = options |
| 125 | let server: |
| 126 | | Awaited<ReturnType<typeof startOpencodeServerInSandbox>> |
| 127 | | undefined |
| 128 | let handle: OpencodeSessionHandle | undefined |
| 129 | let bridge: HostToolBridge | undefined |
| 130 | const externalSignal = |
| 131 | options.abortController?.signal ?? options.request?.signal ?? undefined |
| 132 | let onAbort: (() => void) | undefined |
| 133 | const runId = options.runId ?? this.generateId() |
| 134 | const threadId = options.threadId ?? this.generateId() |
| 135 | // Surfaces custom events from bridged tools (e.g. code mode console logs) |
| 136 | // on this run's live output stream. |
| 137 | const channel = createBridgeEventChannel({ |
| 138 | model: this.model, |
| 139 | threadId, |
| 140 | runId, |
| 141 | }) |
| 142 | |
| 143 | try { |
| 144 | const sandbox = this.sandboxFrom(options) |
| 145 | const directory = |
| 146 | options.modelOptions?.directory ?? |
| 147 | this.adapterConfig.directory ?? |
| 148 | DEFAULT_WORKDIR |
| 149 | |
| 150 | // Project workspace skills / MCP servers into the sandbox before starting |
| 151 | // the opencode server so the workspace config is in place for the session. |
| 152 | if (options.capabilities !== undefined) { |
| 153 | const projection = getWorkspaceProjection(options.capabilities, { |
| 154 | optional: true, |
| 155 | }) |
| 156 | if (projection !== undefined) { |
| 157 | await projectOpencodeWorkspace(sandbox, projection) |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | const modelOptions = options.modelOptions |
| 162 | const sessionId = modelOptions?.sessionId |
| 163 | const { prompt: resumePrompt } = buildPrompt(options.messages, sessionId) |
| 164 | const { providerID, modelID } = splitModel(this.model) |
| 165 | |
| 166 | // Bridge chat()-provided tools into the in-sandbox server over MCP |
| 167 | // (configured via OPENCODE_CONFIG_CONTENT at server spawn). |
| 168 | const bridgedToolNames = new Set( |
| 169 | (options.tools ?? []).map((tool) => tool.name), |
| 170 | ) |
| 171 | if (options.tools && options.tools.length > 0) { |
| 172 | const provisioner = |
| 173 | (options.capabilities |
| 174 | ? getToolBridgeProvisioner(options.capabilities, { optional: true }) |
| 175 | : undefined) ?? nodeHttpBridgeProvisioner |
| 176 | bridge = await provisioner.provision(options.tools, { |
| 177 | provider: sandbox.provider, |
| 178 | context: options.context, |
no test coverage detected