@animalabs/agent-framework 0.22.3 → 0.23.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 +105 -3
- package/dist/src/agent.d.ts +36 -10
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +76 -32
- package/dist/src/agent.js.map +1 -1
- package/dist/src/code-execution/index.d.ts +1 -1
- package/dist/src/code-execution/index.d.ts.map +1 -1
- package/dist/src/code-execution/index.js.map +1 -1
- package/dist/src/code-execution/py-runner.d.ts +34 -2
- package/dist/src/code-execution/py-runner.d.ts.map +1 -1
- package/dist/src/code-execution/py-runner.js +72 -16
- package/dist/src/code-execution/py-runner.js.map +1 -1
- package/dist/src/code-execution/runtime-py.d.ts +3 -2
- package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
- package/dist/src/code-execution/runtime-py.js +47 -7
- package/dist/src/code-execution/runtime-py.js.map +1 -1
- package/dist/src/code-execution/tool-definition.d.ts +12 -7
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +59 -11
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/config-checks.d.ts +2 -2
- package/dist/src/config-checks.d.ts.map +1 -1
- package/dist/src/config-checks.js +6 -2
- package/dist/src/config-checks.js.map +1 -1
- package/dist/src/framework.d.ts +744 -120
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +3546 -906
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +13 -6
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/held-writes.d.ts +16 -0
- package/dist/src/held-writes.d.ts.map +1 -0
- package/dist/src/held-writes.js +56 -0
- package/dist/src/held-writes.js.map +1 -0
- package/dist/src/index.d.ts +7 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/capability-grant.d.ts +4 -0
- package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
- package/dist/src/mcpl/capability-grant.js +1 -1
- package/dist/src/mcpl/capability-grant.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +95 -18
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +578 -150
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts +2 -2
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +6 -7
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +5 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -1
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +4 -2
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js +6 -7
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +7 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.js +9 -0
- package/dist/src/mcpl/log-value.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +227 -0
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -0
- package/dist/src/mcpl/modern-connection.js +1088 -0
- package/dist/src/mcpl/modern-connection.js.map +1 -0
- package/dist/src/mcpl/prefix-rule.d.ts +18 -0
- package/dist/src/mcpl/prefix-rule.d.ts.map +1 -0
- package/dist/src/mcpl/prefix-rule.js +25 -0
- package/dist/src/mcpl/prefix-rule.js.map +1 -0
- package/dist/src/mcpl/protocol-family.d.ts +179 -0
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -0
- package/dist/src/mcpl/protocol-family.js +697 -0
- package/dist/src/mcpl/protocol-family.js.map +1 -0
- package/dist/src/mcpl/push-coalescer.d.ts +38 -19
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +52 -23
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +66 -15
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +243 -76
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +63 -18
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +117 -32
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +326 -30
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +995 -212
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/server-registry.d.ts +25 -5
- package/dist/src/mcpl/server-registry.d.ts.map +1 -1
- package/dist/src/mcpl/server-registry.js +51 -12
- package/dist/src/mcpl/server-registry.js.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts +54 -0
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -0
- package/dist/src/mcpl/tool-result-normalize.js +232 -0
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -0
- package/dist/src/mcpl/transport.d.ts +56 -13
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +206 -70
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +66 -20
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/mcpl/visible-content.d.ts +2 -1
- package/dist/src/mcpl/visible-content.d.ts.map +1 -1
- package/dist/src/mcpl/visible-content.js +2 -1
- package/dist/src/mcpl/visible-content.js.map +1 -1
- package/dist/src/module-registry.d.ts +16 -6
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +65 -6
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/api/index.d.ts +1 -1
- package/dist/src/modules/api/index.d.ts.map +1 -1
- package/dist/src/modules/api/index.js +3 -2
- package/dist/src/modules/api/index.js.map +1 -1
- package/dist/src/modules/discord/discord-js-client.d.ts +42 -2
- package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
- package/dist/src/modules/discord/discord-js-client.js +268 -65
- package/dist/src/modules/discord/discord-js-client.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts +27 -5
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +366 -76
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/discord/refusal.d.ts +14 -0
- package/dist/src/modules/discord/refusal.d.ts.map +1 -0
- package/dist/src/modules/discord/refusal.js +14 -0
- package/dist/src/modules/discord/refusal.js.map +1 -0
- package/dist/src/modules/discord/types.d.ts +17 -7
- package/dist/src/modules/discord/types.d.ts.map +1 -1
- package/dist/src/modules/health/index.d.ts.map +1 -1
- package/dist/src/modules/health/index.js +6 -2
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/index.d.ts +1 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.d.ts +25 -2
- package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +45 -5
- package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts +2 -1
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +19 -9
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +214 -42
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +667 -113
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +240 -8
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +554 -24
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +10 -1
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +42 -0
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js +130 -25
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/silent-heartbeat.d.ts +112 -39
- package/dist/src/silent-heartbeat.d.ts.map +1 -1
- package/dist/src/silent-heartbeat.js +100 -29
- package/dist/src/silent-heartbeat.js.map +1 -1
- package/dist/src/tool-args.d.ts +40 -0
- package/dist/src/tool-args.d.ts.map +1 -0
- package/dist/src/tool-args.js +207 -0
- package/dist/src/tool-args.js.map +1 -0
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +9 -2
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/types/agent.d.ts +27 -17
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +8 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +17 -2
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +54 -10
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +2 -2
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/agent.ts +99 -36
- package/src/code-execution/index.ts +1 -0
- package/src/code-execution/py-runner.ts +104 -17
- package/src/code-execution/runtime-py.ts +47 -7
- package/src/code-execution/tool-definition.ts +65 -11
- package/src/config-checks.ts +4 -2
- package/src/framework.ts +3633 -956
- package/src/gate/event-gate.ts +14 -6
- package/src/held-writes.ts +59 -0
- package/src/index.ts +19 -4
- package/src/mcpl/capability-grant.ts +1 -1
- package/src/mcpl/channel-registry.ts +613 -160
- package/src/mcpl/convert-block.ts +15 -7
- package/src/mcpl/index.ts +14 -1
- package/src/mcpl/inference-router.ts +8 -7
- package/src/mcpl/log-value.ts +10 -0
- package/src/mcpl/modern-connection.ts +1182 -0
- package/src/mcpl/prefix-rule.ts +32 -0
- package/src/mcpl/protocol-family.ts +691 -0
- package/src/mcpl/push-coalescer.ts +67 -29
- package/src/mcpl/reference-fetcher.ts +288 -82
- package/src/mcpl/references.ts +123 -33
- package/src/mcpl/server-connection.ts +1050 -221
- package/src/mcpl/server-registry.ts +50 -12
- package/src/mcpl/tool-result-normalize.ts +294 -0
- package/src/mcpl/transport.ts +204 -62
- package/src/mcpl/types.ts +67 -20
- package/src/mcpl/visible-content.ts +2 -1
- package/src/module-registry.ts +68 -13
- package/src/modules/api/index.ts +3 -2
- package/src/modules/discord/discord-js-client.ts +288 -72
- package/src/modules/discord/index.ts +380 -77
- package/src/modules/discord/refusal.ts +13 -0
- package/src/modules/discord/types.ts +17 -9
- package/src/modules/health/index.ts +6 -2
- package/src/modules/index.ts +1 -1
- package/src/modules/workspace/disk-agreement.ts +46 -5
- package/src/modules/workspace/effects.ts +18 -7
- package/src/modules/workspace/index.ts +722 -124
- package/src/modules/workspace/observe.ts +591 -22
- package/src/modules/workspace/types.ts +10 -1
- package/src/modules/workspace/watcher.ts +126 -25
- package/src/silent-heartbeat.ts +184 -59
- package/src/tool-args.ts +213 -0
- package/src/tool-presentation.ts +9 -2
- package/src/types/agent.ts +27 -17
- package/src/types/events.ts +8 -0
- package/src/types/framework.ts +17 -2
- package/src/types/module.ts +55 -10
- package/src/types/trace.ts +2 -2
package/dist/src/framework.d.ts
CHANGED
|
@@ -83,9 +83,15 @@ export interface HostModeStatus {
|
|
|
83
83
|
/** Context writes (module events, api message.send) withheld because the
|
|
84
84
|
* host is quiesced. Persisted while quiesced and flushed by resume(). */
|
|
85
85
|
deferredWrites: number;
|
|
86
|
-
/** Agents whose turn `abandon`
|
|
87
|
-
* no stream
|
|
88
|
-
*
|
|
86
|
+
/** Agents whose turn `abandon` had not ended when its grace ran out: a
|
|
87
|
+
* turn token held with no stream to cancel and no check ahead to stop it
|
|
88
|
+
* at (a puppet tool turn, a store surgery's reservation, a turn finishing
|
|
89
|
+
* its last delivery), or a turn with no stream that hasn't reached its
|
|
90
|
+
* next check, such as one in a hook that hasn't returned. A turn whose
|
|
91
|
+
* stream the abandon cancelled isn't listed, even one still running when
|
|
92
|
+
* the grace runs out, as one whose tool-result guard waits on its speech
|
|
93
|
+
* may be. Present only after an abandon that left such turns behind, while
|
|
94
|
+
* the host stays quiesced. */
|
|
89
95
|
unabandonable?: string[];
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
@@ -203,21 +209,25 @@ export declare class AgentFramework {
|
|
|
203
209
|
private stopPromise;
|
|
204
210
|
private stopCompleted;
|
|
205
211
|
private ownedStoreClosed;
|
|
206
|
-
/** Whether the latest stop()
|
|
207
|
-
*
|
|
208
|
-
* whatever failed after that
|
|
209
|
-
*
|
|
212
|
+
/** Whether the latest stop() got through its teardown with nothing failed:
|
|
213
|
+
* every step and every wait up to and including the one on awareness
|
|
214
|
+
* drains, whatever failed after that, in the storage work that finishes
|
|
215
|
+
* the stop. A step that threw may have left part of its work running, as
|
|
216
|
+
* a wait that ran out does. create()'s release reads it to say whether part
|
|
217
|
+
* of what a failed create() started may still be running. */
|
|
210
218
|
private stopFinishedTeardown;
|
|
211
219
|
/** An operator's operations in flight, and the config materializations they
|
|
212
220
|
* start. stop() waits until this set is empty before it tears down, unless
|
|
213
221
|
* its wait budget runs out. */
|
|
214
222
|
private readonly operatorOperations;
|
|
215
223
|
/** What a wait of stop()'s left running when its budget ran out, by its
|
|
216
|
-
* promise: a stream it cancelled or an event loop still in a call
|
|
224
|
+
* promise: a stream it cancelled or an event loop still in a call; and a
|
|
225
|
+
* stream whose cancel threw, which stop() doesn't wait for. A later
|
|
217
226
|
* stop() waits for each again, beside what it finds, whatever has happened
|
|
218
227
|
* since to the entry it was found under (a run's end removes its stream's,
|
|
219
|
-
* a start() replaces the loop), so a budget
|
|
220
|
-
* under work still running. Each leaves once it
|
|
228
|
+
* a start() replaces the loop), so neither a budget nor a cancel that
|
|
229
|
+
* threw lets the store close under work still running. Each leaves once it
|
|
230
|
+
* settles. */
|
|
221
231
|
private readonly leftRunning;
|
|
222
232
|
private membrane;
|
|
223
233
|
private queue;
|
|
@@ -285,7 +295,6 @@ export declare class AgentFramework {
|
|
|
285
295
|
/** Per-agent last inference activity (epoch ms), for /healthz + doctor tooling. */
|
|
286
296
|
private lastInferenceAt;
|
|
287
297
|
private processLoggingPersist;
|
|
288
|
-
private processLoggingBroadcast;
|
|
289
298
|
private activeStreams;
|
|
290
299
|
/** Told once per inbound acceptance (mcpl/inbound-source.ts). An internal
|
|
291
300
|
* seam, unset here: the receipt work (shelf-354) assigns it inside the
|
|
@@ -364,10 +373,14 @@ export declare class AgentFramework {
|
|
|
364
373
|
private ephemeralRuns;
|
|
365
374
|
/** Ephemeral namespaces/names are single-generation for this framework
|
|
366
375
|
* lifetime. Reusing one while an old stream drains would let name-keyed
|
|
367
|
-
* liveness/settlement state cross generations.
|
|
376
|
+
* liveness/settlement state cross generations. Each name records what
|
|
377
|
+
* reserved it: an ephemeral run (createEphemeralAgent), which takes no
|
|
378
|
+
* global fallback even after its release, or a conversation fork. */
|
|
368
379
|
private usedEphemeralAgentNames;
|
|
369
380
|
/** One-shot generation tickets minted by createEphemeralAgent. */
|
|
370
381
|
private ephemeralCandidates;
|
|
382
|
+
/** Warn only once per Agent instance after utilities are registered. */
|
|
383
|
+
private emptyUtilityPermissionWarnings;
|
|
371
384
|
/** Physical ephemeral frames deliberately disposed by their run watchdog/caller.
|
|
372
385
|
* The name is single-generation, so these frames still own their terminal
|
|
373
386
|
* typing/outgoing close even after runEphemeralToCompletion deregisters them. */
|
|
@@ -394,7 +407,7 @@ export declare class AgentFramework {
|
|
|
394
407
|
private refusalStreak;
|
|
395
408
|
/** Per-agent count of consecutive refusal-driven rewinds in the current turn
|
|
396
409
|
* chain (reset when a turn completes without a refusal). Bounds the auto
|
|
397
|
-
* rewind loop — see refusalHandling +
|
|
410
|
+
* rewind loop — see refusalHandling + shedNewestTurn. */
|
|
398
411
|
private refusalRewinds;
|
|
399
412
|
/** Per-agent count of poison-history rewinds performed by the hard-down
|
|
400
413
|
* breaker (noteInferenceExhausted). Reset when a turn completes
|
|
@@ -461,7 +474,9 @@ export declare class AgentFramework {
|
|
|
461
474
|
private unackedDeferredWrites;
|
|
462
475
|
/** Monotonic order stamp for deferred writes: the durable queue is always
|
|
463
476
|
* written, restored, drained and flushed in `seq` order, whatever the
|
|
464
|
-
* pending/un-acked split — a re-deferred entry keeps its place.
|
|
477
|
+
* pending/un-acked split — a re-deferred entry keeps its place. Boot
|
|
478
|
+
* recovery numbers the restored queue 1..N in that order, and the stamp
|
|
479
|
+
* goes on from N (restorePersistedDeferredWrites). */
|
|
465
480
|
private deferredSeq;
|
|
466
481
|
/**
|
|
467
482
|
* Per target agent: the store's message count when the OLDEST currently
|
|
@@ -480,8 +495,38 @@ export declare class AgentFramework {
|
|
|
480
495
|
* guessing from the newest message in the window.
|
|
481
496
|
*/
|
|
482
497
|
private activeTurnTriggers;
|
|
498
|
+
/**
|
|
499
|
+
* The `[Continue]` prompt the current round of each turn follows, keyed by
|
|
500
|
+
* the turn's trigger. Each stream start sets it from what the Agent read in
|
|
501
|
+
* its request (`StartStreamResult.continuePrompt`), and a tool boundary
|
|
502
|
+
* that hands the live stream messages after the results clears it, since
|
|
503
|
+
* the next round follows those messages. `silentTurnRowMetadata` stamps the
|
|
504
|
+
* round's rows with it.
|
|
505
|
+
*/
|
|
506
|
+
private readonly turnPrompts;
|
|
483
507
|
/** The trigger of `agentName`'s turn in progress, if a turn is running. */
|
|
484
508
|
getActiveTurnTrigger(agentName: string): InferenceRequest | undefined;
|
|
509
|
+
/**
|
|
510
|
+
* The window of the frame that holds an agent's turn with no stream to
|
|
511
|
+
* carry a stop and one of its checks ahead: a start, from its entry until
|
|
512
|
+
* it hands its turn to a stream or ends (its checks after the hooks, after
|
|
513
|
+
* the compile, at a failure and after a wait to retry its compile),
|
|
514
|
+
* driveStream's wait to retry a failed inference (its check after the
|
|
515
|
+
* wait), and the tool-result guard's wait for the agent's speech (its
|
|
516
|
+
* check after the wait, which the window lets the abandon reach once a
|
|
517
|
+
* caller's cancelStream() has left the agent holding no stream). Each
|
|
518
|
+
* frame opens a window of its own and closes it only while it
|
|
519
|
+
* is still the agent's, so a start that ends after a later frame opened
|
|
520
|
+
* one, such as its retry's stream waiting to retry, leaves that one open.
|
|
521
|
+
* An operator's abandon marks the window, and the frame's check collects
|
|
522
|
+
* the mark, which goes with the window. abortInference() and the abandon
|
|
523
|
+
* count a turn with no stream only here; a stop made anywhere else, as
|
|
524
|
+
* while an agent is idle, a turn finishes its last delivery or a provider
|
|
525
|
+
* hold has parked it, has no check to end it, and the next start drops
|
|
526
|
+
* it. Keyed by the Agent, so a replacement agent under the same name
|
|
527
|
+
* never shares one.
|
|
528
|
+
*/
|
|
529
|
+
private checkAhead;
|
|
485
530
|
/** Structured calls executed in the current logical turn. Unlike the
|
|
486
531
|
* per-stream local this survives framework retries and budget restarts. */
|
|
487
532
|
private logicalTurnToolCalls;
|
|
@@ -523,6 +568,9 @@ export declare class AgentFramework {
|
|
|
523
568
|
* ephemeral agents have isolated slots and are their own only readers.
|
|
524
569
|
*/
|
|
525
570
|
private readonly sharedSlotAgents;
|
|
571
|
+
/** The windows of forks and runs deregistered while the host was quiesced,
|
|
572
|
+
* by agent name; resume() releases them (releaseWindowNowOrAfterResume). */
|
|
573
|
+
private readonly releasesAfterResume;
|
|
526
574
|
/** The coalescing commit in flight, if any (see commitCoalescingDurable). */
|
|
527
575
|
private coalescingCommit;
|
|
528
576
|
private inferenceRouter;
|
|
@@ -587,11 +635,20 @@ export declare class AgentFramework {
|
|
|
587
635
|
private mcplToolRefreshPending;
|
|
588
636
|
/** Maps tool prefix → serverId for dispatch routing. */
|
|
589
637
|
private mcplPrefixMap;
|
|
590
|
-
/** Namespaced tool name → the server whose tools/list produced it
|
|
591
|
-
*
|
|
638
|
+
/** Namespaced tool name → the server whose tools/list produced it, from
|
|
639
|
+
* its first listing of the name. resolveMcplTool reads it first. */
|
|
592
640
|
private mcplToolServers;
|
|
593
641
|
/** Servers whose tools/list answered in the latest refresh. */
|
|
594
642
|
private mcplListedServers;
|
|
643
|
+
/** refreshMcplTools' starts, and the start whose result was published
|
|
644
|
+
* last: a refresh that a later-started one has overtaken publishes
|
|
645
|
+
* nothing, since that one listed every server after it. */
|
|
646
|
+
private mcplToolsRefreshStarted;
|
|
647
|
+
private mcplToolsRefreshPublished;
|
|
648
|
+
/** How many times each server's connection has closed. A listing that
|
|
649
|
+
* began before its server's latest close is of a session that's over,
|
|
650
|
+
* and refreshMcplTools publishes none of it. */
|
|
651
|
+
private mcplServerCloses;
|
|
595
652
|
/** Zero-match tool-pattern diagnostics (checkToolPatterns): set at the end
|
|
596
653
|
* of create(), when the tool universe is first complete. */
|
|
597
654
|
private toolPatternChecksArmed;
|
|
@@ -602,6 +659,27 @@ export declare class AgentFramework {
|
|
|
602
659
|
private toolPatternKnownPrefixes;
|
|
603
660
|
/** Maps serverId → McplServerConfig for prefix lookup. */
|
|
604
661
|
private mcplServerConfigs;
|
|
662
|
+
/** Modern-MCP (2026-07-28) servers, by id; read through modernServers().
|
|
663
|
+
* They are kept apart from the MCPL registry on purpose: they have no
|
|
664
|
+
* grant, planes or server→host traffic, so the MCPL machinery (quiesce's
|
|
665
|
+
* plane pauses, awareness gates, policy) never sees them. They take part
|
|
666
|
+
* only through the tool paths, and their list changes reach agents
|
|
667
|
+
* through ordinary admission. */
|
|
668
|
+
private modernMcpConnections;
|
|
669
|
+
/** Connects and disconnects in flight, by server id (holdMcpServerId);
|
|
670
|
+
* created on first use, like modernMcpConnections. */
|
|
671
|
+
private mcpServerOps;
|
|
672
|
+
/** Each legacy connect in flight's own abort (connectHeldMcplServer):
|
|
673
|
+
* stop() and a disconnect of its id end it at once, its launch reaped,
|
|
674
|
+
* rather than waiting out its handshake. Created on first use, as the
|
|
675
|
+
* restart claims are (legacyConnectAborts()). */
|
|
676
|
+
private legacyConnectAbortMap;
|
|
677
|
+
/** The ids and tool prefixes restarts hold, each with the claim of the
|
|
678
|
+
* restart holding it, from the restart's checks through its connect
|
|
679
|
+
* (restartMcplServer): no other connect or restart takes them while the
|
|
680
|
+
* old server is torn down. Created on first use (restartClaims), like
|
|
681
|
+
* mcpServerOps. */
|
|
682
|
+
private mcpRestartClaims;
|
|
605
683
|
/** Host capabilities advertised during the MCP handshake — stored so servers
|
|
606
684
|
* can be connected at runtime (connectMcplServer) after initialization. */
|
|
607
685
|
private mcplHostCapabilities;
|
|
@@ -639,9 +717,10 @@ export declare class AgentFramework {
|
|
|
639
717
|
* Create and start the framework. A create() that fails releases what it
|
|
640
718
|
* had acquired before its error reaches the caller, so that the caller can
|
|
641
719
|
* try again in the same process: the framework it had begun is stopped, as
|
|
642
|
-
* stop() stops one, but giving up after 30 s on each of stop()'s
|
|
643
|
-
* waits, for an operator's operations already running
|
|
644
|
-
* modules and MCPL servers, and
|
|
720
|
+
* stop() stops one, but giving up after 30 s on each of stop()'s cleanup
|
|
721
|
+
* waits, for an operator's operations already running, then for its
|
|
722
|
+
* modules and MCPL servers, and then for awareness drains a failed startup
|
|
723
|
+
* barrier left running, and a store it opened is closed. A store the
|
|
645
724
|
* caller passed in is left open.
|
|
646
725
|
*/
|
|
647
726
|
static create(config: FrameworkConfig): Promise<AgentFramework>;
|
|
@@ -687,23 +766,38 @@ export declare class AgentFramework {
|
|
|
687
766
|
private static joinDiagnostics;
|
|
688
767
|
private printDiagnostics;
|
|
689
768
|
/**
|
|
690
|
-
* Start the event loop.
|
|
769
|
+
* Start the event loop. A start() on a running framework does nothing.
|
|
770
|
+
* Refused, with an error, from a stop() call until that stop() settles,
|
|
771
|
+
* since that stop would wait on the lifecycle a start() begins, or tear it
|
|
772
|
+
* down under it. What a start() after a settled stop() should do is #315's
|
|
773
|
+
* question.
|
|
691
774
|
*/
|
|
692
775
|
start(): void;
|
|
693
776
|
/**
|
|
694
|
-
* Stop the event loop.
|
|
695
|
-
*
|
|
696
|
-
*
|
|
777
|
+
* Stop the event loop. Until it settles, start() and addModule() are
|
|
778
|
+
* refused. Each step of the teardown runs whatever an earlier one did: one
|
|
779
|
+
* that throws, such as a host stream's cancel(), fails the stop() once the
|
|
780
|
+
* rest has run. When a step or a wait up to and including
|
|
781
|
+
* the wait on awareness drains fails or times out, storage stays open and
|
|
782
|
+
* stop() can be called again; one that fails after it, in the storage work
|
|
783
|
+
* that finishes the stop, fails the stop() without keeping storage open.
|
|
784
|
+
* A timed-out wait lets teardown go on while what it waited for may still
|
|
785
|
+
* act on what is being torn down.
|
|
697
786
|
* @param teardownTimeoutMs Optional budget for each of stop()'s waits, in
|
|
698
787
|
* turn: on the streams it cancels, on maintenance in flight (a pass or an
|
|
699
788
|
* over-budget drain kick), on the event loop, on an operator's operations
|
|
700
|
-
* already running,
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
789
|
+
* already running, on modules and MCPL together, then on Discord awareness
|
|
790
|
+
* drains, which send nothing once stop() has begun, recording the call the
|
|
791
|
+
* close ended. With a budget, a stop() can take up to six of them, besides
|
|
792
|
+
* the withheld-spill deadline of a guard's write still under way. Omit to
|
|
793
|
+
* wait until each settles, as required by existing module/child contracts.
|
|
794
|
+
* A wait whose budget runs out fails the stop() with a ShutdownTimeoutError
|
|
795
|
+
* naming what it waited for; with more than one, or beside another failure,
|
|
796
|
+
* stop() fails with an AggregateError of them all. A stream whose cancel
|
|
797
|
+
* threw is treated as one whose wait ran out, whatever the budget, and the
|
|
798
|
+
* stop() fails with the cancel's error: that stop() doesn't wait for it,
|
|
799
|
+
* even with no budget, and a later stop() waits for it as for anything an
|
|
800
|
+
* earlier one left running (the last point below). After either:
|
|
707
801
|
* - an agent still registered whose stream is still running keeps its
|
|
708
802
|
* deferred writes queued, since the stream may still write. The stream's
|
|
709
803
|
* own turn-end flush takes them when it settles, if the process lives on,
|
|
@@ -716,11 +810,18 @@ export declare class AgentFramework {
|
|
|
716
810
|
* land in the run's namespace after them.
|
|
717
811
|
* - an event loop still in a call, such as a module's onProcess, finishes
|
|
718
812
|
* that call and the rest of its iteration, and then exits. A start()
|
|
719
|
-
* made
|
|
813
|
+
* made once that stop() has failed runs its own loop beside that last
|
|
814
|
+
* iteration.
|
|
720
815
|
* - a later stop() waits again, within its own budget, for any stream or
|
|
721
816
|
* loop this one left running, so the store never closes under it.
|
|
722
817
|
*/
|
|
723
818
|
stop(teardownTimeoutMs?: number | undefined): Promise<void>;
|
|
819
|
+
/** What start() and addModule() pass before either begins work of a
|
|
820
|
+
* lifecycle. A stop() still running refuses both, from the moment it
|
|
821
|
+
* claims its attempt until that attempt settles. A failed stop() has
|
|
822
|
+
* cleared its attempt, unless it closed an owned store, which is refused
|
|
823
|
+
* first. A completed stop() is cleared, and the call goes on as before;
|
|
824
|
+
* whether a lifecycle should begin after a stop() is #315's question. */
|
|
724
825
|
private resetCompletedStop;
|
|
725
826
|
/** Register before invoking the body, so the set holds the operation for
|
|
726
827
|
* its whole life: its synchronous trace callbacks can reenter stop(), and
|
|
@@ -733,6 +834,22 @@ export declare class AgentFramework {
|
|
|
733
834
|
* queue (after a failed or completed stop()). The admission rule for every
|
|
734
835
|
* operator entry point, the host/command listener included. */
|
|
735
836
|
private stopHasBegun;
|
|
837
|
+
/** stop()'s first step for each connect still in flight, in either engine:
|
|
838
|
+
* end it, so it fails at once and its operation ends, its launch reaped,
|
|
839
|
+
* rather than holding stop()'s wait until its handshake's deadline. A
|
|
840
|
+
* modern connect's connection is registered before it starts and is
|
|
841
|
+
* closed; a legacy one's handshake, and the access provider a WebSocket
|
|
842
|
+
* dial waits for, are aborted (legacyConnectAborts). A modern close's
|
|
843
|
+
* outcome is the teardown's to report (closeModernMcpConnections). */
|
|
844
|
+
private endConnectsInFlight;
|
|
845
|
+
/** Wakers for the waits a connect makes that a stop() ends: see
|
|
846
|
+
* untilStopBegins. Made on first use. */
|
|
847
|
+
private stopWaiters;
|
|
848
|
+
/** `work`, or undefined once stop() has begun, whichever comes first: a
|
|
849
|
+
* connect's last step (its tool listing, which asks every server) needn't
|
|
850
|
+
* hold stop()'s wait for operator operations on a server that doesn't
|
|
851
|
+
* answer. The work goes on; the teardown's close ends what it waits for. */
|
|
852
|
+
private untilStopBegins;
|
|
736
853
|
private refuseOperatorAfterStop;
|
|
737
854
|
/** Wait in rounds until the set is empty: admitted work can still start work
|
|
738
855
|
* of its own. All rounds share the caller's deadline rather than renewing
|
|
@@ -837,7 +954,9 @@ export declare class AgentFramework {
|
|
|
837
954
|
* Wait an error policy's retry delay, all of it: the delay can be a
|
|
838
955
|
* provider's retry-after, and a single timer past 2^31-1 ms fires almost at
|
|
839
956
|
* once. Steps through longer waits; stop() wakes it so a shutting-down
|
|
840
|
-
* framework is never left with a wait parked for days.
|
|
957
|
+
* framework is never left with a wait parked for days. The frame's window
|
|
958
|
+
* (checkWindow) carries a waker that ends the whole wait: a stop
|
|
959
|
+
* abortInference() records, or an operator's abandon, wakes it.
|
|
841
960
|
*/
|
|
842
961
|
private waitForRetry;
|
|
843
962
|
/**
|
|
@@ -968,7 +1087,10 @@ export declare class AgentFramework {
|
|
|
968
1087
|
offTrace(listener: TraceEventListener): void;
|
|
969
1088
|
private removeTraceRegistration;
|
|
970
1089
|
/**
|
|
971
|
-
* Add a module at runtime.
|
|
1090
|
+
* Add a module at runtime. Refused, with a rejection, while a stop() is
|
|
1091
|
+
* still running: a module added then would either be stopped by that stop
|
|
1092
|
+
* or, once the stop has taken its list of modules to stop, stay started
|
|
1093
|
+
* past it.
|
|
972
1094
|
*/
|
|
973
1095
|
addModule(module: Module): Promise<void>;
|
|
974
1096
|
/**
|
|
@@ -989,7 +1111,10 @@ export declare class AgentFramework {
|
|
|
989
1111
|
*/
|
|
990
1112
|
getConversationRouter(): ConversationRouter | null;
|
|
991
1113
|
/**
|
|
992
|
-
* Abort an in-flight inference for an agent.
|
|
1114
|
+
* Abort an in-flight inference for an agent. True when there was one to
|
|
1115
|
+
* stop: a stream, or a turn with no stream and one of its checks ahead (its
|
|
1116
|
+
* hooks or compile, a wait to retry, the tool-result guard's wait), which
|
|
1117
|
+
* ends at that check, before it sends anything more.
|
|
993
1118
|
*/
|
|
994
1119
|
abortInference(agentName: string, reason?: string): boolean;
|
|
995
1120
|
/**
|
|
@@ -1015,9 +1140,10 @@ export declare class AgentFramework {
|
|
|
1015
1140
|
* Terminal for a stop the framework itself made: stop()'s shutdown and an
|
|
1016
1141
|
* operator's quiesce abandon, each recorded in frameworkCancelledStreams
|
|
1017
1142
|
* before the cancel. A stream may report that cancel as `aborted`, as
|
|
1018
|
-
* `error`,
|
|
1019
|
-
*
|
|
1020
|
-
* own text), an
|
|
1143
|
+
* `error`, by just closing, or by throwing, and each of those ends here
|
|
1144
|
+
* (through endFrameworkCancel()), so the four cannot drift: settle the
|
|
1145
|
+
* turn (an ephemeral run rejects with the stop's own text), an
|
|
1146
|
+
* attributable inference-log terminal, ONE inference:aborted
|
|
1021
1147
|
* carrying the framework's reason, gate release. No [turn-interrupted]
|
|
1022
1148
|
* marker, since nobody stopped the agent, and none of the failure
|
|
1023
1149
|
* accounting that inference:failed / inference:exhausted drive.
|
|
@@ -1030,6 +1156,8 @@ export declare class AgentFramework {
|
|
|
1030
1156
|
* Get all registered modules.
|
|
1031
1157
|
*/
|
|
1032
1158
|
getAllModules(): Module[];
|
|
1159
|
+
/** Read the namespaced utility catalogue without adding first-class model tools. */
|
|
1160
|
+
getAllUtilities(): import('./types/index.js').ToolDefinition[];
|
|
1033
1161
|
/**
|
|
1034
1162
|
* Get all available tools from all modules and MCPL servers.
|
|
1035
1163
|
*/
|
|
@@ -1040,11 +1168,22 @@ export declare class AgentFramework {
|
|
|
1040
1168
|
* a writable workspace mount for storage). */
|
|
1041
1169
|
private referenceFetcherInstance?;
|
|
1042
1170
|
private getReferenceFetcher;
|
|
1043
|
-
/** Register every RFC-005 reference in
|
|
1044
|
-
* its server, then
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1171
|
+
/** Register every RFC-005 reference in an MCPL peer's tool-result content
|
|
1172
|
+
* against its server, then fetch by `mode`:
|
|
1173
|
+
* - `register`: nothing. An in-process caller (executeMcplToolCall) may
|
|
1174
|
+
* never show the result to an agent, and an eager fetch would spend the
|
|
1175
|
+
* server's fetch budget, which the agent's own fetch_reference needs, on
|
|
1176
|
+
* bytes nobody asked for. A stub later made of a registered reference is
|
|
1177
|
+
* bound, so fetch_reference can fetch it.
|
|
1178
|
+
* - `model`: eagerly fetch the ones inside the autofetch envelope (below
|
|
1179
|
+
* the eager ceiling, connection origin — never worse than the server
|
|
1180
|
+
* having inlined the bytes). Failures are non-fatal: the stub then says
|
|
1181
|
+
* fetch_reference instead of a path.
|
|
1182
|
+
* - `script`: as `model`, then fetch every reference ("eagerly lazy"): a
|
|
1183
|
+
* script receiving a result is the strongest available signal that the
|
|
1184
|
+
* bytes are wanted (scripts process, they do not browse), so the stub it
|
|
1185
|
+
* receives carries a workspace path it can open directly.
|
|
1186
|
+
* A uri the result calls expired is fetched in no mode. */
|
|
1048
1187
|
private autoFetchReferences;
|
|
1049
1188
|
/** Core agent_settings keys — extension keys must not collide with these. */
|
|
1050
1189
|
private static readonly AGENT_SETTINGS_CORE_KEYS;
|
|
@@ -1084,7 +1223,7 @@ export declare class AgentFramework {
|
|
|
1084
1223
|
* is open again for an instance kept with a store it doesn't own and that
|
|
1085
1224
|
* is still open (start() doesn't restore stopped modules or MCPL
|
|
1086
1225
|
* connections, and refuses an owned store that stop() closed). A start()
|
|
1087
|
-
* made while a stop() is still
|
|
1226
|
+
* made while a stop() is still running is refused. */
|
|
1088
1227
|
private guardSpillsClosedFor;
|
|
1089
1228
|
/** A new agent's guard: its persisted setting, the tool-results spill its
|
|
1090
1229
|
* withheld originals are written to, and the set stop() waits on
|
|
@@ -1097,9 +1236,11 @@ export declare class AgentFramework {
|
|
|
1097
1236
|
/** Each guard that may have queued storage work, once, by agent name: the
|
|
1098
1237
|
* live agents' and every other that isn't idle. */
|
|
1099
1238
|
private guardsWithStorageWork;
|
|
1239
|
+
/** `think` for one agent: its same-round policy, and `skip_reply` named only where the agent may call it. */
|
|
1100
1240
|
private buildThinkTool;
|
|
1101
1241
|
/** agent_settings tool definition with module extension fields merged in. */
|
|
1102
1242
|
private buildAgentSettingsTool;
|
|
1243
|
+
private warnEmptyUtilityPermissions;
|
|
1103
1244
|
private getToolsForAgent;
|
|
1104
1245
|
/** Available is independent of presentation visibility; execution callers keep this surface. */
|
|
1105
1246
|
private availableToolsForPresentation;
|
|
@@ -1472,11 +1613,12 @@ export declare class AgentFramework {
|
|
|
1472
1613
|
/** previewAgentRuntimeSettings for an agent in hand: boot restore previews one not yet registered. */
|
|
1473
1614
|
private previewRuntimeSettingsFor;
|
|
1474
1615
|
/**
|
|
1475
|
-
*
|
|
1616
|
+
* Whether process events and their responses are written to Chronicle
|
|
1617
|
+
* (`processLogging.persist`). `process:completed` trace events are emitted
|
|
1618
|
+
* either way.
|
|
1476
1619
|
*/
|
|
1477
1620
|
isProcessLoggingEnabled(): {
|
|
1478
1621
|
persist: boolean;
|
|
1479
|
-
broadcast: boolean;
|
|
1480
1622
|
};
|
|
1481
1623
|
/**
|
|
1482
1624
|
* Get the underlying store.
|
|
@@ -1605,8 +1747,10 @@ export declare class AgentFramework {
|
|
|
1605
1747
|
/**
|
|
1606
1748
|
* Create an ephemeral agent that is NOT registered in the main event loop.
|
|
1607
1749
|
*
|
|
1608
|
-
* Used by SubagentModule (and similar) to
|
|
1609
|
-
*
|
|
1750
|
+
* Used by SubagentModule (and similar) to prepare short-lived agents.
|
|
1751
|
+
* Call runEphemeralToCompletion(agent, contextManager) to register and run
|
|
1752
|
+
* the returned agent. Framework-created identities have tool authority only
|
|
1753
|
+
* while registered; public tool calls before a run or after retirement fail.
|
|
1610
1754
|
* The returned agent has its own ContextManager on a namespaced state
|
|
1611
1755
|
* within the framework's shared Chronicle store — messages go to
|
|
1612
1756
|
* `{namespace}/messages`, context log to `{namespace}/context`.
|
|
@@ -1713,23 +1857,24 @@ export declare class AgentFramework {
|
|
|
1713
1857
|
private static readonly CHAT_CORE_TAGS;
|
|
1714
1858
|
/**
|
|
1715
1859
|
* Mark an inference refusal visibly: react on the message that holds the
|
|
1716
|
-
* conversational locus (the most recent incoming channel
|
|
1717
|
-
*
|
|
1718
|
-
*
|
|
1860
|
+
* refused agent's conversational locus (the most recent incoming channel
|
|
1861
|
+
* message; an ephemeral run has none, so a subagent's refusal marks no
|
|
1862
|
+
* message) with a category-specific emoji. Best-effort — failures are
|
|
1863
|
+
* logged, never thrown, and non-Discord loci are silently skipped.
|
|
1719
1864
|
*/
|
|
1720
1865
|
private reactToRefusal;
|
|
1721
1866
|
/**
|
|
1722
|
-
*
|
|
1723
|
-
* message
|
|
1724
|
-
*
|
|
1725
|
-
*
|
|
1726
|
-
*
|
|
1727
|
-
*
|
|
1728
|
-
*
|
|
1729
|
-
*
|
|
1867
|
+
* Shed the newest turn: remove the newest message that isn't a system
|
|
1868
|
+
* message, whoever wrote it, with the rest of its exchange (the tool_use
|
|
1869
|
+
* turn paired with a tool result, and the whole of a body stored in
|
|
1870
|
+
* shards). It adds no marker; the caller keeps one consolidated marker for
|
|
1871
|
+
* the episode (updateRewindMarker). The returned record's descriptor says
|
|
1872
|
+
* what was removed and its size, never the content, while the raw record
|
|
1873
|
+
* survives in the chronicle log for forensics. Returns null when only
|
|
1874
|
+
* system messages remain.
|
|
1730
1875
|
*
|
|
1731
|
-
* Shared by the
|
|
1732
|
-
*
|
|
1876
|
+
* Shared by the refusal rewind, automatic or forced by `/unstick`, and by
|
|
1877
|
+
* the shed after inference exhaustion (quarantinePoisonedHistory).
|
|
1733
1878
|
*/
|
|
1734
1879
|
private shedNewestTurn;
|
|
1735
1880
|
/**
|
|
@@ -1741,12 +1886,6 @@ export declare class AgentFramework {
|
|
|
1741
1886
|
* refusal clears. Returns the running count.
|
|
1742
1887
|
*/
|
|
1743
1888
|
private updateRewindMarker;
|
|
1744
|
-
/**
|
|
1745
|
-
* Announce a refusal-rewind on the conversational surface (Discord), used
|
|
1746
|
-
* when the withheld turn was a *human* message so it isn't dropped silently.
|
|
1747
|
-
* Best-effort; mirrors reactToRefusal's locus resolution.
|
|
1748
|
-
*/
|
|
1749
|
-
private announceRewind;
|
|
1750
1889
|
/**
|
|
1751
1890
|
* A turn that ended WITHOUT a refusal (a natural completion that wasn't
|
|
1752
1891
|
* one, or a tool-ended turn) ends the rewind episode: the model responded.
|
|
@@ -2070,13 +2209,13 @@ export declare class AgentFramework {
|
|
|
2070
2209
|
* reconnect or start delivers what is still pending.
|
|
2071
2210
|
*
|
|
2072
2211
|
* Like a server's drain, the delivery runs apart from the operation that
|
|
2073
|
-
* started it: it isn't an operator's operation
|
|
2074
|
-
*
|
|
2075
|
-
*
|
|
2076
|
-
* durable outbox. Once stop()
|
|
2077
|
-
*
|
|
2078
|
-
* marks stay pending, and the next
|
|
2079
|
-
* with the branch and delivers them.
|
|
2212
|
+
* started it: it isn't an operator's operation. A drain already running
|
|
2213
|
+
* when stop() begins sends nothing more, and stop() waits for it to record
|
|
2214
|
+
* the call it had in flight, which closing the connections ends; what it
|
|
2215
|
+
* hasn't sent stays pending in the durable outbox, unrecorded. Once stop()
|
|
2216
|
+
* has begun, none is started, since there's no point opening a drain that
|
|
2217
|
+
* the teardown is about to cut off: the marks stay pending, and the next
|
|
2218
|
+
* start's barrier reconciles the outbox with the branch and delivers them.
|
|
2080
2219
|
*
|
|
2081
2220
|
* @param after What moved the branch, for the log and the alert
|
|
2082
2221
|
* ("rollback", "branch switch", "undo" …).
|
|
@@ -2366,6 +2505,11 @@ export declare class AgentFramework {
|
|
|
2366
2505
|
/** Deliver through the lane's ordinary path; report where it landed. */
|
|
2367
2506
|
private deliverCoalesced;
|
|
2368
2507
|
private wakeForCoalescedBatch;
|
|
2508
|
+
/** Queue a wake for each agent of the batch's audience, when its latest
|
|
2509
|
+
* occurrence triggers inference. `plain`: an ordinary push wake, without
|
|
2510
|
+
* the subject a withdrawal of the batch's wakes goes by, for a render
|
|
2511
|
+
* placed in its agent's deferred queue (wakeToRead). */
|
|
2512
|
+
private queueCoalescedWakes;
|
|
2369
2513
|
/** Withdraw unstarted wakes whose sole cause is this subject (§4.2). */
|
|
2370
2514
|
private cancelCoalescedWakes;
|
|
2371
2515
|
/**
|
|
@@ -2412,13 +2556,25 @@ export declare class AgentFramework {
|
|
|
2412
2556
|
private derivePushEventChannel;
|
|
2413
2557
|
private processInferenceRequests;
|
|
2414
2558
|
/**
|
|
2415
|
-
*
|
|
2416
|
-
*
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
2419
|
-
*
|
|
2420
|
-
*
|
|
2421
|
-
*
|
|
2559
|
+
* Stamps for the rows the agent's reply stores in its current turn: its
|
|
2560
|
+
* assistant responses, its tool_result rows (through `storeResults`), and
|
|
2561
|
+
* the contained-wrapper row that stands in for a response. The turn's other
|
|
2562
|
+
* stores (a delivery receipt, a routing notice, a deferred flush) aren't the
|
|
2563
|
+
* reply's, and carry none.
|
|
2564
|
+
* - A silent heartbeat tick stamps each of them for the whole turn, with the
|
|
2565
|
+
* separator text its request rendered. The stamps keep every row of the
|
|
2566
|
+
* tick identifiable after the turn, for a later retention policy to find
|
|
2567
|
+
* or collapse. The stamp names the agent: residents share one message
|
|
2568
|
+
* slot, and a broadcast tick reaches each of them with the same eventId.
|
|
2569
|
+
* - A `[Continue]` prompt stamps the rows of each round that follows it
|
|
2570
|
+
* (`turnPrompts`).
|
|
2571
|
+
* Request builds render each turn before the first surviving assistant row
|
|
2572
|
+
* that carries its stamp and that they can recognise: one with a tool call,
|
|
2573
|
+
* or with signed or redacted thinking (see silent-heartbeat.ts). The
|
|
2574
|
+
* tool_result rows and the wrapper row are stored as `user`, so their
|
|
2575
|
+
* stamps place nothing: they mark each row as the reply's.
|
|
2576
|
+
* Undefined for ordinary turns, whose rows are stored exactly as before.
|
|
2577
|
+
* (Named for its first use, the silent tick.)
|
|
2422
2578
|
*/
|
|
2423
2579
|
private silentTurnRowMetadata;
|
|
2424
2580
|
/** Record plain-prose segments this turn suppressed without drafts (proseRouting=disabled). */
|
|
@@ -2609,13 +2765,15 @@ export declare class AgentFramework {
|
|
|
2609
2765
|
*/
|
|
2610
2766
|
private repinTurnLocus;
|
|
2611
2767
|
/**
|
|
2612
|
-
* Durable window notice for a channel the agent did not ask to open
|
|
2613
|
-
* subscription-policy admission,
|
|
2614
|
-
*
|
|
2615
|
-
*
|
|
2616
|
-
*
|
|
2617
|
-
*
|
|
2618
|
-
*
|
|
2768
|
+
* Durable window notice for a channel the agent did not ask to open: a
|
|
2769
|
+
* subscription-policy admission, announced as the decision before its
|
|
2770
|
+
* transport RPC (a failed open keeps the decision, and channel_list shows
|
|
2771
|
+
* transport state), or an open that the agent's own delivery or reply
|
|
2772
|
+
* caused (`opened-by-delivery`, `opened-by-reply`), once its transport is
|
|
2773
|
+
* confirmed. Either way it names `channel_close` as the opt-out (their
|
|
2774
|
+
* decision outranks policy). What an open channel delivers is its server's
|
|
2775
|
+
* to say (#406), so the notice doesn't promise its traffic. System message:
|
|
2776
|
+
* never triggers inference, never conversational, never locus-eligible.
|
|
2619
2777
|
*/
|
|
2620
2778
|
private recordChannelAutoOpenNotice;
|
|
2621
2779
|
/**
|
|
@@ -2727,6 +2885,27 @@ export declare class AgentFramework {
|
|
|
2727
2885
|
* newer turn instead.
|
|
2728
2886
|
*/
|
|
2729
2887
|
private abortDroppedTurn;
|
|
2888
|
+
/**
|
|
2889
|
+
* The stop no stream will carry, collected at a check of the frame whose
|
|
2890
|
+
* window it is (a start's checks before it sends anything, and the checks
|
|
2891
|
+
* at a failure and after a wait to retry): an operator's quiesce abandon of
|
|
2892
|
+
* the turn (the window's mark), else a caller's cancelStream() or
|
|
2893
|
+
* abortInference() made while the agent held no stream, since the start
|
|
2894
|
+
* that dropped an older one at its entry. When both are there, the
|
|
2895
|
+
* framework's own stop is the one that ends the turn, as at a stream's
|
|
2896
|
+
* terminal, and the caller's goes with it.
|
|
2897
|
+
*/
|
|
2898
|
+
private takeStartStop;
|
|
2899
|
+
/**
|
|
2900
|
+
* End a start that a stop reached before it sent anything, through the
|
|
2901
|
+
* terminal the same stop gets on a live stream: a caller's stop as
|
|
2902
|
+
* settleDeliberateCancel ends a cancelled stream, with the note saying the
|
|
2903
|
+
* turn was stopped before it sent anything (or, for a start that continues
|
|
2904
|
+
* a turn, before it finished), and a quiesce abandon as
|
|
2905
|
+
* settleFrameworkCancel ends one. Each settles the turn, an ephemeral run
|
|
2906
|
+
* included, and emits the one inference:aborted.
|
|
2907
|
+
*/
|
|
2908
|
+
private endStoppedStart;
|
|
2730
2909
|
/**
|
|
2731
2910
|
* Body of startAgentStream, split out so the caller's try/finally owns the
|
|
2732
2911
|
* turn token unconditionally. Returns true iff the token was handed off to
|
|
@@ -2744,8 +2923,12 @@ export declare class AgentFramework {
|
|
|
2744
2923
|
* call entered through — a public method shared with model callers can
|
|
2745
2924
|
* never confer module trust, whatever the input claims. Module origin
|
|
2746
2925
|
* exists only through the private closure handed to ModuleRegistry
|
|
2747
|
-
* (ctx.callTool → executeToolCallFrom with {kind:'module'})
|
|
2748
|
-
*
|
|
2926
|
+
* (ctx.callTool → executeToolCallFrom with {kind:'module'}), which is exempt
|
|
2927
|
+
* from agent allowlists. Registered agents' allowedTools is enforced at
|
|
2928
|
+
* dispatch, including namespaced utility names; utils only grants the
|
|
2929
|
+
* list/describe/run slot. Genuinely unidentified public callers (including
|
|
2930
|
+
* unknown legacy names) remain unrestricted. Framework-created identities
|
|
2931
|
+
* are refused while unregistered, even if their configured list allows it.
|
|
2749
2932
|
*/
|
|
2750
2933
|
executeToolCall(call: ToolCall): Promise<ToolResult>;
|
|
2751
2934
|
/**
|
|
@@ -2904,14 +3087,45 @@ export declare class AgentFramework {
|
|
|
2904
3087
|
private getOrCreateScriptRunner;
|
|
2905
3088
|
/**
|
|
2906
3089
|
* Resolve one script-inner tool call to the string the script's tool
|
|
2907
|
-
* function returns
|
|
2908
|
-
*
|
|
3090
|
+
* function returns, and whether that result is an error (the script's
|
|
3091
|
+
* `.is_error`). Never rejects: a failure without structured content becomes
|
|
3092
|
+
* an "Error: ..." string, matching the managed PTC runtime ("Claude's code
|
|
3093
|
+
* receives this error"), and a structured one its JSON object.
|
|
2909
3094
|
*
|
|
2910
|
-
*
|
|
2911
|
-
*
|
|
2912
|
-
*
|
|
3095
|
+
* A result without structured content is serialized with the HISTORY
|
|
3096
|
+
* serializer: images become placeholders, since a script variable holding
|
|
3097
|
+
* megabytes of base64 helps nobody. A result with structured content is
|
|
3098
|
+
* one JSON object holding both of the server's views
|
|
3099
|
+
* (scriptStructuredResult), so its content blocks reach the script as the
|
|
3100
|
+
* dispatch gave them, images and payloads included. A module's result that
|
|
3101
|
+
* can't be stored or sent, such as a cyclic object or a BigInt, is already
|
|
3102
|
+
* an error naming the tool when the dispatch returns it (storableToolResult),
|
|
3103
|
+
* so a script reads that error's text.
|
|
2913
3104
|
*/
|
|
2914
3105
|
private handleScriptToolCall;
|
|
3106
|
+
/** The 5MB protocol safety cap on what a script receives. */
|
|
3107
|
+
private static readonly SCRIPT_RESULT_MAX_CHARS;
|
|
3108
|
+
/**
|
|
3109
|
+
* A structured MCP result as a script receives it: one JSON object holding
|
|
3110
|
+
* both of the server's views, `{ content, structuredContent, isError }`,
|
|
3111
|
+
* plus `error` (the text) on a tool error. `content` is the content array
|
|
3112
|
+
* the dispatch gave this call (the direct reading): the server's blocks as
|
|
3113
|
+
* sent, so payloads and images survive, except that an MCPL peer's blocks
|
|
3114
|
+
* get the treatment RFC-005 gives them on every lane the model reads
|
|
3115
|
+
* (referenceBlockForScript). `structuredContent` is the tool's own JSON, as
|
|
3116
|
+
* sent. Past the size cap the result stays valid JSON: the whole object is
|
|
3117
|
+
* saved to the workspace, and the script gets
|
|
3118
|
+
* `{ isError, oversized: { chars, savedTo } }`. If it can't be saved, the
|
|
3119
|
+
* script gets a failure to materialize the result, saying the tool may
|
|
3120
|
+
* already have completed, never a success missing its result. A result
|
|
3121
|
+
* that can't be converted to JSON (a cyclic object, a BigInt), which the
|
|
3122
|
+
* dispatch's own check makes unlikely here, gets the same object empty,
|
|
3123
|
+
* `{ content: [], structuredContent: null, isError: true, error }`, the
|
|
3124
|
+
* error naming the tool. In every form, the script's `.is_error` is the
|
|
3125
|
+
* `isError` of the object its string holds, and its `.structured` is read
|
|
3126
|
+
* from that string.
|
|
3127
|
+
*/
|
|
3128
|
+
private scriptStructuredResult;
|
|
2915
3129
|
/**
|
|
2916
3130
|
* Dispatch a script-inner tool call through the NORMAL dispatch path and
|
|
2917
3131
|
* resolve with its result. The waiter intercept in handleProcessEvent
|
|
@@ -2959,6 +3173,9 @@ export declare class AgentFramework {
|
|
|
2959
3173
|
* entry for it, and its usage can be counted twice in the log. */
|
|
2960
3174
|
private logInference;
|
|
2961
3175
|
private logProcessEvent;
|
|
3176
|
+
/** Count one server's close (see mcplServerCloses). Partially-constructed
|
|
3177
|
+
* frameworks (tests build them with Object.create) have no map yet. */
|
|
3178
|
+
private noteMcplServerClosed;
|
|
2962
3179
|
/** Forget one server's RFC-008 class declarations (see the close handler). */
|
|
2963
3180
|
private dropMcplToolClasses;
|
|
2964
3181
|
/**
|
|
@@ -2994,15 +3211,20 @@ export declare class AgentFramework {
|
|
|
2994
3211
|
}>;
|
|
2995
3212
|
/**
|
|
2996
3213
|
* Find the MCPL server for a tool: [serverId, prefix], or null.
|
|
2997
|
-
*
|
|
2998
|
-
* both. The tool listing decides: the server whose tools/list offered the
|
|
3214
|
+
* The tool listing decides: the server whose tools/list offered the
|
|
2999
3215
|
* name, after its tool policy, as of the last tool refresh (a server that
|
|
3000
|
-
* closed since keeps its names until the next one).
|
|
3001
|
-
*
|
|
3002
|
-
*
|
|
3003
|
-
*
|
|
3216
|
+
* closed since keeps its names until the next one). A name the listing
|
|
3217
|
+
* doesn't hold (invented by the model, or no longer listed) goes to the
|
|
3218
|
+
* longest matching prefix. Prefixes that meet, such as `foo` and
|
|
3219
|
+
* `foo--bar`, are refused at configuration (prefixesMeet, #265), so a name
|
|
3220
|
+
* fits at most one configured server's prefix; this rule doesn't rely on
|
|
3221
|
+
* that. Never prefix-map insertion order.
|
|
3004
3222
|
*/
|
|
3005
3223
|
private resolveMcplTool;
|
|
3224
|
+
/** Registered policy; framework-created identities have no dispatch authority
|
|
3225
|
+
* while unregistered. Genuine legacy caller names retain their surface. */
|
|
3226
|
+
private canAgentUseTool;
|
|
3227
|
+
private agentToolPermissionFailure;
|
|
3006
3228
|
/**
|
|
3007
3229
|
* Why this host refuses a skip_reply call, as the model will read it, or
|
|
3008
3230
|
* undefined when it doesn't (skipReplyWakeRefusal): without an EventGate,
|
|
@@ -3085,13 +3307,20 @@ export declare class AgentFramework {
|
|
|
3085
3307
|
* of the body isn't stored. (Requeued, the
|
|
3086
3308
|
* landed shards would be stored twice, and only the rest could not be
|
|
3087
3309
|
* appended later without splitting the body.) Boot's scan for landed
|
|
3088
|
-
* writes counts a landed shard the same way.
|
|
3310
|
+
* writes counts a landed shard the same way. When the store can't be read
|
|
3311
|
+
* back (storedCopiesOf logs it), nothing is found, and the entry is put
|
|
3312
|
+
* back as one that couldn't be stored: if it had landed, a later flush
|
|
3313
|
+
* stores it again.
|
|
3089
3314
|
*
|
|
3090
3315
|
* Returns what was written (stored, or deferred again by addMessage, whose
|
|
3091
3316
|
* id is then empty), in queue order: for one target, a prefix of its
|
|
3092
|
-
* entries.
|
|
3093
|
-
*
|
|
3094
|
-
*
|
|
3317
|
+
* entries. Each comes with its content: as given, unless the store took it
|
|
3318
|
+
* as more than one message (a sharded body) and can be read back, when its
|
|
3319
|
+
* copies are returned joined, as later compiles render them (asCompiled),
|
|
3320
|
+
* or its write threw after storing it (above). `onLanded` hears an entry
|
|
3321
|
+
* whose write threw after storing it, with the id it landed under, as soon
|
|
3322
|
+
* as it's found: before the writes after it, so whatever it records keeps
|
|
3323
|
+
* their order.
|
|
3095
3324
|
*/
|
|
3096
3325
|
private writeDrainedInOrder;
|
|
3097
3326
|
/** How many messages the agent's store holds: undefined when its store
|
|
@@ -3116,6 +3345,149 @@ export declare class AgentFramework {
|
|
|
3116
3345
|
* the writes after it: an open turn's arrivals keep the order the writes
|
|
3117
3346
|
* landed in, and its newest stays the newest (remainingArrival). */
|
|
3118
3347
|
private readdDrained;
|
|
3348
|
+
/**
|
|
3349
|
+
* Where a notice about an agent's own action belongs: its failed reply, its
|
|
3350
|
+
* bounced prose (beside its `{{unsent}}` clipboard), its background script's
|
|
3351
|
+
* wake, the notices about its drafts. Every registered agent's notice is
|
|
3352
|
+
* addressed to that agent, so it lands in the window that agent reads and
|
|
3353
|
+
* waits on that agent's own turn, stream and tool cycle: a conversation
|
|
3354
|
+
* fork or an ephemeral run reads only its isolated slot, and a resident's
|
|
3355
|
+
* notice would otherwise wait on the primary's turn rather than its own.
|
|
3356
|
+
* Residents share one message slot, so a resident's notice can land there
|
|
3357
|
+
* while another resident's turn is alive; agent-framework #291 covers that.
|
|
3358
|
+
*
|
|
3359
|
+
* null when the agent is no longer registered (a fork or a run already
|
|
3360
|
+
* released): there is no window to write, so the caller writes nothing,
|
|
3361
|
+
* traces nothing and requests no wake. The drop is logged here, once. A
|
|
3362
|
+
* failed reply is passed on by name instead (passFailedReplyToPrimary). The
|
|
3363
|
+
* notice of a channel an agent's own send opened follows the same rule in
|
|
3364
|
+
* recordChannelAutoOpenNotice, which passes it on by name too.
|
|
3365
|
+
*/
|
|
3366
|
+
private noticeTargetFor;
|
|
3367
|
+
/**
|
|
3368
|
+
* A conversation fork or an ephemeral run has been deregistered. A release
|
|
3369
|
+
* never runs while the host is quiesced: it waits for resume()
|
|
3370
|
+
* (releaseWindowNowOrAfterResume), since a write could land mid-surgery.
|
|
3371
|
+
*
|
|
3372
|
+
* The agent never reads its window again, so every failed-reply notice it
|
|
3373
|
+
* never read is passed to the primary, by name, once: each one stored in
|
|
3374
|
+
* its window above its consumed watermark (flushed there at its turn's end,
|
|
3375
|
+
* or stored while it was idle) and not heard at a tool boundary, and each
|
|
3376
|
+
* one still queued for it. Writes still
|
|
3377
|
+
* queued would wait for a boundary it never reaches, and the flush that
|
|
3378
|
+
* finds it gone would drop them, so they land in its own window now, which
|
|
3379
|
+
* Chronicle keeps for investigation. Its stream is over or cancelled, so it
|
|
3380
|
+
* compiles nothing more. One path still stores after these writes: a
|
|
3381
|
+
* `complete` that arrived while the agent still waited for tools awaits
|
|
3382
|
+
* the spill of its last tool results, and stores them once that resolves,
|
|
3383
|
+
* even if a watchdog has ended the run meanwhile. A tool boundary stores
|
|
3384
|
+
* nothing for a round whose turn was stopped while its results were
|
|
3385
|
+
* prepared.
|
|
3386
|
+
*/
|
|
3387
|
+
private releaseWindow;
|
|
3388
|
+
/**
|
|
3389
|
+
* The failed-reply notices stored in `agent`'s window that it never read:
|
|
3390
|
+
* those above the lower of its consumed watermark and the point where the
|
|
3391
|
+
* watermark's branch and the current one part (branchesPartAt), or every
|
|
3392
|
+
* one, when it never compiled. The watermark moves at a compile, and at a
|
|
3393
|
+
* tool boundary whose
|
|
3394
|
+
* stream declares it carries the messages injected there
|
|
3395
|
+
* (markContextConsumed), so a notice the live stream heard is under it, and
|
|
3396
|
+
* one a boundary stored without sending (a turn a tool ended, a budget
|
|
3397
|
+
* restart, a stream that may drop injections) is above it.
|
|
3398
|
+
*/
|
|
3399
|
+
private unreadFailedReplies;
|
|
3400
|
+
/**
|
|
3401
|
+
* The last sequence two branches' histories share: Infinity for one branch,
|
|
3402
|
+
* and for two, the point where they part. A branch's records are numbered
|
|
3403
|
+
* on from its branch point (Chronicle gives each record its branch's head
|
|
3404
|
+
* plus one), so up to that point both hold the same records under the same
|
|
3405
|
+
* numbers, and past it each branch's numbers are its own. -Infinity when
|
|
3406
|
+
* the store knows no shared history for them, as for an empty branch.
|
|
3407
|
+
*/
|
|
3408
|
+
private branchesPartAt;
|
|
3409
|
+
/**
|
|
3410
|
+
* Release a deregistered fork's or run's window (releaseWindow) now, or,
|
|
3411
|
+
* while the host is quiesced, when it resumes. A release lands the agent's
|
|
3412
|
+
* queued writes in its window, and while quiesced a write could land
|
|
3413
|
+
* mid-surgery; dropping them instead would lose them from both the window
|
|
3414
|
+
* and the recovery queue. Only the window waits: the agent is already
|
|
3415
|
+
* deregistered, so its stream can't dispatch anything more and resume
|
|
3416
|
+
* doesn't weigh its context, and a write addressed to it meanwhile is
|
|
3417
|
+
* treated as for any agent no longer registered (dropped, or passed to the
|
|
3418
|
+
* primary if it's a failed reply).
|
|
3419
|
+
*/
|
|
3420
|
+
private releaseWindowNowOrAfterResume;
|
|
3421
|
+
/** resume(): the windows whose release the quiesce window postponed, each on its own. */
|
|
3422
|
+
private runReleasesAfterResume;
|
|
3423
|
+
/**
|
|
3424
|
+
* A fork or an ephemeral run ended before reading that its reply's delivery
|
|
3425
|
+
* to a channel failed: it was released with the notice stored in its window
|
|
3426
|
+
* unread, or its delivery failed after release. (A notice still queued for
|
|
3427
|
+
* it, at release or restored at boot, goes on as the queue entry itself:
|
|
3428
|
+
* queuedFailedReplyForPrimary.) Tell the primary instead, naming the
|
|
3429
|
+
* speaker, so an agent who can still act learns of it and can tell the
|
|
3430
|
+
* human. It gives the reply's length, not its words, which stay in the
|
|
3431
|
+
* speaker's window. Its wording follows the speaker's own notice
|
|
3432
|
+
* (onRouteFailure): a delivery that wasn't confirmed may have been posted,
|
|
3433
|
+
* and neither text says no one saw the reply, since only this channel's
|
|
3434
|
+
* routing failed. Only for a delivery to a channel; a reply that had no
|
|
3435
|
+
* channel to go to (no locus) had no human waiting for it. Never throws:
|
|
3436
|
+
* it runs inside a release, which must complete whatever this write meets.
|
|
3437
|
+
*/
|
|
3438
|
+
private passFailedReplyToPrimary;
|
|
3439
|
+
/**
|
|
3440
|
+
* A queued failed-reply entry for `speaker`, who is gone, as the primary's
|
|
3441
|
+
* by-name notice (passFailedReplyToPrimary's words): the same entry, under
|
|
3442
|
+
* its own id and seq, now addressed to the primary. Written through the
|
|
3443
|
+
* drain, it lands stamped with that id, or waits in the queue under it, so
|
|
3444
|
+
* boot's exactly-once holds for it: a crash before the original's ack
|
|
3445
|
+
* replays one entry, never the original and a separate notice. null when no
|
|
3446
|
+
* one is told (logged): a reply that had no channel to reach, or no primary.
|
|
3447
|
+
*/
|
|
3448
|
+
private queuedFailedReplyForPrimary;
|
|
3449
|
+
/** The primary's by-name notice of `speaker`'s failed reply, or null when no
|
|
3450
|
+
* one is told, which is logged here (see passFailedReplyToPrimary). */
|
|
3451
|
+
private failedReplyNoticeForPrimary;
|
|
3452
|
+
/**
|
|
3453
|
+
* A channel as a notice names it: the label when the registry has one, since
|
|
3454
|
+
* a bare snowflake is unresolvable for the agent (the 2026-07-21 incident
|
|
3455
|
+
* read as "a stale artifact", not a live failure).
|
|
3456
|
+
*/
|
|
3457
|
+
private channelForNotice;
|
|
3458
|
+
/**
|
|
3459
|
+
* A module's write through its context: addMessage's, except that a write
|
|
3460
|
+
* the framework holds is answered by its handle (heldHandle) rather than
|
|
3461
|
+
* '', so the module can find, read, edit and remove what it wrote before
|
|
3462
|
+
* the write lands. The framework's own callers keep the '' they've always
|
|
3463
|
+
* had, which their traces and checks take as a write not stored yet.
|
|
3464
|
+
*/
|
|
3465
|
+
private addModuleMessage;
|
|
3466
|
+
/**
|
|
3467
|
+
* The writes the framework holds for the store `reader` reads, in queue
|
|
3468
|
+
* order: those addressed to it and, when it's an ordinary resident, those
|
|
3469
|
+
* addressed to any ordinary resident, since residents share one message
|
|
3470
|
+
* slot (sharedSlotAgents). A write whose target is gone isn't among them:
|
|
3471
|
+
* no module reads that agent's store, and the write waits for its window's
|
|
3472
|
+
* release (drainDeferredFor) or, at its flush, is dropped (addMessage), a
|
|
3473
|
+
* failed reply passing to the primary as its notice
|
|
3474
|
+
* (queuedFailedReplyForPrimary).
|
|
3475
|
+
*/
|
|
3476
|
+
private heldWritesFor;
|
|
3477
|
+
/**
|
|
3478
|
+
* The writes held for `reader`'s store (heldWritesFor) as the rows a
|
|
3479
|
+
* module's context reads: each under its handle, marked `held`, with the
|
|
3480
|
+
* participant, content and metadata it was written with, the time it was
|
|
3481
|
+
* first held as its timestamp, and a sequence after every row the store
|
|
3482
|
+
* holds, in queue order. The sequence and timestamp are provisional: the
|
|
3483
|
+
* stored row has the store's own.
|
|
3484
|
+
*/
|
|
3485
|
+
private heldRows;
|
|
3486
|
+
/** The row a held write landed as, found by the id it's stored with
|
|
3487
|
+
* (`metadata.deferredWriteId`): the first, for a body stored in shards,
|
|
3488
|
+
* as addMessage answers a stored write. Null when it hasn't landed, or is
|
|
3489
|
+
* no longer in the store. */
|
|
3490
|
+
private landedRow;
|
|
3119
3491
|
private editMessage;
|
|
3120
3492
|
private removeMessage;
|
|
3121
3493
|
private getMessage;
|
|
@@ -3234,6 +3606,44 @@ export declare class AgentFramework {
|
|
|
3234
3606
|
* Fail-open: individual server connection failures don't prevent framework startup.
|
|
3235
3607
|
*/
|
|
3236
3608
|
private initializeMcpl;
|
|
3609
|
+
/** The modern connections, created on first use, so a framework assembled
|
|
3610
|
+
* field by field (as unit tests do) needs no setup for them. */
|
|
3611
|
+
private modernServers;
|
|
3612
|
+
/** The restarts' claims (mcpRestartClaims), created on first use, as the
|
|
3613
|
+
* modern connections are. */
|
|
3614
|
+
private restartClaims;
|
|
3615
|
+
private legacyConnectAborts;
|
|
3616
|
+
/**
|
|
3617
|
+
* Hold a server id for one connect or disconnect, until `release()`.
|
|
3618
|
+
* Together with the live connections (the MCPL registry and the modern
|
|
3619
|
+
* map) this is what holds an id: from a connect's admission until its
|
|
3620
|
+
* teardown is done, one owner at a time. So a connect is refused while
|
|
3621
|
+
* anything holds its id, and a teardown never removes what a later
|
|
3622
|
+
* connection registered. A disconnect takes the hold over, and waits for
|
|
3623
|
+
* the operation it displaced (`previous`); a connect that finds itself
|
|
3624
|
+
* `displaced` ends rather than setting up a server being removed. Each
|
|
3625
|
+
* release frees only its own hold.
|
|
3626
|
+
*/
|
|
3627
|
+
private holdMcpServerId;
|
|
3628
|
+
/** Whether a server's connection still serves it, or is reconnecting to
|
|
3629
|
+
* it. One the host is closing or has closed doesn't, and neither does one
|
|
3630
|
+
* lost for good, whose reconnecting has stopped. */
|
|
3631
|
+
private static mcpConnectionServes;
|
|
3632
|
+
/**
|
|
3633
|
+
* A connect whose failed launch couldn't be confirmed exited. Its
|
|
3634
|
+
* connection stays registered, closed, and holds the id, so nothing
|
|
3635
|
+
* launches beside a child that may still be running; a disconnect retries
|
|
3636
|
+
* the reap, and completes once the exit is confirmed. Once stop() has
|
|
3637
|
+
* begun it refuses a disconnect, and retries the reap itself, so no
|
|
3638
|
+
* disconnect is offered then.
|
|
3639
|
+
*/
|
|
3640
|
+
private unreapedConnectFailure;
|
|
3641
|
+
/** Close every modern-MCP connection, including any connect still in
|
|
3642
|
+
* flight, so none outlives a failed startup or stop(). One whose close
|
|
3643
|
+
* fails or is still pending stays registered, holding its id, as a failed
|
|
3644
|
+
* connect's does, and every failure is thrown, as the MCPL registry's
|
|
3645
|
+
* closeAll does. `timeoutMs` bounds the wait without cancelling cleanup. */
|
|
3646
|
+
private closeModernMcpConnections;
|
|
3237
3647
|
/**
|
|
3238
3648
|
* Reconcile the durable ledger with Chronicle, then deliver every server's
|
|
3239
3649
|
* work. A drain still running is waited for and then followed by a fresh
|
|
@@ -3252,6 +3662,10 @@ export declare class AgentFramework {
|
|
|
3252
3662
|
* Deliver every due ref independently. Permanent Discord failures are kept
|
|
3253
3663
|
* in the ledger for audit but do not block later operations; retryable
|
|
3254
3664
|
* failures remain pending for the next reconnect/list-change attempt.
|
|
3665
|
+
* Once stop() has begun, a drain sends nothing more and records nothing
|
|
3666
|
+
* for what it hasn't sent: that stays pending, as it was, for the next
|
|
3667
|
+
* start's barrier. stop() closes the connections and then waits for each
|
|
3668
|
+
* drain still running to record the call it had in flight.
|
|
3255
3669
|
*/
|
|
3256
3670
|
private drainDiscordAwarenessOutbox;
|
|
3257
3671
|
private readDiscordAwarenessPending;
|
|
@@ -3267,7 +3681,9 @@ export declare class AgentFramework {
|
|
|
3267
3681
|
* its last read of the ledger, missing a batch activated since. So a
|
|
3268
3682
|
* generation that finds a drain running waits for it, then drains again
|
|
3269
3683
|
* with a fresh pass that reads the ledger anew. Two generations waiting on
|
|
3270
|
-
* the same drain share the fresh pass that follows it.
|
|
3684
|
+
* the same drain share the fresh pass that follows it. Once stop() has
|
|
3685
|
+
* begun, a drain sends nothing more, so a gate armed then completes with
|
|
3686
|
+
* what it found pending left for the next start.
|
|
3271
3687
|
*/
|
|
3272
3688
|
private drainForGeneration;
|
|
3273
3689
|
/**
|
|
@@ -3278,10 +3694,57 @@ export declare class AgentFramework {
|
|
|
3278
3694
|
* meanwhile. Rejects as the generation it waited for rejects.
|
|
3279
3695
|
*/
|
|
3280
3696
|
private awaitDiscordAwarenessBarriers;
|
|
3697
|
+
/**
|
|
3698
|
+
* Per connection, the transport epoch whose §5.3 policy exchange is in
|
|
3699
|
+
* flight: a connect's, from when the registry hands the connection back,
|
|
3700
|
+
* or a reconnect's, from its 'reconnect' event. Until the exchange settles,
|
|
3701
|
+
* that transport's traffic must wait for its grant, so a gate that opens
|
|
3702
|
+
* every connection's planes meanwhile (another server's list change, a
|
|
3703
|
+
* resume, an awareness sync, startup's staged open) passes it by
|
|
3704
|
+
* (mcplPlanesMayOpen), and the exchange's own caller opens them once it
|
|
3705
|
+
* settles (openMcplPlanesAfterExchange).
|
|
3706
|
+
*/
|
|
3707
|
+
private readonly mcplPolicyExchanges;
|
|
3708
|
+
/** Whether a gate may open this connection's planes: no policy exchange is
|
|
3709
|
+
* in flight on its current transport (see mcplPolicyExchanges). */
|
|
3710
|
+
private mcplPlanesMayOpen;
|
|
3711
|
+
/**
|
|
3712
|
+
* Run a connection's §5.3 policy exchange with its planes held: it is
|
|
3713
|
+
* marked in flight for the transport it runs on, so no gate releases that
|
|
3714
|
+
* transport's traffic before its grant exists. With `epoch`, it runs only
|
|
3715
|
+
* on that transport: a runtime connect passes the one it registered, and
|
|
3716
|
+
* if that transport is gone, the exchange isn't run, since a reconnect
|
|
3717
|
+
* that adopts a next transport, if one comes, runs that one's. With
|
|
3718
|
+
* `closeOnFailure`, as for a runtime connect or restart, an exchange that
|
|
3719
|
+
* throws closes the connection for good, through the registry, before it
|
|
3720
|
+
* lifts the marker: left live, the connection would be half registered,
|
|
3721
|
+
* and unmarked before its close, a gate completing in between would let
|
|
3722
|
+
* out what it held with no grant. A close that fails keeps the connection
|
|
3723
|
+
* registered, but closed for good, it readies nothing but its own reports.
|
|
3724
|
+
* Without `closeOnFailure`, as for a reconnect or a staged startup connect,
|
|
3725
|
+
* an exchange that throws leaves the connection live with the grant it
|
|
3726
|
+
* reached, empty if the policy step itself threw, and the marker lifts.
|
|
3727
|
+
*/
|
|
3728
|
+
private settlePolicyExchange;
|
|
3729
|
+
/**
|
|
3730
|
+
* Open a connection's planes once its exchange has settled, when the gate
|
|
3731
|
+
* its connect or reconnect installed was replaced during the exchange: the
|
|
3732
|
+
* newer gate passed the connection by, and if it has completed, nothing
|
|
3733
|
+
* else would open it. A connection whose transport dropped meanwhile is
|
|
3734
|
+
* readied as any gate readies one between transports, so its own reports
|
|
3735
|
+
* go on. How far follows what is held now: while a gate is up, only the
|
|
3736
|
+
* control plane opens, since a gate holds data planes alone, and its
|
|
3737
|
+
* completion, which no longer passes this connection by, opens the data
|
|
3738
|
+
* plane; a quiesced host (issue #122) likewise opens only control planes;
|
|
3739
|
+
* otherwise both open.
|
|
3740
|
+
*/
|
|
3741
|
+
private openMcplPlanesAfterExchange;
|
|
3281
3742
|
/**
|
|
3282
3743
|
* Install one framework-global Discord-awareness generation before releasing
|
|
3283
3744
|
* any inference-bearing event. With pending work or a drain still running,
|
|
3284
|
-
* every MCPL data plane is paused while
|
|
3745
|
+
* every MCPL data plane is paused while the control planes remain live,
|
|
3746
|
+
* but for a connection whose policy exchange is in flight, which neither
|
|
3747
|
+
* the release nor the completion opens (mcplPlanesMayOpen).
|
|
3285
3748
|
* With neither, ready() runs synchronously so request responders preserve
|
|
3286
3749
|
* their historical same-stack behavior.
|
|
3287
3750
|
*/
|
|
@@ -3289,6 +3752,14 @@ export declare class AgentFramework {
|
|
|
3289
3752
|
private releaseMcplDataPlaneGate;
|
|
3290
3753
|
private completeMcplDataPlaneGate;
|
|
3291
3754
|
private failMcplDataPlaneGate;
|
|
3755
|
+
/**
|
|
3756
|
+
* Close a legacy connection for good through the registry. A close that
|
|
3757
|
+
* can't confirm its child exited keeps the connection registered, holding
|
|
3758
|
+
* its id, and emits no 'close', so no close listener takes its tools off
|
|
3759
|
+
* the agents' list: this does, then rethrows the failure for the caller to
|
|
3760
|
+
* report. A server the host has given up on leaves the list either way.
|
|
3761
|
+
*/
|
|
3762
|
+
private closeMcplServerForGood;
|
|
3292
3763
|
/**
|
|
3293
3764
|
* Close a runtime connect's new connection for good, through the registry,
|
|
3294
3765
|
* after a step of that connect failed. A close that fails keeps the entry,
|
|
@@ -3303,11 +3774,23 @@ export declare class AgentFramework {
|
|
|
3303
3774
|
* lifecycle API (connectMcplServer). Throws on connection failure.
|
|
3304
3775
|
*/
|
|
3305
3776
|
private connectMcplServerInternal;
|
|
3306
|
-
/**
|
|
3307
|
-
*
|
|
3308
|
-
*
|
|
3309
|
-
*
|
|
3310
|
-
|
|
3777
|
+
/** The part of a connect that runs holding its id, handing back the
|
|
3778
|
+
* connection it registered. `displaced`: whether a disconnect has taken
|
|
3779
|
+
* the id over and is waiting for this connect, which a legacy connect asks
|
|
3780
|
+
* once its handshake is done. */
|
|
3781
|
+
private connectHeldMcplServer;
|
|
3782
|
+
/** Per-connection §17.8 fetch limiter, keyed by the connection, so one
|
|
3783
|
+
* that replaces a removed server under its id starts its own: at most one
|
|
3784
|
+
* fetch in flight; announcements during it coalesce into one refresh run
|
|
3785
|
+
* after it, and announcements within the floor after a fetch into one run
|
|
3786
|
+
* once the floor has passed — the host bounds the rate; it never depends
|
|
3787
|
+
* on server coalescing. A queued refresh runs only on the transport of
|
|
3788
|
+
* the latest announcement it holds (`queuedEpoch`), and its receipt
|
|
3789
|
+
* reports the domains of the announcements coalesced into it there
|
|
3790
|
+
* (`queuedDomains`), since its fetch answers them all. The next
|
|
3791
|
+
* transport's initialize and policy exchange start afresh, and its own
|
|
3792
|
+
* announcements queue their own, so an earlier transport's hints are
|
|
3793
|
+
* dropped. */
|
|
3311
3794
|
private manifestRefreshState;
|
|
3312
3795
|
private static readonly MANIFEST_FETCH_FLOOR_MS;
|
|
3313
3796
|
/**
|
|
@@ -3325,7 +3808,9 @@ export declare class AgentFramework {
|
|
|
3325
3808
|
*/
|
|
3326
3809
|
private handleManifestChanged;
|
|
3327
3810
|
/** A refresh handleManifestChanged schedules for itself, after the fetch
|
|
3328
|
-
* floor or behind a fetch in flight.
|
|
3811
|
+
* floor or behind a fetch in flight. Its announcement is the domains of
|
|
3812
|
+
* the announcements it coalesced (`{ domains }`), the one field
|
|
3813
|
+
* handleManifestChanged reads of one. It's contained as the announcement's
|
|
3329
3814
|
* own run is. Its fetch's own failure is logged by the fetch's catch, as
|
|
3330
3815
|
* in 0.22.x; any other failure emits mcpl:request-handler-error and a
|
|
3331
3816
|
* stderr line through the containment. */
|
|
@@ -3392,13 +3877,25 @@ export declare class AgentFramework {
|
|
|
3392
3877
|
* false or null is refused, as `create()` refuses one.
|
|
3393
3878
|
*/
|
|
3394
3879
|
connectMcplServer(config: import('./mcpl/types.js').McplServerConfig): Promise<void>;
|
|
3880
|
+
/** connectMcplServer's work, for a restart's connect too: the id and tool
|
|
3881
|
+
* prefix its `claim` holds are free to it, and refused to everyone else. */
|
|
3395
3882
|
private runConnectMcplServer;
|
|
3396
3883
|
/**
|
|
3397
|
-
* Disconnect an MCPL server at runtime:
|
|
3398
|
-
*
|
|
3399
|
-
*
|
|
3400
|
-
*
|
|
3884
|
+
* Disconnect an MCPL server at runtime: remove its channels from the
|
|
3885
|
+
* registry (first, cancelling their queued lifecycle work), close the
|
|
3886
|
+
* connection, destroy its feature-set and checkpoint state (permanent
|
|
3887
|
+
* removal — unlike a transient transport close, which preserves checkpoints
|
|
3888
|
+
* for the reconnect), drop routing entries, and refresh tools.
|
|
3401
3889
|
* No-op-ish if the server is not connected (still clears routing state).
|
|
3890
|
+
*
|
|
3891
|
+
* It holds the id throughout (holdMcpServerId): a connect for it is
|
|
3892
|
+
* refused meanwhile, and a connect already in flight is ended (closed, or
|
|
3893
|
+
* displaced when its legacy handshake finishes) and settles before
|
|
3894
|
+
* anything but the channel entries the disconnect found when it began is
|
|
3895
|
+
* removed. A close that can't confirm a child exited fails the disconnect
|
|
3896
|
+
* before anything but those entries is removed: the server stays
|
|
3897
|
+
* registered, closed, so nothing launches beside a child that may still be
|
|
3898
|
+
* running, and disconnecting again retries the reap.
|
|
3402
3899
|
*/
|
|
3403
3900
|
disconnectMcplServer(id: string): Promise<void>;
|
|
3404
3901
|
private runDisconnectMcplServer;
|
|
@@ -3407,11 +3904,63 @@ export declare class AgentFramework {
|
|
|
3407
3904
|
* same (or an updated) config. This actually respawns a stdio child —
|
|
3408
3905
|
* unlike `reconnect: true`, which only retries after transport-level
|
|
3409
3906
|
* failures. Throws if the server has no stored config and none is given.
|
|
3410
|
-
*
|
|
3411
|
-
*
|
|
3907
|
+
* What its connect would refuse is refused before the running server is
|
|
3908
|
+
* torn down. Until the connect, a connect or a restart started meanwhile
|
|
3909
|
+
* is refused the id and the tool prefix the restart moves the server to,
|
|
3910
|
+
* and a module added meanwhile is refused that tool prefix. The id and
|
|
3911
|
+
* prefix it moves the server from are free once its disconnect is done, as
|
|
3912
|
+
* after any disconnect.
|
|
3913
|
+
*
|
|
3914
|
+
* A disconnect of the id the restart moves the server to (its own id, for
|
|
3915
|
+
* a restart under the same id), or a `stop()`, that begins during the
|
|
3916
|
+
* restart ends it, as a disconnect ends a connect in flight: the restart
|
|
3917
|
+
* rejects, saying the server is down, and its holds are released, and the
|
|
3918
|
+
* server isn't left configured, as after any disconnect. A restart whose
|
|
3919
|
+
* connect fails on its own leaves the server down, configured under the
|
|
3920
|
+
* new configuration and its id, and holding its tool prefix, as any failed
|
|
3921
|
+
* connect does: `listMcplServers()` lists it as not connected, and a
|
|
3922
|
+
* restart or a disconnect under that id tries it again or removes it.
|
|
3923
|
+
*
|
|
3924
|
+
* Treat a submitted configuration and its nested values as immutable for
|
|
3925
|
+
* as long as the server uses them. Apply changed settings with
|
|
3926
|
+
* `restartMcplServer(id, newConfig)`; use `accessProvider` for a network
|
|
3927
|
+
* server's rotating credentials (a stdio server's changed `env` goes
|
|
3928
|
+
* through a restart with the new configuration).
|
|
3412
3929
|
*/
|
|
3413
3930
|
restartMcplServer(id: string, newConfig?: import('./mcpl/types.js').McplServerConfig): Promise<void>;
|
|
3414
3931
|
private runRestartMcplServer;
|
|
3932
|
+
/**
|
|
3933
|
+
* A redactor for text that may come from any configured server, with every
|
|
3934
|
+
* server's credentials replaced: those of the configurations present when
|
|
3935
|
+
* it's made, then those present when it's used. An operation makes it
|
|
3936
|
+
* before it waits, so a server removed meanwhile, and one connected
|
|
3937
|
+
* meanwhile, both have their credentials replaced. When one of them can't
|
|
3938
|
+
* be read, the text is withheld, as redactServerText withholds it.
|
|
3939
|
+
*/
|
|
3940
|
+
private everyServerRedactor;
|
|
3941
|
+
/** Why a connect for this id is refused, or null when the id is free. One
|
|
3942
|
+
* owner per id, across both engines (holdMcpServerId): a connect or
|
|
3943
|
+
* disconnect in flight holds it, and so does a registered connection,
|
|
3944
|
+
* including one kept because its launch couldn't be confirmed exited, and
|
|
3945
|
+
* a restart moving its server to the id (mcpRestartClaims), except to
|
|
3946
|
+
* that restart's own connect (`claim`). That connect is still refused
|
|
3947
|
+
* while a disconnect of the id is in flight: the restart's own disconnect
|
|
3948
|
+
* has finished by then, so that one began during the restart, and it ends
|
|
3949
|
+
* the restart. `restarting` words the refusal for a restart of that
|
|
3950
|
+
* server checking the id it would move to. */
|
|
3951
|
+
private mcpServerIdTaken;
|
|
3952
|
+
/** The collision rules create() enforces at startup, as a runtime connect
|
|
3953
|
+
* (or a restart, before its disconnect) meets them, in either engine: the
|
|
3954
|
+
* tool prefix must not shadow a module name or another server's prefix,
|
|
3955
|
+
* or meet another server's (prefixesMeet, #265), and must neither be nor
|
|
3956
|
+
* meet one a restart is moving its server to (mcpRestartClaims). The
|
|
3957
|
+
* server's own prefix is free to keep, so is that of the server a restart
|
|
3958
|
+
* is about to disconnect (`leaving`), and so is the prefix a restart's own
|
|
3959
|
+
* connect holds (`claim`). */
|
|
3960
|
+
private mcplPrefixCollision;
|
|
3961
|
+
/** The protocol family a configuration resolves to, or a refusal naming
|
|
3962
|
+
* every problem with it, before anything is spawned, dialed or torn down. */
|
|
3963
|
+
private static usableConfigFamily;
|
|
3415
3964
|
/**
|
|
3416
3965
|
* List configured MCPL servers with live connection status and the number
|
|
3417
3966
|
* of tools each currently contributes.
|
|
@@ -3420,10 +3969,22 @@ export declare class AgentFramework {
|
|
|
3420
3969
|
id: string;
|
|
3421
3970
|
connected: boolean;
|
|
3422
3971
|
retrying: boolean;
|
|
3972
|
+
/** Which engine serves it: `legacy` (MCP 2024-11-05 + MCPL) or `modern`
|
|
3973
|
+
* (MCP 2026-07-28), as its configuration selects; null when the
|
|
3974
|
+
* configuration names no usable transport (see `refused`). */
|
|
3975
|
+
family: 'legacy' | 'modern' | null;
|
|
3976
|
+
/** The MCP revision its last handshake established; null until one has. */
|
|
3977
|
+
protocolVersion: string | null;
|
|
3978
|
+
/** How it is reached; null when the configuration names no usable transport. */
|
|
3979
|
+
transport: 'stdio' | 'websocket' | 'http' | null;
|
|
3980
|
+
/** Why connecting refuses this configuration, before anything is spawned
|
|
3981
|
+
* or dialed; null when it is usable. */
|
|
3982
|
+
refused: string | null;
|
|
3423
3983
|
toolPrefix: string;
|
|
3424
3984
|
toolCount: number;
|
|
3425
|
-
/** True only after the §5.3 policy receipt activated the grant.
|
|
3426
|
-
|
|
3985
|
+
/** True only after the §5.3 policy receipt activated the grant. Null for
|
|
3986
|
+
* a modern server, which has no MCPL policy. */
|
|
3987
|
+
policyEstablished: boolean | null;
|
|
3427
3988
|
/** Sole normative authorization allowlist for the connection (§5.4). */
|
|
3428
3989
|
effectiveGrant: string[];
|
|
3429
3990
|
/** Advertised paths removed by host enabled/disabled capability config. */
|
|
@@ -3462,6 +4023,10 @@ export declare class AgentFramework {
|
|
|
3462
4023
|
lastNegotiatedAt: number | null;
|
|
3463
4024
|
};
|
|
3464
4025
|
command?: string;
|
|
4026
|
+
/** The url as {@link redactUrl} shows it, since a credential may ride in
|
|
4027
|
+
* it: no userinfo, each query parameter's value replaced, and any path
|
|
4028
|
+
* segment or query parameter name that looks like a credential
|
|
4029
|
+
* replaced. */
|
|
3465
4030
|
url?: string;
|
|
3466
4031
|
}>;
|
|
3467
4032
|
/**
|
|
@@ -3470,6 +4035,9 @@ export declare class AgentFramework {
|
|
|
3470
4035
|
* rejection at this boundary, including failures after channels/register or
|
|
3471
4036
|
* channels/changed has acknowledged the request. It's invoked at once, so
|
|
3472
4037
|
* control-plane replies keep their acknowledge-before-reconcile order.
|
|
4038
|
+
* Each text a failure records, in its trace and its log line, goes through
|
|
4039
|
+
* `recorded`, the server's redactor where the caller has one, since a
|
|
4040
|
+
* handler's error can quote what the server sent.
|
|
3473
4041
|
*/
|
|
3474
4042
|
private containedInboundHandler;
|
|
3475
4043
|
/**
|
|
@@ -3477,9 +4045,29 @@ export declare class AgentFramework {
|
|
|
3477
4045
|
* Push events and inference requests are deferred to Steps 6/7.
|
|
3478
4046
|
*/
|
|
3479
4047
|
private wireMcplEvents;
|
|
4048
|
+
/**
|
|
4049
|
+
* Wire a modern-MCP connection's events. There's less here than for MCPL
|
|
4050
|
+
* on purpose: no push, inference, channels or policy exist on this family.
|
|
4051
|
+
* A list change, including the relist after a reconnect, takes the legacy
|
|
4052
|
+
* engine's refresh path (`handleToolsListChanged`), so any wake it causes
|
|
4053
|
+
* goes through ordinary admission: it parks under quiesce or a hold like
|
|
4054
|
+
* every other wake. It installs no awareness gate, since that gate orders
|
|
4055
|
+
* MCPL data-plane traffic, which this family doesn't carry.
|
|
4056
|
+
*/
|
|
4057
|
+
private wireModernEvents;
|
|
4058
|
+
/** An MCP tool call's trace: a result the server marked an error (or one
|
|
4059
|
+
* the reading couldn't complete) is tool:failed, as on the other tool
|
|
4060
|
+
* paths; anything else is tool:completed. */
|
|
4061
|
+
private traceMcpToolOutcome;
|
|
3480
4062
|
/**
|
|
3481
4063
|
* Discover tools from all connected MCPL servers and cache them.
|
|
3482
4064
|
* Tools are namespaced as `{toolPrefix}--{toolName}` per server config.
|
|
4065
|
+
* No two servers' prefixes meet (prefixesMeet, refused at create(), a
|
|
4066
|
+
* runtime connect and a restart), so no two servers give one name. A
|
|
4067
|
+
* server that lists one name more than once keeps its first listing, and
|
|
4068
|
+
* an ops alert at each refresh that finds it says so (#265): a tool list
|
|
4069
|
+
* holding one name twice is refused by membrane's native formatter and by
|
|
4070
|
+
* Anthropic's API.
|
|
3483
4071
|
*/
|
|
3484
4072
|
private refreshMcplTools;
|
|
3485
4073
|
/**
|
|
@@ -3509,11 +4097,47 @@ export declare class AgentFramework {
|
|
|
3509
4097
|
* Emit a trace event and push an external-message listing newly added tools.
|
|
3510
4098
|
*/
|
|
3511
4099
|
private emitMcplToolDiff;
|
|
4100
|
+
/** The refusal of a tool call whose server isn't one to call yet, for the
|
|
4101
|
+
* model's call, a script's and an in-process one alike: none registered,
|
|
4102
|
+
* or a modern connection whose connect is still under way
|
|
4103
|
+
* (modernStillConnecting). It says "connecting" while a connect of its id
|
|
4104
|
+
* is in flight (mcpServerOps) or a restart holds the id, and "gone"
|
|
4105
|
+
* otherwise. */
|
|
4106
|
+
private mcplServerAbsentText;
|
|
4107
|
+
/** A modern connection a connect still under way registered: it registers
|
|
4108
|
+
* before it starts, so until its first session is up it's no server to
|
|
4109
|
+
* call, and a call reads the "connecting" text, as one during a legacy
|
|
4110
|
+
* connect's handshake does. Once that session is up, a call goes to it,
|
|
4111
|
+
* even while the connect lists its tools. */
|
|
4112
|
+
private modernStillConnecting;
|
|
3512
4113
|
/**
|
|
3513
4114
|
* Dispatch a tool call to an MCPL server.
|
|
3514
4115
|
* Strips the configured toolPrefix and routes to the server.
|
|
3515
4116
|
*/
|
|
3516
4117
|
private dispatchMcplToolCall;
|
|
4118
|
+
/**
|
|
4119
|
+
* The direct path's reading of an MCP tool result (executeToolCall,
|
|
4120
|
+
* ModuleContext.callTool). `data` stays the raw content array, as module
|
|
4121
|
+
* callers have always received it. Two things change: a tool error
|
|
4122
|
+
* (`isError: true`) is now a failure, where every answer used to count as
|
|
4123
|
+
* success, and `structured` is added by presence.
|
|
4124
|
+
*/
|
|
4125
|
+
private static directToolResult;
|
|
4126
|
+
/**
|
|
4127
|
+
* The framework's ToolResult for an MCP tool result on the model path
|
|
4128
|
+
* (model dispatch, and scripts, which ride it). A standard peer, meaning an MCP-only legacy
|
|
4129
|
+
* server or any modern server, gets the standard reading
|
|
4130
|
+
* (tool-result-normalize.ts): typed content blocks, workspace-saved
|
|
4131
|
+
* payloads, and `structured` kept by presence. An MCPL peer keeps the
|
|
4132
|
+
* RFC-005 reading. Its content array passes through when it holds
|
|
4133
|
+
* non-text blocks, so references and images render natively. It gets
|
|
4134
|
+
* `structured` too, with the JSON view when its content is empty. The
|
|
4135
|
+
* direct path (a module's callTool, a channel's tool call) doesn't come
|
|
4136
|
+
* here: it returns the server's result itself (directToolResult), for
|
|
4137
|
+
* either engine, as does a script's call whose result is structured, with
|
|
4138
|
+
* an MCPL peer's blocks given RFC-005's treatment (referenceBlockForScript).
|
|
4139
|
+
*/
|
|
4140
|
+
private mcpToolResult;
|
|
3517
4141
|
/**
|
|
3518
4142
|
* Build BeforeInferenceParams from agent state and trigger context.
|
|
3519
4143
|
*/
|