@rivus/agent 0.13.2 → 0.14.1

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.
Files changed (46) hide show
  1. package/README.md +17 -18
  2. package/dist/acp.d.ts +40 -40
  3. package/dist/acp.js +71 -31
  4. package/dist/bootstrap/pi-feishu.d.ts +20 -0
  5. package/dist/bootstrap/pi-feishu.js +596 -0
  6. package/dist/{agent-loop.d.ts → chunks/agent-loop.d.ts} +293 -44
  7. package/dist/chunks/agent-loop.js +1272 -0
  8. package/dist/chunks/api.d.ts +70 -0
  9. package/dist/chunks/api.js +471 -0
  10. package/dist/{rivus-plugin.d.ts → chunks/api2.d.ts} +271 -120
  11. package/dist/chunks/api2.js +1331 -0
  12. package/dist/chunks/api3.d.ts +402 -0
  13. package/dist/chunks/index.d.ts +3662 -0
  14. package/dist/chunks/module.js +267 -0
  15. package/dist/chunks/pi-skill-tool.js +460 -0
  16. package/dist/chunks/pi-tool-proxy.d.ts +188 -0
  17. package/dist/chunks/pi.js +329 -0
  18. package/dist/{rivus-daemon-cli.js → chunks/rivus-daemon-cli.js} +2197 -1526
  19. package/dist/{rivus-plugin-testkit.d.ts → chunks/rivus-plugin-testkit.d.ts} +1 -1
  20. package/dist/{rivus-plugin-testkit.js → chunks/rivus-plugin-testkit.js} +11 -3
  21. package/dist/chunks/sha256-digest.js +12 -0
  22. package/dist/chunks/spi.d.ts +1 -0
  23. package/dist/chunks/spi.js +2 -0
  24. package/dist/chunks/src.js +9897 -0
  25. package/dist/cli.js +604 -95
  26. package/dist/index.d.ts +8 -3645
  27. package/dist/index.js +9 -10483
  28. package/dist/mcp.d.ts +3 -38
  29. package/dist/mcp.js +4 -114
  30. package/dist/pi.d.ts +95 -9
  31. package/dist/pi.js +3 -146
  32. package/dist/testing/index.d.ts +1 -1
  33. package/dist/testing/index.js +1 -1
  34. package/examples/pi-feishu-deployment.bootstrap.ts +45 -54
  35. package/examples/pi-feishu.bootstrap.ts +53 -37
  36. package/examples/rivus-starter.plugin.mjs +3 -1
  37. package/package.json +12 -14
  38. package/dist/agent-loop.js +0 -121
  39. package/dist/agent-memory.d.ts +0 -100
  40. package/dist/agent-memory.js +0 -114
  41. package/dist/background-session-authority.js +0 -224
  42. package/dist/background-session-input.js +0 -45
  43. package/dist/background-session-service.d.ts +0 -291
  44. package/dist/pi-tool-proxy.d.ts +0 -197
  45. package/dist/rivus-plugin-registry.js +0 -215
  46. package/dist/tool-input-digest.js +0 -128
@@ -0,0 +1,70 @@
1
+ import { Effect } from "effect";
2
+
3
+ //#region src/modules/memory/application/compaction/compaction-service.d.ts
4
+ interface CompactionInput {
5
+ readonly tenantId: string;
6
+ readonly agentId: string;
7
+ readonly instanceId: string;
8
+ readonly conversationId: string;
9
+ readonly profileRevision: string;
10
+ readonly watermark: number;
11
+ readonly transcript: ReadonlyArray<string>;
12
+ }
13
+ interface CompactionSnapshot extends Omit<CompactionInput, "transcript"> {
14
+ readonly id: string;
15
+ readonly summary: string;
16
+ }
17
+ declare class CompactionError extends Error {
18
+ readonly name = "CompactionError";
19
+ }
20
+ //#endregion
21
+ //#region src/modules/memory/domain/scope/memory-scope.d.ts
22
+ declare const MEMORY_SCOPES: readonly ["conversation", "agent-private", "project", "shared-user-profile"];
23
+ type MemoryScope = (typeof MEMORY_SCOPES)[number];
24
+ type MemoryInvocationAudience = "group" | "private";
25
+ interface AgentMemoryIdentity {
26
+ readonly audience: MemoryInvocationAudience;
27
+ readonly conversationId?: string;
28
+ readonly projectId?: string;
29
+ readonly subjectId: string;
30
+ readonly tenantId: string;
31
+ }
32
+ interface AgentMemoryAuthority extends AgentMemoryIdentity {
33
+ readonly scopes: ReadonlyArray<MemoryScope>;
34
+ }
35
+ interface MemoryBinding {
36
+ readonly agentId: string;
37
+ readonly conversationId?: string;
38
+ readonly projectId?: string;
39
+ readonly scope: MemoryScope;
40
+ readonly subjectId: string;
41
+ readonly tenantId: string;
42
+ }
43
+ declare function createMemoryNamespace(binding: MemoryBinding): string;
44
+ declare function restrictMemoryScopesForAudience(scopes: ReadonlyArray<MemoryScope>, audience: MemoryInvocationAudience): ReadonlyArray<MemoryScope>;
45
+ //#endregion
46
+ //#region src/modules/memory/domain/record/memory-record.d.ts
47
+ type MemoryState = "proposed" | "confirmed" | "superseded" | "tombstoned";
48
+ interface MemoryRecord {
49
+ readonly content: string;
50
+ readonly conversationSafe: boolean;
51
+ readonly id: string;
52
+ readonly revision: number;
53
+ readonly scope: MemoryScope;
54
+ readonly state: MemoryState;
55
+ readonly tombstoneReason?: string;
56
+ }
57
+ interface AgentMemorySnapshot {
58
+ readonly binding: MemoryBinding;
59
+ readonly record: MemoryRecord;
60
+ }
61
+ //#endregion
62
+ //#region src/modules/memory/application/storage/agent-memory-service.d.ts
63
+ interface MemorySearchQuery {
64
+ readonly query: string;
65
+ }
66
+ declare class AgentMemoryError extends Error {
67
+ readonly name = "AgentMemoryError";
68
+ }
69
+ //#endregion
70
+ export { MemoryState as a, MEMORY_SCOPES as c, MemoryScope as d, createMemoryNamespace as f, CompactionSnapshot as g, CompactionInput as h, MemoryRecord as i, MemoryBinding as l, CompactionError as m, MemorySearchQuery as n, AgentMemoryAuthority as o, restrictMemoryScopesForAudience as p, AgentMemorySnapshot as r, AgentMemoryIdentity as s, AgentMemoryError as t, MemoryInvocationAudience as u };
@@ -0,0 +1,471 @@
1
+ import { t as createSha256Digest } from "./sha256-digest.js";
2
+ import { Effect } from "effect";
3
+ //#region src/modules/memory/application/compaction/compaction-service.ts
4
+ var CompactionError = class extends Error {
5
+ name = "CompactionError";
6
+ };
7
+ function createEffectCompactionService(options) {
8
+ const candidates = /* @__PURE__ */ new Map();
9
+ const committed = /* @__PURE__ */ new Map();
10
+ const serial = Effect.unsafeMakeSemaphore(1);
11
+ return {
12
+ createCandidate: (input) => {
13
+ const safeInput = Object.freeze({
14
+ agentId: input.agentId,
15
+ conversationId: input.conversationId,
16
+ instanceId: input.instanceId,
17
+ profileRevision: input.profileRevision,
18
+ tenantId: input.tenantId,
19
+ transcript: Object.freeze([...input.transcript]),
20
+ watermark: input.watermark
21
+ });
22
+ return options.compactor.compact(safeInput).pipe(Effect.map((summary) => Object.freeze({
23
+ agentId: input.agentId,
24
+ conversationId: input.conversationId,
25
+ id: `compaction:${options.identity.next()}`,
26
+ instanceId: input.instanceId,
27
+ profileRevision: input.profileRevision,
28
+ summary,
29
+ tenantId: input.tenantId,
30
+ watermark: input.watermark
31
+ })), Effect.tap((candidate) => Effect.sync(() => candidates.set(candidate.id, candidate))));
32
+ },
33
+ commit: (candidateId) => serial.withPermits(1)(Effect.suspend(() => {
34
+ const candidate = candidates.get(candidateId);
35
+ if (!candidate) return Effect.fail(new CompactionError(`unknown compaction candidate: ${candidateId}`));
36
+ const key = `${candidate.instanceId}/${candidate.conversationId}`;
37
+ const current = committed.get(key);
38
+ if (current && current.watermark >= candidate.watermark) return Effect.fail(new CompactionError("compaction watermark conflict"));
39
+ return Effect.sync(() => {
40
+ committed.set(key, candidate);
41
+ candidates.delete(candidateId);
42
+ return candidate;
43
+ });
44
+ })),
45
+ current: (instanceId, conversationId) => committed.get(`${instanceId}/${conversationId}`)
46
+ };
47
+ }
48
+ //#endregion
49
+ //#region src/modules/memory/domain/record/memory-record.ts
50
+ var MemoryRecordError = class extends Error {
51
+ name = "MemoryRecordError";
52
+ };
53
+ function proposeMemory(scope, contentInput, id) {
54
+ const content = contentInput.trim();
55
+ if (!content) throw new MemoryRecordError("memory content must not be empty");
56
+ if (!id.trim()) throw new MemoryRecordError("memory id must not be empty");
57
+ return Object.freeze({
58
+ content,
59
+ conversationSafe: false,
60
+ id,
61
+ revision: 1,
62
+ scope,
63
+ state: "proposed"
64
+ });
65
+ }
66
+ function confirmMemory(current, input) {
67
+ requireRevision(current, input.expectedRevision);
68
+ if (current.state !== "proposed") throw new MemoryRecordError("only proposed memory can be confirmed");
69
+ return Object.freeze({
70
+ ...current,
71
+ conversationSafe: input.conversationSafe ?? false,
72
+ revision: current.revision + 1,
73
+ state: "confirmed"
74
+ });
75
+ }
76
+ function forgetMemory(current, input) {
77
+ requireRevision(current, input.expectedRevision);
78
+ if (current.state === "tombstoned") throw new MemoryRecordError(`memory is already forgotten: ${current.id}`);
79
+ const reason = input.reason?.trim();
80
+ return Object.freeze({
81
+ ...current,
82
+ revision: current.revision + 1,
83
+ state: "tombstoned",
84
+ ...reason ? { tombstoneReason: reason } : {}
85
+ });
86
+ }
87
+ function isVisibleMemory(record) {
88
+ if (record.state === "tombstoned" || record.state === "superseded") return false;
89
+ return record.scope !== "shared-user-profile" && record.scope !== "project" || record.state === "confirmed";
90
+ }
91
+ function isValidMemoryTransition(previous, next) {
92
+ if (!sameBinding(previous.binding, next.binding) || previous.record.id !== next.record.id || previous.record.content !== next.record.content || previous.record.scope !== next.record.scope || next.record.revision !== previous.record.revision + 1) return false;
93
+ switch (previous.record.state) {
94
+ case "proposed": return (next.record.state === "confirmed" || next.record.state === "tombstoned") && (!next.record.conversationSafe || next.record.state === "confirmed");
95
+ case "confirmed":
96
+ case "superseded": return next.record.state === "tombstoned" && next.record.conversationSafe === previous.record.conversationSafe;
97
+ case "tombstoned": return false;
98
+ }
99
+ }
100
+ function sameBinding(left, right) {
101
+ return left.agentId === right.agentId && left.conversationId === right.conversationId && left.projectId === right.projectId && left.scope === right.scope && left.subjectId === right.subjectId && left.tenantId === right.tenantId;
102
+ }
103
+ function requireRevision(current, expectedRevision) {
104
+ if (current.revision !== expectedRevision) throw new MemoryRecordError("memory revision conflict");
105
+ }
106
+ //#endregion
107
+ //#region src/modules/memory/domain/scope/memory-scope.ts
108
+ const MEMORY_SCOPES = [
109
+ "conversation",
110
+ "agent-private",
111
+ "project",
112
+ "shared-user-profile"
113
+ ];
114
+ var MemoryScopeError = class extends Error {
115
+ name = "MemoryScopeError";
116
+ };
117
+ function normalizeMemoryBinding(binding) {
118
+ const tenantId = binding.tenantId.trim();
119
+ const agentId = binding.agentId.trim();
120
+ const subjectId = binding.subjectId.trim();
121
+ if (!tenantId || !agentId || !subjectId || !MEMORY_SCOPES.includes(binding.scope)) throw new MemoryScopeError("Memory binding requires trusted tenant, Agent, subject, and scope");
122
+ const conversationId = binding.conversationId?.trim();
123
+ const projectId = binding.projectId?.trim();
124
+ if (binding.scope === "conversation" && !conversationId) throw new MemoryScopeError("Conversation Memory requires a trusted conversation identity");
125
+ if (binding.scope !== "conversation" && conversationId) throw new MemoryScopeError("Only Conversation Memory accepts a conversation identity");
126
+ if (binding.scope === "project" && !projectId) throw new MemoryScopeError("Project Memory requires a trusted Project Space identity");
127
+ if (binding.scope !== "project" && projectId) throw new MemoryScopeError("Only Project Memory accepts a Project Space identity");
128
+ return Object.freeze({
129
+ agentId,
130
+ ...conversationId ? { conversationId } : {},
131
+ ...projectId ? { projectId } : {},
132
+ scope: binding.scope,
133
+ subjectId,
134
+ tenantId
135
+ });
136
+ }
137
+ function createMemoryNamespace(binding) {
138
+ const encode = (value) => encodeURIComponent(value);
139
+ switch (binding.scope) {
140
+ case "conversation": return [
141
+ binding.tenantId,
142
+ binding.agentId,
143
+ binding.subjectId,
144
+ binding.conversationId ?? "",
145
+ binding.scope
146
+ ].map(encode).join("/");
147
+ case "agent-private": return [
148
+ binding.tenantId,
149
+ binding.agentId,
150
+ binding.subjectId,
151
+ binding.scope
152
+ ].map(encode).join("/");
153
+ case "project": return [
154
+ binding.tenantId,
155
+ binding.agentId,
156
+ binding.projectId ?? "",
157
+ binding.scope
158
+ ].map(encode).join("/");
159
+ case "shared-user-profile": return [
160
+ binding.tenantId,
161
+ binding.subjectId,
162
+ binding.scope
163
+ ].map(encode).join("/");
164
+ }
165
+ }
166
+ function restrictMemoryScopesForAudience(scopes, audience) {
167
+ return audience === "group" ? scopes.filter((scope) => scope === "conversation" || scope === "project") : [...scopes];
168
+ }
169
+ //#endregion
170
+ //#region src/modules/memory/application/storage/agent-memory-repository.ts
171
+ var AgentMemoryRepositoryConflict = class extends Error {
172
+ name = "AgentMemoryRepositoryConflict";
173
+ };
174
+ //#endregion
175
+ //#region src/modules/memory/application/storage/agent-memory-service.ts
176
+ var AgentMemoryError = class extends Error {
177
+ name = "AgentMemoryError";
178
+ };
179
+ function createMemoryService(options) {
180
+ return { bind: (bindingInput) => {
181
+ let binding;
182
+ try {
183
+ binding = normalizeMemoryBinding(bindingInput);
184
+ } catch (error) {
185
+ throw asAgentMemoryError(error);
186
+ }
187
+ const update = (id, transition) => Effect.gen(function* () {
188
+ const current = yield* options.repository.get(binding, id);
189
+ if (!current) return yield* Effect.fail(new AgentMemoryError(`memory not found: ${id}`));
190
+ const record = yield* Effect.try({
191
+ catch: asAgentMemoryError,
192
+ try: () => transition(current)
193
+ });
194
+ return yield* options.repository.save({
195
+ binding,
196
+ record
197
+ }).pipe(Effect.mapError(mapRepositoryConflict));
198
+ });
199
+ const handle = {
200
+ namespace: createMemoryNamespace(binding),
201
+ scope: binding.scope,
202
+ confirm: (input) => update(input.id, (current) => confirmMemory(current, {
203
+ expectedRevision: input.expectedRevision,
204
+ ...input.conversationSafe === void 0 ? {} : { conversationSafe: input.conversationSafe }
205
+ })),
206
+ forgetRequest: (input) => update(input.id, (current) => forgetMemory(current, {
207
+ expectedRevision: input.expectedRevision,
208
+ ...input.reason === void 0 ? {} : { reason: input.reason }
209
+ })),
210
+ inspect: (id) => options.repository.get(binding, id),
211
+ propose: (input) => Effect.gen(function* () {
212
+ const id = yield* Effect.try({
213
+ catch: (error) => error,
214
+ try: () => options.identity.next()
215
+ });
216
+ const record = yield* Effect.try({
217
+ catch: asAgentMemoryError,
218
+ try: () => proposeMemory(binding.scope, input.content, `memory:${id}`)
219
+ });
220
+ return yield* options.repository.save({
221
+ binding,
222
+ record
223
+ }).pipe(Effect.mapError(mapRepositoryConflict));
224
+ }),
225
+ read: (id) => options.repository.get(binding, id).pipe(Effect.map((record) => record && isVisibleMemory(record) ? record : void 0)),
226
+ search: ({ query }) => options.repository.list(binding).pipe(Effect.map((records) => {
227
+ const normalized = query.trim().toLowerCase();
228
+ return records.filter((record) => isVisibleMemory(record) && record.content.toLowerCase().includes(normalized));
229
+ }))
230
+ };
231
+ return Object.freeze(handle);
232
+ } };
233
+ }
234
+ function mapRepositoryConflict(error) {
235
+ return error instanceof AgentMemoryRepositoryConflict ? new AgentMemoryError("memory revision conflict") : error;
236
+ }
237
+ function asAgentMemoryError(error) {
238
+ if (error instanceof AgentMemoryError) return error;
239
+ if (error instanceof MemoryRecordError || error instanceof MemoryScopeError) return new AgentMemoryError(error.message);
240
+ return new AgentMemoryError(error instanceof Error ? error.message : String(error));
241
+ }
242
+ //#endregion
243
+ //#region src/modules/agent-catalog/domain/plugin/rivus-plugin.ts
244
+ const RIVUS_PLUGIN_API_VERSION = "1";
245
+ var InvalidRivusPlugin = class extends Error {
246
+ name = "InvalidRivusPlugin";
247
+ };
248
+ //#endregion
249
+ //#region src/modules/agent-catalog/domain/runtime-tool/rivus-runtime-tool.ts
250
+ const RIVUS_RUNTIME_TOOL_IDS = Object.freeze([
251
+ "read",
252
+ "bash",
253
+ "edit",
254
+ "write",
255
+ "grep",
256
+ "find",
257
+ "ls"
258
+ ]);
259
+ function isRivusRuntimeToolId(value) {
260
+ return RIVUS_RUNTIME_TOOL_IDS.includes(value);
261
+ }
262
+ //#endregion
263
+ //#region src/modules/agent-catalog/domain/tool/rivus-tool.ts
264
+ var RivusToolInputRejected = class extends Error {
265
+ name = "RivusToolInputRejected";
266
+ };
267
+ //#endregion
268
+ //#region src/modules/agent-catalog/domain/policy/rivus-catalog-policy.ts
269
+ function validateRivusPluginManifest(manifest) {
270
+ validateRivusCatalogIdentifier(manifest.id, "plugin");
271
+ if (manifest.apiVersion !== "1") throw new InvalidRivusPlugin(`unsupported plugin API version ${manifest.apiVersion}; expected 1`);
272
+ if (manifest.version.trim() === "") throw new InvalidRivusPlugin("plugin version must not be empty");
273
+ }
274
+ function validateRivusCatalogIdentifier(id, kind) {
275
+ if (!/^[a-z0-9][a-z0-9._/-]*$/.test(id) || id.includes("*") || id.includes("//")) throw new InvalidRivusPlugin(`invalid ${kind} id: ${id}`);
276
+ }
277
+ function uniqueRivusCatalogIds(ids, label) {
278
+ const result = /* @__PURE__ */ new Set();
279
+ for (const id of ids) {
280
+ if (id.includes("*")) throw new InvalidRivusPlugin(`${label} does not support wildcard id: ${id}`);
281
+ validateRivusCatalogIdentifier(id, label);
282
+ if (result.has(id)) throw new InvalidRivusPlugin(`duplicate id in ${label}: ${id}`);
283
+ result.add(id);
284
+ }
285
+ return [...result];
286
+ }
287
+ function validateRivusCatalogReferences(ids, available, owner, kind) {
288
+ for (const id of uniqueRivusCatalogIds(ids, `${owner} ${kind} references`)) if (!available.has(id)) throw new InvalidRivusPlugin(`${owner} references unknown ${kind}: ${id}`);
289
+ }
290
+ function validateRivusMemoryScopes(scopes, owner) {
291
+ const result = /* @__PURE__ */ new Set();
292
+ for (const scope of scopes) {
293
+ if (!MEMORY_SCOPES.includes(scope)) throw new InvalidRivusPlugin(`${owner} references unsupported Memory scope: ${String(scope)}`);
294
+ if (result.has(scope)) throw new InvalidRivusPlugin(`${owner} contains duplicate Memory scope: ${scope}`);
295
+ result.add(scope);
296
+ }
297
+ return [...result];
298
+ }
299
+ function uniqueRivusRuntimeToolIds(ids, owner) {
300
+ const result = /* @__PURE__ */ new Set();
301
+ for (const id of ids) {
302
+ if (typeof id === "string" && id.includes("*")) throw new InvalidRivusPlugin(`${owner} does not support wildcard Runtime Tool: ${id}`);
303
+ if (typeof id !== "string" || !isRivusRuntimeToolId(id)) throw new InvalidRivusPlugin(`${owner} references unknown Runtime Tool: ${String(id)}`);
304
+ if (result.has(id)) throw new InvalidRivusPlugin(`${owner} contains duplicate Runtime Tool: ${id}`);
305
+ result.add(id);
306
+ }
307
+ return [...result];
308
+ }
309
+ //#endregion
310
+ //#region src/platform/values/deep-freeze.ts
311
+ function deepFreeze(value) {
312
+ if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
313
+ Object.freeze(value);
314
+ for (const child of Object.values(value)) deepFreeze(child);
315
+ }
316
+ return value;
317
+ }
318
+ //#endregion
319
+ //#region src/modules/agent-catalog/application/catalog/rivus-plugin-catalog.ts
320
+ function createRivusPluginCatalog() {
321
+ const plugins = /* @__PURE__ */ new Map();
322
+ const profiles = /* @__PURE__ */ new Map();
323
+ const tools = /* @__PURE__ */ new Map();
324
+ const skills = /* @__PURE__ */ new Map();
325
+ const automations = /* @__PURE__ */ new Map();
326
+ return {
327
+ registerPlugin: (plugin) => {
328
+ validateRivusPluginManifest(plugin.manifest);
329
+ rejectDuplicate(plugins, plugin.manifest.id, "plugin");
330
+ const pendingProfiles = [];
331
+ const pendingTools = [];
332
+ const pendingSkills = [];
333
+ const pendingAutomations = [];
334
+ const pendingIds = /* @__PURE__ */ new Set();
335
+ const register = (kind, definition, catalog, destination, namespaced) => {
336
+ validateRivusCatalogIdentifier(definition.id, kind);
337
+ if (namespaced && !definition.id.startsWith(`${plugin.manifest.id}/`)) throw new InvalidRivusPlugin(`${kind} id ${definition.id} must use plugin namespace ${plugin.manifest.id}/`);
338
+ const key = `${kind}:${definition.id}`;
339
+ if (pendingIds.has(key) || catalog.has(definition.id)) throw new InvalidRivusPlugin(`duplicate ${kind} id: ${definition.id}`);
340
+ pendingIds.add(key);
341
+ destination.push(deepFreeze({
342
+ ...definition,
343
+ pluginId: plugin.manifest.id
344
+ }));
345
+ };
346
+ plugin.register({
347
+ registerAgentProfile: (profile) => register("profile", profile, profiles, pendingProfiles, false),
348
+ registerAutomation: (automation) => register("automation", automation, automations, pendingAutomations, true),
349
+ registerSkill: (skill) => register("skill", skill, skills, pendingSkills, true),
350
+ registerTool: (tool) => register("tool", tool, tools, pendingTools, true)
351
+ });
352
+ const availableToolIds = /* @__PURE__ */ new Set([...tools.keys(), ...pendingTools.map(({ id }) => id)]);
353
+ const availableSkillIds = /* @__PURE__ */ new Set([...skills.keys(), ...pendingSkills.map(({ id }) => id)]);
354
+ const availableProfileIds = /* @__PURE__ */ new Set([...profiles.keys(), ...pendingProfiles.map(({ id }) => id)]);
355
+ for (const profile of pendingProfiles) {
356
+ validateRivusMemoryScopes(profile.memory.scopes, `profile ${profile.id}`);
357
+ uniqueRivusRuntimeToolIds(profile.runtimeTools?.allow ?? [], `profile ${profile.id}`);
358
+ validateRivusCatalogReferences(profile.tools.allow, availableToolIds, `profile ${profile.id}`, "tool");
359
+ validateRivusCatalogReferences(profile.skills.allow, availableSkillIds, `profile ${profile.id}`, "skill");
360
+ }
361
+ for (const automation of pendingAutomations) {
362
+ if (!availableProfileIds.has(automation.profileId)) throw new InvalidRivusPlugin(`automation ${automation.id} references unknown profile: ${automation.profileId}`);
363
+ validateRivusCatalogReferences(automation.requestedToolIds, availableToolIds, `automation ${automation.id}`, "tool");
364
+ validateRivusCatalogReferences(automation.requestedSkillIds, availableSkillIds, `automation ${automation.id}`, "skill");
365
+ }
366
+ plugins.set(plugin.manifest.id, deepFreeze({ ...plugin.manifest }));
367
+ for (const profile of pendingProfiles) profiles.set(profile.id, profile);
368
+ for (const tool of pendingTools) tools.set(tool.id, tool);
369
+ for (const skill of pendingSkills) skills.set(skill.id, skill);
370
+ for (const automation of pendingAutomations) automations.set(automation.id, automation);
371
+ },
372
+ snapshot: () => deepFreeze({
373
+ automations: [...automations.values()],
374
+ plugins: [...plugins.values()],
375
+ profiles: [...profiles.values()],
376
+ skills: [...skills.values()],
377
+ tools: [...tools.values()]
378
+ })
379
+ };
380
+ }
381
+ function rejectDuplicate(map, id, kind) {
382
+ if (map.has(id)) throw new InvalidRivusPlugin(`duplicate ${kind} id: ${id}`);
383
+ }
384
+ //#endregion
385
+ //#region src/modules/agent-catalog/application/resolution/rivus-tool-grant-set.ts
386
+ function narrowRivusToolGrantSet(parent, restrictions) {
387
+ const toolIds = intersectToolIds([parent.toolIds, ...restrictions]);
388
+ return deepFreeze({
389
+ revision: createSha256Digest(JSON.stringify({
390
+ parentRevision: parent.revision,
391
+ toolIds
392
+ })),
393
+ toolIds
394
+ });
395
+ }
396
+ function intersectRivusToolIds(sets) {
397
+ const toolIds = intersectToolIds(sets);
398
+ return deepFreeze({
399
+ revision: createSha256Digest(JSON.stringify(toolIds)),
400
+ toolIds
401
+ });
402
+ }
403
+ function intersectToolIds(sets) {
404
+ const [first = [], ...rest] = sets;
405
+ return [...new Set(first)].filter((id) => rest.every((set) => set.includes(id))).sort();
406
+ }
407
+ //#endregion
408
+ //#region src/modules/agent-catalog/application/resolution/rivus-agent-grant-restriction.ts
409
+ function restrictRivusAgentDefinitionGrants(definition, restriction) {
410
+ const toolIds = uniqueIds(restriction.toolIds);
411
+ const skillIds = uniqueIds(restriction.skillIds);
412
+ const runtimeToolIds = uniqueRuntimeToolIds(restriction.runtimeToolIds);
413
+ const memoryScopes = uniqueScopes(restriction.memory.scopes);
414
+ const toolsById = new Map(definition.tools.map((tool) => [tool.id, tool]));
415
+ const skillsById = new Map(definition.skills.map((skill) => [skill.id, skill]));
416
+ const tools = toolIds.map((toolId) => {
417
+ const tool = toolsById.get(toolId);
418
+ if (!tool) throw new Error(`Agent grant restriction requests ungranted Tool: ${toolId}`);
419
+ return tool;
420
+ });
421
+ const skills = skillIds.map((skillId) => {
422
+ const skill = skillsById.get(skillId);
423
+ if (!skill) throw new Error(`Agent grant restriction requests ungranted Skill: ${skillId}`);
424
+ return skill;
425
+ });
426
+ for (const scope of memoryScopes) if (!definition.memory.scopes.includes(scope)) throw new Error(`Agent grant restriction requests ungranted Memory scope: ${scope}`);
427
+ for (const runtimeToolId of runtimeToolIds) if (!definition.runtimeToolGrantSet.toolIds.includes(runtimeToolId)) throw new Error(`Agent grant restriction requests ungranted Runtime Tool: ${runtimeToolId}`);
428
+ if (restriction.memory.tool && !definition.memory.tool) throw new Error("Agent grant restriction cannot enable an ungranted Memory Tool");
429
+ const skillGrantSet = deepFreeze({
430
+ revision: createSha256Digest(JSON.stringify({
431
+ parentRevision: definition.skillGrantSet.revision,
432
+ skillIds
433
+ })),
434
+ skillIds
435
+ });
436
+ const runtimeToolGrantSet = deepFreeze({
437
+ revision: createSha256Digest(JSON.stringify({
438
+ parentRevision: definition.runtimeToolGrantSet.revision,
439
+ toolIds: runtimeToolIds
440
+ })),
441
+ toolIds: runtimeToolIds
442
+ });
443
+ return deepFreeze({
444
+ ...definition,
445
+ memory: {
446
+ scopes: memoryScopes,
447
+ tool: restriction.memory.tool
448
+ },
449
+ runtimeToolGrantSet,
450
+ skillGrantSet,
451
+ skills,
452
+ toolGrantSet: narrowRivusToolGrantSet(definition.toolGrantSet, [toolIds]),
453
+ tools
454
+ });
455
+ }
456
+ function uniqueRuntimeToolIds(ids) {
457
+ const requested = /* @__PURE__ */ new Set();
458
+ for (const id of ids) {
459
+ if (!isRivusRuntimeToolId(id)) throw new Error(`Agent grant restriction requests unknown Runtime Tool: ${id}`);
460
+ requested.add(id);
461
+ }
462
+ return RIVUS_RUNTIME_TOOL_IDS.filter((id) => requested.has(id));
463
+ }
464
+ function uniqueIds(ids) {
465
+ return [...new Set(ids)].sort();
466
+ }
467
+ function uniqueScopes(scopes) {
468
+ return [...new Set(scopes)].sort();
469
+ }
470
+ //#endregion
471
+ export { createEffectCompactionService as C, CompactionError as S, AgentMemoryRepositoryConflict as _, deepFreeze as a, restrictMemoryScopesForAudience as b, validateRivusCatalogIdentifier as c, RIVUS_RUNTIME_TOOL_IDS as d, isRivusRuntimeToolId as f, createMemoryService as g, AgentMemoryError as h, createRivusPluginCatalog as i, validateRivusMemoryScopes as l, RIVUS_PLUGIN_API_VERSION as m, intersectRivusToolIds as n, uniqueRivusCatalogIds as o, InvalidRivusPlugin as p, narrowRivusToolGrantSet as r, uniqueRivusRuntimeToolIds as s, restrictRivusAgentDefinitionGrants as t, RivusToolInputRejected as u, MEMORY_SCOPES as v, isValidMemoryTransition as x, createMemoryNamespace as y };