|
| 1 | +import { mkdir, open, stat } from 'node:fs/promises'; |
| 2 | +import path from 'node:path'; |
| 3 | + |
1 | 4 | const BASE_URL = process.env.ACP_BASE_URL ?? 'http://localhost:8000'; |
2 | 5 | const token = process.env.ACP_TOKEN; |
| 6 | +const STREAM_DIR = '/tmp/headless-coder-sdk'; |
3 | 7 |
|
4 | 8 | function buildHeaders(): HeadersInit { |
5 | | - if (!token) return {}; |
6 | | - return { Authorization: `Bearer ${token}` }; |
| 9 | + const headers: Record<string, string> = { 'Content-Type': 'application/json' }; |
| 10 | + if (token) headers.Authorization = `Bearer ${token}`; |
| 11 | + return headers; |
| 12 | +} |
| 13 | + |
| 14 | +function assert(condition: unknown, message: string): asserts condition { |
| 15 | + if (!condition) { |
| 16 | + throw new Error(message); |
| 17 | + } |
7 | 18 | } |
8 | 19 |
|
9 | | -async function assert(cond: unknown, message: string): Promise<void> { |
10 | | - if (!cond) throw new Error(message); |
| 20 | +async function listAgents() { |
| 21 | + const res = await fetch(`${BASE_URL}/api/acp/agents`, { headers: buildHeaders() }); |
| 22 | + assert(res.ok, `Failed to fetch agents: ${res.status}`); |
| 23 | + const payload = (await res.json()) as { agents: Array<{ id: string }> }; |
| 24 | + assert(payload.agents.length > 0, 'No agents returned'); |
| 25 | + console.log(`ACP client: discovered ${payload.agents.length} agent(s).`); |
| 26 | + return payload.agents[0].id; |
11 | 27 | } |
12 | 28 |
|
13 | | -async function testAgentsEndpoint(): Promise<void> { |
14 | | - const res = await fetch(`${BASE_URL}/api/acp/agents`, { |
| 29 | +async function createSession(provider: string) { |
| 30 | + const res = await fetch(`${BASE_URL}/api/acp/sessions`, { |
| 31 | + method: 'POST', |
15 | 32 | headers: buildHeaders(), |
| 33 | + body: JSON.stringify({ provider }), |
16 | 34 | }); |
17 | | - await assert(res.ok, `Failed to fetch agents: ${res.status}`); |
18 | | - const data = (await res.json()) as { agents: Array<{ id: string }> }; |
19 | | - await assert(Array.isArray(data.agents) && data.agents.length > 0, 'No agents returned'); |
20 | | - console.log(`ACP client: discovered ${data.agents.length} agent(s).`); |
| 35 | + assert(res.ok, `Failed to create session: ${res.status}`); |
| 36 | + const body = (await res.json()) as { sessionId: string }; |
| 37 | + assert(body.sessionId, 'Missing sessionId'); |
| 38 | + return body.sessionId; |
| 39 | +} |
| 40 | + |
| 41 | +async function streamMessage(sessionId: string): Promise<string> { |
| 42 | + await mkdir(STREAM_DIR, { recursive: true }); |
| 43 | + const outPath = path.join(STREAM_DIR, `stream-${Date.now()}.ndjson`); |
| 44 | + const schema = { |
| 45 | + type: 'object', |
| 46 | + properties: { |
| 47 | + summary: { type: 'string' }, |
| 48 | + risks: { type: 'array', items: { type: 'string' }, minItems: 1 }, |
| 49 | + }, |
| 50 | + required: ['summary', 'risks'], |
| 51 | + } as const; |
| 52 | + |
| 53 | + const response = await fetch(`${BASE_URL}/api/acp/messages?stream=true`, { |
| 54 | + method: 'POST', |
| 55 | + headers: buildHeaders(), |
| 56 | + body: JSON.stringify({ |
| 57 | + sessionId, |
| 58 | + content: 'Review the repository and return a JSON summary plus key risks.', |
| 59 | + outputSchema: schema, |
| 60 | + }), |
| 61 | + }); |
| 62 | + assert(response.ok && response.body, `Streaming request failed: ${response.status}`); |
| 63 | + |
| 64 | + const reader = response.body.getReader(); |
| 65 | + const decoder = new TextDecoder(); |
| 66 | + const file = await open(outPath, 'w'); |
| 67 | + |
| 68 | + try { |
| 69 | + while (true) { |
| 70 | + const { done, value } = await reader.read(); |
| 71 | + if (done) break; |
| 72 | + await file.write(decoder.decode(value)); |
| 73 | + } |
| 74 | + } finally { |
| 75 | + await file.close(); |
| 76 | + } |
| 77 | + |
| 78 | + const info = await stat(outPath); |
| 79 | + assert(info.size > 0, 'Stream file is empty'); |
| 80 | + console.log(`ACP client: streamed frames saved to ${outPath}`); |
| 81 | + return outPath; |
21 | 82 | } |
22 | 83 |
|
23 | 84 | async function main(): Promise<void> { |
24 | | - await testAgentsEndpoint(); |
| 85 | + const provider = await listAgents(); |
| 86 | + const sessionId = await createSession(provider); |
| 87 | + await streamMessage(sessionId); |
25 | 88 | console.log('ACP client tests passed'); |
26 | 89 | } |
27 | 90 |
|
|
0 commit comments