@robota-sdk/agent-subagent-runner 3.0.0-beta.66
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/LICENSE +21 -0
- package/dist/node/index.cjs +1 -0
- package/dist/node/index.d.ts +93 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Robota Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`node:child_process`),t=require(`node:fs`),n=require(`node:path`),r=require(`@robota-sdk/agent-executor`),i=require(`@robota-sdk/agent-framework`),a=require(`node:url`);function o(e){return typeof e==`object`&&!!e}function s(e,t){return typeof e[t]==`string`}function c(e){return!o(e)||!s(e,`jobId`)||!o(e.request)||!s(e.request,`type`)||!s(e.request,`prompt`)||!o(e.agentDefinition)||!s(e.agentDefinition,`name`)||!s(e.agentDefinition,`systemPrompt`)||!o(e.parentConfig)||!o(e.parentContext)||!o(e.providerProfile)||!s(e.providerProfile,`type`)?!1:s(e.providerProfile,`model`)}function l(e){if(!o(e)||!s(e,`type`))return!1;switch(e.type){case`start`:return c(e.payload);case`send`:return s(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}function u(e){if(!o(e)||!s(e,`type`))return!1;switch(e.type){case`ready`:return!0;case`text_delta`:return s(e,`delta`);case`tool_start`:return s(e,`toolName`);case`tool_end`:return s(e,`toolName`)&&typeof e.success==`boolean`;case`result`:return s(e,`output`);case`error`:return s(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}function d(e,t,n,i,a){switch(e.type){case`ready`:t();break;case`result`:n(e.output);break;case`error`:i(new r.BackgroundTaskError(`runner`,e.message));break;case`cancelled`:i(new r.BackgroundTaskError(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:a?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:a?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:f(e.toolArgs)});break;case`tool_end`:a?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;default:i(new r.BackgroundTaskError(`runner`,`Unhandled subagent worker message`))}}function f(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function p(e,t){return new Promise((n,i)=>{if(!e.connected){i(new r.BackgroundTaskError(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){i(e);return}n()})})}async function m(e,t){e.child.connected&&await p(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),e.killTimer=setTimeout(()=>{e.child.killed||e.child.kill(`SIGTERM`)},e.killGraceMs)}function h(e){return new Promise((t,n)=>{new g(e,t,n).start()})}var g=class{options;resolve;reject;settled=!1;started=!1;timeoutTimer;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n,this.timeoutTimer=v(this.options.runtime,e=>this.rejectOnce(e))}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;p(e,{type:`start`,payload:this.options.payload}).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!u(e)){this.rejectOnce(new r.BackgroundTaskError(`runner`,`Received malformed subagent worker message`));return}let{job:t}=this.options.runtime;d(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit)};onError=e=>{this.rejectOnce(new r.BackgroundTaskError(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new r.BackgroundTaskError(`crash`,b(e,t)))};resolveOnce=e=>{if(this.settled)return;this.settled=!0,this.clearTimers(),this.cleanup();let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(y(t.job,e,n))};rejectOnce=e=>{this.settled||(this.settled=!0,this.clearTimers(),this.cleanup(),this.reject(e))};clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),this.options.runtime.killTimer&&clearTimeout(this.options.runtime.killTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function _(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(i){t||(t=!0,n(new r.BackgroundTaskError(`runner`,i??`Subagent job cancelled: ${e}`)))}}}function v(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{m(e,`Subagent worker timed out`),t(new r.BackgroundTaskError(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function y(e,t,n){let r=n(e);return{jobId:e.jobId,output:t,...r?{metadata:{transcriptPath:r,logPath:r}}:{}}}function b(e,t){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}`}function x(e){return t=>{let n=new S(t,e);return e.worktreeIsolation===!1?n:(0,r.createWorktreeSubagentRunner)({runner:n,worktreeAdapter:e.worktreeAdapter??(0,r.createGitWorktreeIsolationAdapter)(),hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var S=class{deps;workerPath;execArgv;killGraceMs;providerConfig;env;logsDir;constructor(e,t){this.deps=e,this.workerPath=t.workerPath,this.execArgv=t.execArgv,this.killGraceMs=t.killGraceMs??2e3,this.providerConfig=t.providerConfig,this.env=t.env,this.logsDir=t.logsDir}start(t){let n=(0,e.fork)(this.workerPath,[],{cwd:t.request.cwd,env:{...process.env,...this.env??{}},execArgv:this.execArgv??E(this.workerPath),stdio:[`ignore`,`ignore`,`ignore`,`ipc`]}),r={job:t,child:n,killGraceMs:this.killGraceMs},i=h({runtime:r,payload:this.createStartPayload(t),resolveTranscriptPath:e=>this.resolveTranscriptPath(e)}),a=_(t.jobId);i.catch(()=>void 0);let o=Promise.race([i,a.promise]),s=this.resolveTranscriptPath(t);return{jobId:t.jobId,...n.pid!==void 0&&{pid:n.pid},...s!==void 0&&{transcriptPath:s,logPath:s},result:o,cancel:async e=>{a.reject(e),await m(r,e)},send:async e=>{await p(n,{type:`send`,prompt:e})},...s!==void 0&&{readLog:async e=>D(t.jobId,s,e)}}}createStartPayload(e){let t=C(e.request.type,this.deps.customAgentRegistry);return{jobId:e.jobId,request:e.request,agentDefinition:w(t,e),parentConfig:this.deps.config,parentContext:this.deps.context,providerProfile:T(this.providerConfig,this.deps,e),permissionMode:this.deps.permissionMode,...this.logsDir?{logsDir:this.logsDir}:{}}}resolveTranscriptPath(e){if(this.logsDir)return(0,n.join)(this.logsDir,e.request.parentSessionId,`subagents`,`${e.jobId}.jsonl`)}};function C(e,t){let n=t?.(e)??(0,i.getBuiltInAgent)(e);if(!n)throw new r.BackgroundTaskError(`validation`,`Unknown agent type: ${e}`);return n}function w(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function T(e,t,n){let r=e??t.config.provider;return{profileName:t.config.currentProvider,type:r.name,model:n.request.model??r.model,apiKey:r.apiKey,baseURL:r.baseURL,timeout:r.timeout,options:r.options}}function E(e){return!e.endsWith(`.ts`)||process.execArgv.some(e=>e.includes(`tsx`))?process.execArgv:[...process.execArgv,`--import`,`tsx`]}function D(e,n,i){return(0,t.existsSync)(n)?(0,r.createBackgroundTaskLogPage)(e,(0,t.readFileSync)(n,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function O(){return(0,n.join)((0,n.dirname)((0,a.fileURLToPath)(require(`url`).pathToFileURL(__filename).href)),`child-process-subagent-worker.js`)}exports.ChildProcessSubagentRunner=S,exports.createChildProcessSubagentRunnerFactory=x,exports.getDefaultSubagentWorkerPath=O,exports.isSubagentWorkerChildMessage=u,exports.isSubagentWorkerParentMessage=l;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ISerializableProviderProfile, ISubagentJobHandle, ISubagentJobStart, ISubagentRunner, ISubagentSpawnRequest, ISubagentWorktreeAdapter } from "@robota-sdk/agent-executor";
|
|
2
|
+
import { IProviderConfig, TPermissionMode, TToolArgs } from "@robota-sdk/agent-core";
|
|
3
|
+
import { IAgentDefinition, IInProcessSubagentRunnerDeps, TSubagentRunnerFactory } from "@robota-sdk/agent-framework";
|
|
4
|
+
|
|
5
|
+
//#region src/child-process-subagent-runner.d.ts
|
|
6
|
+
interface IChildProcessSubagentRunnerOptions {
|
|
7
|
+
workerPath: string;
|
|
8
|
+
providerConfig?: IProviderConfig;
|
|
9
|
+
execArgv?: string[];
|
|
10
|
+
killGraceMs?: number;
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
worktreeIsolation?: boolean;
|
|
13
|
+
worktreeAdapter?: ISubagentWorktreeAdapter;
|
|
14
|
+
logsDir?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function createChildProcessSubagentRunnerFactory(options: IChildProcessSubagentRunnerOptions): TSubagentRunnerFactory;
|
|
17
|
+
declare class ChildProcessSubagentRunner implements ISubagentRunner {
|
|
18
|
+
private readonly deps;
|
|
19
|
+
private readonly workerPath;
|
|
20
|
+
private readonly execArgv?;
|
|
21
|
+
private readonly killGraceMs;
|
|
22
|
+
private readonly providerConfig?;
|
|
23
|
+
private readonly env?;
|
|
24
|
+
private readonly logsDir?;
|
|
25
|
+
constructor(deps: IInProcessSubagentRunnerDeps, options: IChildProcessSubagentRunnerOptions);
|
|
26
|
+
start(job: ISubagentJobStart): ISubagentJobHandle;
|
|
27
|
+
private createStartPayload;
|
|
28
|
+
private resolveTranscriptPath;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/child-process-subagent-ipc.d.ts
|
|
32
|
+
type TSubagentWorkerWireValue = string | number | boolean | null | undefined | object;
|
|
33
|
+
interface ISubagentWorkerStartPayload {
|
|
34
|
+
jobId: string;
|
|
35
|
+
request: ISubagentSpawnRequest;
|
|
36
|
+
agentDefinition: IAgentDefinition;
|
|
37
|
+
parentConfig: IInProcessSubagentRunnerDeps['config'];
|
|
38
|
+
parentContext: IInProcessSubagentRunnerDeps['context'];
|
|
39
|
+
providerProfile: ISerializableProviderProfile;
|
|
40
|
+
permissionMode?: TPermissionMode;
|
|
41
|
+
logsDir?: string;
|
|
42
|
+
}
|
|
43
|
+
interface ISubagentWorkerStartMessage {
|
|
44
|
+
type: 'start';
|
|
45
|
+
payload: ISubagentWorkerStartPayload;
|
|
46
|
+
}
|
|
47
|
+
interface ISubagentWorkerSendMessage {
|
|
48
|
+
type: 'send';
|
|
49
|
+
prompt: string;
|
|
50
|
+
}
|
|
51
|
+
interface ISubagentWorkerCancelMessage {
|
|
52
|
+
type: 'cancel';
|
|
53
|
+
reason?: string;
|
|
54
|
+
}
|
|
55
|
+
type TSubagentWorkerParentMessage = ISubagentWorkerStartMessage | ISubagentWorkerSendMessage | ISubagentWorkerCancelMessage;
|
|
56
|
+
interface ISubagentWorkerReadyMessage {
|
|
57
|
+
type: 'ready';
|
|
58
|
+
}
|
|
59
|
+
interface ISubagentWorkerTextDeltaMessage {
|
|
60
|
+
type: 'text_delta';
|
|
61
|
+
delta: string;
|
|
62
|
+
}
|
|
63
|
+
interface ISubagentWorkerToolStartMessage {
|
|
64
|
+
type: 'tool_start';
|
|
65
|
+
toolName: string;
|
|
66
|
+
toolArgs?: TToolArgs;
|
|
67
|
+
}
|
|
68
|
+
interface ISubagentWorkerToolEndMessage {
|
|
69
|
+
type: 'tool_end';
|
|
70
|
+
toolName: string;
|
|
71
|
+
success: boolean;
|
|
72
|
+
}
|
|
73
|
+
interface ISubagentWorkerResultMessage {
|
|
74
|
+
type: 'result';
|
|
75
|
+
output: string;
|
|
76
|
+
}
|
|
77
|
+
interface ISubagentWorkerErrorMessage {
|
|
78
|
+
type: 'error';
|
|
79
|
+
message: string;
|
|
80
|
+
}
|
|
81
|
+
interface ISubagentWorkerCancelledMessage {
|
|
82
|
+
type: 'cancelled';
|
|
83
|
+
reason?: string;
|
|
84
|
+
}
|
|
85
|
+
type TSubagentWorkerChildMessage = ISubagentWorkerReadyMessage | ISubagentWorkerTextDeltaMessage | ISubagentWorkerToolStartMessage | ISubagentWorkerToolEndMessage | ISubagentWorkerResultMessage | ISubagentWorkerErrorMessage | ISubagentWorkerCancelledMessage;
|
|
86
|
+
declare function isSubagentWorkerParentMessage(value: TSubagentWorkerWireValue): value is TSubagentWorkerParentMessage;
|
|
87
|
+
declare function isSubagentWorkerChildMessage(value: TSubagentWorkerWireValue): value is TSubagentWorkerChildMessage;
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/worker-path-resolver.d.ts
|
|
90
|
+
declare function getDefaultSubagentWorkerPath(): string;
|
|
91
|
+
//#endregion
|
|
92
|
+
export { ChildProcessSubagentRunner, type IChildProcessSubagentRunnerOptions, type ISubagentWorkerStartPayload, type TSubagentWorkerChildMessage, type TSubagentWorkerParentMessage, type TSubagentWorkerWireValue, createChildProcessSubagentRunnerFactory, getDefaultSubagentWorkerPath, isSubagentWorkerChildMessage, isSubagentWorkerParentMessage };
|
|
93
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/child-process-subagent-runner.ts","../../src/child-process-subagent-ipc.ts","../../src/worker-path-resolver.ts"],"mappings":";;;;;UAuCiB,kCAAA;EACf,UAAA;EACA,cAAA,GAAiB,eAAA;EACjB,QAAA;EACA,WAAA;EACA,GAAA,GAAM,MAAA,CAAO,UAAA;EACb,iBAAA;EACA,eAAA,GAAkB,wBAAA;EAClB,OAAA;AAAA;AAAA,iBAGc,uCAAA,CACd,OAAA,EAAS,kCAAA,GACR,sBAAsB;AAAA,cAaZ,0BAAA,YAAsC,eAAA;EAAA,iBAS9B,IAAA;EAAA,iBARF,UAAA;EAAA,iBACA,QAAA;EAAA,iBACA,WAAA;EAAA,iBACA,cAAA;EAAA,iBACA,GAAA;EAAA,iBACA,OAAA;cAGE,IAAA,EAAM,4BAAA,EACvB,OAAA,EAAS,kCAAA;EAUX,KAAA,CAAM,GAAA,EAAK,iBAAA,GAAoB,kBAAA;EAAA,QA0CvB,kBAAA;EAAA,QAcA,qBAAA;AAAA;;;KCtIE,wBAAA;AAAA,UAIK,2BAAA;EACf,KAAA;EACA,OAAA,EAAS,qBAAA;EACT,eAAA,EAAiB,gBAAA;EACjB,YAAA,EAAc,4BAAA;EACd,aAAA,EAAe,4BAAA;EACf,eAAA,EAAiB,4BAAA;EACjB,cAAA,GAAiB,eAAA;EACjB,OAAA;AAAA;AAAA,UAGe,2BAAA;EACf,IAAA;EACA,OAAA,EAAS,2BAA2B;AAAA;AAAA,UAGrB,0BAAA;EACf,IAAA;EACA,MAAM;AAAA;AAAA,UAGS,4BAAA;EACf,IAAA;EACA,MAAM;AAAA;AAAA,KAGI,4BAAA,GACR,2BAAA,GACA,0BAAA,GACA,4BAAA;AAAA,UAEa,2BAAA;EACf,IAAI;AAAA;AAAA,UAGW,+BAAA;EACf,IAAA;EACA,KAAK;AAAA;AAAA,UAGU,+BAAA;EACf,IAAA;EACA,QAAA;EACA,QAAA,GAAW,SAAS;AAAA;AAAA,UAGL,6BAAA;EACf,IAAA;EACA,QAAA;EACA,OAAA;AAAA;AAAA,UAGe,4BAAA;EACf,IAAA;EACA,MAAM;AAAA;AAAA,UAGS,2BAAA;EACf,IAAA;EACA,OAAO;AAAA;AAAA,UAGQ,+BAAA;EACf,IAAA;EACA,MAAM;AAAA;AAAA,KAGI,2BAAA,GACR,2BAAA,GACA,+BAAA,GACA,+BAAA,GACA,6BAAA,GACA,4BAAA,GACA,2BAAA,GACA,+BAAA;AAAA,iBA0BY,6BAAA,CACd,KAAA,EAAO,wBAAA,GACN,KAAA,IAAS,4BAA4B;AAAA,iBAcxB,4BAAA,CACd,KAAA,EAAO,wBAAA,GACN,KAAA,IAAS,2BAA2B;;;iBC9HvB,4BAAA,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{fork as e}from"node:child_process";import{existsSync as t,readFileSync as n}from"node:fs";import{dirname as r,join as i}from"node:path";import{BackgroundTaskError as a,createBackgroundTaskLogPage as o,createGitWorktreeIsolationAdapter as s,createWorktreeSubagentRunner as c}from"@robota-sdk/agent-executor";import{getBuiltInAgent as l}from"@robota-sdk/agent-framework";import{fileURLToPath as u}from"node:url";function d(e){return typeof e==`object`&&!!e}function f(e,t){return typeof e[t]==`string`}function p(e){return!d(e)||!f(e,`jobId`)||!d(e.request)||!f(e.request,`type`)||!f(e.request,`prompt`)||!d(e.agentDefinition)||!f(e.agentDefinition,`name`)||!f(e.agentDefinition,`systemPrompt`)||!d(e.parentConfig)||!d(e.parentContext)||!d(e.providerProfile)||!f(e.providerProfile,`type`)?!1:f(e.providerProfile,`model`)}function m(e){if(!d(e)||!f(e,`type`))return!1;switch(e.type){case`start`:return p(e.payload);case`send`:return f(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}function h(e){if(!d(e)||!f(e,`type`))return!1;switch(e.type){case`ready`:return!0;case`text_delta`:return f(e,`delta`);case`tool_start`:return f(e,`toolName`);case`tool_end`:return f(e,`toolName`)&&typeof e.success==`boolean`;case`result`:return f(e,`output`);case`error`:return f(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}function g(e,t,n,r,i){switch(e.type){case`ready`:t();break;case`result`:n(e.output);break;case`error`:r(new a(`runner`,e.message));break;case`cancelled`:r(new a(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:i?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:i?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:_(e.toolArgs)});break;case`tool_end`:i?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;default:r(new a(`runner`,`Unhandled subagent worker message`))}}function _(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function v(e,t){return new Promise((n,r)=>{if(!e.connected){r(new a(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){r(e);return}n()})})}async function y(e,t){e.child.connected&&await v(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),e.killTimer=setTimeout(()=>{e.child.killed||e.child.kill(`SIGTERM`)},e.killGraceMs)}function b(e){return new Promise((t,n)=>{new x(e,t,n).start()})}var x=class{options;resolve;reject;settled=!1;started=!1;timeoutTimer;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n,this.timeoutTimer=C(this.options.runtime,e=>this.rejectOnce(e))}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;v(e,{type:`start`,payload:this.options.payload}).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!h(e)){this.rejectOnce(new a(`runner`,`Received malformed subagent worker message`));return}let{job:t}=this.options.runtime;g(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit)};onError=e=>{this.rejectOnce(new a(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new a(`crash`,T(e,t)))};resolveOnce=e=>{if(this.settled)return;this.settled=!0,this.clearTimers(),this.cleanup();let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(w(t.job,e,n))};rejectOnce=e=>{this.settled||(this.settled=!0,this.clearTimers(),this.cleanup(),this.reject(e))};clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),this.options.runtime.killTimer&&clearTimeout(this.options.runtime.killTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function S(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(r){t||(t=!0,n(new a(`runner`,r??`Subagent job cancelled: ${e}`)))}}}function C(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{y(e,`Subagent worker timed out`),t(new a(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function w(e,t,n){let r=n(e);return{jobId:e.jobId,output:t,...r?{metadata:{transcriptPath:r,logPath:r}}:{}}}function T(e,t){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}`}function E(e){return t=>{let n=new D(t,e);return e.worktreeIsolation===!1?n:c({runner:n,worktreeAdapter:e.worktreeAdapter??s(),hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var D=class{deps;workerPath;execArgv;killGraceMs;providerConfig;env;logsDir;constructor(e,t){this.deps=e,this.workerPath=t.workerPath,this.execArgv=t.execArgv,this.killGraceMs=t.killGraceMs??2e3,this.providerConfig=t.providerConfig,this.env=t.env,this.logsDir=t.logsDir}start(t){let n=e(this.workerPath,[],{cwd:t.request.cwd,env:{...process.env,...this.env??{}},execArgv:this.execArgv??j(this.workerPath),stdio:[`ignore`,`ignore`,`ignore`,`ipc`]}),r={job:t,child:n,killGraceMs:this.killGraceMs},i=b({runtime:r,payload:this.createStartPayload(t),resolveTranscriptPath:e=>this.resolveTranscriptPath(e)}),a=S(t.jobId);i.catch(()=>void 0);let o=Promise.race([i,a.promise]),s=this.resolveTranscriptPath(t);return{jobId:t.jobId,...n.pid!==void 0&&{pid:n.pid},...s!==void 0&&{transcriptPath:s,logPath:s},result:o,cancel:async e=>{a.reject(e),await y(r,e)},send:async e=>{await v(n,{type:`send`,prompt:e})},...s!==void 0&&{readLog:async e=>M(t.jobId,s,e)}}}createStartPayload(e){let t=O(e.request.type,this.deps.customAgentRegistry);return{jobId:e.jobId,request:e.request,agentDefinition:k(t,e),parentConfig:this.deps.config,parentContext:this.deps.context,providerProfile:A(this.providerConfig,this.deps,e),permissionMode:this.deps.permissionMode,...this.logsDir?{logsDir:this.logsDir}:{}}}resolveTranscriptPath(e){if(this.logsDir)return i(this.logsDir,e.request.parentSessionId,`subagents`,`${e.jobId}.jsonl`)}};function O(e,t){let n=t?.(e)??l(e);if(!n)throw new a(`validation`,`Unknown agent type: ${e}`);return n}function k(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function A(e,t,n){let r=e??t.config.provider;return{profileName:t.config.currentProvider,type:r.name,model:n.request.model??r.model,apiKey:r.apiKey,baseURL:r.baseURL,timeout:r.timeout,options:r.options}}function j(e){return!e.endsWith(`.ts`)||process.execArgv.some(e=>e.includes(`tsx`))?process.execArgv:[...process.execArgv,`--import`,`tsx`]}function M(e,r,i){return t(r)?o(e,n(r,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function N(){return i(r(u(import.meta.url)),`child-process-subagent-worker.js`)}export{D as ChildProcessSubagentRunner,E as createChildProcessSubagentRunnerFactory,N as getDefaultSubagentWorkerPath,h as isSubagentWorkerChildMessage,m as isSubagentWorkerParentMessage};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/child-process-subagent-ipc.ts","../../src/child-process-subagent-transport.ts","../../src/child-process-subagent-runner-result.ts","../../src/child-process-subagent-runner.ts","../../src/worker-path-resolver.ts"],"sourcesContent":["import type { TPermissionMode, TToolArgs } from '@robota-sdk/agent-core';\nimport type {\n ISerializableProviderProfile,\n ISubagentSpawnRequest,\n} from '@robota-sdk/agent-executor';\nimport type { IAgentDefinition, IInProcessSubagentRunnerDeps } from '@robota-sdk/agent-framework';\n\nexport type TSubagentWorkerWireValue = string | number | boolean | null | undefined | object;\n\ntype TSubagentWorkerWireRecord = Record<string, TSubagentWorkerWireValue>;\n\nexport interface ISubagentWorkerStartPayload {\n jobId: string;\n request: ISubagentSpawnRequest;\n agentDefinition: IAgentDefinition;\n parentConfig: IInProcessSubagentRunnerDeps['config'];\n parentContext: IInProcessSubagentRunnerDeps['context'];\n providerProfile: ISerializableProviderProfile;\n permissionMode?: TPermissionMode;\n logsDir?: string;\n}\n\nexport interface ISubagentWorkerStartMessage {\n type: 'start';\n payload: ISubagentWorkerStartPayload;\n}\n\nexport interface ISubagentWorkerSendMessage {\n type: 'send';\n prompt: string;\n}\n\nexport interface ISubagentWorkerCancelMessage {\n type: 'cancel';\n reason?: string;\n}\n\nexport type TSubagentWorkerParentMessage =\n | ISubagentWorkerStartMessage\n | ISubagentWorkerSendMessage\n | ISubagentWorkerCancelMessage;\n\nexport interface ISubagentWorkerReadyMessage {\n type: 'ready';\n}\n\nexport interface ISubagentWorkerTextDeltaMessage {\n type: 'text_delta';\n delta: string;\n}\n\nexport interface ISubagentWorkerToolStartMessage {\n type: 'tool_start';\n toolName: string;\n toolArgs?: TToolArgs;\n}\n\nexport interface ISubagentWorkerToolEndMessage {\n type: 'tool_end';\n toolName: string;\n success: boolean;\n}\n\nexport interface ISubagentWorkerResultMessage {\n type: 'result';\n output: string;\n}\n\nexport interface ISubagentWorkerErrorMessage {\n type: 'error';\n message: string;\n}\n\nexport interface ISubagentWorkerCancelledMessage {\n type: 'cancelled';\n reason?: string;\n}\n\nexport type TSubagentWorkerChildMessage =\n | ISubagentWorkerReadyMessage\n | ISubagentWorkerTextDeltaMessage\n | ISubagentWorkerToolStartMessage\n | ISubagentWorkerToolEndMessage\n | ISubagentWorkerResultMessage\n | ISubagentWorkerErrorMessage\n | ISubagentWorkerCancelledMessage;\n\nfunction isRecord(value: TSubagentWorkerWireValue): value is TSubagentWorkerWireRecord {\n return typeof value === 'object' && value !== null;\n}\n\nfunction hasString(value: TSubagentWorkerWireRecord, key: string): boolean {\n return typeof value[key] === 'string';\n}\n\nfunction isStartPayload(value: TSubagentWorkerWireValue): value is ISubagentWorkerStartPayload {\n if (!isRecord(value)) return false;\n if (!hasString(value, 'jobId')) return false;\n if (!isRecord(value.request)) return false;\n if (!hasString(value.request, 'type')) return false;\n if (!hasString(value.request, 'prompt')) return false;\n if (!isRecord(value.agentDefinition)) return false;\n if (!hasString(value.agentDefinition, 'name')) return false;\n if (!hasString(value.agentDefinition, 'systemPrompt')) return false;\n if (!isRecord(value.parentConfig)) return false;\n if (!isRecord(value.parentContext)) return false;\n if (!isRecord(value.providerProfile)) return false;\n if (!hasString(value.providerProfile, 'type')) return false;\n return hasString(value.providerProfile, 'model');\n}\n\nexport function isSubagentWorkerParentMessage(\n value: TSubagentWorkerWireValue,\n): value is TSubagentWorkerParentMessage {\n if (!isRecord(value) || !hasString(value, 'type')) return false;\n switch (value.type) {\n case 'start':\n return isStartPayload(value.payload);\n case 'send':\n return hasString(value, 'prompt');\n case 'cancel':\n return value.reason === undefined || typeof value.reason === 'string';\n default:\n return false;\n }\n}\n\nexport function isSubagentWorkerChildMessage(\n value: TSubagentWorkerWireValue,\n): value is TSubagentWorkerChildMessage {\n if (!isRecord(value) || !hasString(value, 'type')) return false;\n switch (value.type) {\n case 'ready':\n return true;\n case 'text_delta':\n return hasString(value, 'delta');\n case 'tool_start':\n return hasString(value, 'toolName');\n case 'tool_end':\n return hasString(value, 'toolName') && typeof value.success === 'boolean';\n case 'result':\n return hasString(value, 'output');\n case 'error':\n return hasString(value, 'message');\n case 'cancelled':\n return value.reason === undefined || typeof value.reason === 'string';\n default:\n return false;\n }\n}\n","import {\n BackgroundTaskError,\n type ISubagentJobStart,\n type TBackgroundTaskRunnerEvent,\n} from '@robota-sdk/agent-executor';\n\nimport type {\n TSubagentWorkerChildMessage,\n TSubagentWorkerParentMessage,\n} from './child-process-subagent-ipc.js';\nimport type { TToolArgs } from '@robota-sdk/agent-core';\nimport type { ChildProcess } from 'node:child_process';\n\nexport interface IChildProcessRuntime {\n job: ISubagentJobStart;\n child: ChildProcess;\n killGraceMs: number;\n killTimer?: ReturnType<typeof setTimeout>;\n}\n\nexport function handleWorkerMessage(\n message: TSubagentWorkerChildMessage,\n startWorker: () => void,\n resolveOnce: (output: string) => void,\n rejectOnce: (error: Error) => void,\n emit?: (event: TBackgroundTaskRunnerEvent) => void,\n): void {\n switch (message.type) {\n case 'ready':\n startWorker();\n break;\n case 'result':\n resolveOnce(message.output);\n break;\n case 'error':\n rejectOnce(new BackgroundTaskError('runner', message.message));\n break;\n case 'cancelled':\n rejectOnce(new BackgroundTaskError('runner', message.reason ?? 'Subagent worker cancelled'));\n break;\n case 'text_delta':\n emit?.({ type: 'background_task_text_delta', delta: message.delta });\n break;\n case 'tool_start':\n emit?.({\n type: 'background_task_tool_start',\n toolName: message.toolName,\n firstArg: extractFirstArg(message.toolArgs),\n });\n break;\n case 'tool_end':\n emit?.({\n type: 'background_task_tool_end',\n toolName: message.toolName,\n success: message.success,\n });\n break;\n default:\n rejectOnce(new BackgroundTaskError('runner', 'Unhandled subagent worker message'));\n }\n}\n\nfunction extractFirstArg(toolArgs?: TToolArgs): string | undefined {\n if (!toolArgs) return undefined;\n const firstValue = Object.values(toolArgs)[0];\n if (firstValue === undefined) return undefined;\n return typeof firstValue === 'object' ? JSON.stringify(firstValue) : String(firstValue);\n}\n\nexport function sendWorkerMessage(\n child: ChildProcess,\n message: TSubagentWorkerParentMessage,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!child.connected) {\n reject(new BackgroundTaskError('crash', 'Subagent worker IPC channel is closed'));\n return;\n }\n child.send(message, (error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nexport async function cancelChildProcess(\n runtime: IChildProcessRuntime,\n reason?: string,\n): Promise<void> {\n if (runtime.child.connected) {\n await sendWorkerMessage(runtime.child, { type: 'cancel', reason }).catch(() => undefined);\n }\n runtime.killTimer = setTimeout(() => {\n if (!runtime.child.killed) {\n runtime.child.kill('SIGTERM');\n }\n }, runtime.killGraceMs);\n}\n","import {\n BackgroundTaskError,\n type ISubagentJobResult,\n type ISubagentJobStart,\n} from '@robota-sdk/agent-executor';\n\nimport {\n isSubagentWorkerChildMessage,\n type ISubagentWorkerStartPayload,\n type TSubagentWorkerWireValue,\n} from './child-process-subagent-ipc.js';\nimport {\n cancelChildProcess,\n handleWorkerMessage,\n sendWorkerMessage,\n type IChildProcessRuntime,\n} from './child-process-subagent-transport.js';\n\nexport interface ICancellationResult {\n promise: Promise<ISubagentJobResult>;\n reject(reason?: string): void;\n}\n\nexport interface IChildProcessSubagentResultOptions {\n runtime: IChildProcessRuntime;\n payload: ISubagentWorkerStartPayload;\n resolveTranscriptPath: (job: ISubagentJobStart) => string | undefined;\n}\n\nexport function createChildProcessSubagentResult(\n options: IChildProcessSubagentResultOptions,\n): Promise<ISubagentJobResult> {\n return new Promise<ISubagentJobResult>((resolve, reject) => {\n new ChildProcessSubagentResultController(options, resolve, reject).start();\n });\n}\n\nclass ChildProcessSubagentResultController {\n private settled = false;\n private started = false;\n private readonly timeoutTimer?: ReturnType<typeof setTimeout>;\n\n constructor(\n private readonly options: IChildProcessSubagentResultOptions,\n private readonly resolve: (result: ISubagentJobResult) => void,\n private readonly reject: (error: Error) => void,\n ) {\n this.timeoutTimer = createTimeoutTimer(this.options.runtime, (error) => this.rejectOnce(error));\n }\n\n start(): void {\n const { child } = this.options.runtime;\n child.on('message', this.onMessage);\n child.on('error', this.onError);\n child.on('exit', this.onExit);\n child.once('spawn', () => {\n setImmediate(this.startWorker);\n });\n }\n\n private readonly startWorker = (): void => {\n if (this.started) return;\n this.started = true;\n const { child } = this.options.runtime;\n void sendWorkerMessage(child, { type: 'start', payload: this.options.payload }).catch(\n (error) => {\n this.rejectOnce(error instanceof Error ? error : new Error(String(error)));\n },\n );\n };\n\n private readonly onMessage = (message: TSubagentWorkerWireValue): void => {\n if (!isSubagentWorkerChildMessage(message)) {\n this.rejectOnce(\n new BackgroundTaskError('runner', 'Received malformed subagent worker message'),\n );\n return;\n }\n const { job } = this.options.runtime;\n handleWorkerMessage(message, this.startWorker, this.resolveOnce, this.rejectOnce, job.emit);\n };\n\n private readonly onError = (error: Error): void => {\n this.rejectOnce(new BackgroundTaskError('crash', error.message));\n };\n\n private readonly onExit = (code: number | null, signal: NodeJS.Signals | null): void => {\n if (this.settled) return;\n this.rejectOnce(new BackgroundTaskError('crash', formatEarlyExitMessage(code, signal)));\n };\n\n private readonly resolveOnce = (output: string): void => {\n if (this.settled) return;\n this.settled = true;\n this.clearTimers();\n this.cleanup();\n const { runtime, resolveTranscriptPath } = this.options;\n this.resolve(toSubagentResult(runtime.job, output, resolveTranscriptPath));\n };\n\n private readonly rejectOnce = (error: Error): void => {\n if (this.settled) return;\n this.settled = true;\n this.clearTimers();\n this.cleanup();\n this.reject(error);\n };\n\n private clearTimers(): void {\n if (this.timeoutTimer) clearTimeout(this.timeoutTimer);\n if (this.options.runtime.killTimer) clearTimeout(this.options.runtime.killTimer);\n }\n\n private cleanup(): void {\n const { child } = this.options.runtime;\n child.off('message', this.onMessage);\n child.off('error', this.onError);\n child.off('exit', this.onExit);\n }\n}\n\nexport function createCancellationResult(jobId: string): ICancellationResult {\n let settled = false;\n let rejectFn: (error: Error) => void = () => {};\n const promise = new Promise<ISubagentJobResult>((_resolve, reject) => {\n rejectFn = reject;\n });\n return {\n promise,\n reject(reason?: string): void {\n if (settled) return;\n settled = true;\n rejectFn(new BackgroundTaskError('runner', reason ?? `Subagent job cancelled: ${jobId}`));\n },\n };\n}\n\nfunction createTimeoutTimer(\n runtime: IChildProcessRuntime,\n rejectOnce: (error: Error) => void,\n): ReturnType<typeof setTimeout> | undefined {\n if (!runtime.job.request.timeoutMs) return undefined;\n return setTimeout(() => {\n void cancelChildProcess(runtime, 'Subagent worker timed out');\n rejectOnce(new BackgroundTaskError('timeout', 'Subagent worker timed out'));\n }, runtime.job.request.timeoutMs);\n}\n\nfunction toSubagentResult(\n job: ISubagentJobStart,\n output: string,\n resolveTranscriptPath: (job: ISubagentJobStart) => string | undefined,\n): ISubagentJobResult {\n const transcriptPath = resolveTranscriptPath(job);\n return {\n jobId: job.jobId,\n output,\n ...(transcriptPath ? { metadata: { transcriptPath, logPath: transcriptPath } } : {}),\n };\n}\n\nfunction formatEarlyExitMessage(code: number | null, signal: NodeJS.Signals | null): string {\n const detail =\n signal !== null ? `signal ${signal}` : `exit code ${code === null ? 'unknown' : code}`;\n return `Subagent worker exited before result: ${detail}`;\n}\n","import { fork } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport {\n BackgroundTaskError,\n createBackgroundTaskLogPage,\n createGitWorktreeIsolationAdapter,\n createWorktreeSubagentRunner,\n type IBackgroundTaskLogCursor,\n type IBackgroundTaskLogPage,\n type ISerializableProviderProfile,\n type ISubagentJobHandle,\n type ISubagentJobStart,\n type ISubagentRunner,\n type ISubagentWorktreeAdapter,\n} from '@robota-sdk/agent-executor';\nimport { getBuiltInAgent } from '@robota-sdk/agent-framework';\n\nimport {\n createCancellationResult,\n createChildProcessSubagentResult,\n} from './child-process-subagent-runner-result.js';\nimport {\n cancelChildProcess,\n sendWorkerMessage,\n type IChildProcessRuntime,\n} from './child-process-subagent-transport.js';\n\nimport type { ISubagentWorkerStartPayload } from './child-process-subagent-ipc.js';\nimport type { IProviderConfig } from '@robota-sdk/agent-core';\nimport type {\n IAgentDefinition,\n IInProcessSubagentRunnerDeps,\n TSubagentRunnerFactory,\n} from '@robota-sdk/agent-framework';\n\nconst DEFAULT_KILL_GRACE_MS = 2_000;\n\nexport interface IChildProcessSubagentRunnerOptions {\n workerPath: string;\n providerConfig?: IProviderConfig;\n execArgv?: string[];\n killGraceMs?: number;\n env?: NodeJS.ProcessEnv;\n worktreeIsolation?: boolean;\n worktreeAdapter?: ISubagentWorktreeAdapter;\n logsDir?: string;\n}\n\nexport function createChildProcessSubagentRunnerFactory(\n options: IChildProcessSubagentRunnerOptions,\n): TSubagentRunnerFactory {\n return (deps) => {\n const runner = new ChildProcessSubagentRunner(deps, options);\n if (options.worktreeIsolation === false) return runner;\n return createWorktreeSubagentRunner({\n runner,\n worktreeAdapter: options.worktreeAdapter ?? createGitWorktreeIsolationAdapter(),\n hooks: deps.config.hooks,\n hookTypeExecutors: deps.hookTypeExecutors,\n });\n };\n}\n\nexport class ChildProcessSubagentRunner implements ISubagentRunner {\n private readonly workerPath: string;\n private readonly execArgv?: string[];\n private readonly killGraceMs: number;\n private readonly providerConfig?: IProviderConfig;\n private readonly env?: NodeJS.ProcessEnv;\n private readonly logsDir?: string;\n\n constructor(\n private readonly deps: IInProcessSubagentRunnerDeps,\n options: IChildProcessSubagentRunnerOptions,\n ) {\n this.workerPath = options.workerPath;\n this.execArgv = options.execArgv;\n this.killGraceMs = options.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n this.providerConfig = options.providerConfig;\n this.env = options.env;\n this.logsDir = options.logsDir;\n }\n\n start(job: ISubagentJobStart): ISubagentJobHandle {\n const child = fork(this.workerPath, [], {\n cwd: job.request.cwd,\n env: { ...process.env, ...(this.env ?? {}) },\n execArgv: this.execArgv ?? resolveExecArgv(this.workerPath),\n stdio: ['ignore', 'ignore', 'ignore', 'ipc'],\n });\n const runtime: IChildProcessRuntime = {\n job,\n child,\n killGraceMs: this.killGraceMs,\n };\n const payload = this.createStartPayload(job);\n const workerResult = createChildProcessSubagentResult({\n runtime,\n payload,\n resolveTranscriptPath: (request) => this.resolveTranscriptPath(request),\n });\n const cancellation = createCancellationResult(job.jobId);\n void workerResult.catch(() => undefined);\n const result = Promise.race([workerResult, cancellation.promise]);\n const transcriptPath = this.resolveTranscriptPath(job);\n\n return {\n jobId: job.jobId,\n ...(child.pid !== undefined && { pid: child.pid }),\n ...(transcriptPath !== undefined && { transcriptPath, logPath: transcriptPath }),\n result,\n cancel: async (reason?: string) => {\n cancellation.reject(reason);\n await cancelChildProcess(runtime, reason);\n },\n send: async (prompt: string) => {\n await sendWorkerMessage(child, { type: 'send', prompt });\n },\n ...(transcriptPath !== undefined && {\n readLog: async (cursor?: IBackgroundTaskLogCursor) =>\n readTranscriptLog(job.jobId, transcriptPath, cursor),\n }),\n };\n }\n\n private createStartPayload(job: ISubagentJobStart): ISubagentWorkerStartPayload {\n const definition = resolveAgentDefinition(job.request.type, this.deps.customAgentRegistry);\n return {\n jobId: job.jobId,\n request: job.request,\n agentDefinition: applyRequestOverrides(definition, job),\n parentConfig: this.deps.config,\n parentContext: this.deps.context,\n providerProfile: createProviderProfile(this.providerConfig, this.deps, job),\n permissionMode: this.deps.permissionMode,\n ...(this.logsDir ? { logsDir: this.logsDir } : {}),\n };\n }\n\n private resolveTranscriptPath(job: ISubagentJobStart): string | undefined {\n if (!this.logsDir) return undefined;\n return join(this.logsDir, job.request.parentSessionId, 'subagents', `${job.jobId}.jsonl`);\n }\n}\n\nfunction resolveAgentDefinition(\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n): IAgentDefinition {\n const definition = customRegistry?.(agentType) ?? getBuiltInAgent(agentType);\n if (!definition) {\n throw new BackgroundTaskError('validation', `Unknown agent type: ${agentType}`);\n }\n return definition;\n}\n\nfunction applyRequestOverrides(\n definition: IAgentDefinition,\n job: ISubagentJobStart,\n): IAgentDefinition {\n return {\n ...definition,\n ...(job.request.model ? { model: job.request.model } : {}),\n ...(job.request.allowedTools ? { tools: job.request.allowedTools } : {}),\n ...(job.request.disallowedTools ? { disallowedTools: job.request.disallowedTools } : {}),\n };\n}\n\nfunction createProviderProfile(\n providerConfig: IProviderConfig | undefined,\n deps: IInProcessSubagentRunnerDeps,\n job: ISubagentJobStart,\n): ISerializableProviderProfile {\n const provider = providerConfig ?? deps.config.provider;\n return {\n profileName: deps.config.currentProvider,\n type: provider.name,\n model: job.request.model ?? provider.model,\n apiKey: provider.apiKey,\n baseURL: provider.baseURL,\n timeout: provider.timeout,\n options: provider.options,\n };\n}\n\nfunction resolveExecArgv(workerPath: string): string[] {\n if (!workerPath.endsWith('.ts')) {\n return process.execArgv;\n }\n if (process.execArgv.some((arg) => arg.includes('tsx'))) {\n return process.execArgv;\n }\n return [...process.execArgv, '--import', 'tsx'];\n}\n\nfunction readTranscriptLog(\n jobId: string,\n transcriptPath: string,\n cursor?: IBackgroundTaskLogCursor,\n): IBackgroundTaskLogPage {\n if (!existsSync(transcriptPath)) {\n return {\n taskId: jobId,\n cursor,\n lines: [],\n };\n }\n const lines = readFileSync(transcriptPath, 'utf8').split(/\\r?\\n/).filter(Boolean);\n return createBackgroundTaskLogPage(jobId, lines, cursor);\n}\n","import { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function getDefaultSubagentWorkerPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), 'child-process-subagent-worker.js');\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@robota-sdk/agent-subagent-runner",
|
|
3
|
+
"version": "3.0.0-beta.66",
|
|
4
|
+
"description": "Child-process subagent runner for Robota SDK — optional package for running subagents in isolated child processes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/node/index.js",
|
|
7
|
+
"types": "dist/node/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/node/index.d.ts",
|
|
11
|
+
"source": "./src/index.ts",
|
|
12
|
+
"node": {
|
|
13
|
+
"import": "./dist/node/index.js",
|
|
14
|
+
"require": "./dist/node/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"default": {
|
|
17
|
+
"import": "./dist/node/index.js",
|
|
18
|
+
"require": "./dist/node/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/woojubb/robota.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://robota.io/",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/woojubb/robota/issues"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@robota-sdk/agent-core": "3.0.0-beta.66",
|
|
35
|
+
"@robota-sdk/agent-framework": "3.0.0-beta.66",
|
|
36
|
+
"@robota-sdk/agent-executor": "3.0.0-beta.66",
|
|
37
|
+
"@robota-sdk/agent-provider": "3.0.0-beta.66"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^22.14.0",
|
|
41
|
+
"rimraf": "^6.0.1",
|
|
42
|
+
"tsdown": "^0.22.0",
|
|
43
|
+
"typescript": "^5.8.3",
|
|
44
|
+
"vitest": "^1.6.1"
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsdown",
|
|
52
|
+
"build:js": "tsdown --no-dts",
|
|
53
|
+
"build:types": "tsdown --dts",
|
|
54
|
+
"test": "vitest run --passWithNoTests",
|
|
55
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"lint": "eslint src/ --ext .ts",
|
|
58
|
+
"clean": "rimraf dist"
|
|
59
|
+
}
|
|
60
|
+
}
|