@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
package/README.md CHANGED
@@ -10,6 +10,7 @@ The first milestone is intentionally narrow: make the agent loop and agent harne
10
10
 
11
11
  - TypeScript ESM package.
12
12
  - Public Plugin SDK with atomic Plugin registration, immutable Catalog snapshots, deterministic Agent Deployment resolution, an explicit Required/Optional Plugin Loader, safe Node module resolution from a Deployment Root, and a manifest-driven Multi-agent Deployment Daemon. Concrete Agent products remain external packages.
13
+ - Revisioned Pi native Runtime Tool grants with a closed seven-Tool vocabulary, exact Profile ∩ Deployment narrowing, fail-closed defaults, and explicit full capability only in the Personal Home starter. Pi Skill discovery accepts an empty catalog and is limited to user-global plus explicit Project Space roots; project-ambient resources stay disabled.
13
14
  - Host-bound Workspace Instructions API and built-in `AGENTS.md` provider with deterministic root-to-target discovery, immutable source digests, nested mutation refresh diagnostics, UTF-8/path/symlink checks, and whole-source byte budgeting. The deployment example injects the root View into Pi while Tool-target refresh remains enforced by the provider boundary.
14
15
  - Host-issued invocation authority and a call-time Tool Broker that checks exact grants, pinned versions, online revocation, stable operation IDs, durable side-effect fencing, and one-time approval receipts bound to canonical input digests. The Pi Tool Proxy and Feishu Human Interaction gateway are wired in the deployment example.
15
16
  - Multi-agent Host primitives with trusted Endpoint bindings, stable Runtime Generation/Instance identities, lazy per-instance Runtime pooling, isolated active-run gates, and restart restoration from persisted registry records.
@@ -54,22 +55,23 @@ npm install @rivus/agent
54
55
  npx rivus --help
55
56
  ```
56
57
 
57
- Create a standalone one-Agent project without cloning this repository:
58
+ Create the default Personal Agent Home without cloning this repository or installing another local Rivus copy:
58
59
 
59
60
  ```bash
60
- npm install --global @rivus/agent
61
- rivus init my-rivus-agent
62
- cd my-rivus-agent
63
- npm install
64
- cp .env.example .env.local
65
- # Fill the Feishu and model-provider values in .env.local.
66
- npm run doctor
67
- npm start
61
+ npm install --global \
62
+ @rivus/agent \
63
+ @earendil-works/pi-coding-agent@^0.80.6 \
64
+ @larksuiteoapi/node-sdk@^1.70.0
65
+ rivus setup
66
+ cp "$HOME/.rivus-agent/.env.example" "$HOME/.rivus-agent/.env"
67
+ # Fill the Feishu and model-provider values in ~/.rivus-agent/.env.
68
+ rivus doctor
69
+ rivus start
68
70
  ```
69
71
 
70
- `init` refuses to overwrite any generated path. `doctor` checks Node, project files, local dependencies, the deployment manifest, and enabled Endpoint credentials without importing Plugin code or contacting external services. See the [local deployment runbook](docs/en/operations/local-deployment.md) for foreground verification and the generated systemd/launchd templates.
72
+ `setup` refuses to overwrite existing Home files. `start`, `status`, and `check-config` read `RIVUS_HOME` or `~/.rivus-agent`, use its configured Workspace as cwd, and keep state outside npm installation files. `doctor` checks the Home, global modules, manifest, Workspace, and enabled Endpoint credential references without importing Plugin code or contacting external services. Existing standalone projects remain supported through `rivus init <directory>` and `rivus doctor <directory>`. See the [local deployment runbook](docs/en/operations/local-deployment.md).
71
73
 
72
- The Pi plus Feishu example is application-edge code: install `@earendil-works/pi-coding-agent` and `@larksuiteoapi/node-sdk` in the daemon app that uses it. The `@rivus/agent` core package keeps those SDKs out of its runtime dependency graph.
74
+ The Pi plus Feishu Bootstrap is an application-edge package export: install `@earendil-works/pi-coding-agent` and `@larksuiteoapi/node-sdk` beside the global Rivus package. The `@rivus/agent` core keeps those SDKs out of its mandatory runtime dependency graph.
73
75
 
74
76
  ```bash
75
77
  npm install @earendil-works/pi-coding-agent@^0.80.6 @larksuiteoapi/node-sdk@^1.70.0
@@ -87,7 +89,7 @@ vp run check
87
89
 
88
90
  npm releases are produced only by the `Publish npm` GitHub Actions workflow after a GitHub Release is published for an exact `v<package version>` tag on `main`. The workflow uses npm Trusted Publishing through OIDC and contains no long-lived registry token. See the [npm release runbook](docs/en/operations/npm-release.md) for the one-time first-package bootstrap and normal release procedure.
89
91
 
90
- For a manifest-driven multi-agent deployment, keep `rivus.config.json`, its lockfile, and installed Plugin packages in one deployment project. `createConfiguredRivusDeploymentDaemon()` validates the manifest, resolves only declared modules from that directory, disables deployments belonging to failed Optional Plugins, and blocks startup when a Required Plugin fails:
92
+ For a manifest-driven multi-agent deployment, keep `rivus.config.json` in Rivus Home and install declared Plugin packages beside the global Rivus package. `createConfiguredRivusDeploymentDaemon()` validates the manifest, resolves only declared modules from the Home or Host-trusted npm roots, disables deployments belonging to failed Optional Plugins, and blocks startup when a Required Plugin fails:
91
93
 
92
94
  ```json
93
95
  {
@@ -169,7 +171,7 @@ await daemon.start(); // rejects when an enabled Required Endpoint or Automation
169
171
 
170
172
  Endpoint factories receive a Host-bound `handle()` function. Inbound payload fields cannot select another Agent or Endpoint. `createConfiguredRivusDaemonBootstrap()` is the small, explicit single-lane Pi/Feishu composition; manifest deployments use the multi-agent path directly, without a parallel compatibility model.
171
173
 
172
- [`examples/rivus.config.json`](examples/rivus.config.json) and [`examples/pi-feishu-deployment.bootstrap.ts`](examples/pi-feishu-deployment.bootstrap.ts) form a concrete two-bot composition. Each `credentialRef: "env:<PREFIX>"` resolves only `<PREFIX>_APP_ID` and `<PREFIX>_APP_SECRET`; each Endpoint owns its WebSocket client, durable Inbox, bounded concurrent worker, CardKit target/delivery state, Human Interaction JSONL repository, and lifecycle. Its unique Manifest Session Namespace is prepended before the trusted Host route reaches a fair per-session Scheduler, Harness lane, and Pi Session Registry. Startup resolves the Bot Open ID, waits for the SDK `onReady` handshake, repairs missing terminal CardKit projections, and applies `groupPolicy` before the durable accept. The example restores a separate event log, Tool operation ledger, and Pi session directory per Agent Instance, plus one deployment-scoped append-only Agent Memory log. Built-in Pi tools, extensions, prompt templates, themes, and ambient Pi context discovery remain disabled. An Agent with a trusted `projectSpaceId` additionally receives only that Project Space's declared native Skill sources and bounded `AGENTS.md` View; Pi handles progressive Skill loading and `/skill:<name>`, while unknown names fail before model execution. Unbound Agents retain the previous inline Rivus Skill reader behavior.
174
+ [`examples/rivus.config.json`](examples/rivus.config.json) and [`examples/pi-feishu-deployment.bootstrap.ts`](examples/pi-feishu-deployment.bootstrap.ts) form a concrete two-bot composition. Each `credentialRef: "env:<PREFIX>"` resolves only `<PREFIX>_APP_ID` and `<PREFIX>_APP_SECRET`; each Endpoint owns its WebSocket client, durable Inbox, bounded concurrent worker, CardKit target/delivery state, Human Interaction JSONL repository, and lifecycle. Its unique Manifest Session Namespace is prepended before the trusted Host route reaches a fair per-session Scheduler, Harness lane, and Pi Session Registry. Startup resolves the Bot Open ID, waits for the SDK `onReady` handshake, repairs missing terminal CardKit projections, and applies `groupPolicy` before the durable accept. The example restores a separate event log, Tool operation ledger, and Pi session directory per Agent Instance, plus one deployment-scoped append-only Agent Memory log. Native Pi tools default to none and are activated only by the resolved `runtimeToolGrantSet`; custom Tools come only from the resolved Agent definition. Extensions, prompt templates, themes, ambient project settings, and ambient Pi Skill discovery remain disabled. Pi loads existing user-global Skill roots plus only the selected Project Space's explicit sources, accepts an empty catalog, and validates every `/skill:<name>` before model execution. A bounded `AGENTS.md` View supplies context without granting authority.
173
175
 
174
176
  Interactive Endpoints default `progressDisplay` to `collapsed`: public assistant narration and inspectable Skill/Tool actions remain in chronological order, and every action owns a small native collapsible panel rather than being collected into one process appendix. `expanded` opens completed action panels initially and `hidden` omits them; a running action stays open so its safe parameters and current result are visible. A channel-neutral `RunPresentation` read model preserves stable steps, status, duration, and safe Tool input/result projections across streaming updates and successor cards. Sensitive fields are redacted, machine paths normalized, and long values explicitly truncated before a channel renderer sees them; private reasoning and raw Tool payloads never enter the presentation IR. Ordinary replies never gain an empty process panel. A rollover freezes the predecessor exactly as last rendered and starts a blank successor that receives only post-breakpoint content. Scheduled Automations use a separate final-only `AutomationPresentation` IR: Plugins own title, metadata, sections, items, notes, and sources, while the channel renderer owns visual components.
175
177
 
@@ -425,7 +427,7 @@ Recognized variables:
425
427
  - `RIVUS_WEATHER_DEFAULT_LOCATION` selects the example `current-weather` Tool's fallback city and defaults to `北京`; it is not a Core setting.
426
428
  - `RIVUS_TELEMETRY_ENVIRONMENT` defaults to `NODE_ENV`, then `local`; `RIVUS_TELEMETRY_SERVICE_NAME` defaults to `rivus-agent`.
427
429
 
428
- For both SDK bootstrap templates, `PI_MODEL` should use Pi's provider/model form when `PI_API_KEY`, `PI_API_KEY_FILE`, or `PI_BASE_URL` is set, for example `anthropic/claude-opus-4-5` or `zai/glm-5.1` for GLM BYOK. The templates apply the resolved Pi API key through Pi `AuthStorage.setRuntimeApiKey()`, resolve the model through Pi's public `ModelRegistry.find(provider, modelId)` API, and apply `PI_BASE_URL` by writing a local `.rivus/pi-models.json` provider override, matching Pi's `models.json` configuration model.
430
+ For both SDK bootstrap templates, `PI_MODEL` should use Pi's provider/model form when `PI_API_KEY`, `PI_API_KEY_FILE`, or `PI_BASE_URL` is set, for example `anthropic/claude-opus-4-5` or `zai/glm-5.1` for GLM BYOK. The templates apply the resolved Pi API key through Pi `AuthStorage.setRuntimeApiKey()`, resolve the model through Pi's public `ModelRegistry.find(provider, modelId)` API, and apply `PI_BASE_URL` by merging a local `.rivus/pi-models.json` provider override without removing existing custom models or other providers, matching Pi's `models.json` configuration model.
429
431
 
430
432
  ## Core Usage
431
433
 
@@ -463,6 +465,7 @@ catalog.registerPlugin({
463
465
  id: "example",
464
466
  memory: { scopes: [] },
465
467
  model: { provider: "example" },
468
+ runtimeTools: { allow: ["read", "grep", "find", "ls"] },
466
469
  skills: { allow: [] },
467
470
  systemPrompt: "Use trusted example sources.",
468
471
  tools: { allow: ["example-agent/read"] }
@@ -475,11 +478,13 @@ const definition = resolveRivusAgentDefinition(catalog, {
475
478
  endpointIds: ["example-feishu"],
476
479
  pluginId: "example-agent",
477
480
  profileId: "example",
481
+ runtimeTools: { allow: ["read", "grep"] },
482
+ skills: { allow: [] },
478
483
  tools: { allow: ["example-agent/read"] }
479
484
  });
480
485
  ```
481
486
 
482
- The resolved definition exposes immutable Tool schemas and a `ToolGrantSet`; executor factories remain inside the Catalog boundary. Wildcards, duplicate identifiers, unknown references, and incompatible Plugin API versions are rejected.
487
+ The resolved definition exposes immutable Tool schemas, a `ToolGrantSet`, and a `runtimeToolGrantSet` containing only `read` and `grep`; executor factories remain inside the Catalog boundary. Wildcards, duplicate identifiers, unknown references, and incompatible Plugin API versions are rejected. Missing Runtime Tool allowlists resolve to an empty native grant.
483
488
 
484
489
  External Plugin packages can run reusable conformance checks from the testing subpath:
485
490
 
package/dist/acp.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { s as AgentLoopInput, t as AgentLoop } from "./agent-loop.js";
1
+ import { a as AgentLoopInput, t as AgentLoop } from "./chunks/agent-loop.js";
2
2
  import * as acp from "@agentclientprotocol/sdk";
3
3
 
4
- //#region src/infrastructure/acp/acp-agent-loop.d.ts
4
+ //#region src/adapters/acp/runtime/acp-agent-loop.d.ts
5
5
  type AcpToolCallStatus = "pending" | "in_progress" | "completed" | "failed";
6
6
  interface AcpSessionUpdate {
7
7
  readonly content?: unknown;
@@ -25,14 +25,8 @@ interface AcpAgentSession {
25
25
  dispose?(): Promise<void> | void;
26
26
  invalidate?(): Promise<void> | void;
27
27
  }
28
- interface AcpAgentLoopOptions {
29
- readonly cancellationSettleTimeoutMs?: number;
30
- readonly disposeSessionAfterRun?: boolean;
31
- readonly resolveSession: (input: AgentLoopInput) => Promise<AcpAgentSession> | AcpAgentSession;
32
- }
33
- declare function createAcpAgentLoop(options: AcpAgentLoopOptions): AgentLoop;
34
28
  //#endregion
35
- //#region src/infrastructure/acp/acp-permission-policy.d.ts
29
+ //#region src/adapters/acp/runtime/acp-permission-policy.d.ts
36
30
  interface AcpPermissionOption {
37
31
  readonly kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
38
32
  readonly name: string;
@@ -64,24 +58,14 @@ interface AcpSessionPermissionContext {
64
58
  type AcpSessionPermissionPolicy = (request: AcpPermissionRequest, context: AcpSessionPermissionContext) => Promise<AcpPermissionSelection | undefined> | AcpPermissionSelection | undefined;
65
59
  declare function decideAcpPermission(request: AcpPermissionRequest, policy?: AcpPermissionPolicy): Promise<AcpPermissionDecision>;
66
60
  //#endregion
67
- //#region src/infrastructure/acp/acp-permission-bridge.d.ts
61
+ //#region src/adapters/acp/runtime/acp-permission-bridge.d.ts
68
62
  interface AcpPermissionBridge {
69
63
  readonly policy: AcpSessionPermissionPolicy;
70
64
  bind(sessionKey: string, policy: AcpPermissionPolicy): () => void;
71
65
  }
72
66
  declare function createAcpPermissionBridge(): AcpPermissionBridge;
73
67
  //#endregion
74
- //#region src/infrastructure/acp/acp-agent-server.d.ts
75
- interface AcpAgentServerOptions {
76
- readonly agentName?: string;
77
- readonly loop: AgentLoop;
78
- readonly permissionBridge?: AcpPermissionBridge;
79
- readonly workingDirectory: string;
80
- }
81
- declare function createAcpAgentServer(options: AcpAgentServerOptions): acp.AgentApp;
82
- declare function serveAcpAgentOnStdio(app: acp.AgentApp): Promise<void>;
83
- //#endregion
84
- //#region src/infrastructure/acp/acp-session-store.d.ts
68
+ //#region src/adapters/acp/runtime/acp-session-store.d.ts
85
69
  interface AcpSessionRecord {
86
70
  readonly sessionId: string;
87
71
  }
@@ -99,7 +83,7 @@ interface JsonAcpSessionStoreOptions {
99
83
  */
100
84
  declare function createJsonAcpSessionStore(options: JsonAcpSessionStoreOptions): AcpSessionStore;
101
85
  //#endregion
102
- //#region src/infrastructure/acp/acp-stdio-agent-loop.d.ts
86
+ //#region src/adapters/acp/runtime/acp-stdio-agent-loop.d.ts
103
87
  interface AcpMcpServerEnvironmentVariable {
104
88
  readonly name: string;
105
89
  readonly value: string;
@@ -110,35 +94,51 @@ interface AcpMcpServer {
110
94
  readonly env: ReadonlyArray<AcpMcpServerEnvironmentVariable>;
111
95
  readonly name: string;
112
96
  }
97
+ declare class AcpSessionResumeUnavailable extends Error {
98
+ readonly sessionId: string;
99
+ readonly name = "AcpSessionResumeUnavailable";
100
+ constructor(sessionId: string);
101
+ }
102
+ declare class AcpSessionResumeFailed extends Error {
103
+ readonly sessionId: string;
104
+ readonly cause: unknown;
105
+ readonly name = "AcpSessionResumeFailed";
106
+ constructor(sessionId: string, cause: unknown);
107
+ }
108
+ //#endregion
109
+ //#region src/adapters/compatibility/agent-execution/acp/acp-runtime.d.ts
110
+ interface AcpAgentLoopOptions {
111
+ readonly cancellationSettleTimeoutMs?: number;
112
+ readonly disposeSessionAfterRun?: boolean;
113
+ readonly resolveSession: (input: AgentLoopInput) => Promise<AcpAgentSession> | AcpAgentSession;
114
+ }
115
+ interface AcpAgentServerOptions {
116
+ readonly loop: AgentLoop;
117
+ readonly workingDirectory: string;
118
+ readonly agentName?: string;
119
+ readonly permissionBridge?: AcpPermissionBridge;
120
+ }
113
121
  interface AcpStdioAgentLoopOptions {
114
- readonly arguments?: ReadonlyArray<string>;
115
- readonly clientName?: string;
116
122
  readonly command: string;
117
- readonly environment?: Readonly<Record<string, string>>;
118
- readonly initializationTimeoutMs?: number;
123
+ readonly workingDirectory: string;
119
124
  readonly mcpServers?: (input: AgentLoopInput) => ReadonlyArray<AcpMcpServer>;
120
- readonly onStderr?: (text: string) => void;
121
- readonly permissionPolicy?: AcpSessionPermissionPolicy;
122
125
  /** Persist provider session IDs so a restarted ACP child can load/resume them. */
123
126
  readonly sessionStore?: AcpSessionStore;
127
+ readonly permissionPolicy?: AcpSessionPermissionPolicy;
128
+ readonly environment?: Readonly<Record<string, string>>;
129
+ readonly arguments?: ReadonlyArray<string>;
130
+ readonly clientName?: string;
131
+ readonly initializationTimeoutMs?: number;
124
132
  readonly terminationTimeoutMs?: number;
125
- readonly workingDirectory: string;
133
+ readonly onStderr?: (text: string) => void;
126
134
  }
127
135
  interface AcpStdioAgentLoopHandle {
128
136
  readonly loop: AgentLoop;
129
137
  dispose(): Promise<void>;
130
138
  }
139
+ declare function createAcpAgentLoop(options: AcpAgentLoopOptions): AgentLoop;
140
+ declare function createAcpAgentServer(options: AcpAgentServerOptions): acp.AgentApp;
141
+ declare function serveAcpAgentOnStdio(app: acp.AgentApp): Promise<void>;
131
142
  declare function createAcpStdioAgentLoop(options: AcpStdioAgentLoopOptions): AcpStdioAgentLoopHandle;
132
- declare class AcpSessionResumeUnavailable extends Error {
133
- readonly sessionId: string;
134
- readonly name = "AcpSessionResumeUnavailable";
135
- constructor(sessionId: string);
136
- }
137
- declare class AcpSessionResumeFailed extends Error {
138
- readonly sessionId: string;
139
- readonly cause: unknown;
140
- readonly name = "AcpSessionResumeFailed";
141
- constructor(sessionId: string, cause: unknown);
142
- }
143
143
  //#endregion
144
144
  export { type AcpAgentLoopOptions, type AcpAgentServerOptions, type AcpAgentSession, type AcpPermissionBridge, type AcpPermissionDecision, type AcpPermissionOption, type AcpPermissionPolicy, type AcpPermissionRequest, type AcpPermissionSelection, type AcpPermissionToolCall, type AcpPromptResult, type AcpSessionPermissionContext, type AcpSessionPermissionPolicy, type AcpSessionRecord, AcpSessionResumeFailed, AcpSessionResumeUnavailable, type AcpSessionStore, type AcpSessionUpdate, type AcpStdioAgentLoopHandle, type AcpStdioAgentLoopOptions, type AcpToolCallStatus, type JsonAcpSessionStoreOptions, createAcpAgentLoop, createAcpAgentServer, createAcpPermissionBridge, createAcpStdioAgentLoop, createJsonAcpSessionStore, decideAcpPermission, serveAcpAgentOnStdio };
package/dist/acp.js CHANGED
@@ -1,16 +1,16 @@
1
- import { c as createAgentLoopToolExecutionEnd, d as createAgentLoopTurnStart, f as createAsyncIterableAgentLoop, l as createAgentLoopToolExecutionStart, o as createAgentLoopTextDelta, s as createAgentLoopThinkingDelta, u as createAgentLoopToolExecutionUpdate } from "./agent-loop.js";
1
+ import { B as createAgentLoopToolExecutionUpdate, I as createAgentLoopTextDelta, L as createAgentLoopThinkingDelta, R as createAgentLoopToolExecutionEnd, V as createAgentLoopTurnStart, c as toEffectAgentLoop, o as fromEffectAgentLoop, s as toCompatibilityAgentLoopInput, z as createAgentLoopToolExecutionStart } from "./chunks/agent-loop.js";
2
+ import "./chunks/spi.js";
3
+ import * as acp from "@agentclientprotocol/sdk";
2
4
  import { Effect, Stream } from "effect";
3
5
  import { randomUUID } from "node:crypto";
4
6
  import { Readable, Writable } from "node:stream";
5
- import * as acp from "@agentclientprotocol/sdk";
6
7
  import { spawn } from "node:child_process";
7
8
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
8
9
  import { dirname } from "node:path";
9
- //#region src/infrastructure/acp/acp-agent-loop.ts
10
- function createAcpAgentLoop(options) {
11
- const loop = createAsyncIterableAgentLoop({ run: (input) => runAcpSession(input, options) });
10
+ //#region src/adapters/acp/runtime/acp-agent-loop.ts
11
+ function createAcpAgentLoop$1(options) {
12
12
  return {
13
- run: (input) => loop.run(input),
13
+ run: (input) => Stream.fromAsyncIterable(runAcpSession(input, options), (error) => error),
14
14
  supportsSteering: true
15
15
  };
16
16
  }
@@ -41,7 +41,8 @@ async function* runAcpSession(input, options) {
41
41
  });
42
42
  };
43
43
  input.abortSignal.addEventListener("abort", onAbort, { once: true });
44
- let steering = input.steering?.next();
44
+ const takeSteering = () => input.steering ? Effect.runPromise(input.steering.next()) : void 0;
45
+ let steering = takeSteering();
45
46
  try {
46
47
  if (input.abortSignal.aborted) onAbort();
47
48
  while (!currentTurn.completed || updates.length > 0) {
@@ -68,7 +69,7 @@ async function* runAcpSession(input, options) {
68
69
  wake?.();
69
70
  wake = void 0;
70
71
  });
71
- steering = input.steering?.next();
72
+ steering = takeSteering();
72
73
  }
73
74
  if (signal.type === "turn_completed" && currentTurn.completed) break;
74
75
  if (signal.type === "wake") wake = void 0;
@@ -196,8 +197,8 @@ function isRecord$1(value) {
196
197
  return typeof value === "object" && value !== null;
197
198
  }
198
199
  //#endregion
199
- //#region src/infrastructure/acp/acp-agent-server.ts
200
- function createAcpAgentServer(options) {
200
+ //#region src/adapters/acp/runtime/acp-agent-server.ts
201
+ function createAcpAgentServer$1(options) {
201
202
  const sessions = /* @__PURE__ */ new Set();
202
203
  const active = /* @__PURE__ */ new Map();
203
204
  return acp.agent({ name: options.agentName ?? "rivus" }).onRequest(acp.methods.agent.initialize, ({ params }) => ({
@@ -254,7 +255,7 @@ function createAcpAgentServer(options) {
254
255
  active.get(params.sessionId)?.abort();
255
256
  });
256
257
  }
257
- async function serveAcpAgentOnStdio(app) {
258
+ async function serveAcpAgentOnStdio$1(app) {
258
259
  const stream = acp.ndJsonStream(Writable.toWeb(process.stdout), Readable.toWeb(process.stdin));
259
260
  await app.connect(stream).closed;
260
261
  }
@@ -305,22 +306,7 @@ function mapAgentLoopEvent(event) {
305
306
  };
306
307
  }
307
308
  //#endregion
308
- //#region src/infrastructure/acp/acp-permission-bridge.ts
309
- function createAcpPermissionBridge() {
310
- const policies = /* @__PURE__ */ new Map();
311
- return {
312
- bind: (sessionKey, policy) => {
313
- if (policies.has(sessionKey)) throw new Error(`ACP permission bridge is already bound: ${sessionKey}`);
314
- policies.set(sessionKey, policy);
315
- return () => {
316
- if (policies.get(sessionKey) === policy) policies.delete(sessionKey);
317
- };
318
- },
319
- policy: async (request, context) => policies.get(context.sessionKey)?.(request)
320
- };
321
- }
322
- //#endregion
323
- //#region src/infrastructure/acp/acp-permission-policy.ts
309
+ //#region src/adapters/acp/runtime/acp-permission-policy.ts
324
310
  async function decideAcpPermission(request, policy) {
325
311
  const selection = await policy?.(request);
326
312
  if (!selection || !request.options.some((option) => option.optionId === selection.optionId)) return { outcome: "cancelled" };
@@ -330,7 +316,7 @@ async function decideAcpPermission(request, policy) {
330
316
  };
331
317
  }
332
318
  //#endregion
333
- //#region src/infrastructure/acp/acp-stdio-agent-loop.ts
319
+ //#region src/adapters/acp/runtime/acp-stdio-agent-loop.ts
334
320
  async function buildAcpSession(processConnection, options, input) {
335
321
  const mcpServers = createMcpServers(options, input);
336
322
  const persisted = await options.sessionStore?.load(input.sessionKey);
@@ -375,7 +361,7 @@ async function restoreAcpSession(processConnection, options, sessionId, mcpServe
375
361
  throw new AcpSessionResumeFailed(sessionId, error);
376
362
  }
377
363
  }
378
- function createAcpStdioAgentLoop(options) {
364
+ function createAcpStdioAgentLoop$1(options) {
379
365
  let pendingConnection;
380
366
  let activeConnection;
381
367
  let ownedChild;
@@ -433,7 +419,7 @@ function createAcpStdioAgentLoop(options) {
433
419
  if (child) await terminateChild(child, options.terminationTimeoutMs);
434
420
  await current?.catch(() => void 0);
435
421
  },
436
- loop: createAcpAgentLoop({
422
+ loop: createAcpAgentLoop$1({
437
423
  disposeSessionAfterRun: false,
438
424
  resolveSession: async (input) => {
439
425
  const processConnection = await resolveConnection();
@@ -665,7 +651,61 @@ function withTimeout(promise, timeoutMs, message) {
665
651
  });
666
652
  }
667
653
  //#endregion
668
- //#region src/infrastructure/acp/acp-session-store.ts
654
+ //#region src/adapters/compatibility/agent-execution/acp/acp-runtime.ts
655
+ function createAcpAgentLoop(options) {
656
+ return fromEffectAgentLoop(createAcpAgentLoop$1({
657
+ ...options.cancellationSettleTimeoutMs === void 0 ? {} : { cancellationSettleTimeoutMs: options.cancellationSettleTimeoutMs },
658
+ ...options.disposeSessionAfterRun === void 0 ? {} : { disposeSessionAfterRun: options.disposeSessionAfterRun },
659
+ resolveSession: (input) => options.resolveSession(toCompatibilityAgentLoopInput(input))
660
+ }));
661
+ }
662
+ function createAcpAgentServer(options) {
663
+ return createAcpAgentServer$1({
664
+ ...options.agentName === void 0 ? {} : { agentName: options.agentName },
665
+ loop: toEffectAgentLoop(options.loop),
666
+ ...options.permissionBridge ? { permissionBridge: options.permissionBridge } : {},
667
+ workingDirectory: options.workingDirectory
668
+ });
669
+ }
670
+ function serveAcpAgentOnStdio(app) {
671
+ return serveAcpAgentOnStdio$1(app);
672
+ }
673
+ function createAcpStdioAgentLoop(options) {
674
+ const handle = createAcpStdioAgentLoop$1({
675
+ ...options.arguments ? { arguments: options.arguments } : {},
676
+ ...options.clientName === void 0 ? {} : { clientName: options.clientName },
677
+ command: options.command,
678
+ ...options.environment ? { environment: options.environment } : {},
679
+ ...options.initializationTimeoutMs === void 0 ? {} : { initializationTimeoutMs: options.initializationTimeoutMs },
680
+ ...options.mcpServers ? { mcpServers: (input) => options.mcpServers(toCompatibilityAgentLoopInput(input)) } : {},
681
+ ...options.onStderr ? { onStderr: options.onStderr } : {},
682
+ ...options.permissionPolicy ? { permissionPolicy: options.permissionPolicy } : {},
683
+ ...options.sessionStore ? { sessionStore: options.sessionStore } : {},
684
+ ...options.terminationTimeoutMs === void 0 ? {} : { terminationTimeoutMs: options.terminationTimeoutMs },
685
+ workingDirectory: options.workingDirectory
686
+ });
687
+ return {
688
+ dispose: () => handle.dispose(),
689
+ loop: fromEffectAgentLoop(handle.loop)
690
+ };
691
+ }
692
+ //#endregion
693
+ //#region src/adapters/acp/runtime/acp-permission-bridge.ts
694
+ function createAcpPermissionBridge() {
695
+ const policies = /* @__PURE__ */ new Map();
696
+ return {
697
+ bind: (sessionKey, policy) => {
698
+ if (policies.has(sessionKey)) throw new Error(`ACP permission bridge is already bound: ${sessionKey}`);
699
+ policies.set(sessionKey, policy);
700
+ return () => {
701
+ if (policies.get(sessionKey) === policy) policies.delete(sessionKey);
702
+ };
703
+ },
704
+ policy: async (request, context) => policies.get(context.sessionKey)?.(request)
705
+ };
706
+ }
707
+ //#endregion
708
+ //#region src/adapters/acp/runtime/acp-session-store.ts
669
709
  /**
670
710
  * A small deployment-owned store for ACP provider session identities.
671
711
  * The file contains no prompts or credentials, only session-key bindings.
@@ -0,0 +1,20 @@
1
+ import { A as CreateRivusDeploymentBackgroundSessionInput, F as RivusDeploymentBackgroundSession, Fc as AgentRuntimeInput, M as CreateRivusDeploymentEndpointInput, Mc as SessionSchedulerStatus, N as CreateRivusDeploymentRuntimeInput, Pc as AgentRuntimeCancellation, Rc as AgentRuntimeSteering, aa as RivusDeploymentBootstrapContext, dt as ScheduledAutomation, k as CreateRivusDeploymentAutomationInput, la as ProcessDeploymentEndpoint, pl as RecoveryControl } from "../chunks/index.js";
2
+
3
+ //#region examples/pi-feishu-deployment.bootstrap.d.ts
4
+ declare function createRivusDeploymentAdapters(context: RivusDeploymentBootstrapContext): Promise<{
5
+ dispose: () => Promise<void> | undefined;
6
+ createRecoveryControl: () => Promise<RecoveryControl>;
7
+ createBackgroundSession: ((input: CreateRivusDeploymentBackgroundSessionInput) => RivusDeploymentBackgroundSession) | undefined;
8
+ createAutomation: (input: CreateRivusDeploymentAutomationInput) => Promise<ScheduledAutomation>;
9
+ createEndpoint: (input: CreateRivusDeploymentEndpointInput) => Promise<ProcessDeploymentEndpoint>;
10
+ createRuntime: (input: CreateRivusDeploymentRuntimeInput) => Promise<{
11
+ dispose: () => Promise<void>;
12
+ concurrency: "managed";
13
+ status(): SessionSchedulerStatus;
14
+ cancel?(input: AgentRuntimeCancellation): Promise<boolean>;
15
+ steer?(input: AgentRuntimeSteering): Promise<boolean>;
16
+ run(input: AgentRuntimeInput): Promise<unknown>;
17
+ }>;
18
+ }>;
19
+ //#endregion
20
+ export { createRivusDeploymentAdapters };