@rivus/agent 0.5.2 → 0.6.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.
@@ -0,0 +1,194 @@
1
+ import { s as AgentLoopInput } from "./agent-loop.js";
2
+ import { c as MemoryScope, t as AgentMemoryAuthority } from "./agent-memory.js";
3
+ import { A as RivusToolRisk, D as RivusToolGrantSet, b as RivusResolvedToolDescriptor, g as RivusPluginCatalog, m as RivusHostToolDescriptor } from "./rivus-plugin.js";
4
+ import { ToolDefinition } from "@earendil-works/pi-coding-agent";
5
+
6
+ //#region src/domain/recovery-action.d.ts
7
+ interface RecoveryAction {
8
+ readonly actorId: string;
9
+ readonly at: string;
10
+ readonly note: string;
11
+ }
12
+ declare class InvalidRecoveryAction extends Error {
13
+ readonly name = "InvalidRecoveryAction";
14
+ }
15
+ declare function createRecoveryAction(input: RecoveryAction): RecoveryAction;
16
+ //#endregion
17
+ //#region src/application/delegation/tool-operation-ledger.d.ts
18
+ interface ToolOperationBinding {
19
+ readonly agentId: string;
20
+ readonly inputDigest: string;
21
+ readonly instanceId: string;
22
+ readonly sourceMessageId: string;
23
+ readonly toolId: string;
24
+ readonly toolVersion: string;
25
+ }
26
+ type ToolOperationState = {
27
+ readonly status: "pending";
28
+ } | {
29
+ readonly result: unknown;
30
+ readonly status: "completed";
31
+ } | {
32
+ readonly reason: string;
33
+ readonly status: "reconciliation-required";
34
+ } | {
35
+ readonly status: "aborted";
36
+ };
37
+ interface ToolOperationRecord {
38
+ readonly binding: ToolOperationBinding;
39
+ readonly operationId: string;
40
+ readonly reconciliation?: ToolOperationReconciliation;
41
+ readonly revision: number;
42
+ readonly state: ToolOperationState;
43
+ }
44
+ interface ToolOperationReconciliation extends RecoveryAction {
45
+ readonly outcome: "applied" | "not-applied";
46
+ }
47
+ type ToolOperationReconciliationOutcome = {
48
+ readonly result: unknown;
49
+ readonly status: "applied";
50
+ } | {
51
+ readonly status: "not-applied";
52
+ };
53
+ type ToolOperationBeginResult = {
54
+ readonly status: "acquired";
55
+ } | {
56
+ readonly result: unknown;
57
+ readonly status: "completed";
58
+ } | {
59
+ readonly status: "blocked";
60
+ readonly reason: string;
61
+ };
62
+ type ToolOperationInspectResult = {
63
+ readonly status: "missing";
64
+ } | {
65
+ readonly result: unknown;
66
+ readonly status: "completed";
67
+ } | {
68
+ readonly status: "blocked";
69
+ readonly reason: string;
70
+ };
71
+ interface ToolOperationLedger {
72
+ abort(operationId: string, binding: ToolOperationBinding): Promise<void>;
73
+ begin(operationId: string, binding: ToolOperationBinding): Promise<ToolOperationBeginResult>;
74
+ complete(operationId: string, binding: ToolOperationBinding, result: unknown): Promise<void>;
75
+ inspect(operationId: string, binding: ToolOperationBinding): Promise<ToolOperationInspectResult>;
76
+ reconciliationRequired(): ReadonlyArray<ToolOperationRecord>;
77
+ reconcile(input: {
78
+ readonly action: RecoveryAction;
79
+ readonly expectedRevision: number;
80
+ readonly operationId: string;
81
+ readonly outcome: ToolOperationReconciliationOutcome;
82
+ }): Promise<ToolOperationRecord>;
83
+ requireReconciliation(operationId: string, binding: ToolOperationBinding, reason: string): Promise<void>;
84
+ unresolvedForSource(sourceMessageId: string): ReadonlyArray<ToolOperationRecord>;
85
+ }
86
+ declare function createToolOperationLedger(options?: {
87
+ readonly initial?: ReadonlyArray<ToolOperationRecord>;
88
+ readonly persist?: (record: ToolOperationRecord) => Promise<void>;
89
+ }): ToolOperationLedger;
90
+ //#endregion
91
+ //#region src/application/delegation/tool-authority.d.ts
92
+ interface InvocationAuthorityRef {
93
+ readonly id: string;
94
+ }
95
+ interface InvocationAuthority {
96
+ readonly agentId: string;
97
+ readonly instanceId: string;
98
+ readonly memory?: AgentMemoryAuthority;
99
+ readonly runId: string;
100
+ readonly sessionKey: string;
101
+ readonly sourceMessageId: string;
102
+ readonly tenantKey: string;
103
+ readonly toolGrantSet: RivusToolGrantSet;
104
+ }
105
+ declare class InvalidInvocationAuthority extends Error {
106
+ readonly name = "InvalidInvocationAuthority";
107
+ }
108
+ declare function createInvocationAuthority(authority: InvocationAuthority): InvocationAuthorityRef;
109
+ //#endregion
110
+ //#region src/application/delegation/tool-broker.d.ts
111
+ interface AuthorizationPolicyState {
112
+ readonly epoch: number;
113
+ readonly revokedToolIds: ReadonlyArray<string>;
114
+ }
115
+ interface AuthorizationPolicyProvider {
116
+ current(): Promise<AuthorizationPolicyState>;
117
+ }
118
+ interface ToolApprovalRequest {
119
+ readonly approvalId: string;
120
+ readonly agentId: string;
121
+ readonly instanceId: string;
122
+ readonly inputDigest: string;
123
+ readonly operationId: string;
124
+ readonly runId: string;
125
+ readonly sessionKey: string;
126
+ readonly tenantKey: string;
127
+ readonly callId: string;
128
+ readonly toolId: string;
129
+ readonly toolVersion: string;
130
+ readonly risk: RivusToolRisk;
131
+ }
132
+ interface ToolApprovalService {
133
+ consume(request: ToolApprovalRequest): Promise<boolean>;
134
+ }
135
+ interface ToolBrokerOptions {
136
+ readonly approvals: ToolApprovalService;
137
+ readonly catalog: RivusPluginCatalog;
138
+ readonly hostTools?: ReadonlyArray<RivusHostToolDescriptor>;
139
+ readonly policy: AuthorizationPolicyProvider;
140
+ readonly operations?: ToolOperationLedger;
141
+ }
142
+ interface ToolExecutionRequest {
143
+ readonly authority: InvocationAuthorityRef;
144
+ readonly callId: string;
145
+ readonly toolId: string;
146
+ readonly version: string;
147
+ readonly input: unknown;
148
+ readonly operationId?: string;
149
+ readonly approvalId?: string;
150
+ }
151
+ interface ToolBroker {
152
+ execute(request: ToolExecutionRequest): Promise<unknown>;
153
+ }
154
+ declare class ToolInvocationDenied extends Error {
155
+ readonly name = "ToolInvocationDenied";
156
+ }
157
+ declare function createToolBroker(options: ToolBrokerOptions): ToolBroker;
158
+ //#endregion
159
+ //#region src/infrastructure/pi/pi-tool-proxy.d.ts
160
+ interface PiToolApprovalRequest {
161
+ readonly agentId: string;
162
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
163
+ readonly approvalId: string;
164
+ readonly callId: string;
165
+ readonly endpointId: string;
166
+ readonly inputDigest: string;
167
+ readonly instanceId: string;
168
+ readonly operationId: string;
169
+ readonly risk: RivusToolRisk;
170
+ readonly runId: string;
171
+ readonly sessionKey: string;
172
+ readonly signal?: AbortSignal;
173
+ readonly sourceMessageId: string;
174
+ readonly tenantKey: string;
175
+ readonly toolId: string;
176
+ readonly toolVersion: string;
177
+ }
178
+ interface PiToolApprovalGateway {
179
+ requestApproval(request: PiToolApprovalRequest): Promise<void>;
180
+ }
181
+ interface PiToolProxyOptions {
182
+ readonly agentId: string;
183
+ readonly approvals: PiToolApprovalGateway;
184
+ readonly broker: ToolBroker;
185
+ readonly getActiveInput: () => AgentLoopInput | undefined;
186
+ readonly instanceId: string;
187
+ readonly memoryScopes?: ReadonlyArray<MemoryScope>;
188
+ readonly toolGrantSet: RivusToolGrantSet;
189
+ readonly tools: ReadonlyArray<RivusResolvedToolDescriptor>;
190
+ }
191
+ declare function createPiToolProxyDefinitions(options: PiToolProxyOptions): ToolDefinition[];
192
+ declare function createPiToolNameResolver(tools: ReadonlyArray<Pick<RivusResolvedToolDescriptor, "id">>): (toolName: string) => string;
193
+ //#endregion
194
+ export { createRecoveryAction as A, ToolOperationReconciliation as C, createToolOperationLedger as D, ToolOperationState as E, InvalidRecoveryAction as O, ToolOperationLedger as S, ToolOperationRecord as T, InvocationAuthorityRef as _, createPiToolProxyDefinitions as a, ToolOperationBinding as b, ToolApprovalRequest as c, ToolBrokerOptions as d, ToolExecutionRequest as f, InvocationAuthority as g, InvalidInvocationAuthority as h, createPiToolNameResolver as i, RecoveryAction as k, ToolApprovalService as l, createToolBroker as m, PiToolApprovalRequest as n, AuthorizationPolicyProvider as o, ToolInvocationDenied as p, PiToolProxyOptions as r, AuthorizationPolicyState as s, PiToolApprovalGateway as t, ToolBroker as u, createInvocationAuthority as v, ToolOperationReconciliationOutcome as w, ToolOperationInspectResult as x, ToolOperationBeginResult as y };
package/dist/pi.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { a as createPiToolProxyDefinitions, i as createPiToolNameResolver, n as PiToolApprovalRequest, r as PiToolProxyOptions, t as PiToolApprovalGateway } from "./pi-tool-proxy.js";
2
+ import { o as RegisteredRivusSkill } from "./rivus-plugin.js";
1
3
  import { ToolDefinition } from "@earendil-works/pi-coding-agent";
2
4
 
3
5
  //#region src/infrastructure/pi/pi-project-skill-read-tool.d.ts
@@ -9,4 +11,11 @@ declare function createPiProjectSkillReadTool(options: {
9
11
  readonly skillPaths: ReadonlyArray<string>;
10
12
  }): ToolDefinition;
11
13
  //#endregion
12
- export { ProjectSkillReadDenied, createPiProjectSkillReadTool };
14
+ //#region src/infrastructure/pi/pi-skill-tool.d.ts
15
+ interface PiSkillRuntime {
16
+ readonly prompt: string;
17
+ readonly tool?: ToolDefinition;
18
+ }
19
+ declare function createPiSkillRuntime(skills: ReadonlyArray<RegisteredRivusSkill>): PiSkillRuntime;
20
+ //#endregion
21
+ export { type PiSkillRuntime, type PiToolApprovalGateway, type PiToolApprovalRequest, type PiToolProxyOptions, ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };
package/dist/pi.js CHANGED
@@ -1,5 +1,9 @@
1
+ import { d as requiresToolApproval } from "./agent-memory.js";
2
+ import { l as createPiSkillRuntime, o as createInvocationAuthority, r as createToolInputDigest } from "./tool-input-digest.js";
3
+ import { createHash } from "node:crypto";
1
4
  import { isAbsolute, relative } from "node:path";
2
5
  import { readFile, realpath, stat } from "node:fs/promises";
6
+ import { Unsafe } from "typebox";
3
7
  import { createReadToolDefinition } from "@earendil-works/pi-coding-agent";
4
8
  //#region src/infrastructure/pi/pi-project-skill-read-tool.ts
5
9
  var ProjectSkillReadDenied = class extends Error {
@@ -30,4 +34,110 @@ async function authorize(path, sources) {
30
34
  throw new ProjectSkillReadDenied("read is restricted to the bound Project Skill sources");
31
35
  }
32
36
  //#endregion
33
- export { ProjectSkillReadDenied, createPiProjectSkillReadTool };
37
+ //#region src/infrastructure/pi/pi-tool-proxy.ts
38
+ function createPiToolProxyDefinitions(options) {
39
+ const names = /* @__PURE__ */ new Set();
40
+ return options.tools.map((tool) => {
41
+ const name = toPiToolName(tool.id);
42
+ if (names.has(name)) throw new Error(`Pi tool name collision: ${name}`);
43
+ names.add(name);
44
+ return {
45
+ description: tool.description,
46
+ execute: async (callId, input, signal) => {
47
+ const activeInput = options.getActiveInput();
48
+ const invocation = activeInput?.invocation;
49
+ if (!activeInput || !invocation) throw new Error(`tool ${tool.id} requires an active agent run with a trusted invocation`);
50
+ if (!invocation.tenantKey) throw new Error(`tool ${tool.id} requires a trusted tenant identity`);
51
+ throwIfAborted(signal ?? activeInput.abortSignal);
52
+ const inputDigest = createToolInputDigest(input);
53
+ const operationId = createBoundId("operation", {
54
+ agentId: options.agentId,
55
+ inputDigest,
56
+ instanceId: options.instanceId,
57
+ sourceMessageId: invocation.sourceMessageId,
58
+ toolId: tool.id,
59
+ toolVersion: tool.version
60
+ });
61
+ const approvalId = createBoundId("approval", {
62
+ callId,
63
+ operationId,
64
+ runId: activeInput.runId
65
+ });
66
+ if (requiresToolApproval(tool.risk)) {
67
+ if (invocation.allowedActorOpenIds.length === 0) throw new Error(`tool ${tool.id} requires at least one trusted approval actor`);
68
+ await options.approvals.requestApproval({
69
+ agentId: options.agentId,
70
+ allowedActorOpenIds: invocation.allowedActorOpenIds,
71
+ approvalId,
72
+ callId,
73
+ endpointId: invocation.endpointId,
74
+ inputDigest,
75
+ instanceId: options.instanceId,
76
+ operationId,
77
+ risk: tool.risk,
78
+ runId: activeInput.runId,
79
+ sessionKey: activeInput.sessionKey,
80
+ signal: signal ?? activeInput.abortSignal,
81
+ sourceMessageId: invocation.sourceMessageId,
82
+ tenantKey: invocation.tenantKey,
83
+ toolId: tool.id,
84
+ toolVersion: tool.version
85
+ });
86
+ throwIfAborted(signal ?? activeInput.abortSignal);
87
+ }
88
+ const result = await options.broker.execute({
89
+ authority: createInvocationAuthority({
90
+ agentId: options.agentId,
91
+ instanceId: options.instanceId,
92
+ ...invocation.memory ? { memory: {
93
+ ...invocation.memory,
94
+ scopes: options.memoryScopes ?? []
95
+ } } : {},
96
+ runId: activeInput.runId,
97
+ sessionKey: activeInput.sessionKey,
98
+ sourceMessageId: invocation.sourceMessageId,
99
+ tenantKey: invocation.tenantKey,
100
+ toolGrantSet: options.toolGrantSet
101
+ }),
102
+ callId,
103
+ input,
104
+ operationId,
105
+ ...requiresToolApproval(tool.risk) ? { approvalId } : {},
106
+ toolId: tool.id,
107
+ version: tool.version
108
+ });
109
+ return {
110
+ content: [{
111
+ text: stringifyToolResult(result),
112
+ type: "text"
113
+ }],
114
+ details: result
115
+ };
116
+ },
117
+ executionMode: "sequential",
118
+ label: tool.id,
119
+ name,
120
+ parameters: Unsafe(tool.inputSchema),
121
+ promptSnippet: `${name}: ${tool.description}`
122
+ };
123
+ });
124
+ }
125
+ function createPiToolNameResolver(tools) {
126
+ const toolIdsByPiName = new Map(tools.map((tool) => [toPiToolName(tool.id), tool.id]));
127
+ return (toolName) => toolIdsByPiName.get(toolName) ?? toolName;
128
+ }
129
+ function toPiToolName(toolId) {
130
+ return `rivus_${toolId.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
131
+ }
132
+ function createBoundId(kind, binding) {
133
+ return `${kind}:${createHash("sha256").update(JSON.stringify(binding)).digest("hex")}`;
134
+ }
135
+ function throwIfAborted(signal) {
136
+ if (signal.aborted) throw signal.reason ?? /* @__PURE__ */ new Error("tool execution was aborted");
137
+ }
138
+ function stringifyToolResult(result) {
139
+ if (typeof result === "string") return result;
140
+ return JSON.stringify(result ?? null);
141
+ }
142
+ //#endregion
143
+ export { ProjectSkillReadDenied, createPiProjectSkillReadTool, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions };