borderless-agent 0.0.1-alpha.3 → 0.0.1-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentBuilder.d.ts +10 -0
- package/dist/agentBuilder.d.ts.map +1 -1
- package/dist/agentBuilder.js +27 -9
- package/dist/agentBuilder.js.map +1 -1
- package/dist/agentInstance.d.ts +17 -0
- package/dist/agentInstance.d.ts.map +1 -1
- package/dist/agentInstance.js +266 -66
- package/dist/agentInstance.js.map +1 -1
- package/dist/agentsCore.js +4 -8
- package/dist/agentsCore.js.map +1 -1
- package/dist/autonomousLoop.d.ts +2 -0
- package/dist/autonomousLoop.d.ts.map +1 -1
- package/dist/autonomousLoop.js +90 -49
- package/dist/autonomousLoop.js.map +1 -1
- package/dist/cli/index.js +1 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/main.js +49 -88
- package/dist/cli/main.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -58
- package/dist/config.js.map +1 -1
- package/dist/contextCore.js +55 -113
- package/dist/contextCore.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -24
- package/dist/index.js.map +1 -1
- package/dist/llmProtocol.d.ts +2 -0
- package/dist/llmProtocol.d.ts.map +1 -1
- package/dist/llmProtocol.js +89 -22
- package/dist/llmProtocol.js.map +1 -1
- package/dist/loopCore.js +35 -39
- package/dist/loopCore.js.map +1 -1
- package/dist/main.js +2 -4
- package/dist/main.js.map +1 -1
- package/dist/mcpClient.d.ts +54 -0
- package/dist/mcpClient.d.ts.map +1 -0
- package/dist/mcpClient.js +178 -0
- package/dist/mcpClient.js.map +1 -0
- package/dist/memoryCore.js +31 -79
- package/dist/memoryCore.js.map +1 -1
- package/dist/sandbox.js +6 -46
- package/dist/sandbox.js.map +1 -1
- package/dist/server/app.d.ts +2 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +144 -40
- package/dist/server/app.js.map +1 -1
- package/dist/server/humanLoop.d.ts +35 -0
- package/dist/server/humanLoop.d.ts.map +1 -0
- package/dist/server/humanLoop.js +70 -0
- package/dist/server/humanLoop.js.map +1 -0
- package/dist/sessionCore.d.ts +2 -0
- package/dist/sessionCore.d.ts.map +1 -1
- package/dist/sessionCore.js +30 -54
- package/dist/sessionCore.js.map +1 -1
- package/dist/skillsCore.js +6 -43
- package/dist/skillsCore.js.map +1 -1
- package/dist/storage/cloudBackend.js +18 -26
- package/dist/storage/cloudBackend.js.map +1 -1
- package/dist/storage/fileBackend.js +14 -55
- package/dist/storage/fileBackend.js.map +1 -1
- package/dist/storage/index.js +8 -17
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/protocols.js +1 -5
- package/dist/storage/protocols.js.map +1 -1
- package/dist/todoCore.js +2 -6
- package/dist/todoCore.js.map +1 -1
- package/dist/toolsCore.d.ts +3 -0
- package/dist/toolsCore.d.ts.map +1 -1
- package/dist/toolsCore.js +111 -114
- package/dist/toolsCore.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/package.json +9 -7
package/dist/agentBuilder.d.ts
CHANGED
|
@@ -46,6 +46,16 @@ export declare class AgentBuilder {
|
|
|
46
46
|
setMaxToolRounds(max: number): this;
|
|
47
47
|
/** Set approval callback for mutating tools. */
|
|
48
48
|
setApprovalCallback(cb: (toolName: string, args: Record<string, any>) => Promise<boolean> | boolean): this;
|
|
49
|
+
/**
|
|
50
|
+
* Set callback for human-in-the-loop interaction.
|
|
51
|
+
* When the agent needs clarification or input from the user mid-task,
|
|
52
|
+
* it calls the `ask_user` tool which invokes this callback.
|
|
53
|
+
*/
|
|
54
|
+
setHumanInputCallback(cb: (question: string) => Promise<string> | string): this;
|
|
55
|
+
/** Add an MCP server to connect to when the agent is built. */
|
|
56
|
+
addMCPServer(config: import('./mcpClient').MCPServerConfig): this;
|
|
57
|
+
/** Add multiple MCP servers at once. */
|
|
58
|
+
addMCPServers(configs: import('./mcpClient').MCPServerConfig[]): this;
|
|
49
59
|
/** Configure the execution sandbox (file guards, command filtering, resource limits). */
|
|
50
60
|
setSandbox(config: SandboxConfig): this;
|
|
51
61
|
/** Validate config and build the agent instance. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentBuilder.d.ts","sourceRoot":"","sources":["../src/agentBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAkB,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EACH,cAAc,EACd,eAAe,EAEf,SAAS,EACT,aAAa,EAChB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAQb;IAIF,uEAAuE;IACvE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAK/B,sDAAsD;IACtD,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAO3C,iDAAiD;IACjD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOrC,sCAAsC;IACtC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAMnC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAMvC,gFAAgF;IAChF,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAO9C,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAMtC,mCAAmC;IACnC,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI;IAQ1C,iCAAiC;IACjC,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAOvC,qDAAqD;IACrD,YAAY,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK1C,6CAA6C;IAC7C,eAAe,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK7C,qEAAqE;IACrE,aAAa,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK3C,+CAA+C;IAC/C,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKnC,gDAAgD;IAChD,mBAAmB,CACf,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAChF,IAAI;IAOP,yFAAyF;IACzF,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAOvC,oDAAoD;IACpD,KAAK,IAAI,aAAa;CAmBzB"}
|
|
1
|
+
{"version":3,"file":"agentBuilder.d.ts","sourceRoot":"","sources":["../src/agentBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAkB,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EACH,cAAc,EACd,eAAe,EAEf,SAAS,EACT,aAAa,EAChB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAQb;IAIF,uEAAuE;IACvE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAK/B,sDAAsD;IACtD,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAO3C,iDAAiD;IACjD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOrC,sCAAsC;IACtC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAMnC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAMvC,gFAAgF;IAChF,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAO9C,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAMtC,mCAAmC;IACnC,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI;IAQ1C,iCAAiC;IACjC,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAOvC,qDAAqD;IACrD,YAAY,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK1C,6CAA6C;IAC7C,eAAe,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK7C,qEAAqE;IACrE,aAAa,CAAC,MAAM,GAAE,OAAc,GAAG,IAAI;IAK3C,+CAA+C;IAC/C,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKnC,gDAAgD;IAChD,mBAAmB,CACf,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAChF,IAAI;IAKP;;;;OAIG;IACH,qBAAqB,CACjB,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GACnD,IAAI;IAOP,+DAA+D;IAC/D,YAAY,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,eAAe,GAAG,IAAI;IAMjE,wCAAwC;IACxC,aAAa,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,eAAe,EAAE,GAAG,IAAI;IAQrE,yFAAyF;IACzF,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAOvC,oDAAoD;IACpD,KAAK,IAAI,aAAa;CAmBzB"}
|
package/dist/agentBuilder.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* agentBuilder.ts — Fluent builder for creating portable agent instances.
|
|
4
3
|
*
|
|
@@ -13,11 +12,9 @@
|
|
|
13
12
|
* .build();
|
|
14
13
|
* ```
|
|
15
14
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const agentInstance_1 = require("./agentInstance");
|
|
20
|
-
class AgentBuilder {
|
|
15
|
+
import { OpenAIProvider } from './llmProtocol';
|
|
16
|
+
import { AgentInstance } from './agentInstance';
|
|
17
|
+
export class AgentBuilder {
|
|
21
18
|
_config = {
|
|
22
19
|
includeBuiltinTools: true,
|
|
23
20
|
enableMemory: false,
|
|
@@ -107,6 +104,28 @@ class AgentBuilder {
|
|
|
107
104
|
this._config.approvalCallback = cb;
|
|
108
105
|
return this;
|
|
109
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Set callback for human-in-the-loop interaction.
|
|
109
|
+
* When the agent needs clarification or input from the user mid-task,
|
|
110
|
+
* it calls the `ask_user` tool which invokes this callback.
|
|
111
|
+
*/
|
|
112
|
+
setHumanInputCallback(cb) {
|
|
113
|
+
this._config.humanInputCallback = cb;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
// ---- MCP ----
|
|
117
|
+
/** Add an MCP server to connect to when the agent is built. */
|
|
118
|
+
addMCPServer(config) {
|
|
119
|
+
this._config.mcpServers = this._config.mcpServers ?? [];
|
|
120
|
+
this._config.mcpServers.push(config);
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
/** Add multiple MCP servers at once. */
|
|
124
|
+
addMCPServers(configs) {
|
|
125
|
+
this._config.mcpServers = this._config.mcpServers ?? [];
|
|
126
|
+
this._config.mcpServers.push(...configs);
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
110
129
|
// ---- Sandbox ----
|
|
111
130
|
/** Configure the execution sandbox (file guards, command filtering, resource limits). */
|
|
112
131
|
setSandbox(config) {
|
|
@@ -122,15 +141,14 @@ class AgentBuilder {
|
|
|
122
141
|
if (!cfg?.apiKey) {
|
|
123
142
|
throw new Error('AgentBuilder: must call .setLLM({ apiKey }) or .setLLMProvider() before .build()');
|
|
124
143
|
}
|
|
125
|
-
this._config.llm = new
|
|
144
|
+
this._config.llm = new OpenAIProvider({
|
|
126
145
|
apiKey: cfg.apiKey,
|
|
127
146
|
model: cfg.model ?? 'gpt-4o',
|
|
128
147
|
baseUrl: cfg.baseUrl,
|
|
129
148
|
timeout: cfg.timeout ?? 120,
|
|
130
149
|
});
|
|
131
150
|
}
|
|
132
|
-
return new
|
|
151
|
+
return new AgentInstance({ ...this._config });
|
|
133
152
|
}
|
|
134
153
|
}
|
|
135
|
-
exports.AgentBuilder = AgentBuilder;
|
|
136
154
|
//# sourceMappingURL=agentBuilder.js.map
|
package/dist/agentBuilder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentBuilder.js","sourceRoot":"","sources":["../src/agentBuilder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agentBuilder.js","sourceRoot":"","sources":["../src/agentBuilder.ts"],"names":[],"mappings":"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"}
|
package/dist/agentInstance.d.ts
CHANGED
|
@@ -19,8 +19,18 @@ export declare class AgentInstance {
|
|
|
19
19
|
private _streamingEnabled;
|
|
20
20
|
private _contextEnabled;
|
|
21
21
|
private _approvalCallback?;
|
|
22
|
+
private _humanInputCallback?;
|
|
22
23
|
private _sandbox;
|
|
24
|
+
private _mcpManager;
|
|
25
|
+
private _mcpConfigs;
|
|
26
|
+
private _mcpInitialized;
|
|
27
|
+
private _mcpInitPromise;
|
|
23
28
|
constructor(config: AgentConfig);
|
|
29
|
+
/**
|
|
30
|
+
* Initialize MCP server connections. Called lazily on first chat/stream,
|
|
31
|
+
* or can be called explicitly for eager initialization.
|
|
32
|
+
*/
|
|
33
|
+
initMCP(): Promise<void>;
|
|
24
34
|
/** Send a single message (no session, stateless). */
|
|
25
35
|
chat(message: string, history?: Record<string, any>[]): Promise<ChatResult>;
|
|
26
36
|
/** Stream a single message (no session, stateless). */
|
|
@@ -44,10 +54,17 @@ export declare class AgentInstance {
|
|
|
44
54
|
* until self-evaluation meets the quality threshold or max iterations.
|
|
45
55
|
*/
|
|
46
56
|
runTask(config: AutonomousTaskConfig): Promise<AutonomousTaskResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Gracefully shut down MCP server connections.
|
|
59
|
+
* Call this when the agent is no longer needed to release resources.
|
|
60
|
+
*/
|
|
61
|
+
close(): Promise<void>;
|
|
47
62
|
private _wrapSession;
|
|
63
|
+
private _buildAskUserTool;
|
|
48
64
|
private _executeTool;
|
|
49
65
|
private _buildSystemForTurn;
|
|
50
66
|
private _runLoop;
|
|
51
67
|
private _runLoopStream;
|
|
68
|
+
private _llmCallWithRetry;
|
|
52
69
|
}
|
|
53
70
|
//# sourceMappingURL=agentInstance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentInstance.d.ts","sourceRoot":"","sources":["../src/agentInstance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACH,WAAW,EACX,cAAc,EAEd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"agentInstance.d.ts","sourceRoot":"","sources":["../src/agentInstance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACH,WAAW,EACX,cAAc,EAEd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;AAgNnE,qBAAa,aAAa;IACtB,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,iBAAiB,CAAC,CAGM;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAiD;IAC7E,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,eAAe,CAA8B;gBAEzC,MAAM,EAAE,WAAW;IAgE/B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC9B,qDAAqD;IAC/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAMjF,uDAAuD;IAChD,MAAM,CACT,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAChC,cAAc,CAAC,WAAW,CAAC;IAK9B,wEAAwE;IAClE,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC;IAK5C,gDAAgD;IAC1C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAMrE,8BAA8B;IACxB,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIvC,oCAAoC;IAC9B,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IAI1E,uCAAuC;IACvC,IAAI,GAAG,IAAI,WAAW,CAErB;IAED,wCAAwC;IACxC,IAAI,KAAK,IAAI,cAAc,EAAE,CAE5B;IAED;;;;;OAKG;IACG,OAAO,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAK1E;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,iBAAiB;YAiCX,YAAY;YA8CZ,mBAAmB;YAmBnB,QAAQ;YAgIP,cAAc;YAmJf,iBAAiB;CAwBlC"}
|
package/dist/agentInstance.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* agentInstance.ts — Runtime agent returned by AgentBuilder.build().
|
|
4
3
|
*
|
|
5
4
|
* Provides: chat(), stream(), createSession(), restoreSession().
|
|
6
5
|
* All internal modules are wired through dependency injection — no globals.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const sandbox_1 = require("./sandbox");
|
|
7
|
+
import { AutonomousLoop } from './autonomousLoop';
|
|
8
|
+
import { SessionManager } from './sessionCore';
|
|
9
|
+
import { getBudget, selectHistory, assembleSystem, sanitizeUserInput, foldObservation } from './contextCore';
|
|
10
|
+
import { retrieve, consolidateTurn, setMemoryStore } from './memoryCore';
|
|
11
|
+
import { createFileBackend } from './storage/fileBackend';
|
|
12
|
+
import { Sandbox } from './sandbox';
|
|
13
|
+
import { MCPManager } from './mcpClient';
|
|
16
14
|
// ---------------------------------------------------------------------------
|
|
17
15
|
// Internal helpers
|
|
18
16
|
// ---------------------------------------------------------------------------
|
|
@@ -180,7 +178,7 @@ function toolCallsToMsgShape(toolCalls) {
|
|
|
180
178
|
// ---------------------------------------------------------------------------
|
|
181
179
|
// AgentInstance
|
|
182
180
|
// ---------------------------------------------------------------------------
|
|
183
|
-
class AgentInstance {
|
|
181
|
+
export class AgentInstance {
|
|
184
182
|
_llm;
|
|
185
183
|
_systemPrompt;
|
|
186
184
|
_tools;
|
|
@@ -193,15 +191,21 @@ class AgentInstance {
|
|
|
193
191
|
_streamingEnabled;
|
|
194
192
|
_contextEnabled;
|
|
195
193
|
_approvalCallback;
|
|
194
|
+
_humanInputCallback;
|
|
196
195
|
_sandbox;
|
|
196
|
+
_mcpManager = null;
|
|
197
|
+
_mcpConfigs;
|
|
198
|
+
_mcpInitialized = false;
|
|
199
|
+
_mcpInitPromise = null;
|
|
197
200
|
constructor(config) {
|
|
198
201
|
this._llm = config.llm;
|
|
199
202
|
this._maxToolRounds = config.maxToolRounds ?? 20;
|
|
200
|
-
this._sandbox = new
|
|
203
|
+
this._sandbox = new Sandbox(config.sandbox);
|
|
201
204
|
this._memoryEnabled = config.enableMemory ?? false;
|
|
202
205
|
this._streamingEnabled = config.enableStreaming ?? false;
|
|
203
206
|
this._contextEnabled = config.enableContext ?? true;
|
|
204
207
|
this._approvalCallback = config.approvalCallback;
|
|
208
|
+
this._humanInputCallback = config.humanInputCallback;
|
|
205
209
|
// Assemble tools
|
|
206
210
|
this._tools = [];
|
|
207
211
|
if (config.includeBuiltinTools !== false) {
|
|
@@ -215,6 +219,8 @@ class AgentInstance {
|
|
|
215
219
|
const skillTool = buildSkillTool(this._skills);
|
|
216
220
|
if (skillTool)
|
|
217
221
|
this._tools.push(skillTool);
|
|
222
|
+
// Human-in-the-loop tool
|
|
223
|
+
this._tools.push(this._buildAskUserTool());
|
|
218
224
|
// Build lookup and OpenAI format
|
|
219
225
|
this._toolMap = new Map(this._tools.map((t) => [t.name, t]));
|
|
220
226
|
this._openaiTools = toolDefsToOpenAI(this._tools);
|
|
@@ -238,15 +244,51 @@ class AgentInstance {
|
|
|
238
244
|
storage = createCloudBackend();
|
|
239
245
|
}
|
|
240
246
|
else if (config.storage.backend === 'file') {
|
|
241
|
-
storage =
|
|
247
|
+
storage = createFileBackend({ sessionDir: config.storage.dir });
|
|
242
248
|
}
|
|
243
249
|
}
|
|
244
|
-
this._sessionMgr = new
|
|
250
|
+
this._sessionMgr = new SessionManager({
|
|
245
251
|
store: storage?.sessionStore ?? undefined,
|
|
246
252
|
});
|
|
247
253
|
if (storage?.memoryStore && this._memoryEnabled) {
|
|
248
|
-
|
|
254
|
+
setMemoryStore(storage.memoryStore);
|
|
249
255
|
}
|
|
256
|
+
// MCP servers (connected lazily since connect is async)
|
|
257
|
+
this._mcpConfigs = config.mcpServers ?? [];
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Initialize MCP server connections. Called lazily on first chat/stream,
|
|
261
|
+
* or can be called explicitly for eager initialization.
|
|
262
|
+
*/
|
|
263
|
+
async initMCP() {
|
|
264
|
+
if (this._mcpInitialized || !this._mcpConfigs.length)
|
|
265
|
+
return;
|
|
266
|
+
if (this._mcpInitPromise)
|
|
267
|
+
return this._mcpInitPromise;
|
|
268
|
+
this._mcpInitPromise = (async () => {
|
|
269
|
+
try {
|
|
270
|
+
this._mcpManager = new MCPManager();
|
|
271
|
+
await this._mcpManager.connect(this._mcpConfigs);
|
|
272
|
+
// Merge MCP tools into the agent's tool list
|
|
273
|
+
const mcpToolDefs = this._mcpManager.getToolDefinitions();
|
|
274
|
+
for (const mcpTool of mcpToolDefs) {
|
|
275
|
+
this._openaiTools.push({
|
|
276
|
+
type: 'function',
|
|
277
|
+
function: {
|
|
278
|
+
name: mcpTool.name,
|
|
279
|
+
description: mcpTool.description,
|
|
280
|
+
parameters: mcpTool.input_schema,
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch (e) {
|
|
286
|
+
console.error('[AgentInstance] MCP connection failed, continuing without MCP tools:', e.message ?? e);
|
|
287
|
+
this._mcpManager = null;
|
|
288
|
+
}
|
|
289
|
+
this._mcpInitialized = true;
|
|
290
|
+
})();
|
|
291
|
+
return this._mcpInitPromise;
|
|
250
292
|
}
|
|
251
293
|
// ---- Public API ----
|
|
252
294
|
/** Send a single message (no session, stateless). */
|
|
@@ -295,9 +337,21 @@ class AgentInstance {
|
|
|
295
337
|
* until self-evaluation meets the quality threshold or max iterations.
|
|
296
338
|
*/
|
|
297
339
|
async runTask(config) {
|
|
298
|
-
const loop = new
|
|
340
|
+
const loop = new AutonomousLoop(this);
|
|
299
341
|
return loop.run(config);
|
|
300
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Gracefully shut down MCP server connections.
|
|
345
|
+
* Call this when the agent is no longer needed to release resources.
|
|
346
|
+
*/
|
|
347
|
+
async close() {
|
|
348
|
+
if (this._mcpManager) {
|
|
349
|
+
await this._mcpManager.close();
|
|
350
|
+
this._mcpManager = null;
|
|
351
|
+
this._mcpInitialized = false;
|
|
352
|
+
this._mcpInitPromise = null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
301
355
|
// ---- Session wrapper ----
|
|
302
356
|
_wrapSession(session) {
|
|
303
357
|
const self = this;
|
|
@@ -309,7 +363,12 @@ class AgentInstance {
|
|
|
309
363
|
const result = await self._runLoop(message, session.history);
|
|
310
364
|
session.history = result.history;
|
|
311
365
|
session.updatedAt = Date.now() / 1000;
|
|
312
|
-
|
|
366
|
+
try {
|
|
367
|
+
await self._sessionMgr.saveSession(session);
|
|
368
|
+
}
|
|
369
|
+
catch (e) {
|
|
370
|
+
console.error('[AgentInstance] Failed to save session:', e.message ?? e);
|
|
371
|
+
}
|
|
313
372
|
return { ...result, sessionId: session.id };
|
|
314
373
|
},
|
|
315
374
|
async *stream(message) {
|
|
@@ -328,8 +387,48 @@ class AgentInstance {
|
|
|
328
387
|
},
|
|
329
388
|
};
|
|
330
389
|
}
|
|
390
|
+
// ---- Human-in-the-loop ----
|
|
391
|
+
_buildAskUserTool() {
|
|
392
|
+
const self = this;
|
|
393
|
+
return {
|
|
394
|
+
name: 'ask_user',
|
|
395
|
+
description: 'Ask the user a question and wait for their response. ' +
|
|
396
|
+
'Use this when you need clarification, additional information, ' +
|
|
397
|
+
'confirmation on an important decision, or when the task is ambiguous. ' +
|
|
398
|
+
'Do NOT use this for trivial questions you can resolve yourself.',
|
|
399
|
+
parameters: {
|
|
400
|
+
question: {
|
|
401
|
+
type: 'string',
|
|
402
|
+
description: 'The question to ask the user',
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
required: ['question'],
|
|
406
|
+
execute: async (args) => {
|
|
407
|
+
const question = args.question ?? '';
|
|
408
|
+
if (!self._humanInputCallback) {
|
|
409
|
+
return '[Human input not available] No humanInputCallback is configured. Proceed with your best judgment.';
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
const answer = await self._humanInputCallback(question);
|
|
413
|
+
return answer || '(User provided no response)';
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
return `[Human input error] ${e.message ?? String(e)}`;
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
}
|
|
331
421
|
// ---- Internal agent loop ----
|
|
332
422
|
async _executeTool(name, args) {
|
|
423
|
+
// Route MCP tools to MCPManager
|
|
424
|
+
if (this._mcpManager?.isMCPTool(name)) {
|
|
425
|
+
try {
|
|
426
|
+
return await this._mcpManager.callTool(name, args);
|
|
427
|
+
}
|
|
428
|
+
catch (e) {
|
|
429
|
+
return `[MCP tool error] ${name}: ${e.message ?? String(e)}`;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
333
432
|
const tool = this._toolMap.get(name);
|
|
334
433
|
if (!tool)
|
|
335
434
|
return `Unknown tool: ${name}`;
|
|
@@ -366,23 +465,33 @@ class AgentInstance {
|
|
|
366
465
|
return this._systemPrompt;
|
|
367
466
|
let ragLines;
|
|
368
467
|
if (this._memoryEnabled) {
|
|
369
|
-
|
|
370
|
-
|
|
468
|
+
try {
|
|
469
|
+
const memories = await retrieve(userInput, 5);
|
|
470
|
+
ragLines = memories.map((m) => m[0]).filter(Boolean);
|
|
471
|
+
}
|
|
472
|
+
catch (e) {
|
|
473
|
+
console.error('[AgentInstance] Memory retrieval failed, continuing without memories:', e.message ?? e);
|
|
474
|
+
}
|
|
371
475
|
}
|
|
372
|
-
return
|
|
476
|
+
return assembleSystem({
|
|
373
477
|
baseSystem: this._systemPrompt,
|
|
374
478
|
ragLines: ragLines?.length ? ragLines : undefined,
|
|
375
479
|
});
|
|
376
480
|
}
|
|
377
481
|
async _runLoop(userInput, history) {
|
|
378
|
-
|
|
482
|
+
await this.initMCP();
|
|
483
|
+
const sanitized = sanitizeUserInput(userInput);
|
|
379
484
|
const message = sanitized.text;
|
|
380
485
|
const system = await this._buildSystemForTurn(message);
|
|
381
486
|
// Trim history if context management enabled
|
|
382
487
|
let workingHistory = [...history];
|
|
383
488
|
if (this._contextEnabled) {
|
|
384
|
-
const budget =
|
|
385
|
-
|
|
489
|
+
const budget = getBudget();
|
|
490
|
+
const selected = selectHistory(workingHistory, message, budget.history);
|
|
491
|
+
// #16: guarantee at least last 2 messages if history exists
|
|
492
|
+
workingHistory = selected.length > 0 ? selected
|
|
493
|
+
: workingHistory.length >= 2 ? workingHistory.slice(-2)
|
|
494
|
+
: [...workingHistory];
|
|
386
495
|
}
|
|
387
496
|
workingHistory.push({ role: 'user', content: message });
|
|
388
497
|
const apiMessages = [
|
|
@@ -392,21 +501,37 @@ class AgentInstance {
|
|
|
392
501
|
let toolRounds = 0;
|
|
393
502
|
let hadToolCalls = false;
|
|
394
503
|
while (true) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
504
|
+
// #1: LLM call with retry
|
|
505
|
+
let response;
|
|
506
|
+
try {
|
|
507
|
+
response = await this._llmCallWithRetry(apiMessages, false);
|
|
508
|
+
}
|
|
509
|
+
catch (e) {
|
|
510
|
+
const errMsg = `I encountered an error communicating with the AI model: ${e.message ?? String(e)}. Please try again.`;
|
|
511
|
+
workingHistory.push({ role: 'assistant', content: errMsg });
|
|
512
|
+
history.length = 0;
|
|
513
|
+
history.push(...workingHistory);
|
|
514
|
+
return { reply: errMsg, history: workingHistory, hadToolCalls };
|
|
515
|
+
}
|
|
400
516
|
const tcs = response.toolCalls?.length
|
|
401
517
|
? toolCallsToMsgShape(response.toolCalls)
|
|
402
518
|
: [];
|
|
403
519
|
const content = response.content ?? '';
|
|
520
|
+
const thinking = response.thinking ?? null;
|
|
404
521
|
if (!tcs.length) {
|
|
405
|
-
|
|
522
|
+
const assistantMsg = { role: 'assistant', content: content.trim() };
|
|
523
|
+
if (thinking)
|
|
524
|
+
assistantMsg.thinking = thinking;
|
|
525
|
+
workingHistory.push(assistantMsg);
|
|
526
|
+
// #8: memory consolidation failure handling
|
|
406
527
|
if (this._memoryEnabled) {
|
|
407
|
-
|
|
528
|
+
try {
|
|
529
|
+
await consolidateTurn(message, content.trim());
|
|
530
|
+
}
|
|
531
|
+
catch (e) {
|
|
532
|
+
console.error('[AgentInstance] consolidateTurn failed:', e.message ?? e);
|
|
533
|
+
}
|
|
408
534
|
}
|
|
409
|
-
// Sync back
|
|
410
535
|
history.length = 0;
|
|
411
536
|
history.push(...workingHistory);
|
|
412
537
|
return {
|
|
@@ -432,25 +557,36 @@ class AgentInstance {
|
|
|
432
557
|
args = JSON.parse(tc.function.arguments || '{}');
|
|
433
558
|
}
|
|
434
559
|
catch {
|
|
435
|
-
|
|
560
|
+
// #15: inform LLM about parse failure instead of silent {}
|
|
561
|
+
results.push({
|
|
562
|
+
tool_call_id: tc.id,
|
|
563
|
+
content: `[Argument parse error] Could not parse arguments for tool "${tc.function.name}". Raw: ${(tc.function.arguments || '').slice(0, 200)}`,
|
|
564
|
+
});
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
// #4: tool execution try-catch
|
|
568
|
+
let output;
|
|
569
|
+
try {
|
|
570
|
+
output = await this._executeTool(tc.function.name, args);
|
|
571
|
+
}
|
|
572
|
+
catch (e) {
|
|
573
|
+
output = `[Tool error] ${tc.function.name}: ${e.message ?? String(e)}`;
|
|
436
574
|
}
|
|
437
|
-
let output = await this._executeTool(tc.function.name, args);
|
|
438
575
|
if (this._contextEnabled) {
|
|
439
|
-
output =
|
|
576
|
+
output = foldObservation(output);
|
|
440
577
|
}
|
|
441
578
|
results.push({ tool_call_id: tc.id, content: output });
|
|
442
579
|
}
|
|
443
|
-
// Append to conversation
|
|
444
|
-
|
|
580
|
+
// Append to conversation (preserve thinking if present)
|
|
581
|
+
const assistantToolMsg = {
|
|
445
582
|
role: 'assistant',
|
|
446
583
|
content: content || '',
|
|
447
584
|
tool_calls: tcs,
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
});
|
|
585
|
+
};
|
|
586
|
+
if (thinking)
|
|
587
|
+
assistantToolMsg.thinking = thinking;
|
|
588
|
+
apiMessages.push(assistantToolMsg);
|
|
589
|
+
workingHistory.push({ ...assistantToolMsg });
|
|
454
590
|
for (const r of results) {
|
|
455
591
|
apiMessages.push({
|
|
456
592
|
role: 'tool',
|
|
@@ -466,13 +602,17 @@ class AgentInstance {
|
|
|
466
602
|
}
|
|
467
603
|
}
|
|
468
604
|
async *_runLoopStream(userInput, history, onComplete) {
|
|
469
|
-
|
|
605
|
+
await this.initMCP();
|
|
606
|
+
const sanitized = sanitizeUserInput(userInput);
|
|
470
607
|
const message = sanitized.text;
|
|
471
608
|
const system = await this._buildSystemForTurn(message);
|
|
472
609
|
let workingHistory = [...history];
|
|
473
610
|
if (this._contextEnabled) {
|
|
474
|
-
const budget =
|
|
475
|
-
|
|
611
|
+
const budget = getBudget();
|
|
612
|
+
const selected = selectHistory(workingHistory, message, budget.history);
|
|
613
|
+
workingHistory = selected.length > 0 ? selected
|
|
614
|
+
: workingHistory.length >= 2 ? workingHistory.slice(-2)
|
|
615
|
+
: [...workingHistory];
|
|
476
616
|
}
|
|
477
617
|
workingHistory.push({ role: 'user', content: message });
|
|
478
618
|
const apiMessages = [
|
|
@@ -482,26 +622,56 @@ class AgentInstance {
|
|
|
482
622
|
let toolRounds = 0;
|
|
483
623
|
let hadToolCalls = false;
|
|
484
624
|
while (true) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
625
|
+
let streamGen;
|
|
626
|
+
try {
|
|
627
|
+
streamGen = await this._llmCallWithRetry(apiMessages, true);
|
|
628
|
+
}
|
|
629
|
+
catch (e) {
|
|
630
|
+
const errMsg = `I encountered an error communicating with the AI model: ${e.message ?? String(e)}. Please try again.`;
|
|
631
|
+
workingHistory.push({ role: 'assistant', content: errMsg });
|
|
632
|
+
history.length = 0;
|
|
633
|
+
history.push(...workingHistory);
|
|
634
|
+
if (onComplete)
|
|
635
|
+
onComplete({ reply: errMsg, history: workingHistory, hadToolCalls });
|
|
636
|
+
yield { reply: errMsg, done: true };
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
490
639
|
let lastResponse = null;
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
640
|
+
try {
|
|
641
|
+
for await (const r of streamGen) {
|
|
642
|
+
if (r.content && !r.toolCalls?.length) {
|
|
643
|
+
yield { delta: r.content, done: false };
|
|
644
|
+
}
|
|
645
|
+
lastResponse = r;
|
|
494
646
|
}
|
|
495
|
-
|
|
647
|
+
}
|
|
648
|
+
catch (e) {
|
|
649
|
+
const errMsg = `Stream interrupted: ${e.message ?? String(e)}`;
|
|
650
|
+
workingHistory.push({ role: 'assistant', content: errMsg });
|
|
651
|
+
history.length = 0;
|
|
652
|
+
history.push(...workingHistory);
|
|
653
|
+
if (onComplete)
|
|
654
|
+
onComplete({ reply: errMsg, history: workingHistory, hadToolCalls });
|
|
655
|
+
yield { reply: errMsg, done: true };
|
|
656
|
+
return;
|
|
496
657
|
}
|
|
497
658
|
const content = lastResponse?.content ?? '';
|
|
659
|
+
const thinking = lastResponse?.thinking ?? null;
|
|
498
660
|
const tcs = lastResponse?.toolCalls?.length
|
|
499
661
|
? toolCallsToMsgShape(lastResponse.toolCalls)
|
|
500
662
|
: [];
|
|
501
663
|
if (!tcs.length) {
|
|
502
|
-
|
|
664
|
+
const assistantMsg = { role: 'assistant', content: content.trim() };
|
|
665
|
+
if (thinking)
|
|
666
|
+
assistantMsg.thinking = thinking;
|
|
667
|
+
workingHistory.push(assistantMsg);
|
|
503
668
|
if (this._memoryEnabled) {
|
|
504
|
-
|
|
669
|
+
try {
|
|
670
|
+
await consolidateTurn(message, content.trim());
|
|
671
|
+
}
|
|
672
|
+
catch (e) {
|
|
673
|
+
console.error('[AgentInstance] consolidateTurn failed:', e.message ?? e);
|
|
674
|
+
}
|
|
505
675
|
}
|
|
506
676
|
history.length = 0;
|
|
507
677
|
history.push(...workingHistory);
|
|
@@ -536,23 +706,32 @@ class AgentInstance {
|
|
|
536
706
|
args = JSON.parse(tc.function.arguments || '{}');
|
|
537
707
|
}
|
|
538
708
|
catch {
|
|
539
|
-
|
|
709
|
+
results.push({
|
|
710
|
+
tool_call_id: tc.id,
|
|
711
|
+
content: `[Argument parse error] Could not parse arguments for tool "${tc.function.name}". Raw: ${(tc.function.arguments || '').slice(0, 200)}`,
|
|
712
|
+
});
|
|
713
|
+
continue;
|
|
714
|
+
}
|
|
715
|
+
let output;
|
|
716
|
+
try {
|
|
717
|
+
output = await this._executeTool(tc.function.name, args);
|
|
718
|
+
}
|
|
719
|
+
catch (e) {
|
|
720
|
+
output = `[Tool error] ${tc.function.name}: ${e.message ?? String(e)}`;
|
|
540
721
|
}
|
|
541
|
-
let output = await this._executeTool(tc.function.name, args);
|
|
542
722
|
if (this._contextEnabled)
|
|
543
|
-
output =
|
|
723
|
+
output = foldObservation(output);
|
|
544
724
|
results.push({ tool_call_id: tc.id, content: output });
|
|
545
725
|
}
|
|
546
|
-
|
|
547
|
-
role: 'assistant',
|
|
548
|
-
content: content || '',
|
|
549
|
-
tool_calls: tcs,
|
|
550
|
-
});
|
|
551
|
-
workingHistory.push({
|
|
726
|
+
const assistantToolMsg = {
|
|
552
727
|
role: 'assistant',
|
|
553
728
|
content: content || '',
|
|
554
729
|
tool_calls: tcs,
|
|
555
|
-
}
|
|
730
|
+
};
|
|
731
|
+
if (thinking)
|
|
732
|
+
assistantToolMsg.thinking = thinking;
|
|
733
|
+
apiMessages.push(assistantToolMsg);
|
|
734
|
+
workingHistory.push({ ...assistantToolMsg });
|
|
556
735
|
for (const r of results) {
|
|
557
736
|
apiMessages.push({
|
|
558
737
|
role: 'tool',
|
|
@@ -567,6 +746,27 @@ class AgentInstance {
|
|
|
567
746
|
}
|
|
568
747
|
}
|
|
569
748
|
}
|
|
749
|
+
// #1: LLM call with exponential backoff retry
|
|
750
|
+
async _llmCallWithRetry(apiMessages, stream, maxRetries = 3) {
|
|
751
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
752
|
+
try {
|
|
753
|
+
return this._llm.chat(apiMessages, {
|
|
754
|
+
tools: this._openaiTools,
|
|
755
|
+
maxTokens: 8000,
|
|
756
|
+
stream,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
catch (e) {
|
|
760
|
+
const status = e?.status ?? e?.response?.status;
|
|
761
|
+
const retryable = [429, 500, 502, 503].includes(status);
|
|
762
|
+
if (attempt < maxRetries && retryable) {
|
|
763
|
+
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt - 1)));
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
throw e;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
throw new Error('LLM call failed after retries');
|
|
770
|
+
}
|
|
570
771
|
}
|
|
571
|
-
exports.AgentInstance = AgentInstance;
|
|
572
772
|
//# sourceMappingURL=agentInstance.js.map
|