@lloyal-labs/lloyal-agents 1.0.0 → 1.2.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/README.md +28 -50
- package/dist/Tool.d.ts +13 -3
- package/dist/Tool.d.ts.map +1 -1
- package/dist/Tool.js +7 -2
- package/dist/Tool.js.map +1 -1
- package/dist/agent-pool.d.ts +9 -11
- package/dist/agent-pool.d.ts.map +1 -1
- package/dist/agent-pool.js +156 -101
- package/dist/agent-pool.js.map +1 -1
- package/dist/context.d.ts +32 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +31 -1
- package/dist/context.js.map +1 -1
- package/dist/generate.d.ts +20 -5
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +80 -9
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +4 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +5 -1
- package/dist/init.js.map +1 -1
- package/dist/shared-root.d.ts +3 -3
- package/dist/shared-root.d.ts.map +1 -1
- package/dist/shared-root.js +66 -5
- package/dist/shared-root.js.map +1 -1
- package/dist/source.d.ts +27 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +25 -0
- package/dist/source.js.map +1 -0
- package/dist/trace-scope.d.ts +25 -0
- package/dist/trace-scope.d.ts.map +1 -0
- package/dist/trace-scope.js +41 -0
- package/dist/trace-scope.js.map +1 -0
- package/dist/trace-types.d.ts +178 -0
- package/dist/trace-types.d.ts.map +1 -0
- package/dist/trace-types.js +3 -0
- package/dist/trace-types.js.map +1 -0
- package/dist/trace-writer.d.ts +58 -0
- package/dist/trace-writer.d.ts.map +1 -0
- package/dist/trace-writer.js +56 -0
- package/dist/trace-writer.js.map +1 -0
- package/dist/types.d.ts +8 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
# @lloyal-labs/lloyal-agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Continuous Context agent runtime.
|
|
4
4
|
|
|
5
|
-
`lloyal-agents` runs multi-agent inference inside the decode loop.
|
|
5
|
+
`lloyal-agents` runs multi-agent inference inside the decode loop. Instead of N independent model calls rebuilding the prompt each step, all agents advance inside one continuous decode process — forked from shared KV cache state, driven through a single GPU forward pass per tick, spawning sub-agents from their own live branches at arbitrary depth.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
npm i @lloyal-labs/lloyal-agents
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
**Backends:** [lloyal.node](https://github.com/lloyal-ai/lloyal.node) — prebuilt binaries for macOS (Metal, CPU), Linux (CPU, CUDA, Vulkan), and Windows (CPU, CUDA, Vulkan). GPU selection at runtime.
|
|
7
|
+
Built on [lloyal.node](https://github.com/lloyal-ai/lloyal.node), which provides forkable decode state and continuous tree batching over llama.cpp. `lloyal-agents` adds structured concurrency, tool dispatch, and a four-phase tick loop. Orchestration is not a layer above inference. It is inference.
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
<picture>
|
|
10
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/lloyal-ai/sdk/main/assets/continuous-context-dark.svg">
|
|
11
|
+
<img src="https://raw.githubusercontent.com/lloyal-ai/sdk/main/assets/continuous-context.svg" alt="Traditional Agents vs Continuous Context Agents — shared KV prefix, tool prefill, sub-agent spawning" width="100%">
|
|
12
|
+
</picture>
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
```bash
|
|
15
|
+
npm i @lloyal-labs/lloyal-agents @lloyal-labs/lloyal.node
|
|
16
|
+
```
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
`lloyal-agents` provides the agent runtime. [`lloyal.node`](https://github.com/lloyal-ai/lloyal.node) provides the native inference backend — prebuilt binaries for macOS (Metal, CPU), Linux (CPU, CUDA, Vulkan), and Windows (CPU, CUDA, Vulkan). Both are required. GPU selection at runtime.
|
|
18
19
|
|
|
19
20
|
The public API surface:
|
|
20
21
|
|
|
@@ -91,7 +92,7 @@ yield *
|
|
|
91
92
|
|
|
92
93
|
## In-Loop Orchestration
|
|
93
94
|
|
|
94
|
-
All active agents advance together in a
|
|
95
|
+
All active agents advance together in a four-phase tick loop:
|
|
95
96
|
|
|
96
97
|
**PRODUCE.** Every generating agent calls `produceSync()` — synchronous sampling with no async gap between agents. This matters because it means the entire produce phase is a single uninterrupted pass over the active set.
|
|
97
98
|
|
|
@@ -99,6 +100,8 @@ All active agents advance together in a three-phase tick loop:
|
|
|
99
100
|
|
|
100
101
|
**SETTLE.** Tool results that resolved during COMMIT are drained from a buffer. Each result is tokenized into a delta, budget-checked against a fresh `ContextPressure` snapshot, and batch-prefilled into the agent's branch. Grammar state resets. The agent transitions back to `generating`.
|
|
101
102
|
|
|
103
|
+
**DISPATCH.** Tool calls collected during PRODUCE are executed sequentially via `scoped()` + `call()`. Each tool runs to completion before the next begins — no concurrent `llama_decode` during dispatch. Tools return `Operation<unknown>`, so they can `yield*` into framework primitives like `useAgentPool` or `runAgents`, spawning recursive sub-agents within the calling agent's scope.
|
|
104
|
+
|
|
102
105
|
```typescript
|
|
103
106
|
// From the tick loop — Phase 1
|
|
104
107
|
const entries: [Branch, number][] = [];
|
|
@@ -122,7 +125,7 @@ if (entries.length > 0) {
|
|
|
122
125
|
}
|
|
123
126
|
```
|
|
124
127
|
|
|
125
|
-
When no agent is generating and tools are still pending, the loop
|
|
128
|
+
When no agent is generating and tools are still pending, the loop yields control until the next tool resolves. No polling. No sleep loops.
|
|
126
129
|
|
|
127
130
|
## Structured Concurrency DAG
|
|
128
131
|
|
|
@@ -140,40 +143,15 @@ function* setupAgent(parent, task, ctx) {
|
|
|
140
143
|
}
|
|
141
144
|
```
|
|
142
145
|
|
|
143
|
-
If the scope exits — error, cancellation, normal completion — the branch is pruned. Orphaned branches are structurally impossible. Tool dispatch uses `
|
|
146
|
+
If the scope exits — error, cancellation, normal completion — the branch is pruned. Orphaned branches are structurally impossible. Tool dispatch uses `scoped()` + `call()` — each tool executes inside a scoped error boundary within the agent pool scope. If the scope tears down, pending tools are cancelled. The DAG is not imposed on the orchestration. It is intrinsic to the Effection task tree.
|
|
144
147
|
|
|
145
148
|
`useAgentPool` is an Effection `resource()` — it suspends via `provide()` after all agents complete, but keeps their branches alive. The caller can fork sub-agents from any completed agent's branch. Those sub-agents inherit the parent agent's full KV state — everything it generated, every tool result it consumed, every reasoning step it took. No summarization. No context window management. The sub-agent continues from the parent's frontier.
|
|
146
149
|
|
|
147
|
-
|
|
150
|
+
Recursive agents work at two levels. At the **harness level**, a completed pool's branches can be forked into follow-up pools — sub-agents inherit the parent's full KV state and continue from the fork point. At the **model level**, a tool's `execute()` method returns `Operation<unknown>`, so it can `yield*` directly into `useAgentPool` or `runAgents`. An agent that calls such a tool spawns sub-agents mid-generation — inside its own scope, inheriting its KV state, with cleanup guaranteed by structured concurrency.
|
|
148
151
|
|
|
149
|
-
|
|
150
|
-
function* reportPass(pool: AgentPoolResult, opts: WorkflowOpts) {
|
|
151
|
-
const hardCut = pool.agents.filter((a) => !a.findings && !a.branch.disposed);
|
|
152
|
-
if (hardCut.length === 0) return;
|
|
153
|
-
|
|
154
|
-
const reporters = yield* runAgents({
|
|
155
|
-
tasks: hardCut.map((a) => ({
|
|
156
|
-
systemPrompt: REPORT_PROMPT,
|
|
157
|
-
content: "Report your findings.",
|
|
158
|
-
tools: reportOnlyTools,
|
|
159
|
-
parent: a.branch, // fork from the parent agent's branch
|
|
160
|
-
})),
|
|
161
|
-
tools: new Map([["report", reportTool]]),
|
|
162
|
-
terminalTool: "report",
|
|
163
|
-
});
|
|
152
|
+
In both cases, the sub-agent sees everything the parent saw — system prompt, tool calls, partial reasoning — because that state is already in the KV cache at the fork point. No summarization. No context reconstruction. The sub-agent just continues from the parent's frontier.
|
|
164
153
|
|
|
165
|
-
|
|
166
|
-
if (reporters.agents[i]?.findings)
|
|
167
|
-
a.findings = reporters.agents[i].findings;
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
The sub-agent sees everything the parent saw — its system prompt, its tool calls, its partial reasoning — because that state is already in the KV cache at the fork point. The sub-agent just continues from where the parent was cut off, with a tighter mandate.
|
|
173
|
-
|
|
174
|
-
This is the DAG in practice: parent agents form the first level, reporter sub-agents form the second. `runAgents` wraps `useAgentPool` in `scoped()`, so the reporter branches are pruned when it returns. The parent branches are still alive in the outer scope. When that outer scope exits, every `ensure()` callback fires and prunes the parents. Teardown propagates top-down. Cleanup is guaranteed bottom-up.
|
|
175
|
-
|
|
176
|
-
There is nothing in the framework that limits this to two levels. Agents can spawn sub-agents that spawn sub-agents. An agent pool can run inside another agent pool's scope. The structured concurrency guarantees compose at every depth.
|
|
154
|
+
There is nothing in the framework that limits depth. Agents can spawn sub-agents that spawn sub-agents. An agent pool can run inside another agent pool's scope. The structured concurrency guarantees compose at every level.
|
|
177
155
|
|
|
178
156
|
## Hallucination Detection
|
|
179
157
|
|
|
@@ -198,19 +176,15 @@ const result =
|
|
|
198
176
|
// Losers already pruned. Winner's branch is caller's responsibility.
|
|
199
177
|
```
|
|
200
178
|
|
|
201
|
-
The harness decides how to compare.
|
|
179
|
+
The harness decides how to compare. `diverge()` returns all outputs with their perplexity scores — the harness can apply any equivalence measure: bigram overlap, embedding similarity, or model-based evaluation. Where branches agree, the model is confident; where they diverge, hallucination risk is high.
|
|
202
180
|
|
|
203
181
|
This directly operationalizes the semantic entropy work from Farquhar et al. ([Nature, 2024](https://www.nature.com/articles/s41586-024-07421-0)) — but as a runtime primitive, not a post-hoc metric. The key constraint: divergence from a common computational ancestor is signal. Divergence from independently-constructed contexts is sampling variance. This measurement is only meaningful because agents share a frontier.
|
|
204
182
|
|
|
205
183
|
## Session Accumulation
|
|
206
184
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
This is the cold/warm session distinction. A cold query runs the full pipeline: plan the decomposition, dispatch research agents, synthesize via `diverge`, evaluate convergence, promote. A warm query — one where a trusted trunk already exists — skips verification entirely. The frontier is already established. Agents fork from it, research, and the session responds directly from findings.
|
|
210
|
-
|
|
211
|
-
Each promote is an epistemic commitment: this branch survived N-way comparison and convergence evaluation, so it becomes the basis for future reasoning. The session doesn't just carry forward text — it carries forward the KV state of a branch that survived verification. Future agents fork from this state. Their shared frontier is not an empty system prompt. It is the accumulated, verified reasoning of every previous cycle.
|
|
185
|
+
`Session.promote(branch)` retains only that branch and makes it the session trunk. Future queries fork from this trunk — its KV cache already contains everything the promoted branch generated, every tool result it consumed, every verification it passed.
|
|
212
186
|
|
|
213
|
-
|
|
187
|
+
A cold query starts from position 0. A warm query starts from an existing trunk. Over multiple queries, the session compounds — each promote advances the frontier, and future agents inherit the accumulated state.
|
|
214
188
|
|
|
215
189
|
## Context Pressure
|
|
216
190
|
|
|
@@ -237,6 +211,8 @@ Tools are class-based with OpenAI-compatible function schemas:
|
|
|
237
211
|
|
|
238
212
|
```typescript
|
|
239
213
|
import { Tool } from "@lloyal-labs/lloyal-agents";
|
|
214
|
+
import { call } from "effection";
|
|
215
|
+
import type { Operation } from "effection";
|
|
240
216
|
import type { ToolContext } from "@lloyal-labs/lloyal-agents";
|
|
241
217
|
|
|
242
218
|
class SearchTool extends Tool<{ query: string }> {
|
|
@@ -248,8 +224,10 @@ class SearchTool extends Tool<{ query: string }> {
|
|
|
248
224
|
required: ["query"],
|
|
249
225
|
};
|
|
250
226
|
|
|
251
|
-
|
|
252
|
-
const results =
|
|
227
|
+
*execute(args: { query: string }, context?: ToolContext): Operation<unknown> {
|
|
228
|
+
const results = yield* call(() =>
|
|
229
|
+
this.reranker.rank(args.query, this.chunks),
|
|
230
|
+
);
|
|
253
231
|
context?.onProgress?.({
|
|
254
232
|
filled: results.length,
|
|
255
233
|
total: this.chunks.length,
|
package/dist/Tool.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Operation } from 'effection';
|
|
1
2
|
import type { JsonSchema, ToolSchema, ToolContext } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Abstract base class for tools usable by agents in the runtime
|
|
@@ -11,6 +12,11 @@ import type { JsonSchema, ToolSchema, ToolContext } from './types';
|
|
|
11
12
|
* and `toolsJson` pair consumed by {@link useAgentPool} and
|
|
12
13
|
* {@link runAgents}.
|
|
13
14
|
*
|
|
15
|
+
* `execute()` returns an Effection `Operation`, enabling tools to
|
|
16
|
+
* spawn sub-agents via {@link runAgents} or {@link withSharedRoot}.
|
|
17
|
+
* For async work, wrap in `call()`. For synchronous tools, return
|
|
18
|
+
* directly from the generator body.
|
|
19
|
+
*
|
|
14
20
|
* @example Search tool
|
|
15
21
|
* ```typescript
|
|
16
22
|
* class SearchTool extends Tool<{ query: string; topK?: number }> {
|
|
@@ -25,8 +31,8 @@ import type { JsonSchema, ToolSchema, ToolContext } from './types';
|
|
|
25
31
|
* required: ['query'],
|
|
26
32
|
* };
|
|
27
33
|
*
|
|
28
|
-
*
|
|
29
|
-
* const results =
|
|
34
|
+
* *execute(args: { query: string; topK?: number }, ctx?: ToolContext): Operation<unknown> {
|
|
35
|
+
* const results = yield* call(() => this.reranker.rank(args.query, args.topK ?? 5));
|
|
30
36
|
* return { results };
|
|
31
37
|
* }
|
|
32
38
|
* }
|
|
@@ -48,11 +54,15 @@ export declare abstract class Tool<TArgs = Record<string, unknown>> {
|
|
|
48
54
|
* this tool's name. The return value is JSON-serialized and prefilled
|
|
49
55
|
* back into the agent's context as a tool result.
|
|
50
56
|
*
|
|
57
|
+
* Returns an Effection Operation — implement as a generator method.
|
|
58
|
+
* The operation runs inside the agent pool's scope, so it has access
|
|
59
|
+
* to Ctx, Store, and Events contexts for nested agent spawning.
|
|
60
|
+
*
|
|
51
61
|
* @param args - Parsed arguments from the model's tool call
|
|
52
62
|
* @param context - Execution context with progress reporting callback
|
|
53
63
|
* @returns Tool result (will be JSON-serialized)
|
|
54
64
|
*/
|
|
55
|
-
abstract execute(args: TArgs, context?: ToolContext):
|
|
65
|
+
abstract execute(args: TArgs, context?: ToolContext): Operation<unknown>;
|
|
56
66
|
/**
|
|
57
67
|
* OpenAI-compatible function tool schema
|
|
58
68
|
*
|
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,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEnE
|
|
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;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,UAAU,CASvB;CACF"}
|
package/dist/Tool.js
CHANGED
|
@@ -13,6 +13,11 @@ exports.Tool = void 0;
|
|
|
13
13
|
* and `toolsJson` pair consumed by {@link useAgentPool} and
|
|
14
14
|
* {@link runAgents}.
|
|
15
15
|
*
|
|
16
|
+
* `execute()` returns an Effection `Operation`, enabling tools to
|
|
17
|
+
* spawn sub-agents via {@link runAgents} or {@link withSharedRoot}.
|
|
18
|
+
* For async work, wrap in `call()`. For synchronous tools, return
|
|
19
|
+
* directly from the generator body.
|
|
20
|
+
*
|
|
16
21
|
* @example Search tool
|
|
17
22
|
* ```typescript
|
|
18
23
|
* class SearchTool extends Tool<{ query: string; topK?: number }> {
|
|
@@ -27,8 +32,8 @@ exports.Tool = void 0;
|
|
|
27
32
|
* required: ['query'],
|
|
28
33
|
* };
|
|
29
34
|
*
|
|
30
|
-
*
|
|
31
|
-
* const results =
|
|
35
|
+
* *execute(args: { query: string; topK?: number }, ctx?: ToolContext): Operation<unknown> {
|
|
36
|
+
* const results = yield* call(() => this.reranker.rank(args.query, args.topK ?? 5));
|
|
32
37
|
* return { results };
|
|
33
38
|
* }
|
|
34
39
|
* }
|
package/dist/Tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tool.js","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Tool.js","sourceRoot":"","sources":["../src/Tool.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAsB,IAAI;IAyBxB;;;;;;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;AA1CD,oBA0CC"}
|
package/dist/agent-pool.d.ts
CHANGED
|
@@ -6,11 +6,10 @@ import type { PressureThresholds, AgentPoolOptions, AgentPoolResult } from './ty
|
|
|
6
6
|
*
|
|
7
7
|
* Created from `SessionContext._storeKvPressure()` which returns
|
|
8
8
|
* `{ nCtx, cellsUsed, remaining }` where `remaining = nCtx - cellsUsed`.
|
|
9
|
-
* `cellsUsed`
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* becomes increasingly pessimistic as branches are pruned mid-run.
|
|
9
|
+
* `cellsUsed` tracks unique KV cells per branch — incremented on
|
|
10
|
+
* `decode_each` / `decode_scatter`, decremented on release by
|
|
11
|
+
* `position - fork_head` (unique cells above the fork point), reset on
|
|
12
|
+
* bulk ops like `retainOnly` and `drain`.
|
|
14
13
|
*
|
|
15
14
|
* Two thresholds partition `remaining` into three zones:
|
|
16
15
|
*
|
|
@@ -44,8 +43,6 @@ export declare class ContextPressure {
|
|
|
44
43
|
/**
|
|
45
44
|
* KV slots remaining (`nCtx - cellsUsed`).
|
|
46
45
|
* Infinity when nCtx ≤ 0 (no context limit).
|
|
47
|
-
* Conservative: may undercount actual free space when branches have been
|
|
48
|
-
* pruned, since `cellsUsed` is monotonic.
|
|
49
46
|
*/
|
|
50
47
|
readonly remaining: number;
|
|
51
48
|
/** Remaining KV floor — tokens reserved for downstream work */
|
|
@@ -67,17 +64,18 @@ export declare class ContextPressure {
|
|
|
67
64
|
/**
|
|
68
65
|
* Concurrent agent generation loop as an Effection resource
|
|
69
66
|
*
|
|
70
|
-
* Runs N agents in parallel using a
|
|
67
|
+
* Runs N agents in parallel using a four-phase tick loop over shared
|
|
71
68
|
* {@link BranchStore} infrastructure. Each agent forks from a parent
|
|
72
69
|
* branch, generates tokens, invokes tools, and reports findings.
|
|
73
70
|
*
|
|
74
|
-
* **
|
|
71
|
+
* **Four-phase tick loop:**
|
|
75
72
|
* 1. **PRODUCE** — sample all active agents via `produceSync()` (no async gap)
|
|
76
73
|
* 2. **COMMIT** — single GPU call via `store.commit()` for all produced tokens
|
|
77
74
|
* 3. **SETTLE** — drain settled tool results, batch prefill, reset grammars
|
|
75
|
+
* 4. **DISPATCH** — execute collected tool calls sequentially via `scoped()` + `call()`
|
|
78
76
|
*
|
|
79
|
-
* Tool dispatch uses `
|
|
80
|
-
*
|
|
77
|
+
* Tool dispatch uses `scoped()` + `call()` — each tool executes to completion
|
|
78
|
+
* before the next tick, ensuring exclusive `llama_context` access (no concurrent decode).
|
|
81
79
|
*
|
|
82
80
|
* **Resource semantics:** `provide()` suspends after all agents complete,
|
|
83
81
|
* keeping branches alive so the caller can fork from them (e.g. for
|
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,
|
|
1
|
+
{"version":3,"file":"agent-pool.d.ts","sourceRoot":"","sources":["../src/agent-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,WAAW,CAAC;AAEpD,OAAO,EAA+G,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKpK,OAAO,KAAK,EAEV,kBAAkB,EAElB,gBAAgB,EAChB,eAAe,EAEhB,MAAM,SAAS,CAAC;AAqCjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,eAAe;IAC1B,kEAAkE;IAClE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,QAAQ;IAC1C,2DAA2D;IAC3D,MAAM,CAAC,QAAQ,CAAC,kBAAkB,OAAO;IAEzC;;;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;IAO1D;;;;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;CACpC;AA0DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAAC,eAAe,CAAC,CAsa/E"}
|