@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
package/dist/mcp.d.ts CHANGED
@@ -1,42 +1,7 @@
1
- import { k as BackgroundSessionAuthority, r as BackgroundSessionService } from "./background-session-service.js";
1
+ import { _ as BackgroundSessionControlContext, b as createBackgroundSessionControl, g as BackgroundSessionControlCommand, h as BackgroundSessionControl, v as BackgroundSessionControlError, x as toControlContext, y as BackgroundSessionControlOrigin } from "./chunks/api3.js";
2
2
  import { Readable, Writable } from "node:stream";
3
3
 
4
- //#region src/application/background-session/background-session-control.d.ts
5
- type BackgroundSessionControlCommand = "start" | "wait" | "list" | "status" | "send" | "stop";
6
- interface BackgroundSessionControlOrigin {
7
- readonly allowedActorOpenIds: ReadonlyArray<string>;
8
- readonly conversationId?: string;
9
- readonly endpointId: string;
10
- readonly tenantKey: string;
11
- }
12
- interface BackgroundSessionControlContext {
13
- readonly agentId: string;
14
- readonly authority: BackgroundSessionAuthority;
15
- readonly origin: BackgroundSessionControlOrigin;
16
- readonly policyEpoch: number;
17
- readonly runId: string;
18
- readonly sessionKey: string;
19
- readonly sourceMessageId: string;
20
- }
21
- interface BackgroundSessionControl {
22
- handle(command: BackgroundSessionControlCommand, context: BackgroundSessionControlContext, input: unknown): Promise<unknown>;
23
- }
24
- declare function createBackgroundSessionControl(options: {
25
- readonly service: BackgroundSessionService;
26
- }): BackgroundSessionControl;
27
- declare class BackgroundSessionControlError extends Error {
28
- readonly name = "BackgroundSessionControlError";
29
- }
30
- declare function toControlContext(input: {
31
- readonly agentId: string;
32
- readonly authority: BackgroundSessionAuthority;
33
- readonly origin: BackgroundSessionControlOrigin;
34
- readonly policyEpoch: number;
35
- readonly sessionKey: string;
36
- readonly sourceMessageId?: string;
37
- }): BackgroundSessionControlContext;
38
- //#endregion
39
- //#region src/infrastructure/mcp/background-session-mcp-server.d.ts
4
+ //#region src/adapters/mcp/background-session-mcp-server.d.ts
40
5
  declare const BACKGROUND_SESSION_MCP_SERVER_NAME = "rivus-background-sessions";
41
6
  declare const BACKGROUND_SESSION_MCP_SERVER_VERSION = "1.0.0";
42
7
  interface BackgroundSessionMcpServerOptions {
@@ -64,7 +29,7 @@ interface RunBackgroundSessionMcpServerEnv {
64
29
  }
65
30
  declare function runBackgroundSessionMcpServer(options?: RunBackgroundSessionMcpServerEnv): Promise<void>;
66
31
  //#endregion
67
- //#region src/infrastructure/http/background-session-control-http-server.d.ts
32
+ //#region src/adapters/http/background-session-control-http-server.d.ts
68
33
  interface BackgroundSessionControlHttpServerOptions {
69
34
  readonly control: BackgroundSessionControl;
70
35
  readonly host?: string;
package/dist/mcp.js CHANGED
@@ -1,9 +1,8 @@
1
- import { l as createBackgroundSessionToolContracts, s as createBackgroundSessionKey } from "./background-session-authority.js";
2
- import { a as readBackgroundSessionWaitInput, i as readBackgroundSessionString, n as readBackgroundSessionObject, r as readBackgroundSessionPhase, t as readBackgroundSessionInteger } from "./background-session-input.js";
1
+ import { F as createBackgroundSessionControl, I as toControlContext, P as BackgroundSessionControlError, q as createBackgroundSessionToolContracts } from "./chunks/api2.js";
3
2
  import { randomUUID } from "node:crypto";
4
- import { pathToFileURL } from "node:url";
5
3
  import { createServer } from "node:http";
6
- //#region src/infrastructure/mcp/background-session-mcp-server.ts
4
+ import { pathToFileURL } from "node:url";
5
+ //#region src/adapters/mcp/background-session-mcp-server.ts
7
6
  const BACKGROUND_SESSION_MCP_SERVER_NAME = "rivus-background-sessions";
8
7
  const BACKGROUND_SESSION_MCP_SERVER_VERSION = "1.0.0";
9
8
  var BackgroundSessionMcpError = class extends Error {
@@ -202,116 +201,7 @@ function isRecord(value) {
202
201
  return value !== null && typeof value === "object" && !Array.isArray(value);
203
202
  }
204
203
  //#endregion
205
- //#region src/application/background-session/background-session-control.ts
206
- function createBackgroundSessionControl(options) {
207
- return { handle: async (command, context, input) => {
208
- const executionContext = {
209
- agentId: context.agentId,
210
- callId: `mcp-call:${randomUUID()}`,
211
- instanceId: `mcp:${context.agentId}`,
212
- policyEpoch: context.policyEpoch,
213
- runId: context.runId,
214
- sessionKey: context.sessionKey,
215
- sourceMessageId: context.sourceMessageId,
216
- toolId: `background.${command}`,
217
- toolVersion: "1.0.0",
218
- origin: toToolOrigin(context.origin)
219
- };
220
- switch (command) {
221
- case "start": {
222
- const { displayName, prompt } = readObject(input, ["displayName", "prompt"]);
223
- if (typeof prompt !== "string" || prompt.trim() === "") throw new BackgroundSessionControlError("background.start requires a non-empty prompt");
224
- const sessionId = `bg-${randomUUID()}`;
225
- return options.service.start({
226
- authority: {
227
- ...context.authority,
228
- sessionKey: createBackgroundSessionKey(sessionId)
229
- },
230
- context: executionContext,
231
- ...displayName === void 0 ? {} : { displayName: readString(displayName, "displayName") },
232
- prompt,
233
- sessionId
234
- });
235
- }
236
- case "wait": return options.service.wait({
237
- context: executionContext,
238
- ...readBackgroundSessionWaitInput(input, (message) => new BackgroundSessionControlError(message))
239
- });
240
- case "list": {
241
- const { limit, phase } = readObject(input, ["limit", "phase"]);
242
- return options.service.list({
243
- context: executionContext,
244
- ...limit === void 0 ? {} : { limit: readInteger(limit, "limit") },
245
- ...phase === void 0 ? {} : { phase: readPhase(phase) }
246
- });
247
- }
248
- case "status": {
249
- const { sessionId } = readObject(input, ["sessionId"]);
250
- return options.service.status({
251
- context: executionContext,
252
- sessionId: readString(sessionId, "sessionId")
253
- });
254
- }
255
- case "send": {
256
- const { message, sessionId } = readObject(input, ["message", "sessionId"]);
257
- return options.service.send({
258
- context: executionContext,
259
- message: readString(message, "message"),
260
- sessionId: readString(sessionId, "sessionId")
261
- });
262
- }
263
- case "stop": {
264
- const { reason, sessionId } = readObject(input, ["reason", "sessionId"]);
265
- return options.service.stop({
266
- context: executionContext,
267
- ...reason === void 0 ? {} : { reason: readString(reason, "reason") },
268
- sessionId: readString(sessionId, "sessionId")
269
- });
270
- }
271
- }
272
- } };
273
- }
274
- var BackgroundSessionControlError = class extends Error {
275
- name = "BackgroundSessionControlError";
276
- };
277
- function toControlContext(input) {
278
- return {
279
- agentId: input.agentId,
280
- authority: input.authority,
281
- origin: {
282
- allowedActorOpenIds: input.origin.allowedActorOpenIds,
283
- ...input.origin.conversationId === void 0 ? {} : { conversationId: input.origin.conversationId },
284
- endpointId: input.origin.endpointId,
285
- tenantKey: input.origin.tenantKey
286
- },
287
- policyEpoch: input.policyEpoch,
288
- runId: `mcp:${randomUUID()}`,
289
- sessionKey: input.sessionKey,
290
- sourceMessageId: input.sourceMessageId ?? `mcp:${randomUUID()}`
291
- };
292
- }
293
- function toToolOrigin(origin) {
294
- return {
295
- allowedActorOpenIds: origin.allowedActorOpenIds,
296
- endpointId: origin.endpointId,
297
- tenantKey: origin.tenantKey,
298
- ...origin.conversationId === void 0 ? {} : { conversationId: origin.conversationId }
299
- };
300
- }
301
- function readObject(input, allowed) {
302
- return readBackgroundSessionObject(input, allowed, (message) => new BackgroundSessionControlError(message));
303
- }
304
- function readString(value, name) {
305
- return readBackgroundSessionString(value, name, (message) => new BackgroundSessionControlError(message));
306
- }
307
- function readInteger(value, name) {
308
- return readBackgroundSessionInteger(value, name, (message) => new BackgroundSessionControlError(message));
309
- }
310
- function readPhase(value) {
311
- return readBackgroundSessionPhase(value, (message) => new BackgroundSessionControlError(message));
312
- }
313
- //#endregion
314
- //#region src/infrastructure/http/background-session-control-http-server.ts
204
+ //#region src/adapters/http/background-session-control-http-server.ts
315
205
  var BackgroundSessionControlHttpError = class extends Error {
316
206
  statusCode;
317
207
  name = "BackgroundSessionControlHttpError";
package/dist/pi.d.ts CHANGED
@@ -1,21 +1,107 @@
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";
3
- import { ToolDefinition } from "@earendil-works/pi-coding-agent";
1
+ import { a as AgentLoopInput } from "./chunks/agent-loop.js";
2
+ import { d as MemoryScope } from "./chunks/api.js";
3
+ import { Q as RivusResolvedToolDescriptor, ft as RivusRuntimeToolId, rt as RivusToolGrantSet, st as RegisteredRivusSkill } from "./chunks/api2.js";
4
+ import { a as PiToolResult, i as PiToolDefinition, n as PiToolApprovalRequest, r as PiToolContent, t as PiToolApprovalGateway, u as ToolExecutionRequest } from "./chunks/pi-tool-proxy.js";
4
5
 
5
- //#region src/infrastructure/pi/pi-project-skill-read-tool.d.ts
6
+ //#region src/adapters/pi/skills/pi-skill-read-tool.d.ts
6
7
  declare class ProjectSkillReadDenied extends Error {
7
8
  readonly name = "ProjectSkillReadDenied";
8
9
  }
9
- declare function createPiProjectSkillReadTool(options: {
10
+ declare function createPiSkillReadTool(options: {
10
11
  readonly cwd: string;
11
12
  readonly skillPaths: ReadonlyArray<string>;
12
- }): ToolDefinition;
13
+ }): PiToolDefinition;
14
+ declare const createPiProjectSkillReadTool: typeof createPiSkillReadTool;
15
+ declare function createPiSkillReadTools(options: {
16
+ readonly cwd: string;
17
+ readonly runtimeToolIds: ReadonlyArray<RivusRuntimeToolId>;
18
+ readonly skillPaths: ReadonlyArray<string>;
19
+ }): PiToolDefinition[];
13
20
  //#endregion
14
- //#region src/infrastructure/pi/pi-skill-tool.d.ts
21
+ //#region src/adapters/pi/skills/pi-skill-tool.d.ts
22
+ interface PiSkillReadDetails {
23
+ readonly contentLength: number;
24
+ readonly digest: string;
25
+ readonly skillId: string;
26
+ readonly title: string;
27
+ readonly version: string;
28
+ }
15
29
  interface PiSkillRuntime {
16
30
  readonly prompt: string;
17
- readonly tool?: ToolDefinition;
31
+ readonly tool?: PiToolDefinition<PiSkillReadDetails>;
18
32
  }
19
33
  declare function createPiSkillRuntime(skills: ReadonlyArray<RegisteredRivusSkill>): PiSkillRuntime;
20
34
  //#endregion
21
- export { type PiSkillRuntime, type PiToolApprovalGateway, type PiToolApprovalRequest, type PiToolProxyOptions, ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };
35
+ //#region src/adapters/pi/skills/pi-skill-catalog.d.ts
36
+ interface PiSkillCatalogEntry {
37
+ readonly name: string;
38
+ }
39
+ interface PiSkillCatalogDiagnostic {
40
+ readonly message: string;
41
+ readonly path?: string;
42
+ readonly type: "warning" | "error" | "collision";
43
+ }
44
+ declare class InvalidPiSkillCatalog extends Error {
45
+ readonly name = "InvalidPiSkillCatalog";
46
+ }
47
+ declare function validatePiSkillCatalog(input: {
48
+ readonly diagnostics: ReadonlyArray<PiSkillCatalogDiagnostic>;
49
+ readonly skills: ReadonlyArray<PiSkillCatalogEntry>;
50
+ }): ReadonlySet<string>;
51
+ declare function validatePiSkillCommand(text: string, skillNames: ReadonlySet<string>): void;
52
+ //#endregion
53
+ //#region src/adapters/pi/skills/pi-skill-sources.d.ts
54
+ declare class InvalidPiSkillSource extends Error {
55
+ readonly name = "InvalidPiSkillSource";
56
+ }
57
+ interface ResolvePiSkillSourcesOptions {
58
+ readonly agentDir: string;
59
+ readonly homeDirectory: string;
60
+ readonly projectSkillPaths?: ReadonlyArray<string>;
61
+ }
62
+ declare function resolvePiSkillSources(options: ResolvePiSkillSourcesOptions): Promise<ReadonlyArray<string>>;
63
+ //#endregion
64
+ //#region src/adapters/pi/tool-execution/pi-session-tools.d.ts
65
+ interface PiNamedTool {
66
+ readonly name: string;
67
+ }
68
+ declare function resolvePiSessionToolNames(runtimeToolIds: ReadonlyArray<RivusRuntimeToolId>, customTools: ReadonlyArray<PiNamedTool>): ReadonlyArray<string>;
69
+ //#endregion
70
+ //#region src/adapters/pi/runtime/pi-session-resources.d.ts
71
+ interface CreatePiSessionResourcesOptions {
72
+ readonly agentDir: string;
73
+ readonly appendSystemPromptOverride?: (base: string[]) => string[];
74
+ readonly cwd: string;
75
+ readonly homeDirectory: string;
76
+ readonly projectSkillPaths?: ReadonlyArray<string>;
77
+ readonly systemPromptOverride?: (base: string | undefined) => string | undefined;
78
+ }
79
+ interface PiSessionResources {
80
+ readonly skillNames: ReadonlySet<string>;
81
+ readonly skillPaths: ReadonlyArray<string>;
82
+ readonly withSessionOptions: <Options extends object>(options: Options) => BoundPiSessionOptions<Options>;
83
+ }
84
+ type BoundPiSessionOptions<Options extends object> = Omit<Options, "agentDir" | "cwd" | "resourceLoader" | "settingsManager"> & {
85
+ readonly agentDir: string;
86
+ readonly cwd: string;
87
+ };
88
+ declare function createPiSessionResources(options: CreatePiSessionResourcesOptions): Promise<PiSessionResources>;
89
+ //#endregion
90
+ //#region src/adapters/compatibility/agent-execution/pi/pi-tool-proxy.d.ts
91
+ interface ToolBroker {
92
+ execute(request: ToolExecutionRequest): Promise<unknown>;
93
+ }
94
+ interface PiToolProxyOptions {
95
+ readonly agentId: string;
96
+ readonly instanceId: string;
97
+ readonly tools: ReadonlyArray<RivusResolvedToolDescriptor>;
98
+ readonly toolGrantSet: RivusToolGrantSet;
99
+ readonly broker: ToolBroker;
100
+ readonly approvals: PiToolApprovalGateway;
101
+ readonly getActiveInput: () => AgentLoopInput | undefined;
102
+ readonly memoryScopes?: ReadonlyArray<MemoryScope>;
103
+ }
104
+ declare function createPiToolProxyDefinitions(options: PiToolProxyOptions): PiToolDefinition[];
105
+ declare function createPiToolNameResolver(tools: ReadonlyArray<Pick<RivusResolvedToolDescriptor, "id">>): (toolName: string) => string;
106
+ //#endregion
107
+ export { type CreatePiSessionResourcesOptions, InvalidPiSkillCatalog, InvalidPiSkillSource, type PiSessionResources, type PiSkillRuntime, type PiToolApprovalGateway, type PiToolApprovalRequest, type PiToolContent, type PiToolDefinition, type PiToolProxyOptions, type PiToolResult, ProjectSkillReadDenied, type ResolvePiSkillSourcesOptions, createPiProjectSkillReadTool, createPiSessionResources, createPiSkillReadTool, createPiSkillReadTools, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions, resolvePiSessionToolNames, resolvePiSkillSources, validatePiSkillCatalog, validatePiSkillCommand };
package/dist/pi.js CHANGED
@@ -1,146 +1,3 @@
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";
4
- import { readFile, realpath, stat } from "node:fs/promises";
5
- import { isAbsolute, relative } from "node:path";
6
- import { Unsafe } from "typebox";
7
- import { createReadToolDefinition } from "@earendil-works/pi-coding-agent";
8
- //#region src/infrastructure/pi/pi-project-skill-read-tool.ts
9
- var ProjectSkillReadDenied = class extends Error {
10
- name = "ProjectSkillReadDenied";
11
- };
12
- function createPiProjectSkillReadTool(options) {
13
- const { skillPaths } = options;
14
- if (skillPaths.length === 0) throw new ProjectSkillReadDenied("Project Skill read requires a trusted Skill source");
15
- const allowedRoots = [...skillPaths];
16
- return createReadToolDefinition(options.cwd, { operations: {
17
- access: async (absolutePath) => {
18
- await stat(await authorize(absolutePath, allowedRoots));
19
- },
20
- readFile: async (absolutePath) => readFile(await authorize(absolutePath, allowedRoots))
21
- } });
22
- }
23
- async function authorize(path, sources) {
24
- const candidate = await realpath(path);
25
- for (const source of sources) {
26
- const canonicalSource = await realpath(source);
27
- if (!(await stat(canonicalSource)).isDirectory()) {
28
- if (candidate === canonicalSource) return candidate;
29
- continue;
30
- }
31
- const relation = relative(canonicalSource, candidate);
32
- if (relation === "" || !relation.startsWith("..") && !isAbsolute(relation)) return candidate;
33
- }
34
- throw new ProjectSkillReadDenied("read is restricted to the bound Project Skill sources");
35
- }
36
- //#endregion
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
- allowedActorOpenIds: invocation.allowedActorOpenIds,
92
- ...invocation.kind === "background-session" ? invocation.conversationId ? { conversationId: invocation.conversationId } : {} : invocation.memory?.conversationId ? { conversationId: invocation.memory.conversationId } : {},
93
- endpointId: invocation.endpointId,
94
- instanceId: options.instanceId,
95
- ...invocation.memory ? { memory: {
96
- ...invocation.memory,
97
- scopes: options.memoryScopes ?? []
98
- } } : {},
99
- runId: activeInput.runId,
100
- sessionKey: activeInput.sessionKey,
101
- sourceMessageId: invocation.sourceMessageId,
102
- tenantKey: invocation.tenantKey,
103
- toolGrantSet: options.toolGrantSet
104
- }),
105
- callId,
106
- input,
107
- operationId,
108
- ...requiresToolApproval(tool.risk) ? { approvalId } : {},
109
- toolId: tool.id,
110
- version: tool.version
111
- });
112
- return {
113
- content: [{
114
- text: stringifyToolResult(result),
115
- type: "text"
116
- }],
117
- details: result
118
- };
119
- },
120
- executionMode: "sequential",
121
- label: tool.id,
122
- name,
123
- parameters: Unsafe(tool.inputSchema),
124
- promptSnippet: `${name}: ${tool.description}`
125
- };
126
- });
127
- }
128
- function createPiToolNameResolver(tools) {
129
- const toolIdsByPiName = new Map(tools.map((tool) => [toPiToolName(tool.id), tool.id]));
130
- return (toolName) => toolIdsByPiName.get(toolName) ?? toolName;
131
- }
132
- function toPiToolName(toolId) {
133
- return `rivus_${toolId.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
134
- }
135
- function createBoundId(kind, binding) {
136
- return `${kind}:${createHash("sha256").update(JSON.stringify(binding)).digest("hex")}`;
137
- }
138
- function throwIfAborted(signal) {
139
- if (signal.aborted) throw signal.reason ?? /* @__PURE__ */ new Error("tool execution was aborted");
140
- }
141
- function stringifyToolResult(result) {
142
- if (typeof result === "string") return result;
143
- return JSON.stringify(result ?? null);
144
- }
145
- //#endregion
146
- export { ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };
1
+ import { n as createPiSkillRuntime } from "./chunks/pi-skill-tool.js";
2
+ import { a as InvalidPiSkillSource, c as validatePiSkillCatalog, d as createPiProjectSkillReadTool, f as createPiSkillReadTool, i as resolvePiSessionToolNames, l as validatePiSkillCommand, n as createPiToolProxyDefinitions, o as resolvePiSkillSources, p as createPiSkillReadTools, r as createPiSessionResources, s as InvalidPiSkillCatalog, t as createPiToolNameResolver, u as ProjectSkillReadDenied } from "./chunks/pi.js";
3
+ export { InvalidPiSkillCatalog, InvalidPiSkillSource, ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSessionResources, createPiSkillReadTool, createPiSkillReadTools, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions, resolvePiSessionToolNames, resolvePiSkillSources, validatePiSkillCatalog, validatePiSkillCommand };
@@ -1,4 +1,4 @@
1
- import { a as assertRivusPluginConforms, i as RivusPluginLifecycleProbe, n as RivusPluginConformanceInput, o as createFakeRivusPlugin, r as RivusPluginConformanceReport, t as RivusPluginConformanceError } from "../rivus-plugin-testkit.js";
1
+ import { a as assertRivusPluginConforms, i as RivusPluginLifecycleProbe, n as RivusPluginConformanceInput, o as createFakeRivusPlugin, r as RivusPluginConformanceReport, t as RivusPluginConformanceError } from "../chunks/rivus-plugin-testkit.js";
2
2
 
3
3
  //#region src/testing/langfuse-drive-e2e.d.ts
4
4
  interface LangfuseObservation {
@@ -1,4 +1,4 @@
1
- import { n as assertRivusPluginConforms, r as createFakeRivusPlugin, t as RivusPluginConformanceError } from "../rivus-plugin-testkit.js";
1
+ import { n as assertRivusPluginConforms, r as createFakeRivusPlugin, t as RivusPluginConformanceError } from "../chunks/rivus-plugin-testkit.js";
2
2
  //#region src/testing/langfuse-drive-e2e.ts
3
3
  async function runLangfuseDriveE2E(options) {
4
4
  const timeoutMs = options.timeoutMs ?? 12e4;
@@ -1,15 +1,10 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
1
+ import { mkdir, readFile } from "node:fs/promises";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
+ import { homedir } from "node:os";
3
4
  import { join, relative } from "node:path";
4
5
  import { Effect } from "effect";
5
6
  import * as Lark from "@larksuiteoapi/node-sdk";
6
- import {
7
- AuthStorage,
8
- createAgentSession,
9
- DefaultResourceLoader,
10
- ModelRegistry,
11
- SessionManager
12
- } from "@earendil-works/pi-coding-agent";
7
+ import { createAgentSession, ModelRuntime, SessionManager } from "@earendil-works/pi-coding-agent";
13
8
  import {
14
9
  createAgentsMdInstructionsProvider,
15
10
  createAgentHarness,
@@ -51,6 +46,7 @@ import {
51
46
  createUuidRunIds,
52
47
  createWorkspaceRootHandle,
53
48
  loadRivusDeploymentManifest,
49
+ mergePiProviderBaseUrlOverride,
54
50
  openJsonlBackgroundSessionDeliveryStore,
55
51
  openJsonlBackgroundSessionRepository,
56
52
  resolveBackgroundSessionSupervisorIntervalMs,
@@ -65,8 +61,6 @@ import {
65
61
  readAutomationPresentation,
66
62
  resolveFeishuEndpointCredentials,
67
63
  resolveLangfuseTelemetryConfig,
68
- validateProjectSkillCatalog,
69
- validateProjectSkillCommand,
70
64
  type CreateRivusDeploymentBackgroundSessionInput,
71
65
  type CreateRivusDeploymentEndpointInput,
72
66
  type CreateRivusDeploymentAutomationInput,
@@ -81,10 +75,13 @@ import {
81
75
  type RivusThinkingLevel
82
76
  } from "@rivus/agent";
83
77
  import {
84
- createPiProjectSkillReadTool,
78
+ createPiSkillReadTools,
79
+ createPiSessionResources,
85
80
  createPiSkillRuntime,
81
+ resolvePiSessionToolNames,
86
82
  createPiToolNameResolver,
87
- createPiToolProxyDefinitions
83
+ createPiToolProxyDefinitions,
84
+ validatePiSkillCommand
88
85
  } from "@rivus/agent/pi";
89
86
 
90
87
  type PiSessionOptions = NonNullable<Parameters<typeof createAgentSession>[0]>;
@@ -500,15 +497,21 @@ export async function createRivusDeploymentAdapters(context: RivusDeploymentBoot
500
497
  const sessionRegistry = createPiSessionRegistry({
501
498
  createSession: async (firstInput) => {
502
499
  let activeInput = firstInput;
500
+ const resources = await createPiSessionResources({
501
+ agentDir: PI_AGENT_DIR,
502
+ appendSystemPromptOverride: () =>
503
+ [workspaceInstructions.content, skillRuntime.prompt].filter((content) => content.length > 0),
504
+ cwd: workingDirectory,
505
+ homeDirectory: homedir(),
506
+ ...(input.projectSpace ? { projectSkillPaths: input.projectSpace.skillPaths } : {}),
507
+ systemPromptOverride: () => input.definition.systemPrompt
508
+ });
503
509
  const customTools = [
504
- ...(input.projectSpace
505
- ? [
506
- createPiProjectSkillReadTool({
507
- cwd: input.projectSpace.workingDirectory,
508
- skillPaths: input.projectSpace.skillPaths
509
- })
510
- ]
511
- : []),
510
+ ...createPiSkillReadTools({
511
+ cwd: workingDirectory,
512
+ runtimeToolIds: input.definition.runtimeToolGrantSet.toolIds,
513
+ skillPaths: resources.skillNames.size > 0 ? resources.skillPaths : []
514
+ }),
512
515
  ...createPiToolProxyDefinitions({
513
516
  agentId: input.agentId,
514
517
  approvals: createHumanInteractionToolApprovalGateway({ registry: interactionRegistry }),
@@ -521,37 +524,23 @@ export async function createRivusDeploymentAdapters(context: RivusDeploymentBoot
521
524
  }),
522
525
  ...(skillRuntime.tool ? [skillRuntime.tool] : [])
523
526
  ];
524
- const resourceLoader = new DefaultResourceLoader({
525
- agentDir: PI_AGENT_DIR,
526
- ...(input.projectSpace ? { additionalSkillPaths: [...input.projectSpace.skillPaths] } : {}),
527
- appendSystemPromptOverride: () =>
528
- [workspaceInstructions.content, skillRuntime.prompt].filter((content) => content.length > 0),
529
- cwd: workingDirectory,
530
- noContextFiles: true,
531
- noExtensions: true,
532
- noPromptTemplates: true,
533
- noSkills: true,
534
- noThemes: true,
535
- systemPromptOverride: () => input.definition.systemPrompt
536
- });
537
- await resourceLoader.reload();
538
- const nativeSkillNames = input.projectSpace
539
- ? validateProjectSkillCatalog(resourceLoader.getSkills())
540
- : new Set<string>();
541
- const result = await createAgentSession({
542
- ...piOptions,
543
- customTools,
544
- resourceLoader,
545
- sessionManager: SessionManager.create(workingDirectory, join(instanceState, "sessions")),
546
- tools: customTools.map(({ name }) => name)
547
- });
527
+ const activeToolNames = resolvePiSessionToolNames(input.definition.runtimeToolGrantSet.toolIds, customTools);
528
+ const result = await createAgentSession(
529
+ resources.withSessionOptions({
530
+ ...piOptions,
531
+ customTools,
532
+ excludeTools: [],
533
+ sessionManager: SessionManager.create(workingDirectory, join(instanceState, "sessions")),
534
+ tools: [...activeToolNames]
535
+ })
536
+ );
548
537
  return {
549
538
  activate: (loopInput) => {
550
539
  activeInput = loopInput;
551
540
  },
552
541
  dispose: () => result.session.dispose(),
553
542
  preparePrompt: async (loopInput) => {
554
- validateProjectSkillCommand(loopInput.text, nativeSkillNames);
543
+ validatePiSkillCommand(loopInput.text, resources.skillNames);
555
544
  return prepareProjectMemory ? prepareProjectMemory(loopInput) : loopInput.text;
556
545
  },
557
546
  resolveToolName,
@@ -731,7 +720,6 @@ async function resolveFeishuBotOpenId(
731
720
  }
732
721
 
733
722
  async function createPiSessionOptions(context: RivusDeploymentBootstrapContext): Promise<PiSessionOptions> {
734
- const authStorage = AuthStorage.create(PI_AUTH_FILE);
735
723
  const modelReference = optional(context.env.PI_MODEL);
736
724
  const configuredModel = modelReference ? parseModelReference(modelReference) : undefined;
737
725
  const provider = configuredModel?.provider;
@@ -740,16 +728,19 @@ async function createPiSessionOptions(context: RivusDeploymentBootstrapContext):
740
728
  if ((apiKey || baseUrl) && !provider) {
741
729
  throw new Error("PI_API_KEY and PI_BASE_URL require PI_MODEL in provider/model form");
742
730
  }
743
- if (apiKey) authStorage.setRuntimeApiKey(provider!, apiKey);
744
731
  if (baseUrl) await writeProviderBaseUrlOverride(provider!, baseUrl);
745
- const modelRegistry = ModelRegistry.create(authStorage, baseUrl ? PI_MODELS_FILE : undefined);
746
- const model = configuredModel ? modelRegistry.find(configuredModel.provider, configuredModel.modelId) : undefined;
747
- if (modelReference && !model) throw new Error(`PI_MODEL ${modelReference} was not found in the Pi model registry`);
732
+ const modelRuntime = await ModelRuntime.create({
733
+ allowModelNetwork: false,
734
+ authPath: PI_AUTH_FILE,
735
+ modelsPath: baseUrl ? PI_MODELS_FILE : null
736
+ });
737
+ if (apiKey) await modelRuntime.setRuntimeApiKey(provider!, apiKey);
738
+ const model = configuredModel ? modelRuntime.getModel(configuredModel.provider, configuredModel.modelId) : undefined;
739
+ if (modelReference && !model) throw new Error(`PI_MODEL ${modelReference} was not found in the Pi model runtime`);
748
740
  const thinkingLevel = readThinkingLevel(context.env.PI_THINKING_LEVEL);
749
741
  return {
750
- authStorage,
751
742
  cwd: process.cwd(),
752
- modelRegistry,
743
+ modelRuntime,
753
744
  ...(model ? { model } : {}),
754
745
  ...(thinkingLevel ? { thinkingLevel } : {})
755
746
  };
@@ -773,7 +764,7 @@ function optional(value: string | undefined): string | undefined {
773
764
  function parseModelReference(reference: string): { readonly modelId: string; readonly provider: string } {
774
765
  const separator = reference.indexOf("/");
775
766
  if (separator <= 0 || separator === reference.length - 1) {
776
- throw new Error("PI_MODEL must use provider/model form, for example zai/glm-5.1");
767
+ throw new Error("PI_MODEL must use provider/model form, for example zai/glm-5.2");
777
768
  }
778
769
  return { modelId: reference.slice(separator + 1), provider: reference.slice(0, separator) };
779
770
  }
@@ -792,5 +783,5 @@ function sleep(ms: number): Effect.Effect<void> {
792
783
  }
793
784
 
794
785
  async function writeProviderBaseUrlOverride(provider: string, baseUrl: string): Promise<void> {
795
- await writeFile(PI_MODELS_FILE, `${JSON.stringify({ providers: { [provider]: { baseUrl } } }, null, 2)}\n`, "utf8");
786
+ await mergePiProviderBaseUrlOverride({ baseUrl, filePath: PI_MODELS_FILE, provider });
796
787
  }