* 与 Agent 对话(流式) * @param agentId Agent ID * @param request Chat 请求 * @returns AsyncIterable 流式事件
(agentId: string, request: ChatRequest)
| 138 | * @returns AsyncIterable 流式事件 |
| 139 | */ |
| 140 | async *chatStream(agentId: string, request: ChatRequest): AsyncIterable<StreamChatEvent> { |
| 141 | const response = await fetch(`${this.options.baseUrl}/v1/agents/${agentId}/chat/stream`, { |
| 142 | method: "POST", |
| 143 | headers: { |
| 144 | "Content-Type": "application/json", |
| 145 | ...(this.options.apiKey && { |
| 146 | Authorization: `Bearer ${this.options.apiKey}`, |
| 147 | }), |
| 148 | }, |
| 149 | body: JSON.stringify(request), |
| 150 | }); |
| 151 | |
| 152 | if (!response.ok) { |
| 153 | throw new Error(`Chat stream failed: ${response.statusText}`); |
| 154 | } |
| 155 | |
| 156 | const reader = response.body?.getReader(); |
| 157 | if (!reader) { |
| 158 | throw new Error("Response body is not readable"); |
| 159 | } |
| 160 | |
| 161 | const decoder = new TextDecoder(); |
| 162 | let buffer = ""; |
| 163 | |
| 164 | try { |
| 165 | while (true) { |
| 166 | const { done, value } = await reader.read(); |
| 167 | if (done) break; |
| 168 | |
| 169 | buffer += decoder.decode(value, { stream: true }); |
| 170 | const lines = buffer.split("\n"); |
| 171 | buffer = lines.pop() || ""; |
| 172 | |
| 173 | for (const line of lines) { |
| 174 | if (line.startsWith("data: ")) { |
| 175 | const data = line.slice(6); |
| 176 | if (data === "[DONE]") { |
| 177 | return; |
| 178 | } |
| 179 | try { |
| 180 | const event = JSON.parse(data) as StreamChatEvent; |
| 181 | yield event; |
| 182 | } catch (error) { |
| 183 | console.error("Failed to parse SSE data:", data); |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | } finally { |
| 189 | reader.releaseLock(); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // ========================================================================== |
| 194 | // Agent Templates |