@rivus/runtime 0.16.2

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.
@@ -0,0 +1,386 @@
1
+ import { Pt as AgentRunId, it as AgentMemoryInvocationIdentity, rt as AgentInvocationOrigin } from "./agent-loop.js";
2
+ import { Effect } from "effect";
3
+
4
+ //#region src/core/application/agent-execution/contracts/model-runtime.d.ts
5
+ /**
6
+ * Runtime-owned model contracts. These describe the actual model binding and
7
+ * the validate/activate/restore operations plus the bounded paid-call budget
8
+ * that real Pi resources need. Gateway policy (persistent requests,
9
+ * authorization, budget reservation/settlement, recovery) maps onto these
10
+ * capabilities but does not live here.
11
+ */
12
+ interface ModelReference {
13
+ readonly model: string;
14
+ readonly provider: string;
15
+ }
16
+ interface ModelBinding extends ModelReference {
17
+ /** Provider/adapter binding revision used to invalidate stale validation. */
18
+ readonly bindingRevision: string;
19
+ }
20
+ interface ModelChangeRuntimeContext {
21
+ readonly baseline: ModelBinding;
22
+ readonly bindingRevision: string;
23
+ readonly target: ModelReference;
24
+ }
25
+ type ModelChangePaidCallKind = "activation" | "restore" | "validation";
26
+ /**
27
+ * Minimal Runtime budget reservation shape. Pi only needs the reservation id
28
+ * (for settlement tracking) and the allocated max output tokens (for the
29
+ * provider call and failure settlement). Request identity, kind, timestamps
30
+ * and paid-request counts are Gateway policy and do not cross this boundary.
31
+ */
32
+ interface ModelChangeBudgetReservation {
33
+ readonly id: string;
34
+ readonly maxOutputTokens: number;
35
+ }
36
+ interface ModelChangeExecutionBudget {
37
+ /** Fixed deadline for every paid call in this accepted request. */
38
+ readonly deadlineAt: string;
39
+ reservePaidCall(input: {
40
+ readonly kind: ModelChangePaidCallKind;
41
+ readonly maxOutputTokens?: number;
42
+ }): Effect.Effect<{
43
+ readonly reservation: ModelChangeBudgetReservation;
44
+ readonly settle: (input: {
45
+ readonly outcome: "known" | "unknown";
46
+ readonly outputTokens: number;
47
+ }) => Effect.Effect<unknown, unknown>;
48
+ }, unknown>;
49
+ }
50
+ interface ModelChangeValidationResult {
51
+ readonly evidence: Readonly<Record<string, unknown>>;
52
+ readonly model: ModelBinding;
53
+ readonly outputTokens: number;
54
+ readonly passed: true;
55
+ }
56
+ interface ModelChangeActivationResult {
57
+ readonly evidence: Readonly<Record<string, unknown>>;
58
+ readonly outputTokens: number;
59
+ readonly switched: true;
60
+ }
61
+ interface ModelChangeRestoreResult {
62
+ readonly evidence: Readonly<Record<string, unknown>>;
63
+ readonly restored: true;
64
+ }
65
+ interface ModelChangeRuntimePort {
66
+ activate(input: {
67
+ readonly beforeApply?: () => Effect.Effect<void, unknown>;
68
+ readonly context: ModelChangeRuntimeContext;
69
+ readonly budget: ModelChangeExecutionBudget;
70
+ readonly validation: ModelChangeValidationResult;
71
+ }): Effect.Effect<ModelChangeActivationResult, unknown>;
72
+ current?(): Effect.Effect<ModelBinding | undefined, unknown>;
73
+ drain(input: ModelChangeRuntimeContext & {
74
+ readonly deadlineAt: string;
75
+ }): Effect.Effect<void, unknown>;
76
+ releasePrevious(input: ModelChangeRuntimeContext & {
77
+ readonly deadlineAt: string;
78
+ }): Effect.Effect<void, unknown>;
79
+ restore(input: {
80
+ readonly budget: ModelChangeExecutionBudget;
81
+ readonly context: ModelChangeRuntimeContext;
82
+ readonly reason: string;
83
+ }): Effect.Effect<ModelChangeRestoreResult, unknown>;
84
+ validate(input: {
85
+ readonly budget: ModelChangeExecutionBudget;
86
+ readonly context: ModelChangeRuntimeContext;
87
+ }): Effect.Effect<ModelChangeValidationResult, unknown>;
88
+ }
89
+ //#endregion
90
+ //#region src/core/application/agent-execution/contracts/rivus-skill.d.ts
91
+ interface RivusSkillDescriptor {
92
+ readonly id: string;
93
+ readonly version: string;
94
+ readonly digest: string;
95
+ readonly title: string;
96
+ readonly content: string;
97
+ }
98
+ interface RegisteredRivusSkill extends RivusSkillDescriptor {
99
+ readonly pluginId: string;
100
+ }
101
+ interface RivusSkillGrantSet {
102
+ readonly skillIds: ReadonlyArray<string>;
103
+ readonly revision: string;
104
+ }
105
+ //#endregion
106
+ //#region src/core/application/agent-execution/contracts/run-admission.d.ts
107
+ /**
108
+ * Runtime-owned run admission mechanism. The execution application owns the
109
+ * active-run counter and the fence that lets a model change drain in-flight
110
+ * work. Waiting Runs are parked outside the active count, so a drain can close
111
+ * admission and wait only for work that actually started.
112
+ *
113
+ * This interface carries no model-change request identity or request deadline.
114
+ * The Gateway coordinator wraps it with the {@link ModelChangeBoundaryPort}
115
+ * protocol (request id, drain deadline, resume semantics) in the deployment
116
+ * boundary.
117
+ */
118
+ interface RunAdmission {
119
+ /** Acquire admission for one concrete Run before resolving a session/model. */
120
+ acquireRun(input?: {
121
+ readonly deadlineAt?: string;
122
+ readonly signal?: AbortSignal;
123
+ }): Effect.Effect<RunAdmissionLease, unknown>;
124
+ /** Synchronously close admission; existing leases continue to drain. */
125
+ fence(): void;
126
+ /** Effect that succeeds when the active run count reaches zero. */
127
+ whenDrained(): Effect.Effect<void, unknown>;
128
+ /** Reopen admission after a model change. Releases waiting runs. */
129
+ reopen(): void;
130
+ readonly activeRunCount: () => number;
131
+ readonly admissionOpen: () => boolean;
132
+ }
133
+ interface RunAdmissionLease {
134
+ /** Release exactly one active Run. Releasing twice is harmless. */
135
+ readonly release: () => void;
136
+ }
137
+ interface RunAdmissionOptions {
138
+ readonly clock: ModelChangeClock;
139
+ }
140
+ interface ModelChangeClock {
141
+ now(): string;
142
+ }
143
+ declare class ModelChangeBoundaryDeadlineError extends Error {
144
+ readonly name = "ModelChangeBoundaryDeadlineError";
145
+ }
146
+ //#endregion
147
+ //#region src/core/application/tool-execution/contracts/rivus-tool.d.ts
148
+ type RivusMemoryScope = "conversation" | "agent-private" | "project" | "shared-user-profile";
149
+ type RivusToolRisk = "observe" | "mutate" | "irreversible" | "host-control";
150
+ type RivusToolIdempotency = "none" | "supported" | "required";
151
+ declare class RivusToolInputRejected extends Error {
152
+ readonly name: string;
153
+ }
154
+ interface RivusToolExecutor {
155
+ execute(input: unknown, context: RivusToolExecutionContext): unknown;
156
+ }
157
+ interface RivusToolExecutionOrigin {
158
+ readonly endpointId: string;
159
+ readonly tenantKey: string;
160
+ readonly conversationId?: string;
161
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
162
+ }
163
+ interface RivusToolExecutionContext {
164
+ readonly agentId: string;
165
+ readonly instanceId: string;
166
+ readonly memory?: RivusMemoryAuthority;
167
+ readonly runId: string;
168
+ readonly callId: string;
169
+ readonly operationId?: string;
170
+ readonly policyEpoch: number;
171
+ readonly toolId: string;
172
+ readonly toolVersion: string;
173
+ readonly sessionKey: string;
174
+ readonly origin?: RivusToolExecutionOrigin;
175
+ readonly sourceMessageId?: string;
176
+ }
177
+ interface RivusMemoryAuthority {
178
+ readonly audience: "group" | "private";
179
+ readonly conversationId?: string;
180
+ readonly projectId?: string;
181
+ readonly scopes: ReadonlyArray<RivusMemoryScope>;
182
+ readonly subjectId: string;
183
+ readonly tenantId: string;
184
+ }
185
+ interface RivusToolFactoryContext {
186
+ readonly toolId: string;
187
+ readonly toolVersion: string;
188
+ }
189
+ interface RivusToolDescriptor {
190
+ readonly id: string;
191
+ readonly version: string;
192
+ readonly digest: string;
193
+ readonly description: string;
194
+ readonly inputSchema: unknown;
195
+ readonly risk: RivusToolRisk;
196
+ readonly idempotency: RivusToolIdempotency;
197
+ readonly createExecutor: (context: RivusToolFactoryContext) => RivusToolExecutor;
198
+ }
199
+ interface RivusHostToolDescriptor extends RivusToolDescriptor {
200
+ readonly replayCompleted?: (input: unknown, completedResult: unknown, context: RivusToolExecutionContext) => unknown;
201
+ }
202
+ interface RegisteredRivusTool extends RivusToolDescriptor {
203
+ readonly pluginId: string;
204
+ }
205
+ interface RivusResolvedToolDescriptor {
206
+ readonly id: string;
207
+ readonly version: string;
208
+ readonly digest: string;
209
+ readonly description: string;
210
+ readonly inputSchema: unknown;
211
+ readonly risk: RivusToolRisk;
212
+ readonly idempotency: RivusToolIdempotency;
213
+ readonly pluginId: string;
214
+ }
215
+ interface RivusToolGrantSet {
216
+ readonly toolIds: ReadonlyArray<string>;
217
+ readonly revision: string;
218
+ }
219
+ interface RivusToolGrantSetOperations {
220
+ narrow(parent: RivusToolGrantSet, restrictions: ReadonlyArray<ReadonlyArray<string>>): RivusToolGrantSet;
221
+ intersect(sets: ReadonlyArray<ReadonlyArray<string>>): RivusToolGrantSet;
222
+ }
223
+ //#endregion
224
+ //#region src/core/application/agent-execution/observation/agent-model-content-observer.d.ts
225
+ interface AgentModelInputObservation {
226
+ readonly input: unknown;
227
+ readonly modelCallId: string;
228
+ readonly runId: AgentRunId;
229
+ }
230
+ interface AgentModelOutputObservation {
231
+ readonly modelCallId: string;
232
+ readonly output: unknown;
233
+ readonly runId: AgentRunId;
234
+ }
235
+ interface AgentModelContentObserver {
236
+ observeInput(observation: AgentModelInputObservation): void;
237
+ observeOutput(observation: AgentModelOutputObservation): void;
238
+ }
239
+ //#endregion
240
+ //#region src/core/application/agent-execution/invocation/agent-invocation-identity.d.ts
241
+ interface NormalizedAgentInvocation {
242
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
243
+ readonly conversationId?: string;
244
+ readonly endpointId: string;
245
+ readonly memory?: AgentMemoryInvocationIdentity;
246
+ readonly sourceMessageId: string;
247
+ readonly tenantKey: string;
248
+ }
249
+ /**
250
+ * Background-session conversationId is captured only from the explicit origin
251
+ * field; when absent it must not fall back to memory, which would expand the
252
+ * association scope beyond the reviewed binding.
253
+ */
254
+ declare function normalizeAgentInvocation(origin: AgentInvocationOrigin): NormalizedAgentInvocation;
255
+ //#endregion
256
+ //#region src/core/application/tool-execution/authority/invocation-authority-registry.d.ts
257
+ type InvocationMemoryScope = "conversation" | "agent-private" | "project" | "shared-user-profile";
258
+ interface InvocationMemoryAuthority {
259
+ readonly audience: "group" | "private";
260
+ readonly conversationId?: string;
261
+ readonly projectId?: string;
262
+ readonly scopes: ReadonlyArray<InvocationMemoryScope>;
263
+ readonly subjectId: string;
264
+ readonly tenantId: string;
265
+ }
266
+ interface InvocationToolGrantSet {
267
+ readonly revision: string;
268
+ readonly toolIds: ReadonlyArray<string>;
269
+ }
270
+ interface InvocationAuthorityRef {
271
+ readonly id: string;
272
+ }
273
+ interface InvocationAuthority {
274
+ readonly agentId: string;
275
+ readonly allowedActorOpenIds?: ReadonlyArray<string>;
276
+ readonly conversationId?: string;
277
+ readonly endpointId?: string;
278
+ readonly instanceId: string;
279
+ readonly memory?: InvocationMemoryAuthority;
280
+ readonly runId: string;
281
+ readonly sessionKey: string;
282
+ readonly sourceMessageId: string;
283
+ readonly tenantKey: string;
284
+ readonly toolGrantSet: InvocationToolGrantSet;
285
+ }
286
+ declare class InvalidInvocationAuthority extends Error {
287
+ readonly name = "InvalidInvocationAuthority";
288
+ }
289
+ interface InvocationAuthorityIdentity {
290
+ next(): string;
291
+ }
292
+ declare function createInvocationAuthority(authority: InvocationAuthority, identity?: InvocationAuthorityIdentity): InvocationAuthorityRef;
293
+ declare function resolveInvocationAuthority(reference: InvocationAuthorityRef): InvocationAuthority;
294
+ //#endregion
295
+ //#region src/core/application/tool-execution/authority/tool-risk-policy.d.ts
296
+ type ToolRisk = "observe" | "mutate" | "irreversible" | "host-control";
297
+ type ToolIdempotency = "none" | "supported" | "required";
298
+ declare function requiresToolApproval(risk: ToolRisk): boolean;
299
+ //#endregion
300
+ //#region src/core/application/tool-execution/brokerage/tool-broker-ports.d.ts
301
+ interface AuthorizationPolicyState {
302
+ readonly epoch: number;
303
+ readonly revokedToolIds: ReadonlyArray<string>;
304
+ }
305
+ interface AuthorizationPolicyProvider {
306
+ current(): Effect.Effect<AuthorizationPolicyState, unknown>;
307
+ }
308
+ interface ToolApprovalRequest {
309
+ readonly approvalId: string;
310
+ readonly agentId: string;
311
+ readonly instanceId: string;
312
+ readonly inputDigest: string;
313
+ readonly operationId: string;
314
+ readonly runId: string;
315
+ readonly sessionKey: string;
316
+ readonly tenantKey: string;
317
+ readonly callId: string;
318
+ readonly toolId: string;
319
+ readonly toolVersion: string;
320
+ readonly risk: ToolRisk;
321
+ }
322
+ interface ToolApprovalService {
323
+ consume(request: ToolApprovalRequest): Effect.Effect<boolean, unknown>;
324
+ }
325
+ interface ToolExecutionOrigin {
326
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
327
+ readonly conversationId?: string;
328
+ readonly endpointId: string;
329
+ readonly tenantKey: string;
330
+ }
331
+ interface ToolExecutionContext {
332
+ readonly agentId: string;
333
+ readonly callId: string;
334
+ readonly instanceId: string;
335
+ readonly memory?: InvocationMemoryAuthority;
336
+ readonly operationId?: string;
337
+ readonly origin?: ToolExecutionOrigin;
338
+ readonly policyEpoch: number;
339
+ readonly runId: string;
340
+ readonly sessionKey: string;
341
+ readonly sourceMessageId?: string;
342
+ readonly toolId: string;
343
+ readonly toolVersion: string;
344
+ }
345
+ interface ToolExecutor {
346
+ execute(input: unknown, context: ToolExecutionContext): Effect.Effect<unknown, unknown>;
347
+ }
348
+ interface ToolDescriptor {
349
+ readonly createExecutor: (context: {
350
+ readonly toolId: string;
351
+ readonly toolVersion: string;
352
+ }) => ToolExecutor;
353
+ readonly id: string;
354
+ readonly idempotency: ToolIdempotency;
355
+ readonly replayCompleted?: (input: unknown, completedResult: unknown, context: ToolExecutionContext) => Effect.Effect<unknown, unknown>;
356
+ readonly risk: ToolRisk;
357
+ readonly version: string;
358
+ }
359
+ interface ToolCatalog {
360
+ snapshot(): {
361
+ readonly tools: ReadonlyArray<ToolDescriptor>;
362
+ };
363
+ }
364
+ interface ToolExecutionRequest {
365
+ readonly approvalId?: string;
366
+ readonly authority: InvocationAuthorityRef;
367
+ readonly callId: string;
368
+ readonly input: unknown;
369
+ readonly operationId?: string;
370
+ readonly toolId: string;
371
+ readonly version: string;
372
+ }
373
+ declare class ToolExecutorInputRejected extends Error {
374
+ readonly name = "ToolExecutorInputRejected";
375
+ }
376
+ //#endregion
377
+ //#region src/core/application/tool-execution/contracts/rivus-runtime-tool.d.ts
378
+ declare const RIVUS_RUNTIME_TOOL_IDS: readonly ["read", "bash", "edit", "write", "grep", "find", "ls"];
379
+ type RivusRuntimeToolId = (typeof RIVUS_RUNTIME_TOOL_IDS)[number];
380
+ interface RivusRuntimeToolGrantSet {
381
+ readonly revision: string;
382
+ readonly toolIds: ReadonlyArray<RivusRuntimeToolId>;
383
+ }
384
+ declare function isRivusRuntimeToolId(value: string): value is RivusRuntimeToolId;
385
+ //#endregion
386
+ export { RegisteredRivusSkill as $, AgentModelContentObserver as A, RivusToolExecutionOrigin as B, InvocationMemoryAuthority as C, resolveInvocationAuthority as D, createInvocationAuthority as E, RivusMemoryAuthority as F, RivusToolIdempotency as G, RivusToolFactoryContext as H, RivusMemoryScope as I, ModelChangeBoundaryDeadlineError as J, RivusToolInputRejected as K, RivusResolvedToolDescriptor as L, AgentModelOutputObservation as M, RegisteredRivusTool as N, NormalizedAgentInvocation as O, RivusHostToolDescriptor as P, RunAdmissionOptions as Q, RivusToolDescriptor as R, InvocationAuthorityRef as S, InvocationToolGrantSet as T, RivusToolGrantSet as U, RivusToolExecutor as V, RivusToolGrantSetOperations as W, RunAdmission as X, ModelChangeClock as Y, RunAdmissionLease as Z, ToolRisk as _, AuthorizationPolicyProvider as a, ModelChangeExecutionBudget as at, InvocationAuthority as b, ToolApprovalService as c, ModelChangeRuntimeContext as ct, ToolExecutionContext as d, ModelReference as dt, RivusSkillDescriptor as et, ToolExecutionOrigin as f, ToolIdempotency as g, ToolExecutorInputRejected as h, isRivusRuntimeToolId as i, ModelChangeBudgetReservation as it, AgentModelInputObservation as j, normalizeAgentInvocation as k, ToolCatalog as l, ModelChangeRuntimePort as lt, ToolExecutor as m, RivusRuntimeToolGrantSet as n, ModelBinding as nt, AuthorizationPolicyState as o, ModelChangePaidCallKind as ot, ToolExecutionRequest as p, RivusToolRisk as q, RivusRuntimeToolId as r, ModelChangeActivationResult as rt, ToolApprovalRequest as s, ModelChangeRestoreResult as st, RIVUS_RUNTIME_TOOL_IDS as t, RivusSkillGrantSet as tt, ToolDescriptor as u, ModelChangeValidationResult as ut, requiresToolApproval as v, InvocationMemoryScope as w, InvocationAuthorityIdentity as x, InvalidInvocationAuthority as y, RivusToolExecutionContext as z };
@@ -0,0 +1,119 @@
1
+ //#region src/core/application/tool-execution/contracts/rivus-tool.ts
2
+ var RivusToolInputRejected = class extends Error {
3
+ name = "RivusToolInputRejected";
4
+ };
5
+ //#endregion
6
+ //#region src/core/application/agent-execution/invocation/agent-invocation-identity.ts
7
+ /**
8
+ * Background-session conversationId is captured only from the explicit origin
9
+ * field; when absent it must not fall back to memory, which would expand the
10
+ * association scope beyond the reviewed binding.
11
+ */
12
+ function normalizeAgentInvocation(origin) {
13
+ const conversationId = origin.kind === "background-session" ? origin.conversationId : origin.memory?.conversationId;
14
+ return {
15
+ allowedActorOpenIds: origin.allowedActorOpenIds,
16
+ ...conversationId ? { conversationId } : {},
17
+ endpointId: origin.endpointId,
18
+ ...origin.memory ? { memory: origin.memory } : {},
19
+ sourceMessageId: origin.sourceMessageId,
20
+ tenantKey: origin.tenantKey
21
+ };
22
+ }
23
+ //#endregion
24
+ //#region src/core/application/tool-execution/authority/invocation-authority-registry.ts
25
+ const authorities = /* @__PURE__ */ new WeakMap();
26
+ let localAuthoritySequence = 0;
27
+ var InvalidInvocationAuthority = class extends Error {
28
+ name = "InvalidInvocationAuthority";
29
+ };
30
+ function createInvocationAuthority(authority, identity = { next: () => String(++localAuthoritySequence) }) {
31
+ const reference = Object.freeze({ id: `authority:${identity.next()}` });
32
+ authorities.set(reference, normalizeInvocationAuthority(authority));
33
+ return reference;
34
+ }
35
+ function resolveInvocationAuthority(reference) {
36
+ const authority = authorities.get(reference);
37
+ if (!authority) throw new InvalidInvocationAuthority("invocation authority was not issued by this host");
38
+ return authority;
39
+ }
40
+ function normalizeInvocationAuthority(authority) {
41
+ if (!isRecord(authority) || typeof authority.sourceMessageId !== "string" || !authority.sourceMessageId.trim()) throw new InvalidInvocationAuthority("invocation authority requires a trusted source message id");
42
+ if (authority.endpointId !== void 0 && (!authority.endpointId || !authority.endpointId.trim())) throw new InvalidInvocationAuthority("invocation authority requires a trusted endpoint id");
43
+ return Object.freeze({
44
+ ...authority,
45
+ ...authority.allowedActorOpenIds === void 0 ? {} : { allowedActorOpenIds: Object.freeze([...authority.allowedActorOpenIds]) },
46
+ ...authority.memory === void 0 ? {} : { memory: freezeMemoryAuthority(authority.memory) },
47
+ toolGrantSet: freezeGrantSet(authority.toolGrantSet)
48
+ });
49
+ }
50
+ function freezeMemoryAuthority(value) {
51
+ const scopes = value.audience === "group" ? value.scopes.filter(isGroupMemoryScope) : [...value.scopes];
52
+ return Object.freeze({
53
+ ...value,
54
+ scopes: Object.freeze(scopes)
55
+ });
56
+ }
57
+ function freezeGrantSet(value) {
58
+ return Object.freeze({
59
+ revision: value.revision,
60
+ toolIds: Object.freeze([...value.toolIds])
61
+ });
62
+ }
63
+ function isGroupMemoryScope(value) {
64
+ return value === "conversation" || value === "project";
65
+ }
66
+ function isRecord(value) {
67
+ return value !== null && typeof value === "object" && !Array.isArray(value);
68
+ }
69
+ //#endregion
70
+ //#region src/core/application/tool-execution/authority/tool-risk-policy.ts
71
+ function requiresToolApproval(risk) {
72
+ return risk === "irreversible" || risk === "host-control";
73
+ }
74
+ //#endregion
75
+ //#region src/core/application/tool-execution/brokerage/tool-input-digest.ts
76
+ var InvalidStableJson = class extends Error {
77
+ name = "InvalidStableJson";
78
+ };
79
+ var InvalidToolInput = class extends InvalidStableJson {
80
+ name = "InvalidToolInput";
81
+ };
82
+ function createToolInputDigest(input, digest) {
83
+ try {
84
+ return digest(serializeStableJson(input, /* @__PURE__ */ new Set()));
85
+ } catch (error) {
86
+ if (error instanceof InvalidStableJson) throw new InvalidToolInput(error.message);
87
+ throw error;
88
+ }
89
+ }
90
+ function normalizeStableJson(value) {
91
+ return JSON.parse(serializeStableJson(value, /* @__PURE__ */ new Set()));
92
+ }
93
+ function serializeStableJson(value, ancestors) {
94
+ if (value === null) return "null";
95
+ if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
96
+ if (typeof value === "number") {
97
+ if (!Number.isFinite(value)) throw new InvalidStableJson("stable JSON numbers must be finite");
98
+ return JSON.stringify(value);
99
+ }
100
+ if (typeof value !== "object" || value === null) throw new InvalidStableJson("value must contain only stable JSON values");
101
+ if (ancestors.has(value)) throw new InvalidStableJson("stable JSON must not contain cycles");
102
+ ancestors.add(value);
103
+ try {
104
+ if (Array.isArray(value)) {
105
+ const output = [];
106
+ for (let index = 0; index < value.length; index += 1) {
107
+ if (!Object.hasOwn(value, index)) throw new InvalidStableJson("stable JSON arrays must not contain holes");
108
+ output.push(serializeStableJson(value[index], ancestors));
109
+ }
110
+ return `[${output.join(",")}]`;
111
+ }
112
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new InvalidStableJson("stable JSON objects must be plain objects");
113
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${serializeStableJson(value[key], ancestors)}`).join(",")}}`;
114
+ } finally {
115
+ ancestors.delete(value);
116
+ }
117
+ }
118
+ //#endregion
119
+ export { requiresToolApproval as a, resolveInvocationAuthority as c, normalizeStableJson as i, normalizeAgentInvocation as l, InvalidToolInput as n, InvalidInvocationAuthority as o, createToolInputDigest as r, createInvocationAuthority as s, InvalidStableJson as t, RivusToolInputRejected as u };