@rivus/agent 0.14.2 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/acp.js +1 -2
- package/dist/bootstrap/pi-feishu.d.ts +1 -1
- package/dist/bootstrap/pi-feishu.js +4 -4
- package/dist/chunks/agent-loop.d.ts +55 -300
- package/dist/chunks/agent-loop.js +3 -1123
- package/dist/chunks/background-session-authority.js +230 -0
- package/dist/chunks/background-session-control-input.js +51 -0
- package/dist/chunks/background-session-service.d.ts +382 -0
- package/dist/chunks/index.d.ts +1201 -538
- package/dist/chunks/pi-tool-proxy.d.ts +22 -90
- package/dist/chunks/pi.js +5 -2
- package/dist/chunks/rivus-agent-definition-resolver.js +508 -0
- package/dist/chunks/rivus-daemon-cli.js +2776 -3244
- package/dist/chunks/rivus-plugin-testkit.d.ts +175 -2
- package/dist/chunks/rivus-plugin-testkit.js +11 -4
- package/dist/chunks/rivus-skill.d.ts +95 -0
- package/dist/chunks/sha256-digest.js +2 -7
- package/dist/chunks/src.js +11941 -7001
- package/dist/chunks/tool-input-digest.js +158 -0
- package/dist/cli.js +764 -712
- package/dist/index.d.ts +6 -7
- package/dist/index.js +7 -8
- package/dist/mcp.d.ts +48 -9
- package/dist/mcp.js +146 -20
- package/dist/pi.d.ts +3 -4
- package/dist/pi.js +1 -1
- package/package.json +5 -5
- package/dist/chunks/api.d.ts +0 -70
- package/dist/chunks/api.js +0 -471
- package/dist/chunks/api2.d.ts +0 -387
- package/dist/chunks/api2.js +0 -1331
- package/dist/chunks/api3.d.ts +0 -402
- package/dist/chunks/module.js +0 -267
- package/dist/chunks/pi-skill-tool.js +0 -460
- package/dist/chunks/spi.d.ts +0 -1
- package/dist/chunks/spi.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivus/agent",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.4",
|
|
4
4
|
"description": "A local agent daemon core built around a usable agent harness and domain events.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -75,23 +75,23 @@
|
|
|
75
75
|
"lint:fix": "vp lint --fix",
|
|
76
76
|
"package-api:update": "vp pack && node scripts/package-api-report.mjs --write",
|
|
77
77
|
"package:check": "node scripts/check-npm-package.mjs",
|
|
78
|
-
"prepublishOnly": "npm run check",
|
|
78
|
+
"prepublishOnly": "npm run check && npm run audit",
|
|
79
79
|
"release:check": "node scripts/check-npm-release.mjs",
|
|
80
80
|
"test": "vp test",
|
|
81
81
|
"test:feishu:offline": "node scripts/run-feishu-offline-tests.mjs",
|
|
82
82
|
"test:coverage": "vp test --coverage",
|
|
83
83
|
"test:watch": "vp test watch",
|
|
84
84
|
"typecheck": "vp check --no-fmt --no-lint",
|
|
85
|
-
"check": "vp check && vp test --coverage && vp run duplicates && vp pack && vp run package:check &&
|
|
85
|
+
"check": "vp check && vp test --coverage && vp run duplicates && vp pack && vp run package:check && ./scripts/check-repository.sh",
|
|
86
86
|
"duplicates": "jscpd src examples --min-lines 6 --min-tokens 40 --threshold 0 --reporters console --ignore '**/*.test.ts,**/*.test.mjs' --format 'typescript,javascript,json'",
|
|
87
87
|
"version-packages": "changeset version && npm install --package-lock-only --ignore-scripts",
|
|
88
|
-
"version-packages:ci": "npm run version-packages && npm run check"
|
|
88
|
+
"version-packages:ci": "npm run version-packages && npm run check && npm run audit"
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
91
|
"@earendil-works/pi-coding-agent": "0.84.4",
|
|
92
92
|
"@larksuiteoapi/node-sdk": "1.71.1",
|
|
93
93
|
"@opentelemetry/api": "^1.9.1",
|
|
94
|
-
"@opentelemetry/exporter-trace-otlp-proto": "^0.
|
|
94
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.221.0",
|
|
95
95
|
"@opentelemetry/resources": "^2.9.0",
|
|
96
96
|
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
|
97
97
|
"@opentelemetry/sdk-trace-node": "^2.9.0",
|
package/dist/chunks/api.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
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 };
|
package/dist/chunks/api.js
DELETED
|
@@ -1,471 +0,0 @@
|
|
|
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 };
|