@rivus/agent 0.6.0 → 0.6.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,194 @@
1
+ import { s as AgentLoopInput } from "./agent-loop.js";
2
+ import { c as MemoryScope, t as AgentMemoryAuthority } from "./agent-memory.js";
3
+ import { A as RivusToolRisk, D as RivusToolGrantSet, b as RivusResolvedToolDescriptor, g as RivusPluginCatalog, m as RivusHostToolDescriptor } from "./rivus-plugin.js";
4
+ import { ToolDefinition } from "@earendil-works/pi-coding-agent";
5
+
6
+ //#region src/domain/recovery-action.d.ts
7
+ interface RecoveryAction {
8
+ readonly actorId: string;
9
+ readonly at: string;
10
+ readonly note: string;
11
+ }
12
+ declare class InvalidRecoveryAction extends Error {
13
+ readonly name = "InvalidRecoveryAction";
14
+ }
15
+ declare function createRecoveryAction(input: RecoveryAction): RecoveryAction;
16
+ //#endregion
17
+ //#region src/application/delegation/tool-operation-ledger.d.ts
18
+ interface ToolOperationBinding {
19
+ readonly agentId: string;
20
+ readonly inputDigest: string;
21
+ readonly instanceId: string;
22
+ readonly sourceMessageId: string;
23
+ readonly toolId: string;
24
+ readonly toolVersion: string;
25
+ }
26
+ type ToolOperationState = {
27
+ readonly status: "pending";
28
+ } | {
29
+ readonly result: unknown;
30
+ readonly status: "completed";
31
+ } | {
32
+ readonly reason: string;
33
+ readonly status: "reconciliation-required";
34
+ } | {
35
+ readonly status: "aborted";
36
+ };
37
+ interface ToolOperationRecord {
38
+ readonly binding: ToolOperationBinding;
39
+ readonly operationId: string;
40
+ readonly reconciliation?: ToolOperationReconciliation;
41
+ readonly revision: number;
42
+ readonly state: ToolOperationState;
43
+ }
44
+ interface ToolOperationReconciliation extends RecoveryAction {
45
+ readonly outcome: "applied" | "not-applied";
46
+ }
47
+ type ToolOperationReconciliationOutcome = {
48
+ readonly result: unknown;
49
+ readonly status: "applied";
50
+ } | {
51
+ readonly status: "not-applied";
52
+ };
53
+ type ToolOperationBeginResult = {
54
+ readonly status: "acquired";
55
+ } | {
56
+ readonly result: unknown;
57
+ readonly status: "completed";
58
+ } | {
59
+ readonly status: "blocked";
60
+ readonly reason: string;
61
+ };
62
+ type ToolOperationInspectResult = {
63
+ readonly status: "missing";
64
+ } | {
65
+ readonly result: unknown;
66
+ readonly status: "completed";
67
+ } | {
68
+ readonly status: "blocked";
69
+ readonly reason: string;
70
+ };
71
+ interface ToolOperationLedger {
72
+ abort(operationId: string, binding: ToolOperationBinding): Promise<void>;
73
+ begin(operationId: string, binding: ToolOperationBinding): Promise<ToolOperationBeginResult>;
74
+ complete(operationId: string, binding: ToolOperationBinding, result: unknown): Promise<void>;
75
+ inspect(operationId: string, binding: ToolOperationBinding): Promise<ToolOperationInspectResult>;
76
+ reconciliationRequired(): ReadonlyArray<ToolOperationRecord>;
77
+ reconcile(input: {
78
+ readonly action: RecoveryAction;
79
+ readonly expectedRevision: number;
80
+ readonly operationId: string;
81
+ readonly outcome: ToolOperationReconciliationOutcome;
82
+ }): Promise<ToolOperationRecord>;
83
+ requireReconciliation(operationId: string, binding: ToolOperationBinding, reason: string): Promise<void>;
84
+ unresolvedForSource(sourceMessageId: string): ReadonlyArray<ToolOperationRecord>;
85
+ }
86
+ declare function createToolOperationLedger(options?: {
87
+ readonly initial?: ReadonlyArray<ToolOperationRecord>;
88
+ readonly persist?: (record: ToolOperationRecord) => Promise<void>;
89
+ }): ToolOperationLedger;
90
+ //#endregion
91
+ //#region src/application/delegation/tool-authority.d.ts
92
+ interface InvocationAuthorityRef {
93
+ readonly id: string;
94
+ }
95
+ interface InvocationAuthority {
96
+ readonly agentId: string;
97
+ readonly instanceId: string;
98
+ readonly memory?: AgentMemoryAuthority;
99
+ readonly runId: string;
100
+ readonly sessionKey: string;
101
+ readonly sourceMessageId: string;
102
+ readonly tenantKey: string;
103
+ readonly toolGrantSet: RivusToolGrantSet;
104
+ }
105
+ declare class InvalidInvocationAuthority extends Error {
106
+ readonly name = "InvalidInvocationAuthority";
107
+ }
108
+ declare function createInvocationAuthority(authority: InvocationAuthority): InvocationAuthorityRef;
109
+ //#endregion
110
+ //#region src/application/delegation/tool-broker.d.ts
111
+ interface AuthorizationPolicyState {
112
+ readonly epoch: number;
113
+ readonly revokedToolIds: ReadonlyArray<string>;
114
+ }
115
+ interface AuthorizationPolicyProvider {
116
+ current(): Promise<AuthorizationPolicyState>;
117
+ }
118
+ interface ToolApprovalRequest {
119
+ readonly approvalId: string;
120
+ readonly agentId: string;
121
+ readonly instanceId: string;
122
+ readonly inputDigest: string;
123
+ readonly operationId: string;
124
+ readonly runId: string;
125
+ readonly sessionKey: string;
126
+ readonly tenantKey: string;
127
+ readonly callId: string;
128
+ readonly toolId: string;
129
+ readonly toolVersion: string;
130
+ readonly risk: RivusToolRisk;
131
+ }
132
+ interface ToolApprovalService {
133
+ consume(request: ToolApprovalRequest): Promise<boolean>;
134
+ }
135
+ interface ToolBrokerOptions {
136
+ readonly approvals: ToolApprovalService;
137
+ readonly catalog: RivusPluginCatalog;
138
+ readonly hostTools?: ReadonlyArray<RivusHostToolDescriptor>;
139
+ readonly policy: AuthorizationPolicyProvider;
140
+ readonly operations?: ToolOperationLedger;
141
+ }
142
+ interface ToolExecutionRequest {
143
+ readonly authority: InvocationAuthorityRef;
144
+ readonly callId: string;
145
+ readonly toolId: string;
146
+ readonly version: string;
147
+ readonly input: unknown;
148
+ readonly operationId?: string;
149
+ readonly approvalId?: string;
150
+ }
151
+ interface ToolBroker {
152
+ execute(request: ToolExecutionRequest): Promise<unknown>;
153
+ }
154
+ declare class ToolInvocationDenied extends Error {
155
+ readonly name = "ToolInvocationDenied";
156
+ }
157
+ declare function createToolBroker(options: ToolBrokerOptions): ToolBroker;
158
+ //#endregion
159
+ //#region src/infrastructure/pi/pi-tool-proxy.d.ts
160
+ interface PiToolApprovalRequest {
161
+ readonly agentId: string;
162
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
163
+ readonly approvalId: string;
164
+ readonly callId: string;
165
+ readonly endpointId: string;
166
+ readonly inputDigest: string;
167
+ readonly instanceId: string;
168
+ readonly operationId: string;
169
+ readonly risk: RivusToolRisk;
170
+ readonly runId: string;
171
+ readonly sessionKey: string;
172
+ readonly signal?: AbortSignal;
173
+ readonly sourceMessageId: string;
174
+ readonly tenantKey: string;
175
+ readonly toolId: string;
176
+ readonly toolVersion: string;
177
+ }
178
+ interface PiToolApprovalGateway {
179
+ requestApproval(request: PiToolApprovalRequest): Promise<void>;
180
+ }
181
+ interface PiToolProxyOptions {
182
+ readonly agentId: string;
183
+ readonly approvals: PiToolApprovalGateway;
184
+ readonly broker: ToolBroker;
185
+ readonly getActiveInput: () => AgentLoopInput | undefined;
186
+ readonly instanceId: string;
187
+ readonly memoryScopes?: ReadonlyArray<MemoryScope>;
188
+ readonly toolGrantSet: RivusToolGrantSet;
189
+ readonly tools: ReadonlyArray<RivusResolvedToolDescriptor>;
190
+ }
191
+ declare function createPiToolProxyDefinitions(options: PiToolProxyOptions): ToolDefinition[];
192
+ declare function createPiToolNameResolver(tools: ReadonlyArray<Pick<RivusResolvedToolDescriptor, "id">>): (toolName: string) => string;
193
+ //#endregion
194
+ export { createRecoveryAction as A, ToolOperationReconciliation as C, createToolOperationLedger as D, ToolOperationState as E, InvalidRecoveryAction as O, ToolOperationLedger as S, ToolOperationRecord as T, InvocationAuthorityRef as _, createPiToolProxyDefinitions as a, ToolOperationBinding as b, ToolApprovalRequest as c, ToolBrokerOptions as d, ToolExecutionRequest as f, InvocationAuthority as g, InvalidInvocationAuthority as h, createPiToolNameResolver as i, RecoveryAction as k, ToolApprovalService as l, createToolBroker as m, PiToolApprovalRequest as n, AuthorizationPolicyProvider as o, ToolInvocationDenied as p, PiToolProxyOptions as r, AuthorizationPolicyState as s, PiToolApprovalGateway as t, ToolBroker as u, createInvocationAuthority as v, ToolOperationReconciliationOutcome as w, ToolOperationInspectResult as x, ToolOperationBeginResult as y };
package/dist/pi.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { a as createPiToolProxyDefinitions, i as createPiToolNameResolver, n as PiToolApprovalRequest, r as PiToolProxyOptions, t as PiToolApprovalGateway } from "./pi-tool-proxy.js";
2
+ import { o as RegisteredRivusSkill } from "./rivus-plugin.js";
1
3
  import { ToolDefinition } from "@earendil-works/pi-coding-agent";
2
4
 
3
5
  //#region src/infrastructure/pi/pi-project-skill-read-tool.d.ts
@@ -9,4 +11,11 @@ declare function createPiProjectSkillReadTool(options: {
9
11
  readonly skillPaths: ReadonlyArray<string>;
10
12
  }): ToolDefinition;
11
13
  //#endregion
12
- export { ProjectSkillReadDenied, createPiProjectSkillReadTool };
14
+ //#region src/infrastructure/pi/pi-skill-tool.d.ts
15
+ interface PiSkillRuntime {
16
+ readonly prompt: string;
17
+ readonly tool?: ToolDefinition;
18
+ }
19
+ declare function createPiSkillRuntime(skills: ReadonlyArray<RegisteredRivusSkill>): PiSkillRuntime;
20
+ //#endregion
21
+ export { type PiSkillRuntime, type PiToolApprovalGateway, type PiToolApprovalRequest, type PiToolProxyOptions, ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };
package/dist/pi.js CHANGED
@@ -1,5 +1,9 @@
1
+ import { d as requiresToolApproval } from "./agent-memory.js";
2
+ import { l as createPiSkillRuntime, o as createInvocationAuthority, r as createToolInputDigest } from "./tool-input-digest.js";
3
+ import { createHash } from "node:crypto";
1
4
  import { isAbsolute, relative } from "node:path";
2
5
  import { readFile, realpath, stat } from "node:fs/promises";
6
+ import { Unsafe } from "typebox";
3
7
  import { createReadToolDefinition } from "@earendil-works/pi-coding-agent";
4
8
  //#region src/infrastructure/pi/pi-project-skill-read-tool.ts
5
9
  var ProjectSkillReadDenied = class extends Error {
@@ -30,4 +34,110 @@ async function authorize(path, sources) {
30
34
  throw new ProjectSkillReadDenied("read is restricted to the bound Project Skill sources");
31
35
  }
32
36
  //#endregion
33
- export { ProjectSkillReadDenied, createPiProjectSkillReadTool };
37
+ //#region src/infrastructure/pi/pi-tool-proxy.ts
38
+ function createPiToolProxyDefinitions(options) {
39
+ const names = /* @__PURE__ */ new Set();
40
+ return options.tools.map((tool) => {
41
+ const name = toPiToolName(tool.id);
42
+ if (names.has(name)) throw new Error(`Pi tool name collision: ${name}`);
43
+ names.add(name);
44
+ return {
45
+ description: tool.description,
46
+ execute: async (callId, input, signal) => {
47
+ const activeInput = options.getActiveInput();
48
+ const invocation = activeInput?.invocation;
49
+ if (!activeInput || !invocation) throw new Error(`tool ${tool.id} requires an active agent run with a trusted invocation`);
50
+ if (!invocation.tenantKey) throw new Error(`tool ${tool.id} requires a trusted tenant identity`);
51
+ throwIfAborted(signal ?? activeInput.abortSignal);
52
+ const inputDigest = createToolInputDigest(input);
53
+ const operationId = createBoundId("operation", {
54
+ agentId: options.agentId,
55
+ inputDigest,
56
+ instanceId: options.instanceId,
57
+ sourceMessageId: invocation.sourceMessageId,
58
+ toolId: tool.id,
59
+ toolVersion: tool.version
60
+ });
61
+ const approvalId = createBoundId("approval", {
62
+ callId,
63
+ operationId,
64
+ runId: activeInput.runId
65
+ });
66
+ if (requiresToolApproval(tool.risk)) {
67
+ if (invocation.allowedActorOpenIds.length === 0) throw new Error(`tool ${tool.id} requires at least one trusted approval actor`);
68
+ await options.approvals.requestApproval({
69
+ agentId: options.agentId,
70
+ allowedActorOpenIds: invocation.allowedActorOpenIds,
71
+ approvalId,
72
+ callId,
73
+ endpointId: invocation.endpointId,
74
+ inputDigest,
75
+ instanceId: options.instanceId,
76
+ operationId,
77
+ risk: tool.risk,
78
+ runId: activeInput.runId,
79
+ sessionKey: activeInput.sessionKey,
80
+ signal: signal ?? activeInput.abortSignal,
81
+ sourceMessageId: invocation.sourceMessageId,
82
+ tenantKey: invocation.tenantKey,
83
+ toolId: tool.id,
84
+ toolVersion: tool.version
85
+ });
86
+ throwIfAborted(signal ?? activeInput.abortSignal);
87
+ }
88
+ const result = await options.broker.execute({
89
+ authority: createInvocationAuthority({
90
+ agentId: options.agentId,
91
+ instanceId: options.instanceId,
92
+ ...invocation.memory ? { memory: {
93
+ ...invocation.memory,
94
+ scopes: options.memoryScopes ?? []
95
+ } } : {},
96
+ runId: activeInput.runId,
97
+ sessionKey: activeInput.sessionKey,
98
+ sourceMessageId: invocation.sourceMessageId,
99
+ tenantKey: invocation.tenantKey,
100
+ toolGrantSet: options.toolGrantSet
101
+ }),
102
+ callId,
103
+ input,
104
+ operationId,
105
+ ...requiresToolApproval(tool.risk) ? { approvalId } : {},
106
+ toolId: tool.id,
107
+ version: tool.version
108
+ });
109
+ return {
110
+ content: [{
111
+ text: stringifyToolResult(result),
112
+ type: "text"
113
+ }],
114
+ details: result
115
+ };
116
+ },
117
+ executionMode: "sequential",
118
+ label: tool.id,
119
+ name,
120
+ parameters: Unsafe(tool.inputSchema),
121
+ promptSnippet: `${name}: ${tool.description}`
122
+ };
123
+ });
124
+ }
125
+ function createPiToolNameResolver(tools) {
126
+ const toolIdsByPiName = new Map(tools.map((tool) => [toPiToolName(tool.id), tool.id]));
127
+ return (toolName) => toolIdsByPiName.get(toolName) ?? toolName;
128
+ }
129
+ function toPiToolName(toolId) {
130
+ return `rivus_${toolId.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
131
+ }
132
+ function createBoundId(kind, binding) {
133
+ return `${kind}:${createHash("sha256").update(JSON.stringify(binding)).digest("hex")}`;
134
+ }
135
+ function throwIfAborted(signal) {
136
+ if (signal.aborted) throw signal.reason ?? /* @__PURE__ */ new Error("tool execution was aborted");
137
+ }
138
+ function stringifyToolResult(result) {
139
+ if (typeof result === "string") return result;
140
+ return JSON.stringify(result ?? null);
141
+ }
142
+ //#endregion
143
+ export { ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };
@@ -1,4 +1,5 @@
1
- import { i as MEMORY_SCOPES, n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
1
+ import { t as MEMORY_SCOPES } from "./agent-memory.js";
2
+ import { n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
2
3
  import { createRequire } from "node:module";
3
4
  import { Effect } from "effect";
4
5
  import { createHash, randomUUID } from "node:crypto";
@@ -432,6 +433,7 @@ function createFeishuCardRollover(options) {
432
433
  const leaseMs = options.leaseMs ?? 51e4;
433
434
  if (!Number.isSafeInteger(leaseMs) || leaseMs < 1) throw new Error("Feishu card stream lease must be a positive integer");
434
435
  const counters = createCounters();
436
+ const latestTextByRun = /* @__PURE__ */ new Map();
435
437
  const liveRuns = /* @__PURE__ */ new Map();
436
438
  const semaphore = Effect.unsafeMakeSemaphore(1);
437
439
  const exclusive = (effect) => semaphore.withPermits(1)(effect);
@@ -447,7 +449,7 @@ function createFeishuCardRollover(options) {
447
449
  const presentationId = (runId, generation) => `${runId}#${generation}`;
448
450
  const publishProgress = (action) => Effect.suspend(() => {
449
451
  const chain = options.store.chain(action.runId);
450
- if (chain && acceptsCardPresentationProgress(chain)) return options.publisher.publish(action);
452
+ if (chain && acceptsCardPresentationProgress(chain)) return options.publisher.publish(action).pipe(Effect.tap(() => Effect.sync(() => latestTextByRun.set(action.runId, action.text))));
451
453
  return recordNow({
452
454
  ...chain ? {
453
455
  generation: chain.activeGeneration,
@@ -457,20 +459,28 @@ function createFeishuCardRollover(options) {
457
459
  type: "stale_update_dropped"
458
460
  });
459
461
  });
460
- const publishTerminal = (action) => options.publisher.publish(action).pipe(Effect.tapError((error) => recordNow({
461
- error,
462
- runId: action.runId,
463
- type: "terminal_delivery_failed"
464
- })), Effect.tap(() => options.store.markTerminal({
465
- runId: action.runId,
466
- terminalReceiptId: `${action.runId}:${action.type}`
467
- }).pipe(Effect.catchAll((error) => recordNow({
468
- error,
469
- runId: action.runId,
470
- type: "presentation_write_failed"
471
- })))), Effect.ensuring(Effect.sync(() => {
472
- liveRuns.delete(action.runId);
473
- })));
462
+ const publishTerminal = (action) => {
463
+ const latestText = latestTextByRun.get(action.runId);
464
+ const resolvedAction = action.type === "cancel" && action.text === void 0 && latestText !== void 0 ? {
465
+ ...action,
466
+ text: latestText
467
+ } : action;
468
+ return options.publisher.publish(resolvedAction).pipe(Effect.tapError((error) => recordNow({
469
+ error,
470
+ runId: action.runId,
471
+ type: "terminal_delivery_failed"
472
+ })), Effect.tap(() => options.store.markTerminal({
473
+ runId: action.runId,
474
+ terminalReceiptId: `${action.runId}:${action.type}`
475
+ }).pipe(Effect.catchAll((error) => recordNow({
476
+ error,
477
+ runId: action.runId,
478
+ type: "presentation_write_failed"
479
+ })))), Effect.ensuring(Effect.sync(() => {
480
+ latestTextByRun.delete(action.runId);
481
+ liveRuns.delete(action.runId);
482
+ })));
483
+ };
474
484
  const publishAction = (action) => {
475
485
  switch (action.type) {
476
486
  case "update_text": return publishProgress(action);
@@ -504,6 +514,7 @@ function createFeishuCardRollover(options) {
504
514
  };
505
515
  const predecessor = start.presentation;
506
516
  const generation = predecessor.generation + 1;
517
+ const text = latestTextByRun.get(runId);
507
518
  record({
508
519
  cardId: predecessor.cardId,
509
520
  generation,
@@ -516,7 +527,8 @@ function createFeishuCardRollover(options) {
516
527
  const created = yield* options.createSuccessor({
517
528
  generation,
518
529
  presentationId: successorId,
519
- run
530
+ run,
531
+ ...text === void 0 ? {} : { text }
520
532
  }).pipe(Effect.map((target) => ({ target })), Effect.catchAll((error) => options.store.failHandoff({
521
533
  failedAt: startedAt.toISOString(),
522
534
  runId
@@ -538,6 +550,7 @@ function createFeishuCardRollover(options) {
538
550
  };
539
551
  yield* options.publisher.publish({
540
552
  runId,
553
+ ...text === void 0 ? {} : { text },
541
554
  type: "handoff"
542
555
  }).pipe(Effect.catchAll((error) => recordNow({
543
556
  cardId: predecessor.cardId,
@@ -583,6 +596,7 @@ function createFeishuCardRollover(options) {
583
596
  runId: run.runId,
584
597
  sourceMessageId: run.messageId
585
598
  });
599
+ latestTextByRun.delete(run.runId);
586
600
  liveRuns.set(run.runId, run);
587
601
  return presentation;
588
602
  })),
@@ -603,6 +617,10 @@ function createFeishuCardRollover(options) {
603
617
  });
604
618
  },
605
619
  publish: (action) => exclusive(publishAction(action)),
620
+ releaseRun: (runId) => Effect.sync(() => {
621
+ latestTextByRun.delete(runId);
622
+ liveRuns.delete(runId);
623
+ }),
606
624
  recover: () => exclusive(Effect.gen(function* () {
607
625
  const compensatedAt = yield* options.clock.now;
608
626
  const compensated = yield* options.store.compensateInterruptedHandoffs(compensatedAt.toISOString());
@@ -1,117 +1,5 @@
1
+ import { c as InvalidRivusPlugin, o as createRivusMemoryToolContract, r as RIVUS_MEMORY_TOOL_PLUGIN_ID, t as MEMORY_SCOPES } from "./agent-memory.js";
1
2
  import { createHash } from "node:crypto";
2
- //#region src/domain/rivus-plugin.ts
3
- const RIVUS_PLUGIN_API_VERSION = "1";
4
- function requiresToolApproval(risk) {
5
- return risk === "irreversible" || risk === "host-control";
6
- }
7
- var RivusToolInputRejected = class extends Error {
8
- name = "RivusToolInputRejected";
9
- };
10
- var InvalidRivusPlugin = class extends Error {
11
- name = "InvalidRivusPlugin";
12
- };
13
- //#endregion
14
- //#region src/domain/agent-memory.ts
15
- const MEMORY_SCOPES = [
16
- "conversation",
17
- "agent-private",
18
- "project",
19
- "shared-user-profile"
20
- ];
21
- const RIVUS_MEMORY_TOOL_ID = "memory";
22
- const RIVUS_MEMORY_TOOL_PLUGIN_ID = "rivus-core";
23
- const RIVUS_MEMORY_TOOL_VERSION = "1.0.0";
24
- function createMemoryNamespace(binding) {
25
- const encode = (value) => encodeURIComponent(value);
26
- switch (binding.scope) {
27
- case "conversation": return [
28
- binding.tenantId,
29
- binding.agentId,
30
- binding.subjectId,
31
- binding.conversationId ?? "",
32
- binding.scope
33
- ].map(encode).join("/");
34
- case "agent-private": return [
35
- binding.tenantId,
36
- binding.agentId,
37
- binding.subjectId,
38
- binding.scope
39
- ].map(encode).join("/");
40
- case "project": return [
41
- binding.tenantId,
42
- binding.agentId,
43
- binding.projectId ?? "",
44
- binding.scope
45
- ].map(encode).join("/");
46
- case "shared-user-profile": return [
47
- binding.tenantId,
48
- binding.subjectId,
49
- binding.scope
50
- ].map(encode).join("/");
51
- }
52
- }
53
- function restrictMemoryScopesForAudience(scopes, audience) {
54
- return audience === "group" ? scopes.filter((scope) => scope === "conversation" || scope === "project") : [...scopes];
55
- }
56
- function createRivusMemoryToolContract(scopes) {
57
- return Object.freeze({
58
- description: "Search and read Memory inside Host-bound scopes; propose or request forgetting only in writable private scopes.",
59
- digest: "sha256:rivus-memory-v3",
60
- id: RIVUS_MEMORY_TOOL_ID,
61
- idempotency: "required",
62
- inputSchema: Object.freeze({
63
- additionalProperties: false,
64
- properties: {
65
- command: {
66
- description: "One of search, read, propose, or forget_request.",
67
- enum: [
68
- "search",
69
- "read",
70
- "propose",
71
- "forget_request"
72
- ],
73
- type: "string"
74
- },
75
- id: {
76
- description: "Required for read and forget_request.",
77
- minLength: 1,
78
- type: "string"
79
- },
80
- input: {
81
- additionalProperties: false,
82
- description: "Required for propose.",
83
- properties: { content: {
84
- minLength: 1,
85
- type: "string"
86
- } },
87
- required: ["content"],
88
- type: "object"
89
- },
90
- query: {
91
- additionalProperties: false,
92
- description: "Required for search.",
93
- properties: { query: { type: "string" } },
94
- required: ["query"],
95
- type: "object"
96
- },
97
- reason: {
98
- description: "Optional reason for forget_request.",
99
- type: "string"
100
- },
101
- ...scopes.length === 0 ? {} : { scope: {
102
- description: "Optional Host-granted scope for search or propose. Confirmed Project and Shared User Profile Memory are read-only to the model.",
103
- enum: [...scopes],
104
- type: "string"
105
- } }
106
- },
107
- required: ["command"],
108
- type: "object"
109
- }),
110
- risk: "mutate",
111
- version: RIVUS_MEMORY_TOOL_VERSION
112
- });
113
- }
114
- //#endregion
115
3
  //#region src/application/plugin/deep-freeze.ts
116
4
  function deepFreeze(value) {
117
5
  if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
@@ -321,4 +209,4 @@ function stableJson(value) {
321
209
  return JSON.stringify(value);
322
210
  }
323
211
  //#endregion
324
- export { RIVUS_MEMORY_TOOL_ID as a, createMemoryNamespace as c, InvalidRivusPlugin as d, RIVUS_PLUGIN_API_VERSION as f, MEMORY_SCOPES as i, createRivusMemoryToolContract as l, requiresToolApproval as m, resolveRivusAgentDefinition as n, RIVUS_MEMORY_TOOL_PLUGIN_ID as o, RivusToolInputRejected as p, deepFreeze as r, RIVUS_MEMORY_TOOL_VERSION as s, createRivusPluginCatalog as t, restrictMemoryScopesForAudience as u };
212
+ export { resolveRivusAgentDefinition as n, deepFreeze as r, createRivusPluginCatalog as t };