@almyty/acp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/auth.test.d.ts +1 -0
- package/dist/__tests__/auth.test.js +29 -0
- package/dist/__tests__/events.test.d.ts +1 -0
- package/dist/__tests__/events.test.js +81 -0
- package/dist/__tests__/integration.test.d.ts +1 -0
- package/dist/__tests__/integration.test.js +144 -0
- package/dist/__tests__/session.test.d.ts +1 -0
- package/dist/__tests__/session.test.js +69 -0
- package/dist/agent.d.ts +85 -0
- package/dist/agent.js +527 -0
- package/dist/auth.d.ts +22 -0
- package/dist/auth.js +36 -0
- package/dist/events.d.ts +76 -0
- package/dist/events.js +247 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +205 -0
- package/dist/proxy.d.ts +78 -0
- package/dist/proxy.js +209 -0
- package/dist/session.d.ts +56 -0
- package/dist/session.js +77 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { resolveCredentials } from '../auth.js';
|
|
3
|
+
describe('resolveCredentials', () => {
|
|
4
|
+
const originalEnv = process.env;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
process.env = { ...originalEnv };
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
process.env = originalEnv;
|
|
10
|
+
vi.restoreAllMocks();
|
|
11
|
+
});
|
|
12
|
+
it('reads token from ALMYTY_TOKEN env var', () => {
|
|
13
|
+
process.env.ALMYTY_TOKEN = 'test-token-123';
|
|
14
|
+
const creds = resolveCredentials();
|
|
15
|
+
expect(creds).not.toBeNull();
|
|
16
|
+
expect(creds.token).toBe('test-token-123');
|
|
17
|
+
});
|
|
18
|
+
it('reads URL from ALMYTY_URL env var', () => {
|
|
19
|
+
process.env.ALMYTY_TOKEN = 'tok';
|
|
20
|
+
process.env.ALMYTY_URL = 'https://custom.api.com';
|
|
21
|
+
const creds = resolveCredentials();
|
|
22
|
+
expect(creds.url).toBe('https://custom.api.com');
|
|
23
|
+
});
|
|
24
|
+
it('prefers env var over credentials file', () => {
|
|
25
|
+
process.env.ALMYTY_TOKEN = 'env-token';
|
|
26
|
+
const creds = resolveCredentials();
|
|
27
|
+
expect(creds.token).toBe('env-token');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { mapStreamEvent, buildPlanFromPipeline, isTerminalEvent, extractFinalOutput } from '../events.js';
|
|
3
|
+
describe('mapStreamEvent', () => {
|
|
4
|
+
it('maps node.started to tool_call with running status', () => {
|
|
5
|
+
const results = mapStreamEvent({ event: 'node.started', data: { nodeId: 'n1', nodeType: 'tool_call', name: 'get_users' } });
|
|
6
|
+
expect(results.length).toBeGreaterThan(0);
|
|
7
|
+
const tc = results.find(r => r.type === 'tool_call');
|
|
8
|
+
expect(tc).toBeDefined();
|
|
9
|
+
expect(tc.status).toBe('running');
|
|
10
|
+
});
|
|
11
|
+
it('maps node.completed to tool_call_update', () => {
|
|
12
|
+
const results = mapStreamEvent({ event: 'node.completed', data: { nodeId: 'n1', output: { users: [] } } });
|
|
13
|
+
expect(results.length).toBeGreaterThan(0);
|
|
14
|
+
const update = results.find(r => r.type === 'tool_call_update');
|
|
15
|
+
expect(update).toBeDefined();
|
|
16
|
+
expect(update.status).toBe('completed');
|
|
17
|
+
});
|
|
18
|
+
it('maps node.error to tool_call_update with error', () => {
|
|
19
|
+
const results = mapStreamEvent({ event: 'node.error', data: { nodeId: 'n1', error: 'timeout' } });
|
|
20
|
+
expect(results.length).toBeGreaterThan(0);
|
|
21
|
+
const update = results.find(r => r.type === 'tool_call_update');
|
|
22
|
+
expect(update).toBeDefined();
|
|
23
|
+
expect(update.status).toBe('error');
|
|
24
|
+
});
|
|
25
|
+
it('maps text events to agent_message_chunk', () => {
|
|
26
|
+
for (const event of ['text', 'message', 'chunk', 'token']) {
|
|
27
|
+
const results = mapStreamEvent({ event, data: { text: 'hello' } });
|
|
28
|
+
expect(results.length).toBeGreaterThan(0);
|
|
29
|
+
expect(results[0].type).toBe('agent_message_chunk');
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
it('maps thinking events to agent_thought_chunk', () => {
|
|
33
|
+
const results = mapStreamEvent({ event: 'thinking', data: { text: 'hmm' } });
|
|
34
|
+
expect(results.length).toBeGreaterThan(0);
|
|
35
|
+
expect(results[0].type).toBe('agent_thought_chunk');
|
|
36
|
+
});
|
|
37
|
+
it('returns empty array for unknown events', () => {
|
|
38
|
+
expect(mapStreamEvent({ event: 'unknown_xyz', data: {} })).toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('buildPlanFromPipeline', () => {
|
|
42
|
+
it('converts pipeline nodes to plan entries (filters input/output)', () => {
|
|
43
|
+
const nodes = [
|
|
44
|
+
{ id: 'n1', type: 'input', data: {} },
|
|
45
|
+
{ id: 'n2', type: 'llm_call', data: {} },
|
|
46
|
+
{ id: 'n3', type: 'tool_call', data: { toolName: 'fetch' } },
|
|
47
|
+
{ id: 'n4', type: 'output', data: {} },
|
|
48
|
+
];
|
|
49
|
+
const plan = buildPlanFromPipeline(nodes);
|
|
50
|
+
expect(plan.type).toBe('plan');
|
|
51
|
+
// input + output filtered out, llm_call + tool_call remain
|
|
52
|
+
expect(plan.entries.length).toBe(2);
|
|
53
|
+
});
|
|
54
|
+
it('returns empty plan for empty pipeline', () => {
|
|
55
|
+
const plan = buildPlanFromPipeline([]);
|
|
56
|
+
expect(plan.entries).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('isTerminalEvent', () => {
|
|
60
|
+
it('recognizes terminal events', () => {
|
|
61
|
+
expect(isTerminalEvent({ event: 'execution.completed', data: {} })).toBe(true);
|
|
62
|
+
expect(isTerminalEvent({ event: 'execution.error', data: {} })).toBe(true);
|
|
63
|
+
expect(isTerminalEvent({ event: 'run.completed', data: {} })).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it('rejects non-terminal events', () => {
|
|
66
|
+
expect(isTerminalEvent({ event: 'text', data: {} })).toBe(false);
|
|
67
|
+
expect(isTerminalEvent({ event: 'node.started', data: {} })).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('extractFinalOutput', () => {
|
|
71
|
+
it('extracts text from output', () => {
|
|
72
|
+
expect(extractFinalOutput({ event: 'execution.completed', data: { output: 'result' } })).toBe('result');
|
|
73
|
+
});
|
|
74
|
+
it('stringifies object output', () => {
|
|
75
|
+
const result = extractFinalOutput({ event: 'execution.completed', data: { output: { key: 'val' } } });
|
|
76
|
+
expect(result).toContain('key');
|
|
77
|
+
});
|
|
78
|
+
it('returns undefined for missing output', () => {
|
|
79
|
+
expect(extractFinalOutput({ event: 'execution.completed', data: {} })).toBeUndefined();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test: spawn the ACP server as a child process,
|
|
3
|
+
* connect via stdin/stdout ndjson, run the full ACP lifecycle.
|
|
4
|
+
*
|
|
5
|
+
* Uses a mock HTTP server standing in for the almyty backend.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
9
|
+
import { createServer } from 'node:http';
|
|
10
|
+
import { createInterface } from 'node:readline';
|
|
11
|
+
import { resolve } from 'node:path';
|
|
12
|
+
// ── Mock backend ────────────────────────────────────────────────
|
|
13
|
+
const MOCK_AGENT = {
|
|
14
|
+
id: 'agent-123',
|
|
15
|
+
name: 'Test Agent',
|
|
16
|
+
description: 'A test agent',
|
|
17
|
+
mode: 'autonomous',
|
|
18
|
+
status: 'active',
|
|
19
|
+
pipeline: { nodes: [], edges: [] },
|
|
20
|
+
};
|
|
21
|
+
function createMockBackend() {
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
const server = createServer((req, res) => {
|
|
24
|
+
let body = '';
|
|
25
|
+
req.on('data', (chunk) => (body += chunk));
|
|
26
|
+
req.on('end', () => {
|
|
27
|
+
const url = req.url || '';
|
|
28
|
+
res.setHeader('Content-Type', 'application/json');
|
|
29
|
+
// Auth profile check
|
|
30
|
+
if (url === '/auth/profile') {
|
|
31
|
+
res.end(JSON.stringify({ id: 'user-1', email: 'test@test.com', organizations: [{ id: 'org-1', name: 'Test', role: 'owner' }] }));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// List agents
|
|
35
|
+
if (url.startsWith('/agents') && req.method === 'GET' && !url.includes('/')) {
|
|
36
|
+
res.end(JSON.stringify({ agents: [MOCK_AGENT] }));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Get agent by ID
|
|
40
|
+
if (url.match(/\/agents\/agent-123$/) && req.method === 'GET') {
|
|
41
|
+
res.end(JSON.stringify(MOCK_AGENT));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Start run
|
|
45
|
+
if (url.match(/\/agents\/agent-123\/runs$/) && req.method === 'POST') {
|
|
46
|
+
res.end(JSON.stringify({ id: 'run-1', status: 'completed', output: { message: 'Hello from the agent' } }));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Get run
|
|
50
|
+
if (url.match(/\/agents\/agent-123\/runs\/run-1$/) && req.method === 'GET') {
|
|
51
|
+
res.end(JSON.stringify({ id: 'run-1', status: 'completed', output: { message: 'Hello from the agent' } }));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Fallback
|
|
55
|
+
res.statusCode = 404;
|
|
56
|
+
res.end(JSON.stringify({ error: { message: 'Not found', statusCode: 404 } }));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
server.listen(0, '127.0.0.1', () => {
|
|
60
|
+
const addr = server.address();
|
|
61
|
+
resolve({ server, port: addr.port });
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// ── ndjson helpers ───────────────────────────────────────────────
|
|
66
|
+
function sendRequest(proc, method, params, id) {
|
|
67
|
+
const msg = JSON.stringify({ jsonrpc: '2.0', id: id ?? 1, method, params: params ?? {} });
|
|
68
|
+
proc.stdin.write(msg + '\n');
|
|
69
|
+
}
|
|
70
|
+
function readResponses(proc, count, timeoutMs = 10000) {
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
const results = [];
|
|
73
|
+
const rl = createInterface({ input: proc.stdout });
|
|
74
|
+
const timer = setTimeout(() => {
|
|
75
|
+
rl.close();
|
|
76
|
+
resolve(results); // return what we have
|
|
77
|
+
}, timeoutMs);
|
|
78
|
+
rl.on('line', (line) => {
|
|
79
|
+
try {
|
|
80
|
+
results.push(JSON.parse(line));
|
|
81
|
+
if (results.length >= count) {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
rl.close();
|
|
84
|
+
resolve(results);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// skip malformed lines
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// ── Tests ───────────────────────────────────────────────────────
|
|
94
|
+
describe('ACP server integration', () => {
|
|
95
|
+
let mockBackend;
|
|
96
|
+
let backendPort;
|
|
97
|
+
let proc;
|
|
98
|
+
beforeAll(async () => {
|
|
99
|
+
const backend = await createMockBackend();
|
|
100
|
+
mockBackend = backend.server;
|
|
101
|
+
backendPort = backend.port;
|
|
102
|
+
});
|
|
103
|
+
afterAll(() => {
|
|
104
|
+
proc?.kill('SIGTERM');
|
|
105
|
+
mockBackend?.close();
|
|
106
|
+
});
|
|
107
|
+
it('completes full lifecycle: initialize -> authenticate -> session/new -> session/prompt', async () => {
|
|
108
|
+
const entryPoint = resolve(__dirname, '../../dist/index.js');
|
|
109
|
+
proc = spawn('node', [entryPoint, 'agent-123'], {
|
|
110
|
+
env: {
|
|
111
|
+
...process.env,
|
|
112
|
+
ALMYTY_URL: `http://127.0.0.1:${backendPort}`,
|
|
113
|
+
ALMYTY_TOKEN: 'test-token',
|
|
114
|
+
},
|
|
115
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
116
|
+
});
|
|
117
|
+
// Give the process a moment to start
|
|
118
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
119
|
+
// 1. Initialize
|
|
120
|
+
sendRequest(proc, 'initialize', { protocolVersion: 1, clientCapabilities: {} }, 1);
|
|
121
|
+
const [initResp] = await readResponses(proc, 1, 5000);
|
|
122
|
+
expect(initResp.id).toBe(1);
|
|
123
|
+
expect(initResp.result).toBeDefined();
|
|
124
|
+
expect(initResp.result.protocolVersion).toBe(1);
|
|
125
|
+
// 2. Authenticate
|
|
126
|
+
sendRequest(proc, 'authenticate', { methodId: 'env_var' }, 2);
|
|
127
|
+
const [authResp] = await readResponses(proc, 1, 5000);
|
|
128
|
+
expect(authResp.id).toBe(2);
|
|
129
|
+
expect(authResp.error).toBeUndefined();
|
|
130
|
+
// 3. Session new
|
|
131
|
+
sendRequest(proc, 'session/new', { cwd: '/tmp' }, 3);
|
|
132
|
+
const [sessionResp] = await readResponses(proc, 1, 5000);
|
|
133
|
+
expect(sessionResp.id).toBe(3);
|
|
134
|
+
expect(sessionResp.result?.sessionId).toBeDefined();
|
|
135
|
+
const sessionId = sessionResp.result.sessionId;
|
|
136
|
+
// 4. Close session
|
|
137
|
+
sendRequest(proc, 'session/close', { sessionId }, 4);
|
|
138
|
+
const [closeResp] = await readResponses(proc, 1, 5000);
|
|
139
|
+
expect(closeResp.id).toBe(4);
|
|
140
|
+
expect(closeResp.error).toBeUndefined();
|
|
141
|
+
// Clean up
|
|
142
|
+
proc.kill('SIGTERM');
|
|
143
|
+
}, 30000);
|
|
144
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { SessionManager } from '../session.js';
|
|
3
|
+
describe('SessionManager', () => {
|
|
4
|
+
let mgr;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
mgr = new SessionManager();
|
|
7
|
+
});
|
|
8
|
+
it('creates a session with a UUID', () => {
|
|
9
|
+
const s = mgr.create('agent-1', 'workflow');
|
|
10
|
+
expect(s.id).toMatch(/^[0-9a-f]{8}-/);
|
|
11
|
+
expect(s.agentId).toBe('agent-1');
|
|
12
|
+
expect(s.mode).toBe('workflow');
|
|
13
|
+
expect(s.lastActivity).toBeGreaterThan(0);
|
|
14
|
+
});
|
|
15
|
+
it('retrieves a session by ID', () => {
|
|
16
|
+
const s = mgr.create('agent-1', 'autonomous');
|
|
17
|
+
expect(mgr.get(s.id)).toBe(s);
|
|
18
|
+
});
|
|
19
|
+
it('returns undefined for unknown session', () => {
|
|
20
|
+
expect(mgr.get('nonexistent')).toBeUndefined();
|
|
21
|
+
});
|
|
22
|
+
it('lists all sessions', () => {
|
|
23
|
+
mgr.create('a1', 'workflow');
|
|
24
|
+
mgr.create('a2', 'autonomous');
|
|
25
|
+
expect(mgr.list()).toHaveLength(2);
|
|
26
|
+
});
|
|
27
|
+
it('updates session fields', () => {
|
|
28
|
+
const s = mgr.create('a1', 'autonomous');
|
|
29
|
+
mgr.update(s.id, { conversationId: 'conv-1', activeRunId: 'run-1' });
|
|
30
|
+
const updated = mgr.get(s.id);
|
|
31
|
+
expect(updated.conversationId).toBe('conv-1');
|
|
32
|
+
expect(updated.activeRunId).toBe('run-1');
|
|
33
|
+
});
|
|
34
|
+
it('cancel aborts the controller and clears activeRunId', () => {
|
|
35
|
+
const s = mgr.create('a1', 'autonomous');
|
|
36
|
+
const ac = new AbortController();
|
|
37
|
+
mgr.update(s.id, { abortController: ac, activeRunId: 'run-1' });
|
|
38
|
+
mgr.cancel(s.id);
|
|
39
|
+
expect(ac.signal.aborted).toBe(true);
|
|
40
|
+
expect(mgr.get(s.id).activeRunId).toBeUndefined();
|
|
41
|
+
});
|
|
42
|
+
it('close removes the session', () => {
|
|
43
|
+
const s = mgr.create('a1', 'workflow');
|
|
44
|
+
expect(mgr.close(s.id)).toBe(true);
|
|
45
|
+
expect(mgr.get(s.id)).toBeUndefined();
|
|
46
|
+
expect(mgr.close(s.id)).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
it('closeAll aborts all and clears', () => {
|
|
49
|
+
const ac1 = new AbortController();
|
|
50
|
+
const ac2 = new AbortController();
|
|
51
|
+
const s1 = mgr.create('a1', 'workflow');
|
|
52
|
+
const s2 = mgr.create('a2', 'autonomous');
|
|
53
|
+
mgr.update(s1.id, { abortController: ac1 });
|
|
54
|
+
mgr.update(s2.id, { abortController: ac2 });
|
|
55
|
+
mgr.closeAll();
|
|
56
|
+
expect(ac1.signal.aborted).toBe(true);
|
|
57
|
+
expect(ac2.signal.aborted).toBe(true);
|
|
58
|
+
expect(mgr.list()).toHaveLength(0);
|
|
59
|
+
});
|
|
60
|
+
it('handles concurrent sessions for different agents', () => {
|
|
61
|
+
const s1 = mgr.create('agent-a', 'workflow');
|
|
62
|
+
const s2 = mgr.create('agent-b', 'autonomous');
|
|
63
|
+
const s3 = mgr.create('agent-a', 'autonomous');
|
|
64
|
+
expect(mgr.list()).toHaveLength(3);
|
|
65
|
+
expect(mgr.get(s1.id).agentId).toBe('agent-a');
|
|
66
|
+
expect(mgr.get(s2.id).agentId).toBe('agent-b');
|
|
67
|
+
expect(mgr.get(s3.id).agentId).toBe('agent-a');
|
|
68
|
+
});
|
|
69
|
+
});
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlmytyAcpAgent: handles all ACP JSON-RPC methods.
|
|
3
|
+
*
|
|
4
|
+
* Bridges the ACP protocol to the almyty backend REST API. Manages
|
|
5
|
+
* session lifecycle, dispatches prompts to the correct execution engine,
|
|
6
|
+
* and streams SessionUpdate notifications back to the client.
|
|
7
|
+
*/
|
|
8
|
+
import type { AlmytyProxy } from './proxy.js';
|
|
9
|
+
/** JSON-RPC 2.0 request. */
|
|
10
|
+
export interface JsonRpcRequest {
|
|
11
|
+
jsonrpc: '2.0';
|
|
12
|
+
id?: string | number;
|
|
13
|
+
method: string;
|
|
14
|
+
params?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/** JSON-RPC 2.0 response. */
|
|
17
|
+
export interface JsonRpcResponse {
|
|
18
|
+
jsonrpc: '2.0';
|
|
19
|
+
id: string | number | null;
|
|
20
|
+
result?: unknown;
|
|
21
|
+
error?: {
|
|
22
|
+
code: number;
|
|
23
|
+
message: string;
|
|
24
|
+
data?: unknown;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** JSON-RPC 2.0 notification (no id). */
|
|
28
|
+
export interface JsonRpcNotification {
|
|
29
|
+
jsonrpc: '2.0';
|
|
30
|
+
method: string;
|
|
31
|
+
params?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
type JsonRpcMessage = JsonRpcResponse | JsonRpcNotification;
|
|
34
|
+
/** Callback for sending messages to the ACP client. */
|
|
35
|
+
export type SendFn = (msg: JsonRpcMessage) => void;
|
|
36
|
+
export declare class AlmytyAcpAgent {
|
|
37
|
+
private readonly proxy;
|
|
38
|
+
private readonly sessions;
|
|
39
|
+
private readonly agentId;
|
|
40
|
+
private send;
|
|
41
|
+
private agentInfo;
|
|
42
|
+
private authenticated;
|
|
43
|
+
constructor(proxy: AlmytyProxy, agentId: string, send: SendFn);
|
|
44
|
+
/**
|
|
45
|
+
* Update the send function (used if transport is re-initialized).
|
|
46
|
+
*/
|
|
47
|
+
setSend(send: SendFn): void;
|
|
48
|
+
/**
|
|
49
|
+
* Handle an incoming JSON-RPC message from the ACP client.
|
|
50
|
+
*/
|
|
51
|
+
handleMessage(msg: JsonRpcRequest): Promise<void>;
|
|
52
|
+
private handleInitialize;
|
|
53
|
+
private handleAuthenticate;
|
|
54
|
+
private handleSessionNew;
|
|
55
|
+
private handleSessionList;
|
|
56
|
+
private handleSessionLoad;
|
|
57
|
+
private handleSessionPrompt;
|
|
58
|
+
/**
|
|
59
|
+
* Handle a prompt for a workflow agent: POST /agents/:id/stream.
|
|
60
|
+
* Streams events via SSE and maps them to ACP session updates.
|
|
61
|
+
*/
|
|
62
|
+
private handleWorkflowPrompt;
|
|
63
|
+
/**
|
|
64
|
+
* Handle a prompt for an autonomous agent: start or continue a run.
|
|
65
|
+
* If the session has no active conversation, starts a new run.
|
|
66
|
+
* If the agent is waiting for input, sends input to the existing run.
|
|
67
|
+
*/
|
|
68
|
+
private handleAutonomousPrompt;
|
|
69
|
+
/**
|
|
70
|
+
* Poll a run until it reaches a terminal state or the signal is aborted.
|
|
71
|
+
*/
|
|
72
|
+
private pollRunToCompletion;
|
|
73
|
+
private handleSessionCancel;
|
|
74
|
+
private handleSessionSetMode;
|
|
75
|
+
private handleSessionClose;
|
|
76
|
+
private sendResult;
|
|
77
|
+
private sendError;
|
|
78
|
+
private sendNotification;
|
|
79
|
+
private sendSessionUpdate;
|
|
80
|
+
/**
|
|
81
|
+
* Clean up all sessions. Called during shutdown.
|
|
82
|
+
*/
|
|
83
|
+
shutdown(): void;
|
|
84
|
+
}
|
|
85
|
+
export {};
|