( conversationId: string, body: Record<string, unknown>, opts?: SendOptions )
| 88 | } |
| 89 | |
| 90 | async function* streamRequest( |
| 91 | conversationId: string, |
| 92 | body: Record<string, unknown>, |
| 93 | opts?: SendOptions |
| 94 | ): AsyncGenerator<StreamEvent> { |
| 95 | // Cancel any existing stream for this conversation |
| 96 | activeControllers.get(conversationId)?.abort(); |
| 97 | const controller = new AbortController(); |
| 98 | activeControllers.set(conversationId, controller); |
| 99 | |
| 100 | const signal = combineSignals(opts?.signal, controller.signal); |
| 101 | |
| 102 | try { |
| 103 | const res = await apiClient.postStream("/api/chat", body, { signal }); |
| 104 | yield* parseStream(res, { signal, onProgress: opts?.onProgress }); |
| 105 | } catch (err) { |
| 106 | if (err instanceof ApiError && err.type === "abort") return; // stop() was called |
| 107 | throw err; |
| 108 | } finally { |
| 109 | if (activeControllers.get(conversationId) === controller) { |
| 110 | activeControllers.delete(conversationId); |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | export const messageAPI: MessageAPI = { |
| 116 | async *send(conversationId, content, history, opts) { |
no test coverage detected