@awcp/sdk 0.0.0-dev-202601301521 → 0.0.0-dev-202601310829
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/delegator/bin/daemon.d.ts +0 -53
- package/dist/delegator/bin/daemon.d.ts.map +1 -1
- package/dist/delegator/bin/daemon.js +0 -95
- package/dist/delegator/bin/daemon.js.map +1 -1
- package/dist/delegator/executor-client.d.ts +6 -13
- package/dist/delegator/executor-client.d.ts.map +1 -1
- package/dist/delegator/executor-client.js +52 -14
- package/dist/delegator/executor-client.js.map +1 -1
- package/dist/delegator/service.d.ts +6 -2
- package/dist/delegator/service.d.ts.map +1 -1
- package/dist/delegator/service.js +85 -8
- package/dist/delegator/service.js.map +1 -1
- package/dist/executor/index.d.ts +0 -1
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +0 -1
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/service.d.ts +7 -3
- package/dist/executor/service.d.ts.map +1 -1
- package/dist/executor/service.js +77 -34
- package/dist/executor/service.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/express/awcp-delegator-handler.d.ts +0 -41
- package/dist/server/express/awcp-delegator-handler.d.ts.map +1 -1
- package/dist/server/express/awcp-delegator-handler.js +0 -49
- package/dist/server/express/awcp-delegator-handler.js.map +1 -1
- package/dist/server/express/awcp-executor-handler.d.ts +0 -27
- package/dist/server/express/awcp-executor-handler.d.ts.map +1 -1
- package/dist/server/express/awcp-executor-handler.js +23 -38
- package/dist/server/express/awcp-executor-handler.js.map +1 -1
- package/package.json +6 -2
- package/dist/executor/delegator-client.d.ts +0 -18
- package/dist/executor/delegator-client.d.ts.map +0 -1
- package/dist/executor/delegator-client.js +0 -37
- package/dist/executor/delegator-client.js.map +0 -1
|
@@ -3,13 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Runs the Delegator as an independent daemon process that can be accessed
|
|
5
5
|
* by multiple clients (MCP, CLI, HTTP API, etc.)
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* npx delegator-daemon --port 3100 --config delegator.json
|
|
9
|
-
*
|
|
10
|
-
* Or programmatically:
|
|
11
|
-
* import { startDelegatorDaemon } from '@awcp/sdk/delegator/bin/daemon';
|
|
12
|
-
* await startDelegatorDaemon({ port: 3100, config: myConfig });
|
|
13
6
|
*/
|
|
14
7
|
import { DelegatorService } from '../service.js';
|
|
15
8
|
import type { DelegatorConfig } from '../config.js';
|
|
@@ -17,66 +10,20 @@ import type { DelegatorConfig } from '../config.js';
|
|
|
17
10
|
* Daemon configuration
|
|
18
11
|
*/
|
|
19
12
|
export interface DaemonConfig {
|
|
20
|
-
/** Port to listen on (default: 3100) */
|
|
21
13
|
port?: number;
|
|
22
|
-
/** Host to bind to (default: 'localhost') */
|
|
23
14
|
host?: string;
|
|
24
|
-
/** Delegator configuration */
|
|
25
15
|
delegator: DelegatorConfig;
|
|
26
16
|
}
|
|
27
17
|
/**
|
|
28
18
|
* Running daemon instance
|
|
29
19
|
*/
|
|
30
20
|
export interface DaemonInstance {
|
|
31
|
-
/** Stop the daemon */
|
|
32
21
|
stop: () => Promise<void>;
|
|
33
|
-
/** Get the service instance */
|
|
34
22
|
service: DelegatorService;
|
|
35
|
-
/** Get the base URL */
|
|
36
23
|
url: string;
|
|
37
24
|
}
|
|
38
25
|
/**
|
|
39
26
|
* Start the Delegator Daemon
|
|
40
|
-
*
|
|
41
|
-
* This starts an HTTP server that provides:
|
|
42
|
-
* - POST /delegate - Create a new delegation
|
|
43
|
-
* - GET /delegations - List all delegations
|
|
44
|
-
* - GET /delegation/:id - Get delegation status
|
|
45
|
-
* - DELETE /delegation/:id - Cancel a delegation
|
|
46
|
-
* - POST /callback - Receive messages from Executor
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* import { SshfsTransport } from '@awcp/transport-sshfs';
|
|
51
|
-
*
|
|
52
|
-
* const daemon = await startDelegatorDaemon({
|
|
53
|
-
* port: 3100,
|
|
54
|
-
* delegator: {
|
|
55
|
-
* export: { baseDir: '/tmp/awcp/exports' },
|
|
56
|
-
* transport: new SshfsTransport({
|
|
57
|
-
* delegator: {
|
|
58
|
-
* host: 'localhost',
|
|
59
|
-
* user: process.env.USER,
|
|
60
|
-
* caKeyPath: '~/.awcp/ca',
|
|
61
|
-
* },
|
|
62
|
-
* }),
|
|
63
|
-
* },
|
|
64
|
-
* });
|
|
65
|
-
*
|
|
66
|
-
* // Create delegation via HTTP
|
|
67
|
-
* const response = await fetch('http://localhost:3100/delegate', {
|
|
68
|
-
* method: 'POST',
|
|
69
|
-
* headers: { 'Content-Type': 'application/json' },
|
|
70
|
-
* body: JSON.stringify({
|
|
71
|
-
* executorUrl: 'http://executor:4001/awcp',
|
|
72
|
-
* localDir: '/path/to/project',
|
|
73
|
-
* task: { description: 'Fix bug', prompt: '...' },
|
|
74
|
-
* }),
|
|
75
|
-
* });
|
|
76
|
-
*
|
|
77
|
-
* // Stop daemon
|
|
78
|
-
* await daemon.stop();
|
|
79
|
-
* ```
|
|
80
27
|
*/
|
|
81
28
|
export declare function startDelegatorDaemon(config: DaemonConfig): Promise<DaemonInstance>;
|
|
82
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/delegator/bin/daemon.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/delegator/bin/daemon.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAgC,MAAM,eAAe,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAoHxF;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAyC1C"}
|
|
@@ -3,13 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Runs the Delegator as an independent daemon process that can be accessed
|
|
5
5
|
* by multiple clients (MCP, CLI, HTTP API, etc.)
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* npx delegator-daemon --port 3100 --config delegator.json
|
|
9
|
-
*
|
|
10
|
-
* Or programmatically:
|
|
11
|
-
* import { startDelegatorDaemon } from '@awcp/sdk/delegator/bin/daemon';
|
|
12
|
-
* await startDelegatorDaemon({ port: 3100, config: myConfig });
|
|
13
6
|
*/
|
|
14
7
|
import { createServer } from 'node:http';
|
|
15
8
|
import express, { json } from 'express';
|
|
@@ -17,46 +10,6 @@ import { DelegatorService } from '../service.js';
|
|
|
17
10
|
import { AwcpError } from '@awcp/core';
|
|
18
11
|
/**
|
|
19
12
|
* Start the Delegator Daemon
|
|
20
|
-
*
|
|
21
|
-
* This starts an HTTP server that provides:
|
|
22
|
-
* - POST /delegate - Create a new delegation
|
|
23
|
-
* - GET /delegations - List all delegations
|
|
24
|
-
* - GET /delegation/:id - Get delegation status
|
|
25
|
-
* - DELETE /delegation/:id - Cancel a delegation
|
|
26
|
-
* - POST /callback - Receive messages from Executor
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```typescript
|
|
30
|
-
* import { SshfsTransport } from '@awcp/transport-sshfs';
|
|
31
|
-
*
|
|
32
|
-
* const daemon = await startDelegatorDaemon({
|
|
33
|
-
* port: 3100,
|
|
34
|
-
* delegator: {
|
|
35
|
-
* export: { baseDir: '/tmp/awcp/exports' },
|
|
36
|
-
* transport: new SshfsTransport({
|
|
37
|
-
* delegator: {
|
|
38
|
-
* host: 'localhost',
|
|
39
|
-
* user: process.env.USER,
|
|
40
|
-
* caKeyPath: '~/.awcp/ca',
|
|
41
|
-
* },
|
|
42
|
-
* }),
|
|
43
|
-
* },
|
|
44
|
-
* });
|
|
45
|
-
*
|
|
46
|
-
* // Create delegation via HTTP
|
|
47
|
-
* const response = await fetch('http://localhost:3100/delegate', {
|
|
48
|
-
* method: 'POST',
|
|
49
|
-
* headers: { 'Content-Type': 'application/json' },
|
|
50
|
-
* body: JSON.stringify({
|
|
51
|
-
* executorUrl: 'http://executor:4001/awcp',
|
|
52
|
-
* localDir: '/path/to/project',
|
|
53
|
-
* task: { description: 'Fix bug', prompt: '...' },
|
|
54
|
-
* }),
|
|
55
|
-
* });
|
|
56
|
-
*
|
|
57
|
-
* // Stop daemon
|
|
58
|
-
* await daemon.stop();
|
|
59
|
-
* ```
|
|
60
13
|
*/
|
|
61
14
|
export async function startDelegatorDaemon(config) {
|
|
62
15
|
const port = config.port ?? 3100;
|
|
@@ -64,29 +17,12 @@ export async function startDelegatorDaemon(config) {
|
|
|
64
17
|
const baseUrl = `http://${host}:${port}`;
|
|
65
18
|
const app = express();
|
|
66
19
|
app.use(json());
|
|
67
|
-
// Create service with callback URL pointing to this daemon
|
|
68
20
|
const serviceOptions = {
|
|
69
21
|
config: config.delegator,
|
|
70
|
-
callbackUrl: `${baseUrl}/callback`,
|
|
71
22
|
};
|
|
72
23
|
const service = new DelegatorService(serviceOptions);
|
|
73
|
-
// ============================================
|
|
74
|
-
// API Routes
|
|
75
|
-
// ============================================
|
|
76
24
|
/**
|
|
77
25
|
* POST /delegate - Create a new delegation
|
|
78
|
-
*
|
|
79
|
-
* Body:
|
|
80
|
-
* {
|
|
81
|
-
* executorUrl: string,
|
|
82
|
-
* localDir: string,
|
|
83
|
-
* task: { description: string, prompt: string },
|
|
84
|
-
* ttlSeconds?: number,
|
|
85
|
-
* accessMode?: 'ro' | 'rw'
|
|
86
|
-
* }
|
|
87
|
-
*
|
|
88
|
-
* Response:
|
|
89
|
-
* { delegationId: string }
|
|
90
26
|
*/
|
|
91
27
|
app.post('/delegate', async (req, res) => {
|
|
92
28
|
try {
|
|
@@ -153,30 +89,12 @@ export async function startDelegatorDaemon(config) {
|
|
|
153
89
|
});
|
|
154
90
|
}
|
|
155
91
|
});
|
|
156
|
-
/**
|
|
157
|
-
* POST /callback - Receive messages from Executor
|
|
158
|
-
*
|
|
159
|
-
* This endpoint receives ACCEPT, DONE, and ERROR messages from Executors.
|
|
160
|
-
*/
|
|
161
|
-
app.post('/callback', async (req, res) => {
|
|
162
|
-
try {
|
|
163
|
-
await service.handleMessage(req.body);
|
|
164
|
-
res.json({ ok: true });
|
|
165
|
-
}
|
|
166
|
-
catch (error) {
|
|
167
|
-
console.error('[Delegator Daemon] Error handling callback:', error);
|
|
168
|
-
res.status(500).json({
|
|
169
|
-
error: error instanceof Error ? error.message : 'Internal error',
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
92
|
/**
|
|
174
93
|
* GET /health - Health check
|
|
175
94
|
*/
|
|
176
95
|
app.get('/health', (_req, res) => {
|
|
177
96
|
res.json({ status: 'ok' });
|
|
178
97
|
});
|
|
179
|
-
// Start server
|
|
180
98
|
const server = createServer(app);
|
|
181
99
|
await new Promise((resolve, reject) => {
|
|
182
100
|
server.listen(port, host, () => {
|
|
@@ -205,7 +123,6 @@ export async function startDelegatorDaemon(config) {
|
|
|
205
123
|
* CLI entry point
|
|
206
124
|
*/
|
|
207
125
|
export async function main() {
|
|
208
|
-
// Parse command line arguments
|
|
209
126
|
const args = process.argv.slice(2);
|
|
210
127
|
let port = 3100;
|
|
211
128
|
let configPath;
|
|
@@ -221,27 +138,15 @@ export async function main() {
|
|
|
221
138
|
}
|
|
222
139
|
if (!configPath) {
|
|
223
140
|
console.error('Usage: delegator-daemon --port 3100 --config <config.ts>');
|
|
224
|
-
console.error('');
|
|
225
|
-
console.error('Config file should export a DelegatorConfig:');
|
|
226
|
-
console.error('');
|
|
227
|
-
console.error(" import { SshfsTransport } from '@awcp/transport-sshfs';");
|
|
228
|
-
console.error('');
|
|
229
|
-
console.error(' export default {');
|
|
230
|
-
console.error(" export: { baseDir: '/tmp/awcp/exports' },");
|
|
231
|
-
console.error(' transport: new SshfsTransport({ delegator: { ... } }),');
|
|
232
|
-
console.error(' };');
|
|
233
141
|
process.exit(1);
|
|
234
142
|
}
|
|
235
|
-
// Load config
|
|
236
143
|
const fs = await import('node:fs/promises');
|
|
237
144
|
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
238
145
|
const delegatorConfig = JSON.parse(configContent);
|
|
239
|
-
// Start daemon
|
|
240
146
|
const daemon = await startDelegatorDaemon({
|
|
241
147
|
port,
|
|
242
148
|
delegator: delegatorConfig,
|
|
243
149
|
});
|
|
244
|
-
// Handle shutdown
|
|
245
150
|
process.on('SIGINT', async () => {
|
|
246
151
|
console.log('\n[Delegator Daemon] Shutting down...');
|
|
247
152
|
await daemon.stop();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/delegator/bin/daemon.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/delegator/bin/daemon.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAgC,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoBvC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAoB;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC;IACxC,MAAM,OAAO,GAAG,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;IAEzC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAEhB,MAAM,cAAc,GAA4B;QAC9C,MAAM,EAAE,MAAM,CAAC,SAAS;KACzB,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAErD;;OAEG;IACH,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAEzE,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBACvC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,sDAAsD;iBAC9D,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC;gBAC1C,WAAW;gBACX,QAAQ;gBACR,IAAI;gBACJ,UAAU;gBACV,UAAU;aACX,CAAC,CAAC;YAEH,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;YAEtE,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B;iBAC9E,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB;aACnE,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAEjC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YAC7B,OAAO,CAAC,GAAG,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnB,IAAI,GAAG;wBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;wBAChB,OAAO,EAAE,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;QACP,GAAG,EAAE,OAAO;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,UAA8B,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;YAClC,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,UAAU,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAoB,CAAC;IAErE,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;QACxC,IAAI;QACJ,SAAS,EAAE,eAAe;KAC3B,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,8CAA8C,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTTP Client for sending AWCP messages to Executor
|
|
3
3
|
*/
|
|
4
|
-
import type { AwcpMessage, AcceptMessage, ErrorMessage } from '@awcp/core';
|
|
5
|
-
/**
|
|
6
|
-
* Response from Executor for INVITE message
|
|
7
|
-
*/
|
|
4
|
+
import type { AwcpMessage, AcceptMessage, ErrorMessage, TaskEvent } from '@awcp/core';
|
|
8
5
|
export type InviteResponse = AcceptMessage | ErrorMessage;
|
|
9
|
-
/**
|
|
10
|
-
* Client for sending AWCP messages to Executor daemon
|
|
11
|
-
*/
|
|
12
6
|
export declare class ExecutorClient {
|
|
13
7
|
private timeout;
|
|
14
|
-
|
|
15
|
-
constructor(options: {
|
|
8
|
+
constructor(options?: {
|
|
16
9
|
timeout?: number;
|
|
17
|
-
callbackUrl: string;
|
|
18
10
|
});
|
|
19
11
|
/**
|
|
20
12
|
* Send INVITE to Executor and get ACCEPT/ERROR response
|
|
@@ -25,12 +17,13 @@ export declare class ExecutorClient {
|
|
|
25
17
|
*/
|
|
26
18
|
sendStart(executorUrl: string, message: AwcpMessage): Promise<void>;
|
|
27
19
|
/**
|
|
28
|
-
*
|
|
20
|
+
* Subscribe to task events via SSE
|
|
29
21
|
*/
|
|
30
|
-
|
|
22
|
+
subscribeTask(executorUrl: string, delegationId: string): AsyncIterable<TaskEvent>;
|
|
31
23
|
/**
|
|
32
|
-
*
|
|
24
|
+
* Request Executor to cancel a delegation
|
|
33
25
|
*/
|
|
26
|
+
sendCancel(executorUrl: string, delegationId: string): Promise<void>;
|
|
34
27
|
private send;
|
|
35
28
|
}
|
|
36
29
|
//# sourceMappingURL=executor-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor-client.d.ts","sourceRoot":"","sources":["../../src/delegator/executor-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"executor-client.d.ts","sourceRoot":"","sources":["../../src/delegator/executor-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtF,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,YAAY,CAAC;AAE1D,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IAI1C;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAMpF;;OAEG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzE;;OAEG;IACI,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC;IAoDzF;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAqB5D,IAAI;CAwBnB"}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTTP Client for sending AWCP messages to Executor
|
|
3
3
|
*/
|
|
4
|
-
/**
|
|
5
|
-
* Client for sending AWCP messages to Executor daemon
|
|
6
|
-
*/
|
|
7
4
|
export class ExecutorClient {
|
|
8
5
|
timeout;
|
|
9
|
-
callbackUrl;
|
|
10
6
|
constructor(options) {
|
|
11
|
-
this.timeout = options
|
|
12
|
-
this.callbackUrl = options.callbackUrl;
|
|
7
|
+
this.timeout = options?.timeout ?? 30000;
|
|
13
8
|
}
|
|
14
9
|
/**
|
|
15
10
|
* Send INVITE to Executor and get ACCEPT/ERROR response
|
|
@@ -26,7 +21,56 @@ export class ExecutorClient {
|
|
|
26
21
|
await this.send(executorUrl, message);
|
|
27
22
|
}
|
|
28
23
|
/**
|
|
29
|
-
*
|
|
24
|
+
* Subscribe to task events via SSE
|
|
25
|
+
*/
|
|
26
|
+
async *subscribeTask(executorUrl, delegationId) {
|
|
27
|
+
const baseUrl = executorUrl.replace(/\/$/, '').replace(/\/awcp$/, '');
|
|
28
|
+
const url = `${baseUrl}/awcp/tasks/${delegationId}/events`;
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
headers: { Accept: 'text/event-stream' },
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
34
|
+
}
|
|
35
|
+
if (!response.body) {
|
|
36
|
+
throw new Error('SSE connection failed: no response body');
|
|
37
|
+
}
|
|
38
|
+
const reader = response.body.getReader();
|
|
39
|
+
const decoder = new TextDecoder();
|
|
40
|
+
let buffer = '';
|
|
41
|
+
try {
|
|
42
|
+
while (true) {
|
|
43
|
+
const { done, value } = await reader.read();
|
|
44
|
+
if (done)
|
|
45
|
+
break;
|
|
46
|
+
buffer += decoder.decode(value, { stream: true });
|
|
47
|
+
const lines = buffer.split('\n');
|
|
48
|
+
buffer = lines.pop() ?? '';
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
if (line.startsWith('data: ')) {
|
|
51
|
+
const data = line.slice(6);
|
|
52
|
+
if (data) {
|
|
53
|
+
try {
|
|
54
|
+
const event = JSON.parse(data);
|
|
55
|
+
yield event;
|
|
56
|
+
if (event.type === 'done' || event.type === 'error') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Ignore parse errors
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
reader.releaseLock();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Request Executor to cancel a delegation
|
|
30
74
|
*/
|
|
31
75
|
async sendCancel(executorUrl, delegationId) {
|
|
32
76
|
const cancelUrl = executorUrl.replace(/\/$/, '') + `/cancel/${delegationId}`;
|
|
@@ -47,19 +91,13 @@ export class ExecutorClient {
|
|
|
47
91
|
clearTimeout(timeoutId);
|
|
48
92
|
}
|
|
49
93
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Internal send method
|
|
52
|
-
*/
|
|
53
94
|
async send(executorUrl, message) {
|
|
54
95
|
const controller = new AbortController();
|
|
55
96
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
56
97
|
try {
|
|
57
98
|
const response = await fetch(executorUrl, {
|
|
58
99
|
method: 'POST',
|
|
59
|
-
headers: {
|
|
60
|
-
'Content-Type': 'application/json',
|
|
61
|
-
'X-AWCP-Callback-URL': this.callbackUrl,
|
|
62
|
-
},
|
|
100
|
+
headers: { 'Content-Type': 'application/json' },
|
|
63
101
|
body: JSON.stringify(message),
|
|
64
102
|
signal: controller.signal,
|
|
65
103
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor-client.js","sourceRoot":"","sources":["../../src/delegator/executor-client.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"executor-client.js","sourceRoot":"","sources":["../../src/delegator/executor-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,11 +25,9 @@ export interface DelegatorServiceStatus {
|
|
|
25
25
|
}
|
|
26
26
|
export interface DelegatorServiceOptions {
|
|
27
27
|
config: DelegatorConfig;
|
|
28
|
-
callbackUrl: string;
|
|
29
28
|
}
|
|
30
29
|
export declare class DelegatorService {
|
|
31
30
|
private config;
|
|
32
|
-
private callbackUrl;
|
|
33
31
|
private transport;
|
|
34
32
|
private admissionController;
|
|
35
33
|
private exportManager;
|
|
@@ -40,6 +38,12 @@ export declare class DelegatorService {
|
|
|
40
38
|
constructor(options: DelegatorServiceOptions);
|
|
41
39
|
delegate(params: DelegateParams): Promise<string>;
|
|
42
40
|
handleAccept(message: AcceptMessage): Promise<void>;
|
|
41
|
+
private subscribeToTaskEvents;
|
|
42
|
+
private handleTaskEvent;
|
|
43
|
+
/**
|
|
44
|
+
* Apply result from Executor back to original workspace
|
|
45
|
+
*/
|
|
46
|
+
private applyResult;
|
|
43
47
|
handleDone(message: DoneMessage): Promise<void>;
|
|
44
48
|
handleError(message: ErrorMessage): Promise<void>;
|
|
45
49
|
handleMessage(message: AwcpMessage): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/delegator/service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/delegator/service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAGb,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EASpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,eAAe,EAAwD,MAAM,aAAa,CAAC;AAKzG,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,aAAa,CAA6C;IAClE,OAAO,CAAC,YAAY,CAA6B;gBAErC,OAAO,EAAE,uBAAuB;IAkBtC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IA0EjD,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;YAsD3C,qBAAqB;YAarB,eAAe;IA0C7B;;OAEG;YACW,WAAW;IA4BnB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/C,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBjD,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlD,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIrD,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,GAAE,MAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA4B7F,SAAS,IAAI,sBAAsB;YAarB,OAAO;CAKtB"}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* Manages the AWCP delegation protocol on the Delegator side.
|
|
5
5
|
*/
|
|
6
6
|
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import * as os from 'node:os';
|
|
7
10
|
import { DelegationStateMachine, createDelegation, applyMessageToDelegation, PROTOCOL_VERSION, AwcpError, WorkspaceTooLargeError, } from '@awcp/core';
|
|
8
11
|
import { resolveDelegatorConfig } from './config.js';
|
|
9
12
|
import { AdmissionController } from './admission.js';
|
|
@@ -11,7 +14,6 @@ import { ExportManager } from './export-manager.js';
|
|
|
11
14
|
import { ExecutorClient } from './executor-client.js';
|
|
12
15
|
export class DelegatorService {
|
|
13
16
|
config;
|
|
14
|
-
callbackUrl;
|
|
15
17
|
transport;
|
|
16
18
|
admissionController;
|
|
17
19
|
exportManager;
|
|
@@ -21,7 +23,6 @@ export class DelegatorService {
|
|
|
21
23
|
executorUrls = new Map();
|
|
22
24
|
constructor(options) {
|
|
23
25
|
this.config = resolveDelegatorConfig(options.config);
|
|
24
|
-
this.callbackUrl = options.callbackUrl;
|
|
25
26
|
this.transport = this.config.transport;
|
|
26
27
|
this.admissionController = new AdmissionController({
|
|
27
28
|
maxTotalBytes: this.config.admission.maxTotalBytes,
|
|
@@ -32,9 +33,7 @@ export class DelegatorService {
|
|
|
32
33
|
baseDir: this.config.export.baseDir,
|
|
33
34
|
strategy: this.config.export.strategy,
|
|
34
35
|
});
|
|
35
|
-
this.executorClient = new ExecutorClient(
|
|
36
|
-
callbackUrl: this.callbackUrl,
|
|
37
|
-
});
|
|
36
|
+
this.executorClient = new ExecutorClient();
|
|
38
37
|
}
|
|
39
38
|
async delegate(params) {
|
|
40
39
|
const delegationId = randomUUID();
|
|
@@ -105,7 +104,7 @@ export class DelegatorService {
|
|
|
105
104
|
const updated = applyMessageToDelegation(delegation, message);
|
|
106
105
|
updated.state = stateMachine.getState();
|
|
107
106
|
this.delegations.set(delegation.id, updated);
|
|
108
|
-
const {
|
|
107
|
+
const { workDirInfo } = await this.transport.prepare({
|
|
109
108
|
delegationId: delegation.id,
|
|
110
109
|
exportPath: updated.exportPath,
|
|
111
110
|
ttlSeconds: delegation.leaseConfig.ttlSeconds,
|
|
@@ -119,7 +118,7 @@ export class DelegatorService {
|
|
|
119
118
|
expiresAt,
|
|
120
119
|
accessMode: delegation.leaseConfig.accessMode,
|
|
121
120
|
},
|
|
122
|
-
|
|
121
|
+
workDir: workDirInfo,
|
|
123
122
|
};
|
|
124
123
|
stateMachine.transition({ type: 'SEND_START', message: startMessage });
|
|
125
124
|
updated.state = stateMachine.getState();
|
|
@@ -128,6 +127,84 @@ export class DelegatorService {
|
|
|
128
127
|
this.delegations.set(delegation.id, updated);
|
|
129
128
|
await this.executorClient.sendStart(executorUrl, startMessage);
|
|
130
129
|
this.config.hooks.onDelegationStarted?.(updated);
|
|
130
|
+
// Subscribe to SSE events for task completion
|
|
131
|
+
this.subscribeToTaskEvents(delegation.id, executorUrl);
|
|
132
|
+
}
|
|
133
|
+
async subscribeToTaskEvents(delegationId, executorUrl) {
|
|
134
|
+
try {
|
|
135
|
+
for await (const event of this.executorClient.subscribeTask(executorUrl, delegationId)) {
|
|
136
|
+
await this.handleTaskEvent(delegationId, event);
|
|
137
|
+
if (event.type === 'done' || event.type === 'error') {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error(`[AWCP Delegator] SSE subscription error for ${delegationId}:`, error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async handleTaskEvent(delegationId, event) {
|
|
147
|
+
const delegation = this.delegations.get(delegationId);
|
|
148
|
+
if (!delegation)
|
|
149
|
+
return;
|
|
150
|
+
const stateMachine = this.stateMachines.get(delegationId);
|
|
151
|
+
if (event.type === 'status' && stateMachine.getState() === 'started') {
|
|
152
|
+
stateMachine.transition({ type: 'SETUP_COMPLETE' });
|
|
153
|
+
delegation.state = stateMachine.getState();
|
|
154
|
+
delegation.updatedAt = new Date().toISOString();
|
|
155
|
+
this.delegations.set(delegationId, delegation);
|
|
156
|
+
}
|
|
157
|
+
if (event.type === 'done') {
|
|
158
|
+
// Apply result back to workspace if present
|
|
159
|
+
if (event.resultBase64 && delegation.localDir) {
|
|
160
|
+
await this.applyResult(delegationId, delegation.localDir, event.resultBase64);
|
|
161
|
+
}
|
|
162
|
+
const doneMessage = {
|
|
163
|
+
version: PROTOCOL_VERSION,
|
|
164
|
+
type: 'DONE',
|
|
165
|
+
delegationId,
|
|
166
|
+
finalSummary: event.summary,
|
|
167
|
+
highlights: event.highlights,
|
|
168
|
+
};
|
|
169
|
+
await this.handleDone(doneMessage);
|
|
170
|
+
}
|
|
171
|
+
if (event.type === 'error') {
|
|
172
|
+
const errorMessage = {
|
|
173
|
+
version: PROTOCOL_VERSION,
|
|
174
|
+
type: 'ERROR',
|
|
175
|
+
delegationId,
|
|
176
|
+
code: event.code,
|
|
177
|
+
message: event.message,
|
|
178
|
+
hint: event.hint,
|
|
179
|
+
};
|
|
180
|
+
await this.handleError(errorMessage);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Apply result from Executor back to original workspace
|
|
185
|
+
*/
|
|
186
|
+
async applyResult(delegationId, localDir, resultBase64) {
|
|
187
|
+
try {
|
|
188
|
+
// Decode base64 to buffer
|
|
189
|
+
const buffer = Buffer.from(resultBase64, 'base64');
|
|
190
|
+
// Write to temp file
|
|
191
|
+
const tempDir = path.join(os.tmpdir(), 'awcp-results');
|
|
192
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
193
|
+
const archivePath = path.join(tempDir, `${delegationId}-result.zip`);
|
|
194
|
+
await fs.writeFile(archivePath, buffer);
|
|
195
|
+
// Extract to localDir (overwriting existing files)
|
|
196
|
+
const { exec } = await import('node:child_process');
|
|
197
|
+
const { promisify } = await import('node:util');
|
|
198
|
+
const execAsync = promisify(exec);
|
|
199
|
+
// Use unzip to extract, overwriting existing files
|
|
200
|
+
await execAsync(`unzip -o "${archivePath}" -d "${localDir}"`);
|
|
201
|
+
// Cleanup temp file
|
|
202
|
+
await fs.unlink(archivePath).catch(() => { });
|
|
203
|
+
console.log(`[AWCP Delegator] Applied result to ${localDir}`);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error(`[AWCP Delegator] Failed to apply result for ${delegationId}:`, error);
|
|
207
|
+
}
|
|
131
208
|
}
|
|
132
209
|
async handleDone(message) {
|
|
133
210
|
const delegation = this.delegations.get(message.delegationId);
|
|
@@ -137,7 +214,7 @@ export class DelegatorService {
|
|
|
137
214
|
}
|
|
138
215
|
const stateMachine = this.stateMachines.get(message.delegationId);
|
|
139
216
|
if (stateMachine.getState() === 'started') {
|
|
140
|
-
stateMachine.transition({ type: '
|
|
217
|
+
stateMachine.transition({ type: 'SETUP_COMPLETE' });
|
|
141
218
|
}
|
|
142
219
|
const result = stateMachine.transition({ type: 'RECEIVE_DONE', message });
|
|
143
220
|
if (!result.success) {
|