@lloyal-labs/lloyal-agents 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +107 -0
- package/LICENSE-FAQ.md +256 -0
- package/README.md +17 -1
- package/dist/Agent.d.ts +13 -2
- package/dist/Agent.d.ts.map +1 -1
- package/dist/Agent.js +10 -0
- package/dist/Agent.js.map +1 -1
- package/dist/AgentPolicy.d.ts +84 -7
- package/dist/AgentPolicy.d.ts.map +1 -1
- package/dist/AgentPolicy.js +32 -4
- package/dist/AgentPolicy.js.map +1 -1
- package/dist/Tool.d.ts +44 -0
- package/dist/Tool.d.ts.map +1 -1
- package/dist/Tool.js +49 -1
- package/dist/Tool.js.map +1 -1
- package/dist/agent-pool.d.ts.map +1 -1
- package/dist/agent-pool.js +187 -16
- package/dist/agent-pool.js.map +1 -1
- package/dist/app-config.d.ts +50 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +27 -0
- package/dist/app-config.js.map +1 -0
- package/dist/app-types.d.ts +309 -0
- package/dist/app-types.d.ts.map +1 -0
- package/dist/app-types.js +28 -0
- package/dist/app-types.js.map +1 -0
- package/dist/chunk.d.ts +118 -0
- package/dist/chunk.d.ts.map +1 -0
- package/dist/chunk.js +19 -0
- package/dist/chunk.js.map +1 -0
- package/dist/context.d.ts +68 -12
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +64 -12
- package/dist/context.js.map +1 -1
- package/dist/create-agent-pool.d.ts +10 -4
- package/dist/create-agent-pool.d.ts.map +1 -1
- package/dist/create-agent-pool.js +7 -6
- package/dist/create-agent-pool.js.map +1 -1
- package/dist/grant-store.d.ts +49 -0
- package/dist/grant-store.d.ts.map +1 -0
- package/dist/grant-store.js +33 -0
- package/dist/grant-store.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/orchestrators.d.ts +7 -0
- package/dist/orchestrators.d.ts.map +1 -1
- package/dist/orchestrators.js.map +1 -1
- package/dist/source.d.ts +31 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +32 -2
- package/dist/source.js.map +1 -1
- package/dist/spine.d.ts +0 -6
- package/dist/spine.d.ts.map +1 -1
- package/dist/spine.js +18 -2
- package/dist/spine.js.map +1 -1
- package/dist/toolkit.d.ts +44 -17
- package/dist/toolkit.d.ts.map +1 -1
- package/dist/toolkit.js +24 -14
- package/dist/toolkit.js.map +1 -1
- package/dist/trace-types.d.ts +34 -2
- package/dist/trace-types.d.ts.map +1 -1
- package/dist/types.d.ts +27 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/use-agent.d.ts +9 -4
- package/dist/use-agent.d.ts.map +1 -1
- package/dist/use-agent.js +15 -12
- package/dist/use-agent.js.map +1 -1
- package/package.json +7 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPolicy.d.ts","sourceRoot":"","sources":["../src/AgentPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAuBlD
|
|
1
|
+
{"version":3,"file":"AgentPolicy.d.ts","sourceRoot":"","sources":["../src/AgentPolicy.ts"],"names":[],"mappings":"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"}
|
package/dist/AgentPolicy.js
CHANGED
|
@@ -29,6 +29,26 @@ function parseHistoryArgs(argsStr) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
exports.defaultToolGuards = [
|
|
32
|
+
// Framework-injected authGuard. Runs FIRST so a
|
|
33
|
+
// protected-tool rejection fires before any dedup guard — the pool
|
|
34
|
+
// emits a structured `tool:authReject` event keyed off
|
|
35
|
+
// `ProduceAction.nudge.guard === 'auth_reject'` for security
|
|
36
|
+
// observability. Reads/gather tools are OPEN: the guard only fires for
|
|
37
|
+
// a `protected` tool (in `config.protectedTools`) the session has not
|
|
38
|
+
// been granted (`config.grants`). When no tools are protected — the
|
|
39
|
+
// common case — this is a no-op.
|
|
40
|
+
{
|
|
41
|
+
name: 'auth_reject',
|
|
42
|
+
tools: '*',
|
|
43
|
+
reject: (_args, _history, _agent, toolName, config) => {
|
|
44
|
+
if (!config.protectedTools?.has(toolName))
|
|
45
|
+
return false; // open by default
|
|
46
|
+
return !config.grants?.has(toolName); // protected → deny unless granted
|
|
47
|
+
},
|
|
48
|
+
message: 'This action is protected and requires authorization that has not been ' +
|
|
49
|
+
'granted for this session. Use the available read tools to gather what ' +
|
|
50
|
+
'you can, and report what blocks completion.',
|
|
51
|
+
},
|
|
32
52
|
{
|
|
33
53
|
tools: ['fetch_page'],
|
|
34
54
|
reject: (args, history) => {
|
|
@@ -58,6 +78,7 @@ class DefaultAgentPolicy {
|
|
|
58
78
|
_recovery;
|
|
59
79
|
_budget;
|
|
60
80
|
_terminalToolName;
|
|
81
|
+
_maxToolRetries;
|
|
61
82
|
_startTime;
|
|
62
83
|
constructor(opts) {
|
|
63
84
|
this._minToolCalls = opts?.minToolCallsBeforeReturn ?? 2;
|
|
@@ -70,8 +91,12 @@ class DefaultAgentPolicy {
|
|
|
70
91
|
this._recovery = opts?.recovery ?? null;
|
|
71
92
|
this._budget = opts?.budget ?? null;
|
|
72
93
|
this._terminalToolName = opts?.terminalToolName ?? null;
|
|
94
|
+
this._maxToolRetries = opts?.maxToolRetries ?? 1;
|
|
73
95
|
this._startTime = performance.now();
|
|
74
96
|
}
|
|
97
|
+
onToolRetry(_agent, _tool, _error, attempt) {
|
|
98
|
+
return attempt <= this._maxToolRetries ? { type: 'retry' } : { type: 'fail' };
|
|
99
|
+
}
|
|
75
100
|
/**
|
|
76
101
|
* Elapsed wall time for *this agent* (since its first idle→active transition),
|
|
77
102
|
* falling back to the policy's own construction time when the agent hasn't
|
|
@@ -109,7 +134,7 @@ class DefaultAgentPolicy {
|
|
|
109
134
|
// guard — stuck agents (same query repeated past maxTurns) saw only
|
|
110
135
|
// turn-limit nudges instead of the dedup message that named the
|
|
111
136
|
// actual problem (see trace-1776819196054 agent 65539).
|
|
112
|
-
const guardRejection = this._checkGuards(tc, agent);
|
|
137
|
+
const guardRejection = this._checkGuards(tc, agent, config);
|
|
113
138
|
if (guardRejection)
|
|
114
139
|
return guardRejection;
|
|
115
140
|
if (this._isOverBudget(agent, tc, pressure, config))
|
|
@@ -173,7 +198,7 @@ class DefaultAgentPolicy {
|
|
|
173
198
|
}
|
|
174
199
|
return { type: 'idle', reason: agent.turns >= config.maxTurns ? 'max_turns' : 'pressure_softcut' };
|
|
175
200
|
}
|
|
176
|
-
_checkGuards(tc, agent) {
|
|
201
|
+
_checkGuards(tc, agent, config) {
|
|
177
202
|
const lineageHistory = agent.walkAncestors(a => a.toolHistory);
|
|
178
203
|
let toolArgs;
|
|
179
204
|
try {
|
|
@@ -183,8 +208,11 @@ class DefaultAgentPolicy {
|
|
|
183
208
|
toolArgs = {};
|
|
184
209
|
}
|
|
185
210
|
for (const guard of this._guards) {
|
|
186
|
-
|
|
187
|
-
|
|
211
|
+
const applies = guard.tools === '*' || guard.tools.includes(tc.name);
|
|
212
|
+
if (!applies)
|
|
213
|
+
continue;
|
|
214
|
+
if (guard.reject(toolArgs, lineageHistory, agent, tc.name, config)) {
|
|
215
|
+
return { type: 'nudge', message: guard.message, guard: guard.name };
|
|
188
216
|
}
|
|
189
217
|
}
|
|
190
218
|
return null;
|
package/dist/AgentPolicy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPolicy.js","sourceRoot":"","sources":["../src/AgentPolicy.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"AgentPolicy.js","sourceRoot":"","sources":["../src/AgentPolicy.ts"],"names":[],"mappings":"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"}
|
package/dist/Tool.d.ts
CHANGED
|
@@ -47,6 +47,28 @@ export declare abstract class Tool<TArgs = Record<string, unknown>> {
|
|
|
47
47
|
abstract readonly description: string;
|
|
48
48
|
/** JSON Schema describing the tool's expected arguments */
|
|
49
49
|
abstract readonly parameters: JsonSchema;
|
|
50
|
+
/**
|
|
51
|
+
* Whether invoking this tool requires authorization.
|
|
52
|
+
*
|
|
53
|
+
* **Open by default** (`false`/unset): any agent may call the tool. This
|
|
54
|
+
* is the right setting for read/gather tools — search, fetch, grep — where
|
|
55
|
+
* agents discover an app's coverage by *trying*, the frontier-agentic
|
|
56
|
+
* pattern. The spine loads every app's tools for KV amortization; an open
|
|
57
|
+
* tool is callable regardless of which app a spawn nominally belongs to.
|
|
58
|
+
*
|
|
59
|
+
* **Protected** (`true`): the tool mutates state or takes a consequential
|
|
60
|
+
* action (transfer funds, file a ticket, send a message). The framework's
|
|
61
|
+
* authGuard denies the call unless the session holds a **grant** for it
|
|
62
|
+
* (held in {@link GrantStoreCtx}, acquired via consent — the model never
|
|
63
|
+
* sees the credential). A denied attempt rejects at dispatch time and
|
|
64
|
+
* emits `tool:authReject`.
|
|
65
|
+
*
|
|
66
|
+
* Trust changes *which grants a session holds*, never tool behaviour:
|
|
67
|
+
* execution is identical for trusted and untrusted apps. An app MAY mark
|
|
68
|
+
* an exfiltration-capable "read" (one that fetches arbitrary URLs) as
|
|
69
|
+
* protected — the binary flag delegates that judgment to the app.
|
|
70
|
+
*/
|
|
71
|
+
readonly protected?: boolean;
|
|
50
72
|
/**
|
|
51
73
|
* Execute the tool with parsed arguments
|
|
52
74
|
*
|
|
@@ -86,4 +108,26 @@ export declare abstract class Tool<TArgs = Record<string, unknown>> {
|
|
|
86
108
|
*/
|
|
87
109
|
get schema(): ToolSchema;
|
|
88
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Thrown by a tool (or its backend provider) when the operation failed
|
|
113
|
+
* transiently and should be retried after a delay — rate limiting being the
|
|
114
|
+
* canonical case.
|
|
115
|
+
*
|
|
116
|
+
* The pool's DISPATCH phase catches this BEFORE the generic tool-error
|
|
117
|
+
* handler: instead of settling an error into the agent's KV, it parks the
|
|
118
|
+
* agent (`awaiting_tool` — skipped by PRODUCE at zero cost) and re-executes
|
|
119
|
+
* the same call after `retryAfterMs`. The model never sees transient
|
|
120
|
+
* infrastructure weather in its context; from its side the tool call just
|
|
121
|
+
* took longer. One retry is budgeted — a second ToolRetryError settles an
|
|
122
|
+
* honest "unavailable, use other sources" result, because at that point the
|
|
123
|
+
* outage is a fact the model needs in order to pivot.
|
|
124
|
+
*
|
|
125
|
+
* Observability: the pool emits `agent:tool_retry` (TUI) and `tool:retry`
|
|
126
|
+
* (trace) when parking, so a waiting agent is never mistaken for a hung one.
|
|
127
|
+
*/
|
|
128
|
+
export declare class ToolRetryError extends Error {
|
|
129
|
+
readonly retryAfterMs: number;
|
|
130
|
+
readonly name = "ToolRetryError";
|
|
131
|
+
constructor(message: string, retryAfterMs: number);
|
|
132
|
+
}
|
|
89
133
|
//# sourceMappingURL=Tool.d.ts.map
|
package/dist/Tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,8BAAsB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;IAExE;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAEtC;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,UAAU,CASvB;CACF"}
|
|
1
|
+
{"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,8BAAsB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;IAExE;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAEtC;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,UAAU,CASvB;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,cAAe,SAAQ,KAAK;IAEV,QAAQ,CAAC,YAAY,EAAE,MAAM;IAD1D,SAAkB,IAAI,oBAAoB;gBAC9B,OAAO,EAAE,MAAM,EAAW,YAAY,EAAE,MAAM;CAG3D"}
|
package/dist/Tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Tool = void 0;
|
|
3
|
+
exports.ToolRetryError = exports.Tool = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Abstract base class for tools usable by agents in the runtime
|
|
6
6
|
*
|
|
@@ -42,6 +42,28 @@ exports.Tool = void 0;
|
|
|
42
42
|
* @category Agents
|
|
43
43
|
*/
|
|
44
44
|
class Tool {
|
|
45
|
+
/**
|
|
46
|
+
* Whether invoking this tool requires authorization.
|
|
47
|
+
*
|
|
48
|
+
* **Open by default** (`false`/unset): any agent may call the tool. This
|
|
49
|
+
* is the right setting for read/gather tools — search, fetch, grep — where
|
|
50
|
+
* agents discover an app's coverage by *trying*, the frontier-agentic
|
|
51
|
+
* pattern. The spine loads every app's tools for KV amortization; an open
|
|
52
|
+
* tool is callable regardless of which app a spawn nominally belongs to.
|
|
53
|
+
*
|
|
54
|
+
* **Protected** (`true`): the tool mutates state or takes a consequential
|
|
55
|
+
* action (transfer funds, file a ticket, send a message). The framework's
|
|
56
|
+
* authGuard denies the call unless the session holds a **grant** for it
|
|
57
|
+
* (held in {@link GrantStoreCtx}, acquired via consent — the model never
|
|
58
|
+
* sees the credential). A denied attempt rejects at dispatch time and
|
|
59
|
+
* emits `tool:authReject`.
|
|
60
|
+
*
|
|
61
|
+
* Trust changes *which grants a session holds*, never tool behaviour:
|
|
62
|
+
* execution is identical for trusted and untrusted apps. An app MAY mark
|
|
63
|
+
* an exfiltration-capable "read" (one that fetches arbitrary URLs) as
|
|
64
|
+
* protected — the binary flag delegates that judgment to the app.
|
|
65
|
+
*/
|
|
66
|
+
protected;
|
|
45
67
|
/**
|
|
46
68
|
* Optional reasoning probe prefilled after this tool's result settles.
|
|
47
69
|
*
|
|
@@ -75,4 +97,30 @@ class Tool {
|
|
|
75
97
|
}
|
|
76
98
|
}
|
|
77
99
|
exports.Tool = Tool;
|
|
100
|
+
/**
|
|
101
|
+
* Thrown by a tool (or its backend provider) when the operation failed
|
|
102
|
+
* transiently and should be retried after a delay — rate limiting being the
|
|
103
|
+
* canonical case.
|
|
104
|
+
*
|
|
105
|
+
* The pool's DISPATCH phase catches this BEFORE the generic tool-error
|
|
106
|
+
* handler: instead of settling an error into the agent's KV, it parks the
|
|
107
|
+
* agent (`awaiting_tool` — skipped by PRODUCE at zero cost) and re-executes
|
|
108
|
+
* the same call after `retryAfterMs`. The model never sees transient
|
|
109
|
+
* infrastructure weather in its context; from its side the tool call just
|
|
110
|
+
* took longer. One retry is budgeted — a second ToolRetryError settles an
|
|
111
|
+
* honest "unavailable, use other sources" result, because at that point the
|
|
112
|
+
* outage is a fact the model needs in order to pivot.
|
|
113
|
+
*
|
|
114
|
+
* Observability: the pool emits `agent:tool_retry` (TUI) and `tool:retry`
|
|
115
|
+
* (trace) when parking, so a waiting agent is never mistaken for a hung one.
|
|
116
|
+
*/
|
|
117
|
+
class ToolRetryError extends Error {
|
|
118
|
+
retryAfterMs;
|
|
119
|
+
name = 'ToolRetryError';
|
|
120
|
+
constructor(message, retryAfterMs) {
|
|
121
|
+
super(message);
|
|
122
|
+
this.retryAfterMs = retryAfterMs;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.ToolRetryError = ToolRetryError;
|
|
78
126
|
//# sourceMappingURL=Tool.js.map
|
package/dist/Tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tool.js","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAsB,IAAI;
|
|
1
|
+
{"version":3,"file":"Tool.js","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAsB,IAAI;IAQxB;;;;;;;;;;;;;;;;;;;;OAoBG;IACM,SAAS,CAAW;IAmB7B;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAgB,IAAmB,OAAO,IAAI,CAAC,CAAC,CAAC;IAEvD;;;;;;OAMG;IACH,IAAI,MAAM;QACR,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B;SACF,CAAC;IACJ,CAAC;CACF;AAhFD,oBAgFC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,cAAe,SAAQ,KAAK;IAED;IADpB,IAAI,GAAG,gBAAgB,CAAC;IAC1C,YAAY,OAAe,EAAW,YAAoB;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,iBAAY,GAAZ,YAAY,CAAQ;IAE1D,CAAC;CACF;AALD,wCAKC"}
|
package/dist/agent-pool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-pool.d.ts","sourceRoot":"","sources":["../src/agent-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,
|
|
1
|
+
{"version":3,"file":"agent-pool.d.ts","sourceRoot":"","sources":["../src/agent-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAA0F,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAY/I,OAAO,KAAK,EACV,kBAAkB,EAElB,gBAAgB,EAChB,eAAe,EACf,UAAU,EAEX,MAAM,SAAS,CAAC;AAsBjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,eAAe;IAC1B,kEAAkE;IAClE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,QAAQ;IAC1C;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,OAAO;IACzC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,eAAe,OAAO;IAEtC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,kBAAkB;IAS1D;;;;OAIG;IACH,IAAI,QAAQ,IAAI,MAAM,CAA4C;IAElE,qEAAqE;IACrE,IAAI,QAAQ,IAAI,OAAO,CAA4C;IAEnE,iEAAiE;IACjE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAEnC;;;;;OAKG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAI7B;CACF;AA6SD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAs4BzG"}
|
package/dist/agent-pool.js
CHANGED
|
@@ -9,6 +9,7 @@ const sdk_2 = require("@lloyal-labs/sdk");
|
|
|
9
9
|
const trace_scope_1 = require("./trace-scope");
|
|
10
10
|
const Agent_1 = require("./Agent");
|
|
11
11
|
const AgentPolicy_1 = require("./AgentPolicy");
|
|
12
|
+
const Tool_1 = require("./Tool");
|
|
12
13
|
/**
|
|
13
14
|
* Immutable KV budget snapshot for one tick of the agent loop
|
|
14
15
|
*
|
|
@@ -181,7 +182,7 @@ function* recoverInline(agent, policy, ctx, store, tw, parentTraceId, events, pr
|
|
|
181
182
|
try {
|
|
182
183
|
const parsed = JSON.parse(output);
|
|
183
184
|
if (parsed?.result) {
|
|
184
|
-
agent.setResult(parsed.result, '
|
|
185
|
+
agent.setResult(stripDanglingToolCall(parsed.result), 'recovery');
|
|
185
186
|
yield* events.send({ type: 'agent:recovered', agentId: agent.id, result: agent.result });
|
|
186
187
|
reported = true;
|
|
187
188
|
tw.write({
|
|
@@ -221,8 +222,25 @@ function* recoverInline(agent, policy, ctx, store, tw, parentTraceId, events, pr
|
|
|
221
222
|
// ── PRODUCE action handlers ─────────────────────────────────────
|
|
222
223
|
// Each handler encapsulates state transitions, events, and trace for one
|
|
223
224
|
// policy action outcome. The PRODUCE switch dispatches to these.
|
|
225
|
+
/**
|
|
226
|
+
* Strip a trailing UNCLOSED `<tool_call>` fragment from text captured as an
|
|
227
|
+
* agent result. When generation is cut mid-tool-call-emission (produce
|
|
228
|
+
* budget, pressure, maxTurns), the parser finds no complete call and the
|
|
229
|
+
* raw tail — `…</think>\n<tool_call><function=read_file>…` with no closing
|
|
230
|
+
* tags — rides into `a.result` verbatim. Any downstream consumer that
|
|
231
|
+
* injects results into another agent's prompt (synth findings, delegation
|
|
232
|
+
* returns) then carries a literal in-context demonstration of emitting tool
|
|
233
|
+
* calls, priming no-tool agents to imitate it (observed:
|
|
234
|
+
* trace-2026-06-11T00-02, agent 65539 → synth rabbit hole).
|
|
235
|
+
*
|
|
236
|
+
* Complete `<tool_call>…</tool_call>` blocks are left alone — they are
|
|
237
|
+
* either parsed before reaching a capture path or deliberate quoting.
|
|
238
|
+
*/
|
|
239
|
+
function stripDanglingToolCall(text) {
|
|
240
|
+
return text.replace(/<tool_call>(?:(?!<\/tool_call>)[\s\S])*$/, '').trimEnd();
|
|
241
|
+
}
|
|
224
242
|
function* handleFreeTextReturn(a, content, events) {
|
|
225
|
-
a.setResult(content, 'free_text');
|
|
243
|
+
a.setResult(stripDanglingToolCall(content), 'free_text');
|
|
226
244
|
a.transition('idle');
|
|
227
245
|
yield* events.send({ type: 'agent:return', agentId: a.id, result: a.result });
|
|
228
246
|
yield* events.send({ type: 'agent:done', agentId: a.id });
|
|
@@ -247,7 +265,7 @@ function* handleNudge(a, message, tc, ctx, tools) {
|
|
|
247
265
|
return { agentId: a.id, prefillTokens, toolName: tc?.name || '', callId, args: tc?.arguments || '', probe };
|
|
248
266
|
}
|
|
249
267
|
function* handleReturn(a, result, tc, terminalToolName, pruneOnReturn, events) {
|
|
250
|
-
a.setResult(result, 'voluntary_return');
|
|
268
|
+
a.setResult(stripDanglingToolCall(result), 'voluntary_return');
|
|
251
269
|
a.transition('idle');
|
|
252
270
|
a.incrementToolCalls();
|
|
253
271
|
yield* events.send({ type: 'agent:tool_call', agentId: a.id, tool: terminalToolName, args: tc.arguments });
|
|
@@ -312,9 +330,14 @@ function* setupAgent(parent, task, ctx, enableThinking) {
|
|
|
312
330
|
callingAgent = a;
|
|
313
331
|
}
|
|
314
332
|
catch { /* top-level — no caller */ }
|
|
333
|
+
// The spawn's app membership is now a non-enforcing label:
|
|
334
|
+
// the authGuard gates tools by `Tool.protected` + session grants at the
|
|
335
|
+
// pool level, not by app-scoped allow-lists. The label is carried for
|
|
336
|
+
// trace attribution (`tool:authReject`) and harness UI only.
|
|
337
|
+
const assignedApp = task.assignedApp ?? null;
|
|
315
338
|
// In shared mode the new agent's parser/grammar/format/triggers come
|
|
316
339
|
// from the spine's pre-computed fmt — those fields know about the tool
|
|
317
|
-
//
|
|
340
|
+
// set that's in attention via the inherited prefix. In non-shared
|
|
318
341
|
// mode, fresh fmt drives those fields (existing behavior).
|
|
319
342
|
const fmtConfig = sharedFmt
|
|
320
343
|
? {
|
|
@@ -344,6 +367,7 @@ function* setupAgent(parent, task, ctx, enableThinking) {
|
|
|
344
367
|
parent: callingAgent,
|
|
345
368
|
task: task.content,
|
|
346
369
|
fmt: fmtConfig,
|
|
370
|
+
assignedApp,
|
|
347
371
|
});
|
|
348
372
|
return { agent, suffixTokens, formattedPrompt: fmt.prompt };
|
|
349
373
|
}
|
|
@@ -409,7 +433,7 @@ function useAgentPool(opts) {
|
|
|
409
433
|
}
|
|
410
434
|
});
|
|
411
435
|
const tw = yield* context_1.Trace.expect();
|
|
412
|
-
const { spine, orchestrate, toolsJson, tools, maxTurns = 100, terminalToolName, trace = false, pruneOnReturn = false, enableThinking = false } = opts;
|
|
436
|
+
const { spine, orchestrate, toolsJson, tools, maxTurns = 100, terminalToolName, trace = false, pruneOnReturn = false, enableThinking = false, eagerGrammar } = opts;
|
|
413
437
|
// Tool index map for trace — position in toolkit array
|
|
414
438
|
const toolIndexMap = new Map([...tools.keys()].map((name, i) => [name, i]));
|
|
415
439
|
const toolkitSize = tools.size;
|
|
@@ -450,7 +474,23 @@ function useAgentPool(opts) {
|
|
|
450
474
|
`Recovery reserves hardLimit cells for its own decode; if smaller than nBatch, the next batch ` +
|
|
451
475
|
`allocation will OOM. Increase policy.budget.context.hardLimit to at least ${nBatch}.`);
|
|
452
476
|
}
|
|
453
|
-
|
|
477
|
+
// authGuard inputs, resolved once per pool:
|
|
478
|
+
// • protectedTools — names this pool's registry flags `Tool.protected`.
|
|
479
|
+
// • grants — protected names the session is authorized to call, read
|
|
480
|
+
// from GrantStoreCtx. Absent store = fail-closed (no grants).
|
|
481
|
+
// When nothing is protected (the common case) the authGuard never fires.
|
|
482
|
+
const protectedTools = new Set([...tools].filter(([, t]) => t.protected).map(([name]) => name));
|
|
483
|
+
let grants = new Set();
|
|
484
|
+
if (protectedTools.size > 0) {
|
|
485
|
+
try {
|
|
486
|
+
const grantStore = yield* context_1.GrantStoreCtx.expect();
|
|
487
|
+
grants = new Set(yield* grantStore.granted());
|
|
488
|
+
}
|
|
489
|
+
catch { /* no grant store on context — fail-closed (no grants) */ }
|
|
490
|
+
}
|
|
491
|
+
const policyConfig = {
|
|
492
|
+
maxTurns, terminalToolName, hasNonTerminalTools, protectedTools, grants,
|
|
493
|
+
};
|
|
454
494
|
// ── Orchestrator-driven setup ────────────────────────────
|
|
455
495
|
// Agents are spawned lazily via `ctx.spawn` from the orchestrator.
|
|
456
496
|
// The tick loop iterates over whatever agents are currently active.
|
|
@@ -469,7 +509,24 @@ function useAgentPool(opts) {
|
|
|
469
509
|
});
|
|
470
510
|
// Lazy grammar setup — applied inside ctx.spawn after prefill completes.
|
|
471
511
|
const applyLazyGrammar = (a) => {
|
|
472
|
-
|
|
512
|
+
// Eager grammar (schema-based agents like the planner) takes priority
|
|
513
|
+
// over lazy tool-call grammar. Qwen3.5's chat template emits a lazy
|
|
514
|
+
// tool-call grammar even when no tools are passed (a non-empty
|
|
515
|
+
// fmt.grammar with a `<tool_call>` trigger), which would otherwise
|
|
516
|
+
// overwrite a schema grammar set elsewhere — the planner would still
|
|
517
|
+
// be unconstrained. With eager set, we use the strict schema grammar
|
|
518
|
+
// and skip the (no-tools-anyway) lazy trigger.
|
|
519
|
+
if (eagerGrammar) {
|
|
520
|
+
a.branch.setGrammar(eagerGrammar);
|
|
521
|
+
}
|
|
522
|
+
else if (tools.size > 0 && a.fmt.grammar && a.fmt.grammarLazy && a.fmt.grammarTriggers.length > 0) {
|
|
523
|
+
// tools.size guard: with an empty toolkit there is nothing to
|
|
524
|
+
// dispatch, but the template still emits a tool-call grammar (see
|
|
525
|
+
// above). Installing it would not BLOCK the `<tool_call>` trigger —
|
|
526
|
+
// lazy grammars activate on the trigger, they don't prevent it —
|
|
527
|
+
// but once triggered it FORCES syntactic completion of a full call
|
|
528
|
+
// the model may have sampled into by accident. A no-tool agent
|
|
529
|
+
// (synth, eval) must be free to wander back to prose instead.
|
|
473
530
|
const triggers = a.fmt.grammarTriggers.map(t => {
|
|
474
531
|
if (t.type === sdk_1.GrammarTriggerType.WORD) {
|
|
475
532
|
const nlIdx = t.value.indexOf('\n');
|
|
@@ -501,12 +558,20 @@ function useAgentPool(opts) {
|
|
|
501
558
|
tools: toolsJson,
|
|
502
559
|
seed: spec.seed,
|
|
503
560
|
parent,
|
|
561
|
+
assignedApp: spec.assignedApp,
|
|
504
562
|
};
|
|
505
563
|
// Synchronous setup — fork, tokenize suffix, pressure check.
|
|
506
564
|
// No native store call yet; that's the tick loop's SPAWN phase's job.
|
|
507
565
|
const { agent, suffixTokens, formattedPrompt } = yield* setupAgent(parent, task, ctx, enableThinking);
|
|
508
566
|
const pressure = new ContextPressure(ctx, pressureOpts);
|
|
509
|
-
|
|
567
|
+
// Reserve for batch-mates: spawns/extends admitted earlier this tick
|
|
568
|
+
// haven't prefilled yet, so raw pressure doesn't see them. Without
|
|
569
|
+
// the reservation, N individually-valid spawns cram N suffixes into
|
|
570
|
+
// one SPAWN-phase prefill and every agent dies pressure_softcut on
|
|
571
|
+
// turn 0 (trace-2026-06-11T06-21: 6 × 4,819-token suffixes vs 32k).
|
|
572
|
+
const reserved = pendingSpawns.reduce((acc, ps) => acc + ps.suffixTokens.length, 0) +
|
|
573
|
+
pendingExtends.reduce((acc, pe) => acc + (pe.discarded ? 0 : pe.tokens.length), 0);
|
|
574
|
+
if (!pressure.canFit(reserved + suffixTokens.length)) {
|
|
510
575
|
agent.branch.pruneSync();
|
|
511
576
|
agent.dispose();
|
|
512
577
|
tw.write({
|
|
@@ -661,10 +726,18 @@ function useAgentPool(opts) {
|
|
|
661
726
|
}
|
|
662
727
|
return deferred;
|
|
663
728
|
}
|
|
729
|
+
/** Transient-failure parking: a ToolRetryError'd call waits here with its
|
|
730
|
+
* agent in `awaiting_tool` (PRODUCE skips it — no turns, no tokens, no
|
|
731
|
+
* KV) until `notBefore`, then re-enters DISPATCH. Whether to park and
|
|
732
|
+
* for how long is the POLICY's call (`onToolRetry`); this queue is
|
|
733
|
+
* pure mechanism, like SETTLE's deferral. Keep retry delays above the
|
|
734
|
+
* provider's own breaker cooldown or the retry lands on an open
|
|
735
|
+
* breaker. */
|
|
736
|
+
const pendingRetries = [];
|
|
664
737
|
/** DISPATCH: execute tool calls sequentially, return settled items for next tick */
|
|
665
738
|
function* dispatch(calls) {
|
|
666
739
|
const results = [];
|
|
667
|
-
for (const { agent, tc } of calls) {
|
|
740
|
+
for (const { agent, tc, retryAttempt, retryCallId } of calls) {
|
|
668
741
|
let toolArgs;
|
|
669
742
|
try {
|
|
670
743
|
toolArgs = JSON.parse(tc.arguments);
|
|
@@ -672,11 +745,15 @@ function useAgentPool(opts) {
|
|
|
672
745
|
catch {
|
|
673
746
|
toolArgs = {};
|
|
674
747
|
}
|
|
675
|
-
const callId = tc.id || `call_${agent.toolCallCount}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
748
|
+
const callId = retryCallId ?? (tc.id || `call_${agent.toolCallCount}`);
|
|
749
|
+
// Retries re-execute the SAME call — turn/tool-call counters and the
|
|
750
|
+
// agent:tool_call event belong to the original attempt only.
|
|
751
|
+
if (retryAttempt === undefined) {
|
|
752
|
+
agent.incrementToolCalls();
|
|
753
|
+
totalToolCalls++;
|
|
754
|
+
agent.incrementTurns();
|
|
755
|
+
yield* poolChannel.send({ type: 'agent:tool_call', agentId: agent.id, tool: tc.name, args: tc.arguments });
|
|
756
|
+
}
|
|
680
757
|
const tool = tools.get(tc.name);
|
|
681
758
|
const dispatchPressure = new ContextPressure(ctx, pressureOpts);
|
|
682
759
|
const explore = policy.shouldExplore?.(agent, dispatchPressure) ?? true;
|
|
@@ -704,8 +781,19 @@ function useAgentPool(opts) {
|
|
|
704
781
|
try {
|
|
705
782
|
yield* context_1.TraceParent.set(dispatchTraceId);
|
|
706
783
|
yield* context_1.CallingAgent.set(agent);
|
|
784
|
+
// Unknown-tool messaging branches on toolkit emptiness: a no-tool
|
|
785
|
+
// agent emitting tool calls is imitating markup from its context
|
|
786
|
+
// (inherited spine KV or contaminated findings) — a generic
|
|
787
|
+
// "Unknown tool" error reads as transient and invites rephrased
|
|
788
|
+
// retries until maxTurns (observed: trace-2026-06-11T00-02 synth,
|
|
789
|
+
// 10 turns of mimicry). The directive form names the actual
|
|
790
|
+
// situation so the model can recover in one turn.
|
|
707
791
|
const result = yield* (0, effection_1.scoped)(function* () {
|
|
708
|
-
return yield* (0, effection_1.call)(() => tool ? tool.execute(toolArgs, toolContext) : Promise.resolve({
|
|
792
|
+
return yield* (0, effection_1.call)(() => tool ? tool.execute(toolArgs, toolContext) : Promise.resolve({
|
|
793
|
+
error: tools.size === 0
|
|
794
|
+
? 'No tools are available to this agent. Do not emit tool calls — write your answer directly as plain text.'
|
|
795
|
+
: `Unknown tool: ${tc.name}`,
|
|
796
|
+
}));
|
|
709
797
|
});
|
|
710
798
|
const postToolPressure = new ContextPressure(ctx, pressureOpts);
|
|
711
799
|
const contextAvailablePercent = postToolPressure.percentAvailable;
|
|
@@ -730,6 +818,50 @@ function useAgentPool(opts) {
|
|
|
730
818
|
durationMs: performance.now() - toolT0 });
|
|
731
819
|
}
|
|
732
820
|
catch (err) {
|
|
821
|
+
if (err instanceof Tool_1.ToolRetryError) {
|
|
822
|
+
const attempt = (retryAttempt ?? 0) + 1;
|
|
823
|
+
// Strategy is the policy's: park-and-retry (optionally overriding
|
|
824
|
+
// the tool's delay estimate) or fail the call so the model can
|
|
825
|
+
// pivot. Hook absent → one retry at the tool's estimate.
|
|
826
|
+
const retryAction = policy.onToolRetry?.(agent, tc.name, err, attempt)
|
|
827
|
+
?? (attempt <= 1 ? { type: 'retry' } : { type: 'fail' });
|
|
828
|
+
if (retryAction.type === 'retry') {
|
|
829
|
+
// Park: no SettledTool, nothing prefilled — the agent's KV
|
|
830
|
+
// never sees transient infrastructure weather. Surfaced to
|
|
831
|
+
// the TUI + trace so a waiting agent reads as waiting, not hung.
|
|
832
|
+
const afterMs = retryAction.afterMs ?? err.retryAfterMs;
|
|
833
|
+
pendingRetries.push({
|
|
834
|
+
agent, tc, callId,
|
|
835
|
+
notBefore: performance.now() + afterMs,
|
|
836
|
+
attempt,
|
|
837
|
+
});
|
|
838
|
+
yield* poolChannel.send({
|
|
839
|
+
type: 'agent:tool_retry', agentId: agent.id, tool: tc.name,
|
|
840
|
+
retryAfterMs: afterMs, attempt,
|
|
841
|
+
});
|
|
842
|
+
tw.write({ traceId: tw.nextId(), parentTraceId: dispatchTraceId, ts: performance.now(),
|
|
843
|
+
type: 'tool:retry', agentId: agent.id, tool: tc.name,
|
|
844
|
+
callId, retryAfterMs: afterMs, attempt });
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
// Policy chose fail — the outage is now a fact the model needs.
|
|
848
|
+
// Settle an honest, directive result through the normal path
|
|
849
|
+
// (NOT the tool_error path, which kills the agent's run).
|
|
850
|
+
const exhausted = {
|
|
851
|
+
error: retryAction.message
|
|
852
|
+
?? `${tc.name} is currently unavailable (rate-limited; retry failed). ` +
|
|
853
|
+
`Do not call ${tc.name} again — use other sources or proceed with your current findings.`,
|
|
854
|
+
};
|
|
855
|
+
const resultStr = JSON.stringify(exhausted);
|
|
856
|
+
yield* poolChannel.send({ type: 'agent:tool_result', agentId: agent.id, tool: tc.name, result: resultStr });
|
|
857
|
+
const prefillTokens = (0, sdk_2.buildToolResultDelta)(ctx, resultStr, callId, { enableThinking: agent.fmt.enableThinking });
|
|
858
|
+
results.push({ agentId: agent.id, prefillTokens, toolName: tc.name, callId, args: tc.arguments, probe: undefined });
|
|
859
|
+
tw.write({ traceId: tw.nextId(), parentTraceId: dispatchTraceId, ts: performance.now(),
|
|
860
|
+
type: 'tool:result', agentId: agent.id, tool: tc.name,
|
|
861
|
+
result: exhausted, prefillTokenCount: prefillTokens.length,
|
|
862
|
+
durationMs: performance.now() - toolT0 });
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
733
865
|
agent.transition('idle');
|
|
734
866
|
agent.setResult(`Tool error: ${err.message}`, 'tool_error');
|
|
735
867
|
tw.write({ traceId: tw.nextId(), parentTraceId: dispatchTraceId, ts: performance.now(),
|
|
@@ -867,6 +999,19 @@ function useAgentPool(opts) {
|
|
|
867
999
|
yield* handleIdleDrop(a, action.reason, poolChannel, tw, poolScope.traceId);
|
|
868
1000
|
continue;
|
|
869
1001
|
case 'nudge':
|
|
1002
|
+
// authGuard rejection: emit the structured
|
|
1003
|
+
// tool:authReject event BEFORE the generic agentNudge so a
|
|
1004
|
+
// single trace pass captures attribution + rejection context.
|
|
1005
|
+
if (action.guard === 'auth_reject') {
|
|
1006
|
+
tw.write({
|
|
1007
|
+
traceId: tw.nextId(), parentTraceId: poolScope.traceId, ts: performance.now(),
|
|
1008
|
+
type: 'tool:authReject',
|
|
1009
|
+
agentId: a.id,
|
|
1010
|
+
assignedApp: a.assignedApp,
|
|
1011
|
+
attemptedTool: parsed.toolCalls[0].name,
|
|
1012
|
+
lineageHistory: a.walkAncestors((x) => x.toolHistory),
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
870
1015
|
nudges.push(yield* handleNudge(a, action.message, parsed.toolCalls[0], ctx, tools));
|
|
871
1016
|
tw.write({ traceId: tw.nextId(), parentTraceId: poolScope.traceId, ts: performance.now(),
|
|
872
1017
|
type: 'pool:agentNudge', agentId: a.id, reason: 'nudge', message: action.message });
|
|
@@ -971,7 +1116,19 @@ function useAgentPool(opts) {
|
|
|
971
1116
|
deferred.push(...resolved);
|
|
972
1117
|
}
|
|
973
1118
|
// -- Phase 4: DISPATCH
|
|
974
|
-
|
|
1119
|
+
// Due retries re-enter first — their agents have been parked since the
|
|
1120
|
+
// ToolRetryError and re-execute the same call (same callId, no counter
|
|
1121
|
+
// increments).
|
|
1122
|
+
const nowTs = performance.now();
|
|
1123
|
+
const dueRetries = [];
|
|
1124
|
+
for (let i = pendingRetries.length - 1; i >= 0; i--) {
|
|
1125
|
+
if (pendingRetries[i].notBefore <= nowTs)
|
|
1126
|
+
dueRetries.unshift(...pendingRetries.splice(i, 1));
|
|
1127
|
+
}
|
|
1128
|
+
const dispatched = yield* dispatch([
|
|
1129
|
+
...dueRetries.map(r => ({ agent: r.agent, tc: r.tc, retryAttempt: r.attempt, retryCallId: r.callId })),
|
|
1130
|
+
...toolCalls,
|
|
1131
|
+
]);
|
|
975
1132
|
// Deferred + new dispatch results → next tick's SETTLE
|
|
976
1133
|
pendingSettled = [...deferred, ...dispatched];
|
|
977
1134
|
// -- Termination + recovery
|
|
@@ -996,6 +1153,20 @@ function useAgentPool(opts) {
|
|
|
996
1153
|
// All current agents done but orchestrator may spawn more.
|
|
997
1154
|
yield* (0, effection_1.sleep)(1);
|
|
998
1155
|
}
|
|
1156
|
+
// All-parked: nothing active, nothing to settle — only future retries.
|
|
1157
|
+
// Without this the loop busy-spins until the earliest notBefore (parked
|
|
1158
|
+
// agents are awaiting_tool, so the allIdle sleep above never fires).
|
|
1159
|
+
// Cap the nap at 50ms so orchestrator spawns/extends are picked up
|
|
1160
|
+
// promptly.
|
|
1161
|
+
if (pendingRetries.length > 0
|
|
1162
|
+
&& pendingSettled.length === 0
|
|
1163
|
+
&& pendingSpawns.length === 0
|
|
1164
|
+
&& pendingExtends.length === 0
|
|
1165
|
+
&& !agents.some(a => a.status === 'active')) {
|
|
1166
|
+
const nextDue = Math.min(...pendingRetries.map(r => r.notBefore));
|
|
1167
|
+
const nap = Math.max(1, Math.min(50, nextDue - performance.now()));
|
|
1168
|
+
yield* (0, effection_1.sleep)(nap);
|
|
1169
|
+
}
|
|
999
1170
|
}
|
|
1000
1171
|
// ── Close channel with result — consumers get AgentPoolResult as close value ───────
|
|
1001
1172
|
// Branch cleanup is handled by each branch's ensure() from setupAgent —
|