@arnilo/prism 0.8.0 → 0.10.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/CHANGELOG.md +62 -1
- package/README.md +13 -12
- package/dist/agent-approval.d.ts +17 -2
- package/dist/agent-approval.js +15 -6
- package/dist/agent-event-source.d.ts +9 -1
- package/dist/agent-event-source.js +10 -3
- package/dist/agent-loops.js +7 -4
- package/dist/agent-run-lifecycle.d.ts +15 -1
- package/dist/agent-run-lifecycle.js +82 -11
- package/dist/agent-run-state.d.ts +47 -6
- package/dist/agent-run-state.js +154 -6
- package/dist/agent-session/event-subscriber.d.ts +2 -0
- package/dist/agent-session/event-subscriber.js +3 -0
- package/dist/agent-session/helpers.js +14 -0
- package/dist/agent-session/session/assemble.js +281 -32
- package/dist/agent-session/session/persist.d.ts +11 -0
- package/dist/agent-session/session/persist.js +48 -16
- package/dist/agent-session/session/provider-round.d.ts +14 -4
- package/dist/agent-session/session/provider-round.js +226 -19
- package/dist/agent-session/session/tool-round.d.ts +2 -2
- package/dist/agent-session/session/tool-round.js +78 -6
- package/dist/agent-session/session/types.d.ts +44 -3
- package/dist/agent-session/session.d.ts +100 -5
- package/dist/agent-session/session.js +224 -13
- package/dist/attention-compiler.d.ts +51 -2
- package/dist/attention-compiler.js +282 -21
- package/dist/cache-helpers.d.ts +4 -2
- package/dist/cache-helpers.js +8 -6
- package/dist/checkpoint-restore.d.ts +45 -0
- package/dist/checkpoint-restore.js +54 -0
- package/dist/context-budget.d.ts +13 -1
- package/dist/context-budget.js +57 -4
- package/dist/contracts-core/agent.d.ts +52 -1
- package/dist/contracts-core/attention.d.ts +95 -0
- package/dist/contracts-core/content.d.ts +10 -0
- package/dist/contracts-core/extensions.d.ts +3 -0
- package/dist/contracts-core/guardrail-packs.d.ts +46 -0
- package/dist/contracts-core/guardrail-packs.js +2 -0
- package/dist/contracts-core/loop.d.ts +36 -0
- package/dist/contracts-core/provider.d.ts +30 -0
- package/dist/contracts-core/run-limits.d.ts +29 -1
- package/dist/contracts-core/session.d.ts +23 -5
- package/dist/contracts-core/session.js +21 -2
- package/dist/contracts-core/usage.d.ts +40 -0
- package/dist/contracts-core/usage.js +8 -0
- package/dist/contracts-core.d.ts +2 -0
- package/dist/contracts-core.js +2 -0
- package/dist/contracts-protocol.d.ts +81 -5
- package/dist/contracts-run-state.d.ts +91 -2
- package/dist/contributions.d.ts +2 -1
- package/dist/contributions.js +1 -0
- package/dist/extensions.d.ts +15 -1
- package/dist/extensions.js +68 -0
- package/dist/guardrail-packs/coding-standard.d.ts +3 -0
- package/dist/guardrail-packs/coding-standard.js +63 -0
- package/dist/guardrail-packs/destructive-commands.d.ts +3 -0
- package/dist/guardrail-packs/destructive-commands.js +46 -0
- package/dist/guardrail-packs/errors.d.ts +7 -0
- package/dist/guardrail-packs/errors.js +9 -0
- package/dist/guardrail-packs/index.d.ts +4 -0
- package/dist/guardrail-packs/index.js +15 -0
- package/dist/guardrail-packs/secrets-hygiene.d.ts +3 -0
- package/dist/guardrail-packs/secrets-hygiene.js +23 -0
- package/dist/guardrail-packs/types.d.ts +26 -0
- package/dist/guardrail-packs/types.js +2 -0
- package/dist/guardrail-packs/validation-respect.d.ts +3 -0
- package/dist/guardrail-packs/validation-respect.js +69 -0
- package/dist/guardrails.d.ts +61 -1
- package/dist/guardrails.js +377 -0
- package/dist/index.d.ts +16 -11
- package/dist/index.js +10 -7
- package/dist/input.d.ts +8 -1
- package/dist/input.js +68 -6
- package/dist/middleware.d.ts +37 -2
- package/dist/middleware.js +41 -0
- package/dist/node/session-store-jsonl.js +18 -3
- package/dist/observability.js +6 -0
- package/dist/provider-events.d.ts +8 -2
- package/dist/provider-events.js +60 -2
- package/dist/providers/openai-compatible.js +6 -3
- package/dist/run-bundle.d.ts +6 -1
- package/dist/run-bundle.js +5 -1
- package/dist/run-limits.d.ts +11 -1
- package/dist/run-limits.js +59 -0
- package/dist/session-stores.d.ts +12 -1
- package/dist/session-stores.js +21 -4
- package/dist/testing/agent-event-source-conformance.js +41 -2
- package/dist/testing/prefix-stability-conformance.d.ts +59 -0
- package/dist/testing/prefix-stability-conformance.js +172 -0
- package/dist/testing/session-store-conformance.d.ts +3 -2
- package/dist/testing/session-store-conformance.js +48 -0
- package/dist/tools.d.ts +5 -0
- package/dist/tools.js +21 -6
- package/dist/usage-estimation.d.ts +29 -0
- package/dist/usage-estimation.js +79 -0
- package/docs/agent-events.md +75 -4
- package/docs/agent-session-runtime.md +10 -6
- package/docs/attention-compiler.md +89 -8
- package/docs/caveman.md +1 -1
- package/docs/coding-agent-tools.md +1 -1
- package/docs/compaction-and-retry.md +1 -1
- package/docs/compaction-llm.md +2 -0
- package/docs/compaction-observational-memory.md +54 -7
- package/docs/durable-runs.md +46 -3
- package/docs/embeddings.md +9 -0
- package/docs/evaluations.md +5 -0
- package/docs/execution-timeline.md +79 -1
- package/docs/extensions.md +20 -3
- package/docs/guardrails.md +50 -4
- package/docs/hooks.md +282 -0
- package/docs/index.md +37 -15
- package/docs/input-and-prompt-assembly.md +4 -4
- package/docs/instruction-injection.md +1 -0
- package/docs/knowledge-sync.md +4 -0
- package/docs/live-testing.md +3 -1
- package/docs/memory-fabric.md +28 -0
- package/docs/middleware-hooks.md +90 -4
- package/docs/migrate-to-0.9.md +210 -0
- package/docs/migration.md +26 -0
- package/docs/multi-agent-patterns.md +25 -2
- package/docs/node-jsonl-session-store.md +7 -1
- package/docs/observability.md +7 -3
- package/docs/options-index.md +4 -1
- package/docs/policy-and-audit.md +26 -1
- package/docs/prefix-stability-conformance.md +143 -0
- package/docs/provider-caching.md +4 -4
- package/docs/provider-conformance.md +16 -0
- package/docs/provider-packages.md +20 -20
- package/docs/public-contracts.md +3 -2
- package/docs/rag.md +188 -3
- package/docs/release-and-install.md +45 -40
- package/docs/runs-and-usage.md +56 -10
- package/docs/scoped-agent-memory.md +270 -0
- package/docs/scoped-memory.md +138 -0
- package/docs/session-store-conformance.md +1 -2
- package/docs/session-stores.md +17 -17
- package/docs/supervisors.md +32 -12
- package/docs/tools.md +18 -1
- package/docs/wiki.md +4 -2
- package/docs/workflows.md +5 -0
- package/package.json +8 -2
|
@@ -56,7 +56,26 @@ export function resolveSessionSearchQuery(query) {
|
|
|
56
56
|
assertSearchStringBytes(query.userId, "userId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
57
57
|
assertSearchStringBytes(query.fromUpdatedAt, "fromUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
58
58
|
assertSearchStringBytes(query.toUpdatedAt, "toUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
59
|
-
return { ...query, limit, order };
|
|
59
|
+
return { ...query, limit, order, kind: resolveSessionSearchKinds(query.kind) };
|
|
60
|
+
}
|
|
61
|
+
/** Normalize `kind` to concrete entry kinds (`undefined` = any). Unknown or mixed `"any"` fails closed. */
|
|
62
|
+
function resolveSessionSearchKinds(kind) {
|
|
63
|
+
if (kind === undefined || kind === "any")
|
|
64
|
+
return undefined;
|
|
65
|
+
const values = typeof kind === "string" ? [kind] : kind;
|
|
66
|
+
const kinds = [];
|
|
67
|
+
for (const value of values) {
|
|
68
|
+
if (value === "any")
|
|
69
|
+
throw new TypeError('SessionSearchQuery.kind cannot mix "any" with entry kinds');
|
|
70
|
+
if (!isSessionEntryKind(value)) {
|
|
71
|
+
throw new TypeError(`SessionSearchQuery.kind must be a session entry kind or "any"; got ${JSON.stringify(value)}`);
|
|
72
|
+
}
|
|
73
|
+
if (!kinds.includes(value))
|
|
74
|
+
kinds.push(value);
|
|
75
|
+
}
|
|
76
|
+
if (kinds.length === 0)
|
|
77
|
+
throw new TypeError("SessionSearchQuery.kind must name at least one entry kind");
|
|
78
|
+
return kinds;
|
|
60
79
|
}
|
|
61
80
|
function assertSearchStringBytes(value, name, hardMax) {
|
|
62
81
|
if (value === undefined)
|
|
@@ -71,7 +90,7 @@ function assertSearchStringBytes(value, name, hardMax) {
|
|
|
71
90
|
}
|
|
72
91
|
}
|
|
73
92
|
export const SESSION_SEARCH_UNSUPPORTED_CODE = "session_search_unsupported";
|
|
74
|
-
/** Thrown when a store opts out of `searchSessions` (memory `unsupported
|
|
93
|
+
/** Thrown when a store opts out of `searchSessions` (memory `sessionSearchMode: "unsupported"`). */
|
|
75
94
|
export class SessionSearchUnsupportedError extends Error {
|
|
76
95
|
code = SESSION_SEARCH_UNSUPPORTED_CODE;
|
|
77
96
|
constructor(message = "session search is unsupported by this store") {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Contracts-core usage family (plan 091 Task 1): labeled token-estimation types.
|
|
2
|
+
*
|
|
3
|
+
* Estimation exists for the "missing usage is never zero usage" accounting rule:
|
|
4
|
+
* when a provider reports no usage, a host may show a labeled approximation. An
|
|
5
|
+
* estimate is never provider truth — reported usage always wins and is never
|
|
6
|
+
* overwritten by one of these. */
|
|
7
|
+
/** Model families with a chars/token table (`MODEL_FAMILY_TOKENS`). `unknown`
|
|
8
|
+
* is the conservative fallback used when a model id/name matches no family. */
|
|
9
|
+
export type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "openrouter-generic" | "mistral" | "unknown";
|
|
10
|
+
/** Confidence label on an estimated token count. `high` is reserved for a real
|
|
11
|
+
* tokenizer (Prism ships none); the calibrated family tables are `medium`, and
|
|
12
|
+
* the unknown-family fallback is `low`. */
|
|
13
|
+
export type TokenEstimateConfidence = "high" | "medium" | "low";
|
|
14
|
+
/** Labeled token estimate. Never conflate with `Usage`: estimates are
|
|
15
|
+
* approximations for context metering and labeling, reported usage is provider
|
|
16
|
+
* truth for billing. */
|
|
17
|
+
export interface TokenEstimate {
|
|
18
|
+
readonly tokens: number;
|
|
19
|
+
readonly confidence: TokenEstimateConfidence;
|
|
20
|
+
/** Coarse `confidence === "low"` flag for UI badges and host-side labeling. */
|
|
21
|
+
readonly lowConfidence: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Context-fill read for hosts (plan 091 Task 2): the latest provider turn's input
|
|
25
|
+
* tokens with their provenance, plus the cap/budget resolved the same way the
|
|
26
|
+
* turn-budget snapshot resolves them. `source: "reported"` means the provider
|
|
27
|
+
* reported those tokens; `"estimated"` means they are a labeled approximation
|
|
28
|
+
* (never billing, never conflated with reported usage). Cap/budget/ratio are
|
|
29
|
+
* absent when the model or run cannot derive them.
|
|
30
|
+
*/
|
|
31
|
+
export interface ContextMeter {
|
|
32
|
+
readonly inputTokens: number;
|
|
33
|
+
readonly source: "reported" | "estimated";
|
|
34
|
+
/** Per-request input cap from the model window and `attentionCompiler` reserve. */
|
|
35
|
+
readonly inputCap?: number;
|
|
36
|
+
/** Cumulative run input budget (`RunLimits.maxInputTokens`); absent without run limits. */
|
|
37
|
+
readonly runInputBudget?: number;
|
|
38
|
+
/** `inputTokens / inputCap`; absent when no cap is derivable. */
|
|
39
|
+
readonly usedRatio?: number;
|
|
40
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Contracts-core usage family (plan 091 Task 1): labeled token-estimation types.
|
|
2
|
+
*
|
|
3
|
+
* Estimation exists for the "missing usage is never zero usage" accounting rule:
|
|
4
|
+
* when a provider reports no usage, a host may show a labeled approximation. An
|
|
5
|
+
* estimate is never provider truth — reported usage always wins and is never
|
|
6
|
+
* overwritten by one of these. */
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=usage.js.map
|
package/dist/contracts-core.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./contracts-core/compaction.js";
|
|
|
9
9
|
export * from "./contracts-core/content.js";
|
|
10
10
|
export * from "./contracts-core/embeddings.js";
|
|
11
11
|
export * from "./contracts-core/extensions.js";
|
|
12
|
+
export * from "./contracts-core/guardrail-packs.js";
|
|
12
13
|
export * from "./contracts-core/images.js";
|
|
13
14
|
export * from "./contracts-core/loop.js";
|
|
14
15
|
export * from "./contracts-core/moderation.js";
|
|
@@ -19,4 +20,5 @@ export * from "./contracts-core/run-limits.js";
|
|
|
19
20
|
export * from "./contracts-core/session.js";
|
|
20
21
|
export * from "./contracts-core/speech.js";
|
|
21
22
|
export * from "./contracts-core/transcription.js";
|
|
23
|
+
export * from "./contracts-core/usage.js";
|
|
22
24
|
export * from "./contracts-core/video.js";
|
package/dist/contracts-core.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./contracts-core/compaction.js";
|
|
|
5
5
|
export * from "./contracts-core/content.js";
|
|
6
6
|
export * from "./contracts-core/embeddings.js";
|
|
7
7
|
export * from "./contracts-core/extensions.js";
|
|
8
|
+
export * from "./contracts-core/guardrail-packs.js";
|
|
8
9
|
export * from "./contracts-core/images.js";
|
|
9
10
|
export * from "./contracts-core/loop.js";
|
|
10
11
|
export * from "./contracts-core/moderation.js";
|
|
@@ -15,5 +16,6 @@ export * from "./contracts-core/run-limits.js";
|
|
|
15
16
|
export * from "./contracts-core/session.js";
|
|
16
17
|
export * from "./contracts-core/speech.js";
|
|
17
18
|
export * from "./contracts-core/transcription.js";
|
|
19
|
+
export * from "./contracts-core/usage.js";
|
|
18
20
|
export * from "./contracts-core/video.js";
|
|
19
21
|
//# sourceMappingURL=contracts-core.js.map
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CacheUsageReport } from "./cache-helpers.js";
|
|
2
|
+
import type { CheckpointRestoreAudit } from "./checkpoint-restore.js";
|
|
3
|
+
import type { AgentLoopOptions, AgentLoopStrategy, ArtifactValidation, BudgetAxisUsage, BudgetConsumedCounters, CompactionOptions, ContentBlock, ErrorInfo, GuardrailRecord, Guardrails, InstructionInjector, JsonObject, Message, ModelConfig, OwnershipScope, ProviderRequestOptions, ProviderRequestPolicy, ProviderResolver, ProviderStopReason, RetryOptions, RunLimitBreach, RunLimitName, RunLimits, Skill, StopHook, SubscriberOverflowPolicy, SystemPromptConfig, ToolCallAuthority, ToolCallContent, ToolCallSummary, TurnBudgets, TurnPolicyOptions, Usage } from "./contracts-core.js";
|
|
2
4
|
import type { AgentRunInterruption, AgentRunStateOptions } from "./contracts-run-state.js";
|
|
3
5
|
import type { SecretRedactor } from "./redaction.js";
|
|
4
6
|
import type { ToolValidator } from "./tools.js";
|
|
@@ -28,6 +30,7 @@ export type ProviderEvent = {
|
|
|
28
30
|
} | {
|
|
29
31
|
readonly type: "done";
|
|
30
32
|
readonly usage?: Usage;
|
|
33
|
+
readonly stopReason?: ProviderStopReason;
|
|
31
34
|
} | {
|
|
32
35
|
readonly type: "error";
|
|
33
36
|
readonly error: ErrorInfo;
|
|
@@ -108,6 +111,10 @@ export interface RunOptions {
|
|
|
108
111
|
readonly toolNames?: readonly string[];
|
|
109
112
|
/** Tools disclosure: "all" (default) sends every active tool schema; "search" sends top-k + the generated `search_tools` tool. */
|
|
110
113
|
readonly toolsDisclosure?: import("./tool-search.js").ToolsDisclosure;
|
|
114
|
+
/** Per-turn restrictive allow-list over the run grant. Overrides `AgentConfig.toolNarrowing`. */
|
|
115
|
+
readonly toolNarrowing?: import("./contracts-core/agent.js").ToolNarrowing;
|
|
116
|
+
/** Opt-in: tools hidden this turn stay callable by name (default off). Overrides agent config. */
|
|
117
|
+
readonly allowHiddenToolCalls?: true;
|
|
111
118
|
readonly toolsSearch?: import("./tool-search.js").ToolsSearchOptions;
|
|
112
119
|
/** Opt-in projection-only fold for aged large tool results in provider view; store untouched. */
|
|
113
120
|
readonly toolResultFold?: import("./tool-result-fold.js").ToolResultFoldOptions;
|
|
@@ -130,6 +137,8 @@ export interface RunOptions {
|
|
|
130
137
|
* evaluated before every provider request. Omitted → no callback runs.
|
|
131
138
|
*/
|
|
132
139
|
readonly turnPolicy?: TurnPolicyOptions;
|
|
140
|
+
/** Appended to agent-level stop hooks for this run (plan 106 R1). */
|
|
141
|
+
readonly stopHooks?: readonly StopHook[];
|
|
133
142
|
}
|
|
134
143
|
export interface ProviderTurnMetadata {
|
|
135
144
|
readonly providerId: string;
|
|
@@ -140,6 +149,17 @@ export interface ProviderTurnMetadata {
|
|
|
140
149
|
readonly httpStatus?: number;
|
|
141
150
|
readonly rateLimitRemaining?: number;
|
|
142
151
|
readonly rateLimitResetMs?: number;
|
|
152
|
+
/** Why the provider turn stopped (plan 087 T1); present on `provider_turn_finished` only. */
|
|
153
|
+
readonly stopReason?: ProviderStopReason;
|
|
154
|
+
/** Effective budget state at turn end (plan 087 T1); present on `provider_turn_finished` only. */
|
|
155
|
+
readonly budgets?: TurnBudgets;
|
|
156
|
+
/** Provider-reported cache usage and derived hit rate; absent when cache usage is unknown. */
|
|
157
|
+
readonly cache?: CacheUsageReport;
|
|
158
|
+
/** Effective tool menu this turn. Names hashed in request order; never includes args. */
|
|
159
|
+
readonly tools?: {
|
|
160
|
+
readonly count: number;
|
|
161
|
+
readonly idsHash: string;
|
|
162
|
+
};
|
|
143
163
|
}
|
|
144
164
|
export interface ToolExecutionMetadata {
|
|
145
165
|
readonly durationMs: number;
|
|
@@ -175,9 +195,20 @@ export interface DelegatedAgentStep {
|
|
|
175
195
|
readonly label?: string;
|
|
176
196
|
};
|
|
177
197
|
}
|
|
178
|
-
/** Why a run stopped cleanly. `host_policy` is a `RunOptions.turnPolicy` stop; the rest are loop ceilings (F4). */
|
|
179
|
-
export type AgentFinishReason = "turn_limit" | "token_limit" | "refusal" | "host_policy";
|
|
180
|
-
|
|
198
|
+
/** Why a run stopped cleanly. `host_policy` is a `RunOptions.turnPolicy` stop, `hook_limit` a stop-hook continuation cap; the rest are loop ceilings (F4). */
|
|
199
|
+
export type AgentFinishReason = "turn_limit" | "token_limit" | "refusal" | "host_policy" | "hook_limit";
|
|
200
|
+
/**
|
|
201
|
+
* Origin of an agent event forwarded from a delegated child (supervisor child-event passthrough).
|
|
202
|
+
* Present only on child events routed onto a parent stream; absent on a session's own events.
|
|
203
|
+
*/
|
|
204
|
+
export interface ChildEventOrigin {
|
|
205
|
+
readonly childId: string;
|
|
206
|
+
readonly delegationId: string;
|
|
207
|
+
/** Delegation depth: 1 is a direct child of the hosting supervisor. */
|
|
208
|
+
readonly depth: number;
|
|
209
|
+
}
|
|
210
|
+
/** Payload union of every agent event; the exported `AgentEvent` adds the optional child origin tag. */
|
|
211
|
+
type AgentEventPayload = {
|
|
181
212
|
readonly type: "agent_started";
|
|
182
213
|
readonly sessionId: string;
|
|
183
214
|
readonly runId: string;
|
|
@@ -186,7 +217,7 @@ export type AgentEvent = {
|
|
|
186
217
|
readonly sessionId: string;
|
|
187
218
|
readonly runId: string;
|
|
188
219
|
readonly usage?: Usage;
|
|
189
|
-
/** Why the loop stopped, when a limit/ceiling
|
|
220
|
+
/** Why the loop stopped, when a limit/ceiling, a host turn policy, or a stop-hook continuation cap ended the run cleanly (F4). Absent = natural end. */
|
|
190
221
|
readonly finishReason?: AgentFinishReason;
|
|
191
222
|
/** Host stop detail from `TurnPolicyOptions.stop` (≤256 bytes, redacted). Present only with `finishReason: "host_policy"`. */
|
|
192
223
|
readonly stopDetail?: string;
|
|
@@ -201,6 +232,8 @@ export type AgentEvent = {
|
|
|
201
232
|
readonly sessionId: string;
|
|
202
233
|
readonly runId: string;
|
|
203
234
|
readonly version: number;
|
|
235
|
+
/** Plan 094 Task 3: audit of the external-state restore hooks that ran before this claim. */
|
|
236
|
+
readonly restore?: CheckpointRestoreAudit;
|
|
204
237
|
} | {
|
|
205
238
|
readonly type: "agent_denied";
|
|
206
239
|
readonly sessionId: string;
|
|
@@ -217,6 +250,17 @@ export type AgentEvent = {
|
|
|
217
250
|
readonly sessionId: string;
|
|
218
251
|
readonly runId: string;
|
|
219
252
|
readonly turn: number;
|
|
253
|
+
} | {
|
|
254
|
+
/**
|
|
255
|
+
* Host middleware completed this turn without a provider request (plan 096). No `usage` field:
|
|
256
|
+
* a deterministic turn has no provider cost, so accounting must never zero-fill one.
|
|
257
|
+
*/
|
|
258
|
+
readonly type: "deterministic_turn";
|
|
259
|
+
readonly sessionId: string;
|
|
260
|
+
readonly runId: string;
|
|
261
|
+
readonly turn: number;
|
|
262
|
+
/** Answering middleware id (provenance); ids only, never free host code. */
|
|
263
|
+
readonly middleware: string;
|
|
220
264
|
} | {
|
|
221
265
|
readonly type: "provider_turn_started";
|
|
222
266
|
readonly sessionId: string;
|
|
@@ -281,6 +325,13 @@ export type AgentEvent = {
|
|
|
281
325
|
readonly reason: string;
|
|
282
326
|
readonly error: ErrorInfo;
|
|
283
327
|
readonly metadata: ToolExecutionMetadata;
|
|
328
|
+
} | {
|
|
329
|
+
/** Host `toolNarrowing` asked for names outside the run grant; those names were dropped. */
|
|
330
|
+
readonly type: "tool_narrowing_clamped";
|
|
331
|
+
readonly sessionId: string;
|
|
332
|
+
readonly runId: string;
|
|
333
|
+
readonly turn: number;
|
|
334
|
+
readonly dropped: readonly string[];
|
|
284
335
|
} | {
|
|
285
336
|
readonly type: "guardrail_decision";
|
|
286
337
|
readonly sessionId: string;
|
|
@@ -293,6 +344,16 @@ export type AgentEvent = {
|
|
|
293
344
|
readonly sessionId: string;
|
|
294
345
|
readonly runId: string;
|
|
295
346
|
readonly breach: RunLimitBreach;
|
|
347
|
+
} | {
|
|
348
|
+
/** Terminal attribution for a run that died on a run limit (plan 087 T2): which axis fired,
|
|
349
|
+
* counters at exhaustion, how close the other axes were, and hashes of recent tool calls. */
|
|
350
|
+
readonly type: "budget_exhausted";
|
|
351
|
+
readonly sessionId: string;
|
|
352
|
+
readonly runId: string;
|
|
353
|
+
readonly limit: RunLimitName;
|
|
354
|
+
readonly consumed: BudgetConsumedCounters;
|
|
355
|
+
readonly closestOtherAxes: readonly BudgetAxisUsage[];
|
|
356
|
+
readonly recentToolCalls: readonly ToolCallSummary[];
|
|
296
357
|
} | {
|
|
297
358
|
readonly type: "queue_updated";
|
|
298
359
|
readonly sessionId: string;
|
|
@@ -383,6 +444,14 @@ export type AgentEvent = {
|
|
|
383
444
|
readonly attempt: number;
|
|
384
445
|
readonly result: ArtifactValidation;
|
|
385
446
|
};
|
|
447
|
+
/**
|
|
448
|
+
* One agent event. `child` is set only when the event was forwarded from a delegated child
|
|
449
|
+
* (e.g. supervisor `report: "stream"` passthrough), so hosts can route it onto a parent stream
|
|
450
|
+
* without per-event-type special cases. It never replaces the event's own `sessionId`/`runId`.
|
|
451
|
+
*/
|
|
452
|
+
export type AgentEvent = AgentEventPayload & {
|
|
453
|
+
readonly child?: ChildEventOrigin;
|
|
454
|
+
};
|
|
386
455
|
export type ToolEffectKind = "none" | "local_mutation" | "external_mutation";
|
|
387
456
|
export type ToolEffectIdempotency = "none" | "optional" | "required" | "tool_managed" | "unsupported";
|
|
388
457
|
/** Static or validated-argument classification of one tool call's side-effect behavior. */
|
|
@@ -688,4 +757,11 @@ export interface ProviderTurnResult {
|
|
|
688
757
|
readonly messageId?: string;
|
|
689
758
|
readonly started: boolean;
|
|
690
759
|
readonly usage?: Usage;
|
|
760
|
+
/**
|
|
761
|
+
* Provenance for turns that did not come from the provider (plan 096):
|
|
762
|
+
* `{ deterministic: { middleware } }`. Copied onto the assistant `Message.metadata`, so it
|
|
763
|
+
* serializes with the transcript and survives replay. Absent for provider turns.
|
|
764
|
+
*/
|
|
765
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
691
766
|
}
|
|
767
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CheckpointRestoreHook } from "./checkpoint-restore.js";
|
|
2
|
+
import type { AgentSessionCloneOptions, AgentSessionForkOptions, CheckpointRecord, CheckpointStore, CompactionOptions, CompactionResult, ContentBlock, ContextMeter, ErrorInfo, GuardrailPackRef, JsonObject, JsonValue, Message, ModelConfig, OwnershipScope, RunLimitBreach, SessionEntry, SubscribeOptions, ToolCallContent, Usage } from "./contracts-core.js";
|
|
2
3
|
import type { AgentEvent, AgentFinishReason, RunOptions, ToolEffectKind } from "./contracts-protocol.js";
|
|
3
4
|
export type AgentRunStatus = "succeeded" | "failed" | "aborted" | "suspended" | "denied";
|
|
4
5
|
export type AgentRunInterruptionKind = "input_guardrail" | "tool_approval" | "elicitation";
|
|
@@ -26,6 +27,16 @@ export interface PendingDecision {
|
|
|
26
27
|
readonly reason: string;
|
|
27
28
|
/** Typed payload contract for elicitation decisions. */
|
|
28
29
|
readonly elicitationSchema?: JsonObject;
|
|
30
|
+
/**
|
|
31
|
+
* Plan 104 T3: pack `ask` rule that gated this call as `pack:<pack>/<rule>` (bounded by the
|
|
32
|
+
* compile-time id limits), present only when a pack rule raised the decision.
|
|
33
|
+
*/
|
|
34
|
+
readonly guardrail?: string;
|
|
35
|
+
/** Plan 104 T3: machine-readable ids behind `guardrail`, so a host never parses the name. */
|
|
36
|
+
readonly guardrailRule?: {
|
|
37
|
+
readonly pack: string;
|
|
38
|
+
readonly rule: string;
|
|
39
|
+
};
|
|
29
40
|
/** Delegation chain, root-first; core-written, never client-supplied. */
|
|
30
41
|
readonly attribution?: {
|
|
31
42
|
readonly path: readonly string[];
|
|
@@ -37,6 +48,8 @@ export interface AgentRunInterruption {
|
|
|
37
48
|
readonly reason: string;
|
|
38
49
|
readonly toolCallId?: string;
|
|
39
50
|
readonly toolName?: string;
|
|
51
|
+
/** Plan 104 T3: the pack rule that raised this suspension (`pack:<pack>/<rule>`), when one did. */
|
|
52
|
+
readonly guardrail?: string;
|
|
40
53
|
/** All unresolved approval requests of this suspension; absent for legacy single approvals. */
|
|
41
54
|
readonly pendingDecisions?: readonly PendingDecision[];
|
|
42
55
|
}
|
|
@@ -139,6 +152,15 @@ export declare const HARD_MAX_ACTION_CONSTRAINTS = 64;
|
|
|
139
152
|
export declare const MAX_ATTRIBUTION_DEPTH = 8;
|
|
140
153
|
export declare const MAX_ACTION_CONSTRAINT_BYTES: number;
|
|
141
154
|
export declare const HARD_MAX_ACTION_CONSTRAINT_BYTES: number;
|
|
155
|
+
/**
|
|
156
|
+
* Opaque host sidecar pinned to one checkpoint *record* (git commit, document version,
|
|
157
|
+
* workspace fingerprint) — never part of the run-state value, so it costs no `maxStateBytes`
|
|
158
|
+
* budget and is invisible to state parsing. Bounded to `MAX_AGENT_RUN_METADATA_BYTES` (4 KiB)
|
|
159
|
+
* and redacted like the state value at every write.
|
|
160
|
+
*/
|
|
161
|
+
export type AgentRunCheckpointMetadata = Readonly<Record<string, string>>;
|
|
162
|
+
/** Host source for checkpoint sidecar metadata: a fixed map or a live provider resolved per write. */
|
|
163
|
+
export type AgentRunCheckpointMetadataSource = AgentRunCheckpointMetadata | (() => AgentRunCheckpointMetadata | undefined);
|
|
142
164
|
export interface AgentRunStateOptions {
|
|
143
165
|
readonly checkpoints: CheckpointStore;
|
|
144
166
|
/** Host-authored immutable revision required for durable runs. */
|
|
@@ -156,6 +178,12 @@ export interface AgentRunStateOptions {
|
|
|
156
178
|
readonly checkpointPolicy?: "decision" | "every-turn";
|
|
157
179
|
/** Suspend every tool call before its side effect. */
|
|
158
180
|
readonly interruptBeforeTool?: boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Sidecar metadata written with every checkpoint of this run (and carried into a resumed
|
|
183
|
+
* run). A provider is resolved at each checkpoint write, so a host closure can pin state
|
|
184
|
+
* that moves mid-run (e.g. the current git commit). Absent = records stay byte-identical.
|
|
185
|
+
*/
|
|
186
|
+
readonly checkpointMetadata?: AgentRunCheckpointMetadataSource;
|
|
159
187
|
readonly maxStateBytes?: number;
|
|
160
188
|
readonly fencingToken?: number;
|
|
161
189
|
/** Enables sticky auto-apply when a nested suspension first surfaces during this run. */
|
|
@@ -204,6 +232,23 @@ export interface AgentRunResume {
|
|
|
204
232
|
/** Batch decision path; exactly one of decision/decisions. Applied as one atomic CAS transition. */
|
|
205
233
|
readonly decisions?: readonly RunDecision[];
|
|
206
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Checkpoint handed to a restore hook (plan 094 Task 3). `checkpoint.value` is the raw stored
|
|
237
|
+
* run-state value; `metadata` is the redacted, bounded sidecar map hosts write via
|
|
238
|
+
* `AgentRunStateOptions.checkpointMetadata`.
|
|
239
|
+
*/
|
|
240
|
+
export interface AgentCheckpointRestoreContext {
|
|
241
|
+
readonly runId: string;
|
|
242
|
+
readonly sessionId: string;
|
|
243
|
+
/** Version of the checkpoint being claimed; a hook may pass it to an external system's own CAS. */
|
|
244
|
+
readonly version: number;
|
|
245
|
+
/** State being claimed: `running` for crash recovery, `suspended` for a decision resume. */
|
|
246
|
+
readonly status: AgentRunStatus | "running";
|
|
247
|
+
readonly metadata?: AgentRunCheckpointMetadata;
|
|
248
|
+
readonly checkpoint: CheckpointRecord;
|
|
249
|
+
}
|
|
250
|
+
/** Host code restoring one external layer before a durable resume applies. */
|
|
251
|
+
export type AgentCheckpointRestoreHook = CheckpointRestoreHook<AgentCheckpointRestoreContext>;
|
|
207
252
|
export interface AgentRunResumeOptions {
|
|
208
253
|
readonly checkpoints: CheckpointStore;
|
|
209
254
|
/** Current host-authored revision; must exactly match the checkpoint. */
|
|
@@ -224,6 +269,20 @@ export interface AgentRunResumeOptions {
|
|
|
224
269
|
readonly persistSessionState?: boolean;
|
|
225
270
|
/** Opt-in (plan 018 Task 6): restore persisted loaded-skill bodies (requires `persistSessionState` too). */
|
|
226
271
|
readonly includeSkillBodies?: boolean;
|
|
272
|
+
/**
|
|
273
|
+
* Checkpoint sidecar metadata for the claim write (and the resumed run's later checkpoints).
|
|
274
|
+
* Absent = the record's existing metadata is preserved unchanged.
|
|
275
|
+
*/
|
|
276
|
+
readonly checkpointMetadata?: AgentRunCheckpointMetadataSource;
|
|
277
|
+
/**
|
|
278
|
+
* Plan 094 Task 3: external-state restore hooks. Every hook must succeed (sequentially, each
|
|
279
|
+
* within `restoreHookTimeoutMs`) before the claim write and the conversation restore apply;
|
|
280
|
+
* the first failure throws `CheckpointRestoreError` naming the hook and leaves the checkpoint
|
|
281
|
+
* suspended. Hosts that register hooks on the lifecycle instead pass them once there.
|
|
282
|
+
*/
|
|
283
|
+
readonly restoreHooks?: readonly AgentCheckpointRestoreHook[];
|
|
284
|
+
/** Per-hook restore ceiling in ms; defaults to `DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS`. */
|
|
285
|
+
readonly restoreHookTimeoutMs?: number;
|
|
227
286
|
}
|
|
228
287
|
/** Bounded live-event options for `resumeAgentRunStream()`; `signal` is inherited from the base resume options. */
|
|
229
288
|
export interface AgentRunResumeStreamOptions extends AgentRunResumeOptions, SubscribeOptions {
|
|
@@ -235,6 +294,8 @@ export interface AgentRunRef {
|
|
|
235
294
|
export interface AgentRunStatusResult {
|
|
236
295
|
readonly state: AgentRunState;
|
|
237
296
|
readonly version: number;
|
|
297
|
+
/** Checkpoint sidecar metadata; absent when the record carries none (or carries only malformed entries). */
|
|
298
|
+
readonly metadata?: AgentRunCheckpointMetadata;
|
|
238
299
|
}
|
|
239
300
|
export declare class AgentRunStateError extends Error {
|
|
240
301
|
readonly code = "ERR_PRISM_AGENT_RUN_STATE";
|
|
@@ -301,6 +362,12 @@ export interface SteerOptions {
|
|
|
301
362
|
}
|
|
302
363
|
export interface AgentSession {
|
|
303
364
|
readonly id: string;
|
|
365
|
+
/**
|
|
366
|
+
* Plan 104 Task 2: guardrail pack refs this session enforces (the restored rows after a durable
|
|
367
|
+
* resume); `undefined` when it enforces none. Pass to `snapshotRunBundle({ packs })` for the
|
|
368
|
+
* recorded identity that matches enforcement.
|
|
369
|
+
*/
|
|
370
|
+
readonly guardrailPackRefs?: readonly GuardrailPackRef[];
|
|
304
371
|
/** Current branch leaf entry id; advances on every append/run and is re-pointed by `checkout`.
|
|
305
372
|
* Undefined until the first entry lands (a fresh session with no history). */
|
|
306
373
|
readonly leafId: string | undefined;
|
|
@@ -312,13 +379,35 @@ export interface AgentSession {
|
|
|
312
379
|
* Fails closed when no run is active or the pending queue exceeds caps.
|
|
313
380
|
*/
|
|
314
381
|
steer(input: string | Message | readonly Message[], options?: SteerOptions): void;
|
|
315
|
-
/**
|
|
382
|
+
/**
|
|
383
|
+
* Subscribe first, then start exactly one run and yield only that run's events until it terminates.
|
|
384
|
+
* This subscription belongs to `stream()`: it is closed when the owned run settles (so a pre-flight
|
|
385
|
+
* rejection unblocks the consumer instead of parking it behind a run that never emits).
|
|
386
|
+
*/
|
|
316
387
|
stream(input: string | Message | readonly Message[], options?: RunOptions & SubscribeOptions): AsyncIterable<AgentEvent>;
|
|
317
388
|
compact(options?: CompactionOptions): Promise<CompactionResult>;
|
|
389
|
+
/**
|
|
390
|
+
* Subscribe to this session's live events. A run-scoped subscriber (default) is closed when the run
|
|
391
|
+
* ends, suspends, or is denied; `SubscribeOptions.acrossRuns: true` keeps it open across runs until
|
|
392
|
+
* `subscription.close()`, `closeSubscribers()`, or a queue overflow closes it.
|
|
393
|
+
*/
|
|
318
394
|
subscribe(options?: SubscribeOptions): AsyncIterable<AgentEvent>;
|
|
395
|
+
/**
|
|
396
|
+
* Plan 106 R2: session teardown. Dispatches `session_shutdown` middleware once (idempotent), then
|
|
397
|
+
* closes every subscriber (`acrossRuns` included); calling it twice is a no-op. Call after the
|
|
398
|
+
* active run settles. Subscriber-only teardown stays `break`ing the `for await` (or calling the
|
|
399
|
+
* iterator's `return()`). See [Agent/session runtime](agent-session-runtime.md).
|
|
400
|
+
*/
|
|
401
|
+
close(): Promise<void>;
|
|
319
402
|
abort(reason?: unknown): void;
|
|
320
403
|
entries(): Promise<readonly SessionEntry[]>;
|
|
321
404
|
checkout(leafId?: string): Promise<void>;
|
|
405
|
+
/**
|
|
406
|
+
* Context-fill read (plan 091 T2): latest provider turn's input tokens
|
|
407
|
+
* (reported or labeled estimate) plus the resolved per-request cap, run input
|
|
408
|
+
* budget, and used ratio. Before any provider turn it estimates stored history.
|
|
409
|
+
*/
|
|
410
|
+
contextMeter(): ContextMeter;
|
|
322
411
|
fork(options?: AgentSessionForkOptions): AgentSession;
|
|
323
412
|
clone(options?: AgentSessionCloneOptions): Promise<AgentSession>;
|
|
324
413
|
}
|
package/dist/contributions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentDefinition, AuthMethod, CommandDefinition, CompactionStrategy, ContextProvider, CredentialResolver, DiscoveredContribution, InputBuilder, InstructionInjector, PromptBuilder, ProviderPackage, ProviderRequestPolicy, ResourceLoader, RetryPolicy, SettingsProvider, Skill, StoreFactory, SystemPromptContribution, ToolDefinition } from "./contracts.js";
|
|
1
|
+
import type { AgentDefinition, AuthMethod, CommandDefinition, CompactionStrategy, ContextProvider, CredentialResolver, DiscoveredContribution, InputBuilder, InstructionInjector, PromptBuilder, ProviderPackage, ProviderRequestPolicy, ResourceLoader, RetryPolicy, SettingsProvider, Skill, StopHook, StoreFactory, SystemPromptContribution, ToolDefinition } from "./contracts.js";
|
|
2
2
|
import { type ModelRegistry } from "./models.js";
|
|
3
3
|
import { type ProviderRegistry } from "./providers.js";
|
|
4
4
|
import { type DuplicateRegistrationOptions } from "./registry-options.js";
|
|
@@ -35,6 +35,7 @@ export interface ContributionRegistries {
|
|
|
35
35
|
readonly providerRequestPolicies: ContributionRegistry<ProviderRequestPolicy>;
|
|
36
36
|
readonly systemPromptContributions: ContributionRegistry<SystemPromptContribution>;
|
|
37
37
|
readonly instructionInjectors: ContributionRegistry<InstructionInjector>;
|
|
38
|
+
readonly stopHooks: ContributionRegistry<StopHook>;
|
|
38
39
|
}
|
|
39
40
|
export interface ContributionRegistriesOptions extends DuplicateRegistrationOptions {
|
|
40
41
|
}
|
package/dist/contributions.js
CHANGED
|
@@ -49,6 +49,7 @@ export function createContributionRegistries(options = {}) {
|
|
|
49
49
|
providerRequestPolicies: createContributionRegistry(registryOptions("provider request policy")),
|
|
50
50
|
systemPromptContributions: createContributionRegistry(registryOptions("system prompt contribution")),
|
|
51
51
|
instructionInjectors: createContributionRegistry(registryOptions("instruction injector")),
|
|
52
|
+
stopHooks: createContributionRegistry(registryOptions("stop hook")),
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
/** Register discovered contributions into the given registries. Inert: skill
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CommandDefinition, ContextProvider, Extension, ExtensionEvent, ExtensionLifecycleEventName, InstructionInjector, Skill, ToolDefinition } from "./contracts.js";
|
|
1
|
+
import type { AgentEvent, CommandDefinition, ContextProvider, Extension, ExtensionEvent, ExtensionLifecycleEventName, InstructionInjector, Skill, StopHook, ToolDefinition } from "./contracts.js";
|
|
2
2
|
import { type ContributionRegistries } from "./contributions.js";
|
|
3
3
|
import { type MiddlewareRegistry } from "./middleware.js";
|
|
4
4
|
import { type PermissionPolicy } from "./security.js";
|
|
@@ -40,6 +40,18 @@ export interface ExtensionKernel {
|
|
|
40
40
|
}
|
|
41
41
|
export declare function createExtensionEventBus(options?: Pick<ExtensionKernelOptions, "errorPolicy" | "secrets">): ExtensionEventBus;
|
|
42
42
|
export declare function createExtensionKernel(options?: ExtensionKernelOptions): ExtensionKernel;
|
|
43
|
+
export interface AgentEventBridgeOptions {
|
|
44
|
+
/** Bridge-side failure (a source error, or a bus listener that throws under `errorPolicy: "throw"`).
|
|
45
|
+
* Never rethrown — the bridge must not fail the run it is observing. */
|
|
46
|
+
readonly onError?: (error: unknown) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Forward an `AgentEvent` iterable onto the extension bus, one mapped lifecycle event at a time
|
|
50
|
+
* (plan 106 R2). Handlers run in event order and never in the run's path, so a slow or throwing
|
|
51
|
+
* listener cannot stall or fail the observed run. Returns an unsubscribe that stops forwarding and
|
|
52
|
+
* releases the source iterator.
|
|
53
|
+
*/
|
|
54
|
+
export declare function forwardAgentEvents(source: AsyncIterable<AgentEvent>, events: Pick<ExtensionEventBus, "emit">, options?: AgentEventBridgeOptions): () => void;
|
|
43
55
|
/** Host-owned activation: copy contributed entries into the `createAgent()`
|
|
44
56
|
* fields that accept plain arrays. Contributions stay inert until the host
|
|
45
57
|
* passes the returned fields into runtime config. Array slots only —
|
|
@@ -51,6 +63,8 @@ export interface ActivatedKernelConfig {
|
|
|
51
63
|
readonly skills: readonly Skill[];
|
|
52
64
|
readonly instructionInjectors: readonly InstructionInjector[];
|
|
53
65
|
readonly context: readonly ContextProvider[];
|
|
66
|
+
/** Run-end stop hooks (plan 106 R1); pass to `createAgent({ stopHooks })`. */
|
|
67
|
+
readonly stopHooks: readonly StopHook[];
|
|
54
68
|
/** For host command surfaces (CLI/RPC/UI); not part of `AgentConfig`. */
|
|
55
69
|
readonly commands: readonly CommandDefinition[];
|
|
56
70
|
/** The kernel middleware registry itself; runs only when passed to runtime config. */
|
package/dist/extensions.js
CHANGED
|
@@ -143,6 +143,10 @@ export function createExtensionKernel(options = {}) {
|
|
|
143
143
|
registries.instructionInjectors.register(injector.name, injector);
|
|
144
144
|
track?.(() => registries.instructionInjectors.unregister(injector.name));
|
|
145
145
|
},
|
|
146
|
+
registerStopHook(hook) {
|
|
147
|
+
registries.stopHooks.register(hook.name, hook);
|
|
148
|
+
track?.(() => registries.stopHooks.unregister(hook.name));
|
|
149
|
+
},
|
|
146
150
|
});
|
|
147
151
|
const unwind = (undo) => {
|
|
148
152
|
for (const fn of undo.reverse()) {
|
|
@@ -190,12 +194,76 @@ export function createExtensionKernel(options = {}) {
|
|
|
190
194
|
},
|
|
191
195
|
};
|
|
192
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Lifecycle hook each forwarded `AgentEvent` maps onto (plan 106 R2). Notification only: the bus
|
|
199
|
+
* receives the original event as `payload` and nothing is transformed. Events not listed here are
|
|
200
|
+
* ignored — notably `agent_finished` stays an AgentEvent and is not re-emitted as a bus event.
|
|
201
|
+
*/
|
|
202
|
+
const AGENT_EVENT_BRIDGE = {
|
|
203
|
+
agent_started: "before_agent_start",
|
|
204
|
+
turn_started: "turn",
|
|
205
|
+
turn_finished: "turn",
|
|
206
|
+
tool_execution_started: "tool_call",
|
|
207
|
+
tool_execution_finished: "tool_result",
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Forward an `AgentEvent` iterable onto the extension bus, one mapped lifecycle event at a time
|
|
211
|
+
* (plan 106 R2). Handlers run in event order and never in the run's path, so a slow or throwing
|
|
212
|
+
* listener cannot stall or fail the observed run. Returns an unsubscribe that stops forwarding and
|
|
213
|
+
* releases the source iterator.
|
|
214
|
+
*/
|
|
215
|
+
export function forwardAgentEvents(source, events, options = {}) {
|
|
216
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
217
|
+
const report = (error) => {
|
|
218
|
+
try {
|
|
219
|
+
options.onError?.(error);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// A throwing error callback must not become an unhandled rejection.
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
let stopped = false;
|
|
226
|
+
// Serially chained so a listener that awaits keeps event order; the run never awaits this chain.
|
|
227
|
+
let pending = Promise.resolve();
|
|
228
|
+
void (async () => {
|
|
229
|
+
try {
|
|
230
|
+
while (!stopped) {
|
|
231
|
+
const { value, done } = await iterator.next();
|
|
232
|
+
if (done || stopped)
|
|
233
|
+
return;
|
|
234
|
+
const type = AGENT_EVENT_BRIDGE[value.type];
|
|
235
|
+
if (type === undefined)
|
|
236
|
+
continue;
|
|
237
|
+
const event = { type, payload: value };
|
|
238
|
+
pending = pending.then(() => events.emit(event)).catch(report);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
if (!stopped)
|
|
243
|
+
report(error);
|
|
244
|
+
}
|
|
245
|
+
})();
|
|
246
|
+
return () => {
|
|
247
|
+
if (stopped)
|
|
248
|
+
return;
|
|
249
|
+
stopped = true;
|
|
250
|
+
void (async () => {
|
|
251
|
+
try {
|
|
252
|
+
await iterator.return?.();
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
report(error);
|
|
256
|
+
}
|
|
257
|
+
})();
|
|
258
|
+
};
|
|
259
|
+
}
|
|
193
260
|
export function activateKernel(kernel) {
|
|
194
261
|
return {
|
|
195
262
|
tools: kernel.registries.tools.list(),
|
|
196
263
|
skills: kernel.registries.skills.list(),
|
|
197
264
|
instructionInjectors: kernel.registries.instructionInjectors.list(),
|
|
198
265
|
context: kernel.registries.contextProviders.list(),
|
|
266
|
+
stopHooks: kernel.registries.stopHooks.list(),
|
|
199
267
|
commands: kernel.registries.commands.list(),
|
|
200
268
|
middleware: kernel.middleware,
|
|
201
269
|
};
|