subharness 0.0.5 → 0.0.7
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/README.md +59 -3
- package/dist/adapters/claude-process.js +8 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-tools.d.ts +6 -2
- package/dist/adapters/claude-tools.js +14 -12
- package/dist/adapters/claude-tools.js.map +1 -1
- package/dist/adapters/claude-worker-client.d.ts +49 -0
- package/dist/adapters/claude-worker-client.js +359 -0
- package/dist/adapters/claude-worker-client.js.map +1 -0
- package/dist/adapters/claude-worker-process.d.ts +20 -0
- package/dist/adapters/claude-worker-process.js +76 -0
- package/dist/adapters/claude-worker-process.js.map +1 -0
- package/dist/adapters/claude-worker-protocol.d.ts +38 -0
- package/dist/adapters/claude-worker-protocol.js +2 -0
- package/dist/adapters/claude-worker-protocol.js.map +1 -0
- package/dist/adapters/claude-worker.d.ts +1 -0
- package/dist/adapters/claude-worker.js +126 -0
- package/dist/adapters/claude-worker.js.map +1 -0
- package/dist/adapters/claude.d.ts +16 -6
- package/dist/adapters/claude.js +138 -68
- package/dist/adapters/claude.js.map +1 -1
- package/dist/cli/catalog-worker.js.map +1 -1
- package/dist/cli/dashboard-client.js +19 -30
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/main.js +53 -45
- package/dist/cli/main.js.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/approval-registry.d.ts +9 -0
- package/dist/runtime/approval-registry.js +143 -4
- package/dist/runtime/approval-registry.js.map +1 -1
- package/dist/runtime/capture.d.ts +22 -0
- package/dist/runtime/capture.js +320 -0
- package/dist/runtime/capture.js.map +1 -0
- package/dist/runtime/catalog.d.ts +39 -0
- package/dist/runtime/catalog.js +84 -0
- package/dist/runtime/catalog.js.map +1 -0
- package/dist/runtime/client.d.ts +2 -1
- package/dist/runtime/client.js +52 -65
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +44 -7
- package/dist/runtime/coordinator.js +265 -31
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/daemon.js +12 -6
- package/dist/runtime/daemon.js.map +1 -1
- package/dist/runtime/dashboard-workspace.js +5 -1
- package/dist/runtime/dashboard-workspace.js.map +1 -1
- package/dist/runtime/definition.d.ts +6 -1
- package/dist/runtime/definition.js +31 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/native-owner.js +7 -1
- package/dist/runtime/native-owner.js.map +1 -1
- package/dist/runtime/pagination.d.ts +9 -0
- package/dist/runtime/pagination.js +36 -0
- package/dist/runtime/pagination.js.map +1 -0
- package/dist/runtime/sdk-observation.d.ts +8 -0
- package/dist/runtime/sdk-observation.js +75 -0
- package/dist/runtime/sdk-observation.js.map +1 -0
- package/dist/runtime/sdk-projection.d.ts +8 -0
- package/dist/runtime/sdk-projection.js +19 -0
- package/dist/runtime/sdk-projection.js.map +1 -0
- package/dist/runtime/sdk-service.d.ts +11 -0
- package/dist/runtime/sdk-service.js +109 -0
- package/dist/runtime/sdk-service.js.map +1 -0
- package/dist/runtime/select-native.d.ts +4 -1
- package/dist/runtime/select-native.js +14 -17
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.d.ts +11 -1
- package/dist/runtime/service.js +178 -3
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/session-launcher.js +1 -1
- package/dist/runtime/session-launcher.js.map +1 -1
- package/dist/runtime/snapshots.d.ts +103 -0
- package/dist/runtime/snapshots.js +124 -0
- package/dist/runtime/snapshots.js.map +1 -0
- package/dist/runtime/state.d.ts +26 -0
- package/dist/runtime/state.js +86 -17
- package/dist/runtime/state.js.map +1 -1
- package/dist/runtime/task-data.d.ts +38 -0
- package/dist/runtime/task-data.js +2 -0
- package/dist/runtime/task-data.js.map +1 -0
- package/dist/runtime/transport.d.ts +13 -0
- package/dist/runtime/transport.js +166 -0
- package/dist/runtime/transport.js.map +1 -0
- package/dist/runtime/types.d.ts +28 -9
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-client.js +2 -0
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.js +105 -24
- package/dist/runtime/worker-server.js.map +1 -1
- package/dist/sdk/connected-types.d.ts +42 -0
- package/dist/sdk/connected-types.js +2 -0
- package/dist/sdk/connected-types.js.map +1 -0
- package/dist/sdk/connected.d.ts +3 -0
- package/dist/sdk/connected.js +232 -0
- package/dist/sdk/connected.js.map +1 -0
- package/dist/sdk/execution-definition.d.ts +3 -0
- package/dist/sdk/execution-definition.js +59 -0
- package/dist/sdk/execution-definition.js.map +1 -0
- package/dist/sdk/execution-driver.d.ts +6 -0
- package/dist/sdk/execution-driver.js +86 -0
- package/dist/sdk/execution-driver.js.map +1 -0
- package/dist/sdk/execution-observation.d.ts +3 -0
- package/dist/sdk/execution-observation.js +35 -0
- package/dist/sdk/execution-observation.js.map +1 -0
- package/dist/sdk/execution-options.d.ts +17 -0
- package/dist/sdk/execution-options.js +115 -0
- package/dist/sdk/execution-options.js.map +1 -0
- package/dist/sdk/execution-types.d.ts +72 -0
- package/dist/sdk/execution-types.js +2 -0
- package/dist/sdk/execution-types.js.map +1 -0
- package/dist/sdk/execution.d.ts +3 -0
- package/dist/sdk/execution.js +3 -0
- package/dist/sdk/execution.js.map +1 -0
- package/dist/sdk/hosted-error.d.ts +3 -0
- package/dist/sdk/hosted-error.js +14 -0
- package/dist/sdk/hosted-error.js.map +1 -0
- package/dist/sdk/hosted.d.ts +23 -0
- package/dist/sdk/hosted.js +204 -0
- package/dist/sdk/hosted.js.map +1 -0
- package/dist/sdk/runner.d.ts +5 -0
- package/dist/sdk/runner.js +107 -0
- package/dist/sdk/runner.js.map +1 -0
- package/dist/sdk/tools.js +4 -1
- package/dist/sdk/tools.js.map +1 -1
- package/package.json +3 -3
- package/sdk/access-config.md +2 -0
- package/sdk/adapter-contract.md +8 -0
- package/sdk/agent.md +1 -1
- package/sdk/approvals.md +2 -0
- package/sdk/completion-notifications.md +2 -0
- package/sdk/distribution.md +4 -2
- package/sdk/examples/chat-tool.ts +126 -0
- package/sdk/execution.md +743 -0
- package/sdk/index.md +45 -21
- package/sdk/message-delivery.md +2 -0
- package/sdk/permissions.md +2 -0
- package/sdk/plugins/sub-agents.md +4 -2
- package/sdk/project-team.md +23 -1
- package/sdk/sessions.md +2 -0
- package/sdk/tools.md +3 -1
- package/sdk/v1-runtime.md +7 -5
- package/dist/cli/catalog.d.ts +0 -26
- package/dist/cli/catalog.js +0 -41
- package/dist/cli/catalog.js.map +0 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { AgentError } from '../errors.js';
|
|
2
|
+
export class CoordinatorTransport {
|
|
3
|
+
endpoint;
|
|
4
|
+
closed = new AbortController();
|
|
5
|
+
constructor(endpoint) {
|
|
6
|
+
this.endpoint = endpoint;
|
|
7
|
+
}
|
|
8
|
+
disconnect() { this.closed.abort(); }
|
|
9
|
+
async one(body, signal) {
|
|
10
|
+
let value;
|
|
11
|
+
let count = 0;
|
|
12
|
+
for await (const record of this.records(body, signal)) {
|
|
13
|
+
throwRemote(record);
|
|
14
|
+
value = record;
|
|
15
|
+
count++;
|
|
16
|
+
if (count > 1)
|
|
17
|
+
throw unavailable('The coordinator returned too many records for one operation.');
|
|
18
|
+
}
|
|
19
|
+
if (count !== 1)
|
|
20
|
+
throw unavailable('The coordinator returned no record for the operation.');
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
stream(body, signal) {
|
|
24
|
+
const transport = this;
|
|
25
|
+
return { [Symbol.asyncIterator]() {
|
|
26
|
+
const lifetime = new AbortController();
|
|
27
|
+
const observerSignal = signal ? AbortSignal.any([signal, lifetime.signal]) : lifetime.signal;
|
|
28
|
+
const source = transport.records(body, observerSignal)[Symbol.asyncIterator]();
|
|
29
|
+
return {
|
|
30
|
+
async next() {
|
|
31
|
+
const result = await source.next();
|
|
32
|
+
if (result.done)
|
|
33
|
+
return { done: true, value: undefined };
|
|
34
|
+
throwRemote(result.value);
|
|
35
|
+
return { done: false, value: result.value };
|
|
36
|
+
},
|
|
37
|
+
async return() {
|
|
38
|
+
lifetime.abort();
|
|
39
|
+
try {
|
|
40
|
+
await source.return?.(undefined);
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
return { done: true, value: undefined };
|
|
44
|
+
},
|
|
45
|
+
async throw(error) {
|
|
46
|
+
lifetime.abort();
|
|
47
|
+
if (source.throw)
|
|
48
|
+
return source.throw(error);
|
|
49
|
+
throw error;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
} };
|
|
53
|
+
}
|
|
54
|
+
async *records(body, signal, options = {}) {
|
|
55
|
+
this.assertOpen();
|
|
56
|
+
const operation = operationName(body);
|
|
57
|
+
const combined = signal
|
|
58
|
+
? AbortSignal.any([this.closed.signal, signal])
|
|
59
|
+
: this.closed.signal;
|
|
60
|
+
let response;
|
|
61
|
+
try {
|
|
62
|
+
response = await fetch(this.endpoint.url, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: { authorization: `Bearer ${this.endpoint.token}`, 'content-type': 'application/json',
|
|
65
|
+
'x-subharness-instance': this.endpoint.instanceId },
|
|
66
|
+
body: JSON.stringify(body),
|
|
67
|
+
signal: combined,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
if (signal?.aborted)
|
|
72
|
+
throw new AgentError('OBSERVATION_CLOSED', 'The observer disconnected.');
|
|
73
|
+
throw unavailable('Connection to the local coordinator failed. The task was not automatically retried.');
|
|
74
|
+
}
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
void response.body?.cancel().catch(() => { });
|
|
77
|
+
if (response.status === 401)
|
|
78
|
+
throw new AgentError('COORDINATOR_AUTH_FAILED', 'The local coordinator rejected its private authentication token.');
|
|
79
|
+
throw unavailable(`The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);
|
|
80
|
+
}
|
|
81
|
+
if (!response.body)
|
|
82
|
+
throw unavailable(`The coordinator returned a successful response with no body${operation ? ` for the ${operation} operation` : ''}.`);
|
|
83
|
+
let buffer = '';
|
|
84
|
+
const decoder = new TextDecoder();
|
|
85
|
+
const reader = response.body.getReader();
|
|
86
|
+
let complete = false;
|
|
87
|
+
try {
|
|
88
|
+
for (;;) {
|
|
89
|
+
const result = await reader.read();
|
|
90
|
+
if (result.done) {
|
|
91
|
+
complete = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
const chunk = result.value;
|
|
95
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
96
|
+
let newline;
|
|
97
|
+
while ((newline = buffer.indexOf('\n')) >= 0) {
|
|
98
|
+
const line = buffer.slice(0, newline);
|
|
99
|
+
buffer = buffer.slice(newline + 1);
|
|
100
|
+
if (!line)
|
|
101
|
+
continue;
|
|
102
|
+
try {
|
|
103
|
+
yield JSON.parse(line);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
buffer += decoder.decode();
|
|
111
|
+
if (buffer.trim()) {
|
|
112
|
+
if (options.allowFinalRecord) {
|
|
113
|
+
try {
|
|
114
|
+
yield JSON.parse(buffer);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else
|
|
121
|
+
throw unavailable(`The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof AgentError)
|
|
126
|
+
throw error;
|
|
127
|
+
if (signal?.aborted)
|
|
128
|
+
throw new AgentError('OBSERVATION_CLOSED', 'The observer disconnected.');
|
|
129
|
+
throw unavailable('The coordinator response stream was interrupted. The task was not automatically retried.');
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
if (!complete)
|
|
133
|
+
await reader.cancel().catch(() => { });
|
|
134
|
+
reader.releaseLock();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
assertOpen() {
|
|
138
|
+
if (this.closed.signal.aborted)
|
|
139
|
+
throw unavailable('The coordinator client is disconnected.');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function throwRemote(value) {
|
|
143
|
+
if (!value || typeof value !== 'object' || value.type !== 'error')
|
|
144
|
+
return;
|
|
145
|
+
const record = value;
|
|
146
|
+
if (!record.error || typeof record.error.code !== 'string' || typeof record.error.message !== 'string')
|
|
147
|
+
throw unavailable('The coordinator returned a malformed error record.');
|
|
148
|
+
throw new AgentError(record.error.code, record.error.message);
|
|
149
|
+
}
|
|
150
|
+
function operationName(body) {
|
|
151
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
152
|
+
return;
|
|
153
|
+
const command = body.command;
|
|
154
|
+
return typeof command === 'string' && operations.has(command) ? command : undefined;
|
|
155
|
+
}
|
|
156
|
+
const operations = new Set([
|
|
157
|
+
'dashboard', 'dashboard-session', 'dashboard-detail', 'parent', 'run', 'send', 'resume', 'wait', 'status', 'queue', 'cancel', 'respond',
|
|
158
|
+
'sdk-agent-list', 'sdk-agent-check',
|
|
159
|
+
'sdk-session-create', 'sdk-session-get', 'sdk-session-list', 'sdk-session-prompt', 'sdk-session-close',
|
|
160
|
+
'sdk-task-get', 'sdk-task-list', 'sdk-task-snapshot', 'sdk-task-inspect', 'sdk-task-result', 'sdk-task-watch',
|
|
161
|
+
'sdk-task-responses', 'sdk-task-cancel', 'sdk-approval-respond',
|
|
162
|
+
]);
|
|
163
|
+
function unavailable(message) {
|
|
164
|
+
return new AgentError('COORDINATOR_UNAVAILABLE', message);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/runtime/transport.ts"],"names":[],"mappings":"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","sourcesContent":["import { AgentError } from '../errors.js';\nimport type { Endpoint } from './state.js';\n\ninterface ErrorRecord {\n readonly version: 1;\n readonly type: 'error';\n readonly error: {readonly code:string;readonly message:string};\n}\n\nexport class CoordinatorTransport {\n private readonly closed = new AbortController();\n constructor(readonly endpoint:Endpoint) {}\n\n disconnect(): void { this.closed.abort(); }\n\n async one<T>(body:unknown,signal?:AbortSignal):Promise<T> {\n let value:T|undefined;\n let count=0;\n for await (const record of this.records(body,signal)) {\n throwRemote(record);\n value=record as T;\n count++;\n if (count > 1) throw unavailable('The coordinator returned too many records for one operation.');\n }\n if (count !== 1) throw unavailable('The coordinator returned no record for the operation.');\n return value!;\n }\n\n stream<T>(body:unknown,signal?:AbortSignal):AsyncIterable<T> {\n const transport=this;\n return {[Symbol.asyncIterator]():AsyncIterator<T> {\n const lifetime=new AbortController();\n const observerSignal=signal ? AbortSignal.any([signal,lifetime.signal]) : lifetime.signal;\n const source=transport.records(body,observerSignal)[Symbol.asyncIterator]();\n return {\n async next() {\n const result=await source.next();\n if(result.done)return {done:true,value:undefined};\n throwRemote(result.value);\n return {done:false,value:result.value as T};\n },\n async return() {\n lifetime.abort();\n try{await source.return?.(undefined);}catch{}\n return {done:true,value:undefined};\n },\n async throw(error?:unknown) {\n lifetime.abort();\n if(source.throw)return source.throw(error) as Promise<IteratorResult<T>>;\n throw error;\n },\n };\n }};\n }\n\n async *records(body:unknown,signal?:AbortSignal,options:{allowFinalRecord?:boolean}={}):AsyncGenerator<unknown> {\n this.assertOpen();\n const operation=operationName(body);\n const combined=signal\n ? AbortSignal.any([this.closed.signal,signal])\n : this.closed.signal;\n let response:Response;\n try {\n response=await fetch(this.endpoint.url,{\n method:'POST',\n headers:{authorization:`Bearer ${this.endpoint.token}`,'content-type':'application/json',\n 'x-subharness-instance':this.endpoint.instanceId},\n body:JSON.stringify(body),\n signal:combined,\n });\n } catch {\n if (signal?.aborted) throw new AgentError('OBSERVATION_CLOSED','The observer disconnected.');\n throw unavailable('Connection to the local coordinator failed. The task was not automatically retried.');\n }\n if (!response.ok) {\n void response.body?.cancel().catch(()=>{});\n if (response.status === 401)\n throw new AgentError('COORDINATOR_AUTH_FAILED','The local coordinator rejected its private authentication token.');\n throw unavailable(`The coordinator rejected ${operation ? `the ${operation} operation` : 'the request'} with HTTP status ${response.status}.`);\n }\n if (!response.body) throw unavailable(\n `The coordinator returned a successful response with no body${operation ? ` for the ${operation} operation` : ''}.`);\n let buffer='';\n const decoder=new TextDecoder();\n const reader=response.body.getReader();\n let complete=false;\n try {\n for (;;) {\n const result=await reader.read();\n if (result.done) { complete=true; break; }\n const chunk=result.value;\n buffer+=decoder.decode(chunk,{stream:true});\n let newline:number;\n while ((newline=buffer.indexOf('\\n')) >= 0) {\n const line=buffer.slice(0,newline); buffer=buffer.slice(newline+1);\n if (!line) continue;\n try { yield JSON.parse(line) as unknown; }\n catch { throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`); }\n }\n }\n buffer+=decoder.decode();\n if (buffer.trim()) {\n if (options.allowFinalRecord) {\n try { yield JSON.parse(buffer) as unknown; }\n catch { throw unavailable(`The coordinator returned a malformed JSON record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`); }\n } else throw unavailable(\n `The coordinator response ended with an incomplete final record${operation ? ` for the ${operation} operation` : ''}. The task was not automatically retried.`);\n }\n } catch (error) {\n if (error instanceof AgentError) throw error;\n if (signal?.aborted) throw new AgentError('OBSERVATION_CLOSED','The observer disconnected.');\n throw unavailable('The coordinator response stream was interrupted. The task was not automatically retried.');\n } finally {\n if (!complete) await reader.cancel().catch(()=>{});\n reader.releaseLock();\n }\n }\n\n private assertOpen():void {\n if (this.closed.signal.aborted) throw unavailable('The coordinator client is disconnected.');\n }\n}\n\nfunction throwRemote(value:unknown):void {\n if (!value || typeof value !== 'object' || (value as {type?:unknown}).type !== 'error') return;\n const record=value as Partial<ErrorRecord>;\n if (!record.error || typeof record.error.code !== 'string' || typeof record.error.message !== 'string')\n throw unavailable('The coordinator returned a malformed error record.');\n throw new AgentError(record.error.code,record.error.message);\n}\n\nfunction operationName(body:unknown):string|undefined {\n if (!body || typeof body !== 'object' || Array.isArray(body)) return;\n const command=(body as {command?:unknown}).command;\n return typeof command === 'string' && operations.has(command) ? command : undefined;\n}\n\nconst operations=new Set([\n 'dashboard','dashboard-session','dashboard-detail','parent','run','send','resume','wait','status','queue','cancel','respond',\n 'sdk-agent-list','sdk-agent-check',\n 'sdk-session-create','sdk-session-get','sdk-session-list','sdk-session-prompt','sdk-session-close',\n 'sdk-task-get','sdk-task-list','sdk-task-snapshot','sdk-task-inspect','sdk-task-result','sdk-task-watch',\n 'sdk-task-responses','sdk-task-cancel','sdk-approval-respond',\n]);\n\nfunction unavailable(message:string):AgentError {\n return new AgentError('COORDINATOR_UNAVAILABLE',message);\n}\n"]}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { ErrorInfo } from '../errors.js';
|
|
|
2
2
|
import type { HarnessRequest, NativeSession } from '../adapters/types.js';
|
|
3
3
|
import type { HarnessKind } from '../sdk/types.js';
|
|
4
4
|
import type { DashboardHarness, DashboardWorkspace } from './dashboard.js';
|
|
5
|
-
import type { ApprovalHandler
|
|
6
|
-
|
|
5
|
+
import type { ApprovalHandler } from '../approvals/types.js';
|
|
6
|
+
import type { AgentDefinition } from '../sdk/types.js';
|
|
7
|
+
import type { ApprovalRequest, TaskState } from './task-data.js';
|
|
8
|
+
export type { ApprovalRequest, TaskState } from './task-data.js';
|
|
7
9
|
export type Delivery = 'queue' | 'steer' | 'interrupt';
|
|
8
10
|
export interface AgentReference {
|
|
9
11
|
file: string;
|
|
@@ -13,7 +15,11 @@ export interface HarnessReference {
|
|
|
13
15
|
kind: 'harness';
|
|
14
16
|
harness: HarnessRequest;
|
|
15
17
|
}
|
|
16
|
-
export
|
|
18
|
+
export interface InlineReference {
|
|
19
|
+
kind: 'inline';
|
|
20
|
+
definition: AgentDefinition;
|
|
21
|
+
}
|
|
22
|
+
export type ExecutionReference = AgentReference | HarnessReference | InlineReference;
|
|
17
23
|
export interface SessionInput {
|
|
18
24
|
reference: ExecutionReference;
|
|
19
25
|
cwd: string;
|
|
@@ -21,6 +27,7 @@ export interface SessionInput {
|
|
|
21
27
|
prompt: string;
|
|
22
28
|
parentToken?: string;
|
|
23
29
|
}
|
|
30
|
+
export type SessionCreateInput = Omit<SessionInput, 'prompt' | 'parentToken'>;
|
|
24
31
|
export interface DriverInput extends Omit<SessionInput, 'prompt' | 'parentToken'> {
|
|
25
32
|
token: string;
|
|
26
33
|
sessionId: string;
|
|
@@ -30,6 +37,10 @@ export type ManagedNativeSession = NativeSession & {
|
|
|
30
37
|
selectedHarness?: HarnessKind;
|
|
31
38
|
};
|
|
32
39
|
export type DriverFactory = (input: DriverInput) => Promise<ManagedNativeSession>;
|
|
40
|
+
export interface PreparedExecution {
|
|
41
|
+
open(input: DriverInput): Promise<ManagedNativeSession>;
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
}
|
|
33
44
|
export interface RecordBase {
|
|
34
45
|
version: 1;
|
|
35
46
|
type: string;
|
|
@@ -37,17 +48,13 @@ export interface RecordBase {
|
|
|
37
48
|
taskId: string;
|
|
38
49
|
state?: TaskState;
|
|
39
50
|
}
|
|
40
|
-
export interface ApprovalRequest extends NativeApprovalRequest {
|
|
41
|
-
requestId: string;
|
|
42
|
-
taskId: string;
|
|
43
|
-
sessionId: string;
|
|
44
|
-
}
|
|
45
51
|
export interface Observation extends RecordBase {
|
|
46
52
|
state: TaskState;
|
|
47
53
|
responseId?: string;
|
|
48
54
|
text?: string;
|
|
49
55
|
error?: ErrorInfo;
|
|
50
56
|
requests?: ApprovalRequest[];
|
|
57
|
+
stopUnconfirmed?: boolean;
|
|
51
58
|
}
|
|
52
59
|
export interface Receipt extends RecordBase {
|
|
53
60
|
delivery?: Delivery;
|
|
@@ -85,19 +92,31 @@ export interface Task {
|
|
|
85
92
|
failedAt?: number;
|
|
86
93
|
finishedAt?: number;
|
|
87
94
|
updatedAt: number;
|
|
95
|
+
revision: number;
|
|
96
|
+
ordinal: number;
|
|
97
|
+
membership: number;
|
|
88
98
|
changed: Set<() => void>;
|
|
99
|
+
watchers: Set<() => void>;
|
|
89
100
|
}
|
|
90
101
|
export interface Session {
|
|
91
102
|
id: string;
|
|
92
103
|
token: string;
|
|
93
|
-
input:
|
|
104
|
+
input: SessionCreateInput;
|
|
94
105
|
driver?: Promise<ManagedNativeSession>;
|
|
106
|
+
prepared?: PreparedExecution;
|
|
107
|
+
preparedClosed?: boolean;
|
|
95
108
|
tasks: string[];
|
|
96
109
|
active?: string;
|
|
97
110
|
paused: boolean;
|
|
98
111
|
commands: Promise<unknown>;
|
|
99
112
|
controls: number;
|
|
113
|
+
nextOrdinal: number;
|
|
114
|
+
membership: number;
|
|
100
115
|
harness: DashboardHarness;
|
|
116
|
+
selectedHarness?: HarnessKind;
|
|
101
117
|
workspace: Promise<DashboardWorkspace>;
|
|
118
|
+
state: 'open' | 'closing' | 'closed';
|
|
119
|
+
closePromise?: Promise<void>;
|
|
120
|
+
driverClosed?: boolean;
|
|
102
121
|
}
|
|
103
122
|
export declare const terminal: (state: TaskState) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAmDA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC","sourcesContent":["import type { ErrorInfo } from '../errors.js';\nimport type { HarnessRequest, NativeSession } from '../adapters/types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport type { DashboardHarness, DashboardWorkspace } from './dashboard.js';\nimport type { ApprovalHandler } from '../approvals/types.js';\nimport type { AgentDefinition } from '../sdk/types.js';\nimport type { ApprovalRequest, TaskState } from './task-data.js';\n\nexport type { ApprovalRequest, TaskState } from './task-data.js';\n\nexport type Delivery = 'queue' | 'steer' | 'interrupt';\nexport interface AgentReference { file: string; subagents: string[] }\nexport interface HarnessReference { kind: 'harness'; harness: HarnessRequest }\nexport interface InlineReference { kind: 'inline'; definition: AgentDefinition }\nexport type ExecutionReference = AgentReference | HarnessReference | InlineReference;\nexport interface SessionInput { reference: ExecutionReference; cwd: string; env: NodeJS.ProcessEnv; prompt: string; parentToken?: string }\nexport type SessionCreateInput = Omit<SessionInput, 'prompt' | 'parentToken'>;\nexport interface DriverInput extends Omit<SessionInput, 'prompt' | 'parentToken'> { token: string; sessionId: string; onApproval?: ApprovalHandler }\nexport type ManagedNativeSession = NativeSession & { selectedHarness?: HarnessKind };\nexport type DriverFactory = (input: DriverInput) => Promise<ManagedNativeSession>;\nexport interface PreparedExecution {\n open(input: DriverInput): Promise<ManagedNativeSession>;\n close(): Promise<void>;\n}\nexport interface RecordBase { version: 1; type: string; sessionId: string; taskId: string; state?: TaskState }\nexport interface Observation extends RecordBase {\n state: TaskState; responseId?: string; text?: string; error?: ErrorInfo; requests?: ApprovalRequest[];\n stopUnconfirmed?: boolean;\n}\nexport interface Receipt extends RecordBase {\n delivery?: Delivery; requestedDelivery?: Delivery; resumed?: boolean;\n paused?: true; blockedByTaskId?: string;\n}\nexport interface Response extends Observation { type: 'response'; responseId: string; text: string }\nexport interface ChildResult { taskId: string; state: TaskState; text: string }\nexport interface Task {\n id: string; sessionId: string; prompt: string; title: string; parentId?: string; state: TaskState;\n responses: Response[]; children: Set<string>; inbox: ChildResult[]; nativeActive: boolean;\n stopping: boolean; stopPromise?: Promise<void>; stopUnconfirmed?: boolean; error?: ErrorInfo;\n dispatchedAt?: number; failedAt?: number; finishedAt?: number; updatedAt: number; revision: number;\n ordinal: number; membership: number;\n changed: Set<() => void>; watchers: Set<() => void>;\n}\nexport interface Session {\n id: string; token: string; input: SessionCreateInput; driver?: Promise<ManagedNativeSession>;\n prepared?: PreparedExecution; preparedClosed?: boolean;\n tasks: string[]; active?: string; paused: boolean; commands: Promise<unknown>; controls: number;\n nextOrdinal: number; membership: number;\n harness: DashboardHarness; selectedHarness?: HarnessKind; workspace: Promise<DashboardWorkspace>;\n state: 'open' | 'closing' | 'closed'; closePromise?: Promise<void>; driverClosed?: boolean;\n}\nexport const terminal = (state: TaskState) => ['completed', 'failed', 'cancelled', 'interrupted'].includes(state);\n"]}
|
|
@@ -28,6 +28,8 @@ function withTimeout(promise, timeout) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
export async function createWorker(input, options = {}) {
|
|
31
|
+
if ('kind' in input.reference && input.reference.kind === 'inline')
|
|
32
|
+
throw new AgentError('INVALID_DEFINITION', 'Inline agent definitions cannot be loaded by native CLI workers.');
|
|
31
33
|
const launcher = await createSessionLauncher(input.env.AGENT_STATE_DIR, input.token);
|
|
32
34
|
const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);
|
|
33
35
|
const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/runtime/worker-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqB,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAC;AAIrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAOnE,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEhC,MAAM,qBAAqB,GAA0B;IACnD,IAAI,EAAC,SAAS;IACd,IAAI,EAAC,iBAAiB;IACtB,KAAK,EAAC,UAAU;IAChB,SAAS,EAAC,cAAc;IACxB,MAAM,EAAC,UAAU;IACjB,KAAK,EAAC,SAAS;IACf,kBAAkB,EAAC,mBAAmB;CACvC,CAAC;AAEF,SAAS,UAAU,CAAC,OAAyB,EAAE,OAAe;IAC5D,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAC,OAAO,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CACV,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAC7C,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAI,OAAmB,EAAE,OAAe;IAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAC,MAAM,EAAE,EAAE;QACpC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAC,8CAA8C,CAAC,CAAC,EAAC,OAAO,CAAC,CAAC;QAChI,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACjD,KAAK,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAkB,EAAE,OAAO,GAAwB,EAAE;IACtF,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAgB,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnI,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE;YAC5C,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,EAAC,GAAG,KAAK,CAAC,GAAG,EAAC,kBAAkB,EAAC,KAAK,CAAC,KAAK,EAAC,cAAc,EAAC,QAAQ,CAAC,IAAI;gBAC5F,IAAI,EAAC,QAAQ,CAAC,SAAS,GAAG,SAAS,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAC;YAC/D,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YAC5E,KAAK,EAAE,CAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,EAAC,KAAK,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAC,yDAAyD,CAAC,CAAC;IAAC,CAAC;IACrI,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmF,CAAC;IAC3G,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;IACpD,MAAM,iBAAiB,GAAG,GAAG,EAAE,GAAG,KAAK,MAAM,UAAU,IAAI,SAAS,CAAC,MAAM,EAAE;QAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACxH,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,UAAuB,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,GAAG,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,MAAe,EAAE,YAAY,GAAG,KAAK,EAAE,EAAE;QACpE,IAAI,MAAM;YAAE,OAAO;QACnB,MAAM,GAAG,IAAI,CAAC;QACd,YAAY,GAAG,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,EAAC,MAAM,CAAC,CAAC;QAClF,iBAAiB,EAAE,CAAC;QACpB,UAAU,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YACjD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACvC,OAAO,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAE,YAAY;oBAC1D,CAAC,CAAC,2CAA2C,OAAO,CAAC,SAAS,eAAe;oBAC7E,CAAC,CAAC,mCAAmC,OAAO,CAAC,SAAS,eAAe,YAAY,GAAG,CAAC,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAC,SAAS,EAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAC,MAAM,CAAC,CAAC,CAAC;IACvD,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAqE,EAAE,EAAE;QAC5F,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;YACvB,IAAI,OAAO,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;gBAC1C,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;gBAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACjF,CAAC;iBAAM,IAAI,OAAO,CAAC,KAAK,KAAK,kBAAkB,EAAE,CAAC;gBAChD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;gBACzC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAC,UAAU,CAAC,CAAC;gBAC5C,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;oBAC/B,IAAI,CAAC,KAAK,CAAC,UAAU;wBAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAC,oDAAoD,CAAC,CAAC;oBACnH,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC7D,CAAC,CAAC,CAAC,IAAI,CACL,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM;oBAAE,OAAO,OAAO,CAAC,kBAAkB,EAAC,EAAC,SAAS,EAAC,OAAO,CAAC,SAAS,EAAC,OAAO,EAAC,CAAC,CAAC,CAAC,CAAC,EACnI,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM;oBAAE,OAAO,OAAO,CAAC,kBAAkB,EAAC,EAAC,SAAS,EAAC,OAAO,CAAC,SAAS,EAAC,KAAK,EAAC,SAAS,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CACjJ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;oBACd,qFAAqF;oBACrF,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM;wBACvC,OAAO,OAAO,CAAC,kBAAkB,EAAC,EAAC,SAAS,EAAC,OAAO,CAAC,SAAS,EAAC,KAAK,EAAC,SAAS,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAC5G,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;;YACxF,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,CAAC,MAAa,EAAE,KAAK,GAA0B,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAU,CAAC,OAAO,EAAC,MAAM,EAAE,EAAE;QAC5G,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC;QACtE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAC,2CAA2C,SAAS,eAAe,YAAY,GAAG,CAAC,CAAC,CAAC;YAC5H,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,EAAE,EAAC,EAAC,SAAS,EAAC,OAAO,EAAC,MAAM,EAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,EAAC,EAAE,EAAC,MAAM,EAAC,GAAG,KAAK,EAAC,EAAE,KAAK,CAAC,EAAE;YACvC,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,YAAY,CAAC,GAAG,EAAE;gBAChB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChC,IAAI,CAAC,OAAO,IAAI,MAAM;oBAAE,OAAO;gBAC/B,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnB,OAAO,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAC,yCAAyC,SAAS,eAAe,CAAC,CAAC,CAAC;YACrH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,eAA4B,CAAC;IACjC,MAAM,EAAC,UAAU,EAAC,GAAG,eAAe,EAAC,GAAG,KAAK,CAAC;IAC9C,IAAI,CAAC;QAAC,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,EAAC,EAAC,KAAK,EAAC,eAAe,EAAC,gBAAgB,EAAC,CAAC,CAAC,UAAU,EAAC,CAAgB,CAAC;IAAC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IAC1L,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,MAAM;YAAE,OAAO;QACnB,IAAI,KAAK,CAAC,SAAS;YAAE,IAAI,CAAC;gBAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,yCAAyC,CAAC,CAAC;QACpG,MAAM,OAAO,GAAG,OAAO,CAAC,iBAAiB,IAAI,iBAAiB,CAAC;QAC/D,IAAI,MAAM,UAAU,CAAC,WAAW,EAAC,OAAO,CAAC;YAAE,OAAO;QAClD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,IAAI,MAAM,UAAU,CAAC,WAAW,EAAC,OAAO,CAAC;YAAE,OAAO;QAClD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,IAAI,MAAM,UAAU,CAAC,WAAW,EAAC,OAAO,CAAC;YAAE,OAAO;QAClD,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAC,iDAAiD,CAAC,CAAC;IAC3F,CAAC,CAAC;IACF,OAAO;QACL,eAAe;QACf,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,CAAoB;QAC3D,KAAK,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,iBAAiB,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3E,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAoB;QAClD,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,iBAAiB,EAAE,CAAC;YACpB,IAAI,OAAgB,CAAC;YACrB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,CAAC;oBAAC,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAC,sBAAsB,CAAC,CAAC;gBAAC,CAAC;gBACnE,OAAO,KAAK,EAAE,CAAC;oBAAC,OAAO,GAAG,KAAK,CAAC;gBAAC,CAAC;YACpC,CAAC;YACD,IAAI,CAAC;gBAAC,MAAM,UAAU,EAAE,CAAC;YAAC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAAC,OAAO,KAAK,KAAK,CAAC;YAAC,CAAC;YAChE,IAAI,CAAC;gBAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAAC,OAAO,KAAK,KAAK,CAAC;YAAC,CAAC;YACpE,IAAI,OAAO;gBAAE,MAAM,OAAO,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { fork, type ChildProcess } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { delimiter } from 'node:path';\nimport { AgentError, errorInfo, type ErrorInfo } from '../errors.js';\nimport type { DriverInput } from './types.js';\nimport type { ManagedNativeSession } from './types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport { createSessionLauncher } from './session-launcher.js';\nimport type { ApprovalEvent } from './worker-approvals.js';\nimport { processExitDescription } from '../process-diagnostics.js';\n\ninterface WorkerClientOptions {\n workerModule?: URL;\n shutdownTimeoutMs?: number;\n}\n\nconst closeResponseTimeoutMs = 15_000;\nconst shutdownTimeoutMs = 1_000;\n\nconst workerOperationLabels: Record<string,string> = {\n open:'startup',\n turn:'turn submission',\n steer:'steering',\n interrupt:'interruption',\n resume:'recovery',\n close:'closing',\n 'approval.respond':'approval response',\n};\n\nfunction waitWithin(promise: Promise<unknown>, timeout: number): Promise<boolean> {\n return new Promise(resolve => {\n const timer = setTimeout(() => resolve(false),timeout);\n promise.then(\n () => { clearTimeout(timer); resolve(true); },\n () => { clearTimeout(timer); resolve(true); },\n );\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {\n return new Promise((resolve,reject) => {\n const timer = setTimeout(() => reject(new AgentError('HARNESS_FAILED','The session worker did not complete cleanup.')),timeout);\n promise.then(\n value => { clearTimeout(timer); resolve(value); },\n error => { clearTimeout(timer); reject(error); },\n );\n });\n}\n\nexport async function createWorker(input: DriverInput, options: WorkerClientOptions = {}): Promise<ManagedNativeSession> {\n const launcher = await createSessionLauncher(input.env.AGENT_STATE_DIR!,input.token);\n const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);\n const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';\n let child: ChildProcess;\n try {\n child = fork(fileURLToPath(workerModule), [], {\n cwd: input.cwd, env: {...input.env,AGENT_PARENT_TOKEN:input.token,AGENT_CLI_PATH:launcher.path,\n PATH:launcher.directory + delimiter + (input.env.PATH ?? '')},\n execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [],\n stdio: ['ignore','ignore','ignore','ipc'],\n });\n } catch { await launcher.close(); throw new AgentError('HARNESS_FAILED','The session worker could not be spawned during startup.'); }\n let nextId = 1;\n const pending = new Map<number, {operation:string;resolve(value:unknown):void;reject(error:Error):void}>();\n const approvals = new Map<number,AbortController>();\n const withdrawApprovals = () => { for (const controller of approvals.values()) controller.abort(); approvals.clear(); };\n let exited = false;\n let closing = false;\n let observedExit = '';\n let markExited!: () => void;\n const processExit = new Promise<void>(resolve => { markExited = resolve; });\n const exit = (code: unknown, signal: unknown, spawnFailure = false) => {\n if (exited) return;\n exited = true;\n observedExit = spawnFailure || closing ? '' : processExitDescription(code,signal);\n withdrawApprovals();\n markExited();\n void launcher.close().catch(() => {}).finally(() => {\n for (const waiting of pending.values()) {\n waiting.reject(new AgentError('HARNESS_FAILED', spawnFailure\n ? `The session worker process failed while ${waiting.operation} was pending.`\n : `The session worker exited while ${waiting.operation} was pending${observedExit}.`));\n }\n pending.clear();\n });\n };\n child.once('error', () => exit(undefined,undefined,true));\n child.once('exit', (code,signal) => exit(code,signal));\n child.on('message', (message: ApprovalEvent | {id:number;result?:unknown;error?:ErrorInfo}) => {\n if ('event' in message) {\n if (message.event === 'approval.withdraw') {\n approvals.get(message.requestId)?.abort(); approvals.delete(message.requestId);\n } else if (message.event === 'approval.request') {\n const controller = new AbortController();\n approvals.set(message.requestId,controller);\n void Promise.resolve().then(() => {\n if (!input.onApproval) throw new AgentError('INPUT_REQUIRED','Native tool approval requires an observing caller.');\n return input.onApproval(message.request,controller.signal);\n }).then(\n content => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,content}); },\n error => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}); },\n ).catch(error => {\n // A rejected control cannot leave an already-settled caller callback parked forever.\n if (!controller.signal.aborted && !exited)\n return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}).catch(() => {});\n }).finally(() => { approvals.delete(message.requestId); });\n }\n return;\n }\n const waiting = pending.get(message.id);\n if (!waiting) return;\n pending.delete(message.id);\n if (message.error) waiting.reject(new AgentError(message.error.code, message.error.message));\n else waiting.resolve(message.result);\n });\n const request = (method:string, extra:Record<string,unknown> = {}) => new Promise<unknown>((resolve,reject) => {\n const operation = workerOperationLabels[method] ?? 'native operation';\n if (exited) {\n reject(new AgentError('HARNESS_FAILED',`The session worker is unavailable while ${operation} was pending${observedExit}.`));\n return;\n }\n const id = nextId++;\n pending.set(id,{operation,resolve,reject});\n child.send({id,method,...extra}, error => {\n if (!error) return;\n setImmediate(() => {\n const waiting = pending.get(id);\n if (!waiting || exited) return;\n pending.delete(id);\n waiting.reject(new AgentError('HARNESS_FAILED',`Cannot reach the session worker while ${operation} was pending.`));\n });\n });\n });\n let selectedHarness: HarnessKind;\n const {onApproval,...serializedInput} = input;\n try { selectedHarness = await request('open',{input:serializedInput,handlesApprovals:!!onApproval}) as HarnessKind; } catch (error) { child.kill(); await launcher.close(); throw error; }\n const stopWorker = async () => {\n if (exited) return;\n if (child.connected) try { child.disconnect(); } catch { /* Continue to termination escalation. */ }\n const timeout = options.shutdownTimeoutMs ?? shutdownTimeoutMs;\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGTERM');\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGKILL');\n if (await waitWithin(processExit,timeout)) return;\n throw new AgentError('HARNESS_FAILED','The session worker did not confirm termination.');\n };\n return {\n selectedHarness,\n turn: prompt => request('turn',{prompt}) as Promise<string>,\n steer: async prompt => { await request('steer',{prompt}); },\n interrupt: async () => { withdrawApprovals(); await request('interrupt'); },\n resume: () => request('resume') as Promise<string>,\n close: async () => {\n closing = true;\n withdrawApprovals();\n let failure: unknown;\n if (!exited) {\n try { await withTimeout(request('close'),closeResponseTimeoutMs); }\n catch (error) { failure = error; }\n }\n try { await stopWorker(); } catch (error) { failure ??= error; }\n try { await launcher.close(); } catch (error) { failure ??= error; }\n if (failure) throw failure;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/runtime/worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from 'node:child_process';\nimport { fileURLToPath } from 'node:url';\nimport { delimiter } from 'node:path';\nimport { AgentError, errorInfo, type ErrorInfo } from '../errors.js';\nimport type { DriverInput } from './types.js';\nimport type { ManagedNativeSession } from './types.js';\nimport type { HarnessKind } from '../sdk/types.js';\nimport { createSessionLauncher } from './session-launcher.js';\nimport type { ApprovalEvent } from './worker-approvals.js';\nimport { processExitDescription } from '../process-diagnostics.js';\n\ninterface WorkerClientOptions {\n workerModule?: URL;\n shutdownTimeoutMs?: number;\n}\n\nconst closeResponseTimeoutMs = 15_000;\nconst shutdownTimeoutMs = 1_000;\n\nconst workerOperationLabels: Record<string,string> = {\n open:'startup',\n turn:'turn submission',\n steer:'steering',\n interrupt:'interruption',\n resume:'recovery',\n close:'closing',\n 'approval.respond':'approval response',\n};\n\nfunction waitWithin(promise: Promise<unknown>, timeout: number): Promise<boolean> {\n return new Promise(resolve => {\n const timer = setTimeout(() => resolve(false),timeout);\n promise.then(\n () => { clearTimeout(timer); resolve(true); },\n () => { clearTimeout(timer); resolve(true); },\n );\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {\n return new Promise((resolve,reject) => {\n const timer = setTimeout(() => reject(new AgentError('HARNESS_FAILED','The session worker did not complete cleanup.')),timeout);\n promise.then(\n value => { clearTimeout(timer); resolve(value); },\n error => { clearTimeout(timer); reject(error); },\n );\n });\n}\n\nexport async function createWorker(input: DriverInput, options: WorkerClientOptions = {}): Promise<ManagedNativeSession> {\n if ('kind' in input.reference && input.reference.kind === 'inline')\n throw new AgentError('INVALID_DEFINITION', 'Inline agent definitions cannot be loaded by native CLI workers.');\n const launcher = await createSessionLauncher(input.env.AGENT_STATE_DIR!,input.token);\n const workerModule = options.workerModule ?? new URL(`./worker.${import.meta.url.endsWith('.ts') ? 'ts' : 'js'}`, import.meta.url);\n const extension = workerModule.pathname.endsWith('.ts') ? 'ts' : 'js';\n let child: ChildProcess;\n try {\n child = fork(fileURLToPath(workerModule), [], {\n cwd: input.cwd, env: {...input.env,AGENT_PARENT_TOKEN:input.token,AGENT_CLI_PATH:launcher.path,\n PATH:launcher.directory + delimiter + (input.env.PATH ?? '')},\n execArgv: extension === 'ts' ? ['--import', import.meta.resolve('tsx')] : [],\n stdio: ['ignore','ignore','ignore','ipc'],\n });\n } catch { await launcher.close(); throw new AgentError('HARNESS_FAILED','The session worker could not be spawned during startup.'); }\n let nextId = 1;\n const pending = new Map<number, {operation:string;resolve(value:unknown):void;reject(error:Error):void}>();\n const approvals = new Map<number,AbortController>();\n const withdrawApprovals = () => { for (const controller of approvals.values()) controller.abort(); approvals.clear(); };\n let exited = false;\n let closing = false;\n let observedExit = '';\n let markExited!: () => void;\n const processExit = new Promise<void>(resolve => { markExited = resolve; });\n const exit = (code: unknown, signal: unknown, spawnFailure = false) => {\n if (exited) return;\n exited = true;\n observedExit = spawnFailure || closing ? '' : processExitDescription(code,signal);\n withdrawApprovals();\n markExited();\n void launcher.close().catch(() => {}).finally(() => {\n for (const waiting of pending.values()) {\n waiting.reject(new AgentError('HARNESS_FAILED', spawnFailure\n ? `The session worker process failed while ${waiting.operation} was pending.`\n : `The session worker exited while ${waiting.operation} was pending${observedExit}.`));\n }\n pending.clear();\n });\n };\n child.once('error', () => exit(undefined,undefined,true));\n child.once('exit', (code,signal) => exit(code,signal));\n child.on('message', (message: ApprovalEvent | {id:number;result?:unknown;error?:ErrorInfo}) => {\n if ('event' in message) {\n if (message.event === 'approval.withdraw') {\n approvals.get(message.requestId)?.abort(); approvals.delete(message.requestId);\n } else if (message.event === 'approval.request') {\n const controller = new AbortController();\n approvals.set(message.requestId,controller);\n void Promise.resolve().then(() => {\n if (!input.onApproval) throw new AgentError('INPUT_REQUIRED','Native tool approval requires an observing caller.');\n return input.onApproval(message.request,controller.signal);\n }).then(\n content => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,content}); },\n error => { if (!controller.signal.aborted && !exited) return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}); },\n ).catch(error => {\n // A rejected control cannot leave an already-settled caller callback parked forever.\n if (!controller.signal.aborted && !exited)\n return request('approval.respond',{requestId:message.requestId,error:errorInfo(error)}).catch(() => {});\n }).finally(() => { approvals.delete(message.requestId); });\n }\n return;\n }\n const waiting = pending.get(message.id);\n if (!waiting) return;\n pending.delete(message.id);\n if (message.error) waiting.reject(new AgentError(message.error.code, message.error.message));\n else waiting.resolve(message.result);\n });\n const request = (method:string, extra:Record<string,unknown> = {}) => new Promise<unknown>((resolve,reject) => {\n const operation = workerOperationLabels[method] ?? 'native operation';\n if (exited) {\n reject(new AgentError('HARNESS_FAILED',`The session worker is unavailable while ${operation} was pending${observedExit}.`));\n return;\n }\n const id = nextId++;\n pending.set(id,{operation,resolve,reject});\n child.send({id,method,...extra}, error => {\n if (!error) return;\n setImmediate(() => {\n const waiting = pending.get(id);\n if (!waiting || exited) return;\n pending.delete(id);\n waiting.reject(new AgentError('HARNESS_FAILED',`Cannot reach the session worker while ${operation} was pending.`));\n });\n });\n });\n let selectedHarness: HarnessKind;\n const {onApproval,...serializedInput} = input;\n try { selectedHarness = await request('open',{input:serializedInput,handlesApprovals:!!onApproval}) as HarnessKind; } catch (error) { child.kill(); await launcher.close(); throw error; }\n const stopWorker = async () => {\n if (exited) return;\n if (child.connected) try { child.disconnect(); } catch { /* Continue to termination escalation. */ }\n const timeout = options.shutdownTimeoutMs ?? shutdownTimeoutMs;\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGTERM');\n if (await waitWithin(processExit,timeout)) return;\n child.kill('SIGKILL');\n if (await waitWithin(processExit,timeout)) return;\n throw new AgentError('HARNESS_FAILED','The session worker did not confirm termination.');\n };\n return {\n selectedHarness,\n turn: prompt => request('turn',{prompt}) as Promise<string>,\n steer: async prompt => { await request('steer',{prompt}); },\n interrupt: async () => { withdrawApprovals(); await request('interrupt'); },\n resume: () => request('resume') as Promise<string>,\n close: async () => {\n closing = true;\n withdrawApprovals();\n let failure: unknown;\n if (!exited) {\n try { await withTimeout(request('close'),closeResponseTimeoutMs); }\n catch (error) { failure = error; }\n }\n try { await stopWorker(); } catch (error) { failure ??= error; }\n try { await launcher.close(); } catch (error) { failure ??= error; }\n if (failure) throw failure;\n },\n };\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { dirname } from 'node:path';
|
|
1
|
+
import { delimiter, dirname } from 'node:path';
|
|
2
2
|
import { rm } from 'node:fs/promises';
|
|
3
|
-
import { loadExecutionDefinition } from './definition.js';
|
|
3
|
+
import { captureExecutionDefinition, loadExecutionDefinition } from './definition.js';
|
|
4
4
|
import { loadAccess } from '../config/access.js';
|
|
5
|
-
import { errorInfo } from '../errors.js';
|
|
5
|
+
import { AgentError, errorInfo } from '../errors.js';
|
|
6
6
|
import { selectNative } from './select-native.js';
|
|
7
7
|
import { NativeOwner } from './native-owner.js';
|
|
8
8
|
import { shellQuote } from '../shell.js';
|
|
@@ -50,20 +50,39 @@ export function delegationInstructions(definition, launcherPath) {
|
|
|
50
50
|
export function startWorker(dependencies = {}) {
|
|
51
51
|
const removeLauncherDirectory = dependencies.removeLauncherDirectory ??
|
|
52
52
|
((path) => rm(path, { recursive: true, force: true }));
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
53
|
+
const leases = new Map();
|
|
54
|
+
let nextLeaseId = 1;
|
|
55
|
+
const legacyLauncher = process.env.AGENT_CLI_PATH;
|
|
56
|
+
const launcherDirectory = legacyLauncher ? dirname(legacyLauncher) : undefined;
|
|
56
57
|
let closing;
|
|
57
58
|
const reply = (message) => { if (process.connected)
|
|
58
59
|
process.send?.(message, () => { }); };
|
|
59
|
-
const
|
|
60
|
+
const newLease = (definition, reference) => {
|
|
61
|
+
const leaseId = nextLeaseId++;
|
|
62
|
+
const approvals = new WorkerApprovals(event => reply({ ...event, leaseId }));
|
|
63
|
+
leases.set(leaseId, { definition, reference, owner: new NativeOwner(), approvals });
|
|
64
|
+
return leaseId;
|
|
65
|
+
};
|
|
66
|
+
const childSummary = (definition) => Object.entries(definition.subagents ?? {})
|
|
67
|
+
.map(([name, child]) => ({ name, description: child.description }));
|
|
68
|
+
const closeLease = async (leaseId) => {
|
|
69
|
+
const lease = leases.get(leaseId);
|
|
70
|
+
if (!lease)
|
|
71
|
+
return;
|
|
72
|
+
lease.approvals.close();
|
|
73
|
+
await lease.owner.close();
|
|
74
|
+
leases.delete(leaseId);
|
|
75
|
+
};
|
|
60
76
|
const close = () => closing ??= (async () => {
|
|
61
|
-
approvals.close();
|
|
62
77
|
try {
|
|
63
|
-
await
|
|
78
|
+
const results = await Promise.allSettled([...leases.keys()].map(closeLease));
|
|
79
|
+
const failure = results.find(result => result.status === 'rejected');
|
|
80
|
+
if (failure?.status === 'rejected')
|
|
81
|
+
throw failure.reason;
|
|
64
82
|
}
|
|
65
83
|
finally {
|
|
66
|
-
|
|
84
|
+
if (launcherDirectory)
|
|
85
|
+
await removeLauncherDirectory(launcherDirectory);
|
|
67
86
|
}
|
|
68
87
|
})();
|
|
69
88
|
process.on('message', async (message) => {
|
|
@@ -83,43 +102,105 @@ export function startWorker(dependencies = {}) {
|
|
|
83
102
|
}
|
|
84
103
|
try {
|
|
85
104
|
let result;
|
|
86
|
-
if (message.method === '
|
|
87
|
-
|
|
88
|
-
|
|
105
|
+
if (message.method === 'capture') {
|
|
106
|
+
const captured = await captureExecutionDefinition(message.agent, process.cwd());
|
|
107
|
+
const leaseId = newLease(captured.definition, captured.reference);
|
|
108
|
+
result = { leaseId, reference: captured.reference, children: childSummary(captured.definition) };
|
|
109
|
+
}
|
|
110
|
+
else if (message.method === 'capture.reference') {
|
|
111
|
+
const reference = message.reference;
|
|
112
|
+
const definition = await loadExecutionDefinition(reference);
|
|
113
|
+
const leaseId = newLease(definition, reference);
|
|
114
|
+
result = { leaseId, reference, children: childSummary(definition) };
|
|
115
|
+
}
|
|
116
|
+
else if (message.method === 'child') {
|
|
117
|
+
const parent = leases.get(message.leaseId);
|
|
118
|
+
const child = parent?.definition.subagents?.[message.name];
|
|
119
|
+
if (!parent || !child)
|
|
120
|
+
throw new AgentError('INVALID_PARENT', 'This subagent is not available in the captured parent context.');
|
|
121
|
+
const parentReference = parent.reference;
|
|
122
|
+
const reference = 'file' in parentReference
|
|
123
|
+
? { file: parentReference.file, subagents: [...parentReference.subagents, message.name] }
|
|
124
|
+
: parentReference;
|
|
125
|
+
const leaseId = newLease(child, reference);
|
|
126
|
+
result = { leaseId, reference, children: childSummary(child) };
|
|
127
|
+
}
|
|
128
|
+
else if (message.method === 'open') {
|
|
129
|
+
let lease;
|
|
130
|
+
if (message.leaseId === undefined) {
|
|
89
131
|
const input = message.input;
|
|
90
132
|
const definition = await loadExecutionDefinition(input.reference);
|
|
91
|
-
const
|
|
92
|
-
|
|
133
|
+
const leaseId = newLease(definition, input.reference);
|
|
134
|
+
lease = leases.get(leaseId);
|
|
135
|
+
message.leaseId = leaseId;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const retained = leases.get(message.leaseId);
|
|
139
|
+
if (!retained)
|
|
140
|
+
throw new AgentError('HARNESS_FAILED', 'The captured execution lease is closed.');
|
|
141
|
+
lease = retained;
|
|
142
|
+
}
|
|
143
|
+
if (lease.native)
|
|
144
|
+
throw new AgentError('HARNESS_FAILED', 'Native session startup is unavailable.');
|
|
145
|
+
let selectedHarness;
|
|
146
|
+
const current = lease;
|
|
147
|
+
const input = message.input;
|
|
148
|
+
const launcherPath = message.launcherPath ?? legacyLauncher;
|
|
149
|
+
const sessionEnvironment = { ...input.env, AGENT_PARENT_TOKEN: input.token, AGENT_CLI_PATH: launcherPath,
|
|
150
|
+
PATH: dirname(launcherPath) + delimiter + (input.env.PATH ?? '') };
|
|
151
|
+
current.native = await current.owner.open(async () => {
|
|
152
|
+
const instructions = delegationInstructions(current.definition, launcherPath);
|
|
153
|
+
return (dependencies.selectNative ?? selectNative)({ ...current.definition, instructions }, input.cwd, sessionEnvironment, await loadAccess(input.cwd), undefined, harness => { selectedHarness = harness; }, message.handlesApprovals ? current.approvals.handle : undefined);
|
|
93
154
|
});
|
|
155
|
+
current.selectedHarness = selectedHarness;
|
|
94
156
|
result = selectedHarness;
|
|
95
157
|
}
|
|
96
|
-
else if (message.method === 'approval.respond')
|
|
97
|
-
|
|
158
|
+
else if (message.method === 'approval.respond') {
|
|
159
|
+
const lease = message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId);
|
|
160
|
+
lease?.approvals.respond(message.requestId, message.content, message.error);
|
|
161
|
+
}
|
|
98
162
|
else if (message.method === 'turn') {
|
|
163
|
+
const lease = message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId);
|
|
99
164
|
try {
|
|
100
|
-
result = await native.turn(message.prompt);
|
|
165
|
+
result = await lease.native.turn(message.prompt);
|
|
101
166
|
}
|
|
102
167
|
finally {
|
|
103
|
-
approvals.close();
|
|
168
|
+
lease.approvals.close();
|
|
104
169
|
}
|
|
105
170
|
}
|
|
106
171
|
else if (message.method === 'steer')
|
|
107
|
-
result = await native.steer(message.prompt);
|
|
172
|
+
result = await (message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId)).native.steer(message.prompt);
|
|
108
173
|
else if (message.method === 'interrupt') {
|
|
109
|
-
|
|
110
|
-
|
|
174
|
+
const lease = (message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId));
|
|
175
|
+
lease.approvals.close();
|
|
176
|
+
result = await lease.native.interrupt();
|
|
111
177
|
}
|
|
112
178
|
else if (message.method === 'resume') {
|
|
179
|
+
const lease = (message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId));
|
|
113
180
|
try {
|
|
114
|
-
result = await native.resume();
|
|
181
|
+
result = await lease.native.resume();
|
|
115
182
|
}
|
|
116
183
|
finally {
|
|
117
|
-
approvals.close();
|
|
184
|
+
lease.approvals.close();
|
|
118
185
|
}
|
|
119
186
|
}
|
|
187
|
+
else if (message.method === 'native.close') {
|
|
188
|
+
const lease = message.leaseId === undefined ? [...leases.values()][0] : leases.get(message.leaseId);
|
|
189
|
+
if (lease) {
|
|
190
|
+
lease.approvals.close();
|
|
191
|
+
await lease.owner.close();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else if (message.method === 'lease.close') {
|
|
195
|
+
await closeLease(message.leaseId);
|
|
196
|
+
result = null;
|
|
197
|
+
}
|
|
120
198
|
else
|
|
121
199
|
throw new Error('Unknown worker operation');
|
|
122
200
|
reply({ id: message.id, result: result ?? null });
|
|
201
|
+
if (message.method === 'lease.close' && leases.size === 0)
|
|
202
|
+
setImmediate(() => { if (process.connected)
|
|
203
|
+
process.disconnect(); });
|
|
123
204
|
}
|
|
124
205
|
catch (error) {
|
|
125
206
|
reply({ id: message.id, error: errorInfo(error) });
|