()
| 47 | const requestIdMap = new Map<string, { serverId: string; abortController: AbortController }>() |
| 48 | |
| 49 | export function useAgentStreamService() { |
| 50 | return { |
| 51 | runStream( |
| 52 | params: AgentStreamParams, |
| 53 | onChunk?: (chunk: AgentStreamChunk) => void |
| 54 | ): { requestId: string; promise: Promise<AgentStreamResult> } { |
| 55 | const abortController = new AbortController() |
| 56 | const localRequestId = `local_${Date.now()}_${Math.random().toString(36).slice(2, 8)}` |
| 57 | requestIdMap.set(localRequestId, { serverId: '', abortController }) |
| 58 | |
| 59 | const promise = new Promise<AgentStreamResult>((resolve) => { |
| 60 | let resultContent = '' |
| 61 | const toolsUsed: string[] = [] |
| 62 | let toolRounds = 0 |
| 63 | let lastUsage: import('./types').TokenUsage | undefined |
| 64 | let hasError = false |
| 65 | let lastError: AgentStreamResult['error'] |
| 66 | |
| 67 | fetchSSE({ |
| 68 | url: '/_web/ai/agent/stream', |
| 69 | body: params, |
| 70 | signal: abortController.signal, |
| 71 | onEvent: ({ event, data }) => { |
| 72 | try { |
| 73 | const parsed = JSON.parse(data) |
| 74 | |
| 75 | if (event === 'meta') { |
| 76 | const entry = requestIdMap.get(localRequestId) |
| 77 | if (entry) entry.serverId = parsed.requestId ?? '' |
| 78 | return |
| 79 | } |
| 80 | |
| 81 | const chunk = parsed as AgentStreamChunk |
| 82 | onChunk?.(chunk) |
| 83 | |
| 84 | switch (chunk.type) { |
| 85 | case 'content': |
| 86 | if (chunk.content) resultContent += chunk.content |
| 87 | break |
| 88 | case 'tool_start': |
| 89 | if (chunk.toolName) toolsUsed.push(chunk.toolName) |
| 90 | break |
| 91 | case 'status': |
| 92 | if (chunk.status) toolRounds = chunk.status.round |
| 93 | break |
| 94 | case 'done': |
| 95 | if (chunk.usage) lastUsage = chunk.usage |
| 96 | break |
| 97 | case 'error': |
| 98 | hasError = true |
| 99 | lastError = chunk.error as AgentStreamResult['error'] |
| 100 | break |
| 101 | } |
| 102 | } catch { |
| 103 | // skip malformed JSON |
| 104 | } |
| 105 | }, |
| 106 | }) |
no outgoing calls
no test coverage detected