(
sessionId: string,
text: string,
options: {
modelID?: string;
providerID?: string;
agent?: string;
timeoutMs?: number;
} = {},
)
| 230 | } |
| 231 | |
| 232 | async sendPrompt( |
| 233 | sessionId: string, |
| 234 | text: string, |
| 235 | options: { |
| 236 | modelID?: string; |
| 237 | providerID?: string; |
| 238 | agent?: string; |
| 239 | timeoutMs?: number; |
| 240 | } = {}, |
| 241 | ): Promise<unknown> { |
| 242 | // Default bumped from 30s → 180s. CI runners (GitHub-hosted ubuntu) |
| 243 | // can take 10-30s just for opencode serve to process a single prompt |
| 244 | // when historian/compressor work is involved. 180s leaves room for |
| 245 | // multi-step assistant turns while still catching genuinely stuck |
| 246 | // prompts. Individual tests can still pass a smaller timeoutMs. |
| 247 | const timeoutMs = options.timeoutMs ?? 180_000; |
| 248 | const promptPromise = this.client.session.prompt({ |
| 249 | path: { id: sessionId }, |
| 250 | body: { |
| 251 | model: { |
| 252 | providerID: options.providerID ?? "mock-anthropic", |
| 253 | modelID: options.modelID ?? "mock-sonnet", |
| 254 | }, |
| 255 | parts: [{ type: "text", text }], |
| 256 | ...(options.agent ? { agent: options.agent } : {}), |
| 257 | }, |
| 258 | }); |
| 259 | const timeout = new Promise<null>((r) => setTimeout(() => r(null), timeoutMs)); |
| 260 | const result = await Promise.race([promptPromise, timeout]); |
| 261 | if (result === null) { |
| 262 | throw new Error( |
| 263 | `sendPrompt did not complete within ${timeoutMs}ms. stderr:\n${this.opencode.stderr().slice(-2000)}`, |
| 264 | ); |
| 265 | } |
| 266 | return result; |
| 267 | } |
| 268 | |
| 269 | /** |
| 270 | * Open the magic-context SQLite database in read-only mode. |
no outgoing calls