(controller)
| 136 | |
| 137 | const stream = new ReadableStream({ |
| 138 | async start(controller) { |
| 139 | let closed = false; |
| 140 | const safeEnqueue = (chunk: Uint8Array) => { |
| 141 | if (closed) return; |
| 142 | try { |
| 143 | controller.enqueue(chunk); |
| 144 | } catch { |
| 145 | // controller 已关闭——忽略 |
| 146 | closed = true; |
| 147 | } |
| 148 | }; |
| 149 | // 整段逻辑跑在 workspaceContext 作用域内:root_index 预热 + runAgent 深处的所有 |
| 150 | // executeTool 都会读到 workspace,并在调 web 时带上 kb_workspace cookie。 |
| 151 | await workspaceContext.run(workspace, async () => { |
| 152 | try { |
| 153 | const baseSystem = system || DEFAULT_SYSTEM_PROMPT; |
| 154 | const indexContent = await getRootIndexContent(workspace); |
| 155 | const augmentedSystem = appendPrewarmedIndex(baseSystem, indexContent); |
| 156 | |
| 157 | for await (const evt of runAgent({ |
| 158 | provider, |
| 159 | model, |
| 160 | system: augmentedSystem, |
| 161 | messages, |
| 162 | toolBudget: tool_budget, |
| 163 | mode, |
| 164 | signal: abortController.signal, |
| 165 | })) { |
| 166 | if (abortController.signal.aborted) break; |
| 167 | safeEnqueue(sseLine(evt)); |
| 168 | } |
| 169 | safeEnqueue(sseLine({ kind: "stream-end" })); |
| 170 | } catch (e) { |
| 171 | safeEnqueue( |
| 172 | sseLine({ |
| 173 | kind: "turn-end", |
| 174 | reason: "error", |
| 175 | error_message: e instanceof Error ? e.message : String(e), |
| 176 | }), |
| 177 | ); |
| 178 | } finally { |
| 179 | closed = true; |
| 180 | try { |
| 181 | controller.close(); |
| 182 | } catch { |
| 183 | /* 已关闭 */ |
| 184 | } |
| 185 | } |
| 186 | }); |
| 187 | }, |
| 188 | cancel() { |
| 189 | // 客户端拉断 stream(fetch abort)→ 转发到 agent-loop |
| 190 | abortController.abort(); |
nothing calls this directly
no test coverage detected