@rivus/agent 0.13.2 → 0.14.0

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 +20 -15
  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 +594 -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 +602 -93
  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 +35 -46
  35. package/examples/pi-feishu.bootstrap.ts +35 -20
  36. package/examples/rivus-starter.plugin.mjs +3 -1
  37. package/package.json +8 -2
  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
@@ -1,4 +1,5 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
1
+ import { mkdir } from "node:fs/promises";
2
+ import { homedir } from "node:os";
2
3
  import { Effect } from "effect";
3
4
  import * as Lark from "@larksuiteoapi/node-sdk";
4
5
  import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
@@ -7,6 +8,7 @@ import {
7
8
  createJsonFileFeishuCardTargetRegistry,
8
9
  createJsonlAgentEventLog,
9
10
  createLazyFeishuWebSocketEventDispatcher,
11
+ mergePiProviderBaseUrlOverride,
10
12
  createRivusDaemonStatusHttpServer,
11
13
  createPiAgentLoop,
12
14
  createPiSessionRegistry,
@@ -24,6 +26,12 @@ import {
24
26
  type FeishuReceiveMessagePayload,
25
27
  type FeishuReceiveMessageReplayOptions
26
28
  } from "@rivus/agent";
29
+ import {
30
+ createPiSkillReadTools,
31
+ createPiSessionResources,
32
+ resolvePiSessionToolNames,
33
+ validatePiSkillCommand
34
+ } from "@rivus/agent/pi";
27
35
 
28
36
  type PiSessionOptions = NonNullable<Parameters<typeof createAgentSession>[0]>;
29
37
 
@@ -32,21 +40,42 @@ const CARD_TARGETS_FILE = `${STATE_DIR}/feishu-card-targets.json`;
32
40
  const EVENT_LOG_FILE = `${STATE_DIR}/agent-events.jsonl`;
33
41
  const PI_AUTH_FILE = `${STATE_DIR}/pi-auth.json`;
34
42
  const PI_MODELS_FILE = `${STATE_DIR}/pi-models.json`;
43
+ const PI_AGENT_DIR = `${STATE_DIR}/pi-agent`;
35
44
 
36
45
  export async function createRivusDaemonProcess(
37
46
  context: RivusDaemonBootstrapContext
38
47
  ): Promise<RivusDaemonProcess & RivusDaemonPromptRunner & RivusDaemonStatusReporter & RivusDaemonFeishuReplayRunner> {
39
- await mkdir(STATE_DIR, { recursive: true });
48
+ await mkdir(PI_AGENT_DIR, { recursive: true });
40
49
 
41
50
  const piSessionOptions = await createPiSessionOptions(context);
42
51
  const sessionRegistry = createPiSessionRegistry({
43
52
  createSession: async () => {
44
- const result = await createAgentSession({
45
- ...piSessionOptions,
46
- sessionManager: SessionManager.create(process.cwd())
53
+ const cwd = process.cwd();
54
+ const resources = await createPiSessionResources({
55
+ agentDir: PI_AGENT_DIR,
56
+ cwd,
57
+ homeDirectory: homedir()
58
+ });
59
+ const customTools = createPiSkillReadTools({
60
+ cwd,
61
+ runtimeToolIds: [],
62
+ skillPaths: resources.skillNames.size > 0 ? resources.skillPaths : []
47
63
  });
64
+ const result = await createAgentSession(
65
+ resources.withSessionOptions({
66
+ ...piSessionOptions,
67
+ customTools,
68
+ excludeTools: [],
69
+ sessionManager: SessionManager.create(cwd),
70
+ tools: [...resolvePiSessionToolNames([], customTools)]
71
+ })
72
+ );
48
73
  return {
49
74
  dispose: () => result.session.dispose(),
75
+ preparePrompt: (input) => {
76
+ validatePiSkillCommand(input.text, resources.skillNames);
77
+ return input.text;
78
+ },
50
79
  session: result.session
51
80
  };
52
81
  }
@@ -207,19 +236,5 @@ function readOptionalPort(value: string | undefined): number | undefined {
207
236
  }
208
237
 
209
238
  async function writeProviderBaseUrlOverride(provider: string, baseUrl: string): Promise<void> {
210
- await writeFile(
211
- PI_MODELS_FILE,
212
- `${JSON.stringify(
213
- {
214
- providers: {
215
- [provider]: {
216
- baseUrl
217
- }
218
- }
219
- },
220
- null,
221
- 2
222
- )}\n`,
223
- "utf8"
224
- );
239
+ await mergePiProviderBaseUrlOverride({ baseUrl, filePath: PI_MODELS_FILE, provider });
225
240
  }
@@ -1,6 +1,7 @@
1
1
  import { readCurrentWeather } from "./current-weather.mjs";
2
2
 
3
3
  const TOOL_ID = "rivus-starter/current-weather";
4
+ const RUNTIME_TOOLS = ["read", "bash", "edit", "write", "grep", "find", "ls"];
4
5
 
5
6
  export default {
6
7
  manifest: {
@@ -34,8 +35,9 @@ export default {
34
35
  registry.registerAgentProfile({
35
36
  displayName: "Rivus Agent",
36
37
  id: "agent-a",
37
- memory: { scopes: [] },
38
+ memory: { scopes: ["agent-private"] },
38
39
  model: {},
40
+ runtimeTools: { allow: RUNTIME_TOOLS },
39
41
  skills: { allow: [] },
40
42
  systemPrompt:
41
43
  "You are a concise local assistant. For current or today's weather, call current-weather. If the user did not name a location, omit location and report the Tool's resolved place.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivus/agent",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
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",
@@ -45,7 +45,12 @@
45
45
  "./mcp": {
46
46
  "types": "./dist/mcp.d.ts",
47
47
  "import": "./dist/mcp.js"
48
- }
48
+ },
49
+ "./bootstrap/pi-feishu": {
50
+ "types": "./dist/bootstrap/pi-feishu.d.ts",
51
+ "import": "./dist/bootstrap/pi-feishu.js"
52
+ },
53
+ "./plugin/starter": "./examples/rivus-starter.plugin.mjs"
49
54
  },
50
55
  "files": [
51
56
  "dist",
@@ -68,6 +73,7 @@
68
73
  "format:check": "vp fmt --check",
69
74
  "lint": "vp lint",
70
75
  "lint:fix": "vp lint --fix",
76
+ "package-api:update": "vp pack && node scripts/package-api-report.mjs --write",
71
77
  "package:check": "node scripts/check-npm-package.mjs",
72
78
  "prepublishOnly": "npm run check",
73
79
  "release:check": "node scripts/check-npm-release.mjs",
@@ -1,121 +0,0 @@
1
- import { Effect, Stream } from "effect";
2
- //#region src/application/agent/agent-loop.ts
3
- function createAgentLoopTextDelta(delta) {
4
- return {
5
- delta,
6
- type: "assistant_text_delta"
7
- };
8
- }
9
- function createAgentLoopTurnStart() {
10
- return { type: "turn_start" };
11
- }
12
- function normalizeAgentLoopEvent(event) {
13
- return typeof event === "string" ? createAgentLoopTextDelta(event) : event;
14
- }
15
- function createAgentLoopThinkingDelta(delta) {
16
- return {
17
- delta,
18
- type: "assistant_thinking_delta"
19
- };
20
- }
21
- function createAgentLoopModelExecutionStart(options) {
22
- return {
23
- ...options,
24
- type: "model_execution_start"
25
- };
26
- }
27
- function createAgentLoopModelExecutionEnd(options) {
28
- return {
29
- ...options,
30
- type: "model_execution_end"
31
- };
32
- }
33
- function createAgentLoopSkillExecutionStart(options) {
34
- return {
35
- ...options,
36
- type: "skill_execution_start"
37
- };
38
- }
39
- function createAgentLoopSkillExecutionEnd(options) {
40
- return {
41
- ...options,
42
- type: "skill_execution_end"
43
- };
44
- }
45
- function createAgentLoopToolExecutionStart(options) {
46
- return {
47
- input: options.input,
48
- toolCallId: options.toolCallId,
49
- toolName: options.toolName,
50
- type: "tool_execution_start"
51
- };
52
- }
53
- function createAgentLoopToolExecutionUpdate(options) {
54
- return {
55
- input: options.input,
56
- partialResult: options.partialResult,
57
- toolCallId: options.toolCallId,
58
- toolName: options.toolName,
59
- type: "tool_execution_update"
60
- };
61
- }
62
- function createAgentLoopToolExecutionEnd(options) {
63
- return {
64
- isError: options.isError,
65
- result: options.result,
66
- toolCallId: options.toolCallId,
67
- toolName: options.toolName,
68
- type: "tool_execution_end"
69
- };
70
- }
71
- function createEventAgentLoop(options) {
72
- return { run: (input) => {
73
- const events = typeof options.events === "function" ? options.events(input) : options.events;
74
- if (isPromiseLike(events)) return Stream.fromEffect(Effect.tryPromise({
75
- try: () => events,
76
- catch: (cause) => cause
77
- })).pipe(Stream.flatMap((resolvedEvents) => Stream.fromIterable(resolvedEvents)), Stream.map(normalizeAgentLoopEvent));
78
- return Stream.fromIterable(events).pipe(Stream.map(normalizeAgentLoopEvent));
79
- } };
80
- }
81
- function createAsyncIterableAgentLoop(options) {
82
- return { run: (input) => Stream.fromAsyncIterable(options.run(input), (error) => error).pipe(Stream.map(normalizeAgentLoopEvent)) };
83
- }
84
- function createAgentLoopFromCallback(run) {
85
- return { run: (input) => Stream.fromEffect(Effect.try({
86
- try: () => run(input),
87
- catch: (cause) => cause
88
- })).pipe(Stream.flatMap(streamFromAgentLoopCallbackResult)) };
89
- }
90
- function createTextAgentLoop(options) {
91
- return { run: (input) => Stream.fromEffect(options.generate(input)).pipe(Stream.map((delta) => createAgentLoopTextDelta(delta))) };
92
- }
93
- function createTextAgentLoopFromCallback(generate) {
94
- return createTextAgentLoop({ generate: (input) => Effect.tryPromise({
95
- try: async () => generate(input),
96
- catch: (cause) => cause
97
- }) });
98
- }
99
- function isPromiseLike(value) {
100
- return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
101
- }
102
- function streamFromAgentLoopCallbackResult(result) {
103
- if (Effect.isEffect(result)) return Stream.fromEffect(result).pipe(Stream.flatMap(streamFromAgentLoopCallbackOutput));
104
- if (isPromiseLike(result)) return Stream.fromEffect(Effect.tryPromise({
105
- try: () => Promise.resolve(result),
106
- catch: (cause) => cause
107
- })).pipe(Stream.flatMap(streamFromAgentLoopCallbackOutput));
108
- return streamFromAgentLoopCallbackOutput(result);
109
- }
110
- function streamFromAgentLoopCallbackOutput(output) {
111
- if (isEffectStream(output)) return output.pipe(Stream.map(normalizeAgentLoopEvent));
112
- return (isAsyncIterable(output) ? Stream.fromAsyncIterable(output, (error) => error) : Stream.fromIterable(output)).pipe(Stream.map(normalizeAgentLoopEvent));
113
- }
114
- function isAsyncIterable(value) {
115
- return Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
116
- }
117
- function isEffectStream(value) {
118
- return typeof value === "object" && value !== null && Stream.StreamTypeId in value;
119
- }
120
- //#endregion
121
- export { createAgentLoopSkillExecutionStart as a, createAgentLoopToolExecutionEnd as c, createAgentLoopTurnStart as d, createAsyncIterableAgentLoop as f, createTextAgentLoopFromCallback as h, createAgentLoopSkillExecutionEnd as i, createAgentLoopToolExecutionStart as l, createTextAgentLoop as m, createAgentLoopModelExecutionEnd as n, createAgentLoopTextDelta as o, createEventAgentLoop as p, createAgentLoopModelExecutionStart as r, createAgentLoopThinkingDelta as s, createAgentLoopFromCallback as t, createAgentLoopToolExecutionUpdate as u };
@@ -1,100 +0,0 @@
1
- //#region src/domain/agent-memory.d.ts
2
- declare const MEMORY_SCOPES: readonly ["conversation", "agent-private", "project", "shared-user-profile"];
3
- declare const RIVUS_MEMORY_TOOL_ID = "memory";
4
- declare const RIVUS_MEMORY_TOOL_PLUGIN_ID = "rivus-core";
5
- declare const RIVUS_MEMORY_TOOL_VERSION = "1.0.0";
6
- type MemoryScope = (typeof MEMORY_SCOPES)[number];
7
- type MemoryState = "proposed" | "confirmed" | "superseded" | "tombstoned";
8
- type MemoryInvocationAudience = "group" | "private";
9
- interface AgentMemoryIdentity {
10
- readonly audience: MemoryInvocationAudience;
11
- readonly conversationId?: string;
12
- readonly projectId?: string;
13
- readonly subjectId: string;
14
- readonly tenantId: string;
15
- }
16
- interface AgentMemoryAuthority extends AgentMemoryIdentity {
17
- readonly scopes: ReadonlyArray<MemoryScope>;
18
- }
19
- interface MemoryBinding {
20
- readonly agentId: string;
21
- readonly conversationId?: string;
22
- readonly projectId?: string;
23
- readonly scope: MemoryScope;
24
- readonly subjectId: string;
25
- readonly tenantId: string;
26
- }
27
- interface MemoryRecord {
28
- readonly content: string;
29
- readonly conversationSafe: boolean;
30
- readonly id: string;
31
- readonly revision: number;
32
- readonly scope: MemoryScope;
33
- readonly state: MemoryState;
34
- readonly tombstoneReason?: string;
35
- }
36
- interface AgentMemorySnapshot {
37
- readonly binding: MemoryBinding;
38
- readonly record: MemoryRecord;
39
- }
40
- declare function createMemoryNamespace(binding: MemoryBinding): string;
41
- declare function restrictMemoryScopesForAudience(scopes: ReadonlyArray<MemoryScope>, audience: MemoryInvocationAudience): ReadonlyArray<MemoryScope>;
42
- declare function createRivusMemoryToolContract(scopes: ReadonlyArray<MemoryScope>): Readonly<{
43
- description: "Search and read Memory inside Host-bound scopes; propose or request forgetting only in writable private scopes.";
44
- digest: "sha256:rivus-memory-v3";
45
- id: "memory";
46
- idempotency: "required";
47
- inputSchema: Readonly<{
48
- additionalProperties: false;
49
- properties: {
50
- scope?: {
51
- description: string;
52
- enum: ("conversation" | "agent-private" | "project" | "shared-user-profile")[];
53
- type: string;
54
- };
55
- command: {
56
- description: string;
57
- enum: string[];
58
- type: string;
59
- };
60
- id: {
61
- description: string;
62
- minLength: number;
63
- type: string;
64
- };
65
- input: {
66
- additionalProperties: boolean;
67
- description: string;
68
- properties: {
69
- content: {
70
- minLength: number;
71
- type: string;
72
- };
73
- };
74
- required: string[];
75
- type: string;
76
- };
77
- query: {
78
- additionalProperties: boolean;
79
- description: string;
80
- properties: {
81
- query: {
82
- type: string;
83
- };
84
- };
85
- required: string[];
86
- type: string;
87
- };
88
- reason: {
89
- description: string;
90
- type: string;
91
- };
92
- };
93
- required: string[];
94
- type: "object";
95
- }>;
96
- risk: "mutate";
97
- version: "1.0.0";
98
- }>;
99
- //#endregion
100
- export { MemoryBinding as a, MemoryScope as c, RIVUS_MEMORY_TOOL_PLUGIN_ID as d, RIVUS_MEMORY_TOOL_VERSION as f, restrictMemoryScopesForAudience as h, MEMORY_SCOPES as i, MemoryState as l, createRivusMemoryToolContract as m, AgentMemoryIdentity as n, MemoryInvocationAudience as o, createMemoryNamespace as p, AgentMemorySnapshot as r, MemoryRecord as s, AgentMemoryAuthority as t, RIVUS_MEMORY_TOOL_ID as u };
@@ -1,114 +0,0 @@
1
- //#region src/domain/rivus-plugin.ts
2
- const RIVUS_PLUGIN_API_VERSION = "1";
3
- function requiresToolApproval(risk) {
4
- return risk === "irreversible" || risk === "host-control";
5
- }
6
- var RivusToolInputRejected = class extends Error {
7
- name = "RivusToolInputRejected";
8
- };
9
- var InvalidRivusPlugin = class extends Error {
10
- name = "InvalidRivusPlugin";
11
- };
12
- //#endregion
13
- //#region src/domain/agent-memory.ts
14
- const MEMORY_SCOPES = [
15
- "conversation",
16
- "agent-private",
17
- "project",
18
- "shared-user-profile"
19
- ];
20
- const RIVUS_MEMORY_TOOL_ID = "memory";
21
- const RIVUS_MEMORY_TOOL_PLUGIN_ID = "rivus-core";
22
- const RIVUS_MEMORY_TOOL_VERSION = "1.0.0";
23
- function createMemoryNamespace(binding) {
24
- const encode = (value) => encodeURIComponent(value);
25
- switch (binding.scope) {
26
- case "conversation": return [
27
- binding.tenantId,
28
- binding.agentId,
29
- binding.subjectId,
30
- binding.conversationId ?? "",
31
- binding.scope
32
- ].map(encode).join("/");
33
- case "agent-private": return [
34
- binding.tenantId,
35
- binding.agentId,
36
- binding.subjectId,
37
- binding.scope
38
- ].map(encode).join("/");
39
- case "project": return [
40
- binding.tenantId,
41
- binding.agentId,
42
- binding.projectId ?? "",
43
- binding.scope
44
- ].map(encode).join("/");
45
- case "shared-user-profile": return [
46
- binding.tenantId,
47
- binding.subjectId,
48
- binding.scope
49
- ].map(encode).join("/");
50
- }
51
- }
52
- function restrictMemoryScopesForAudience(scopes, audience) {
53
- return audience === "group" ? scopes.filter((scope) => scope === "conversation" || scope === "project") : [...scopes];
54
- }
55
- function createRivusMemoryToolContract(scopes) {
56
- return Object.freeze({
57
- description: "Search and read Memory inside Host-bound scopes; propose or request forgetting only in writable private scopes.",
58
- digest: "sha256:rivus-memory-v3",
59
- id: RIVUS_MEMORY_TOOL_ID,
60
- idempotency: "required",
61
- inputSchema: Object.freeze({
62
- additionalProperties: false,
63
- properties: {
64
- command: {
65
- description: "One of search, read, propose, or forget_request.",
66
- enum: [
67
- "search",
68
- "read",
69
- "propose",
70
- "forget_request"
71
- ],
72
- type: "string"
73
- },
74
- id: {
75
- description: "Required for read and forget_request.",
76
- minLength: 1,
77
- type: "string"
78
- },
79
- input: {
80
- additionalProperties: false,
81
- description: "Required for propose.",
82
- properties: { content: {
83
- minLength: 1,
84
- type: "string"
85
- } },
86
- required: ["content"],
87
- type: "object"
88
- },
89
- query: {
90
- additionalProperties: false,
91
- description: "Required for search.",
92
- properties: { query: { type: "string" } },
93
- required: ["query"],
94
- type: "object"
95
- },
96
- reason: {
97
- description: "Optional reason for forget_request.",
98
- type: "string"
99
- },
100
- ...scopes.length === 0 ? {} : { scope: {
101
- description: "Optional Host-granted scope for search or propose. Confirmed Project and Shared User Profile Memory are read-only to the model.",
102
- enum: [...scopes],
103
- type: "string"
104
- } }
105
- },
106
- required: ["command"],
107
- type: "object"
108
- }),
109
- risk: "mutate",
110
- version: RIVUS_MEMORY_TOOL_VERSION
111
- });
112
- }
113
- //#endregion
114
- export { createMemoryNamespace as a, InvalidRivusPlugin as c, requiresToolApproval as d, RIVUS_MEMORY_TOOL_VERSION as i, RIVUS_PLUGIN_API_VERSION as l, RIVUS_MEMORY_TOOL_ID as n, createRivusMemoryToolContract as o, RIVUS_MEMORY_TOOL_PLUGIN_ID as r, restrictMemoryScopesForAudience as s, MEMORY_SCOPES as t, RivusToolInputRejected as u };