@rivus/agent 0.6.2 → 0.8.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.
- package/README.md +12 -0
- package/dist/acp.d.ts +11 -0
- package/dist/acp.js +14 -1
- package/dist/agent-loop.d.ts +10 -1
- package/dist/background-session-authority.js +224 -0
- package/dist/background-session-input.js +45 -0
- package/dist/background-session-service.d.ts +291 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +191 -2
- package/dist/index.js +1522 -65
- package/dist/mcp.d.ts +86 -0
- package/dist/mcp.js +416 -0
- package/dist/pi-tool-proxy.d.ts +3 -0
- package/dist/pi.js +3 -0
- package/dist/rivus-daemon-cli.js +133 -6
- package/dist/rivus-plugin-registry.js +5 -2
- package/dist/rivus-plugin.d.ts +8 -0
- package/dist/tool-input-digest.js +2 -0
- package/examples/pi-feishu-deployment.bootstrap.ts +187 -4
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ The first milestone is intentionally narrow: make the agent loop and agent harne
|
|
|
15
15
|
- 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.
|
|
16
16
|
- Scoped Agent Memory with a single-writer append-only JSONL adapter, explicit Profile/Deployment grants, Host-bound tenant/subject/conversation/project/audience identity, and a provider-neutral `rivus_memory` Tool wired into the Pi manifest Runtime. Agent-private proposals survive process replacement; group invocations may access only Conversation and confirmed Project Memory, and Shared Profile reads expose only confirmed records. Bound Project Memory is recalled automatically with deterministic limits; durable confirmation UX, typed Shared Profile fields, full provenance/retention metadata, and durable Compaction are still separate work.
|
|
17
17
|
- Manifest-driven fixed-time Agent Automations with daily or weekday-only schedules, stable Mandate/Tick identity, per-template Tool grant narrowing, isolated Runtime and invocation authority, a durable single-writer JSON Tick adapter that records the actual Agent Run, generated-before-delivery recovery, and idempotent proactive Feishu interactive-card delivery. The first Markdown heading becomes the card title while the remaining Markdown stays scannable in the card body. Revisioned Plugin State and the general Delivery Outbox remain composable domain primitives.
|
|
18
|
+
- Opt-in background Agent Sessions (`manifest.backgroundSessions`): the model decides from ordinary natural language that work should continue in the background, calls the generic `background.start` Host Tool, and the foreground Run and card end promptly. A deployment-owned supervisor runs bounded steps on an isolated Runtime lane per Agent with the exact Agent/Profile/Project Space/Skills/Memory policy and a grant narrowed to exclude `background.start`; sessions wait durably (`background.wait`), wake, receive user input once (`background.send`), stop safely, and survive daemon restart on the same stable session and Pi transcript. Progress and one terminal result are delivered idempotently to the trusted source conversation. ACP runtimes reach the same Host Tools through a built-in MCP bridge (`@rivus/agent/mcp`), so Pi and ACP backends share the identical domain, supervisor, persistence, status, and delivery semantics. The Runtime contains no business scenario, meeting, or job code — no pre-model intent router exists.
|
|
18
19
|
- Peer Delegation and Subagent coordination primitives with explicit edges, hop/budget limits, monotonic ToolGrantSet intersection, isolated child authority, denied ambient sender/private-memory/Shell capabilities, and parent cancellation cascading.
|
|
19
20
|
- `@rivus/agent/testing` Conformance TestKit with a reusable Fake Plugin and checks for registration/reference failures, ToolGrantSet expansion, and lifecycle disposal leaks.
|
|
20
21
|
- Effect-based `AgentHarness` use case with result-oriented `prompt()`, turn-oriented `promptTurn()`, event-oriented `stream()`, text-oriented `streamText()`, event-handling `promptWithEvents()`, active-run/run/session state and transcript lookup APIs, and a default runtime factory.
|
|
@@ -125,6 +126,17 @@ For a manifest-driven multi-agent deployment, keep `rivus.config.json`, its lock
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
],
|
|
129
|
+
"backgroundSessions": {
|
|
130
|
+
"enabled": false,
|
|
131
|
+
"required": false,
|
|
132
|
+
"stepTimeoutMs": 300000,
|
|
133
|
+
"maxConcurrentSessions": 4,
|
|
134
|
+
"leaseMs": 30000,
|
|
135
|
+
"leaseRenewalIntervalMs": 10000,
|
|
136
|
+
"maxConsecutiveFailures": 3,
|
|
137
|
+
"retryBackoffMs": 30000,
|
|
138
|
+
"sessionLifetimeMs": 86400000
|
|
139
|
+
},
|
|
128
140
|
"endpoints": [
|
|
129
141
|
{
|
|
130
142
|
"id": "research-feishu",
|
package/dist/acp.d.ts
CHANGED
|
@@ -78,12 +78,23 @@ declare function createAcpAgentServer(options: AcpAgentServerOptions): acp.Agent
|
|
|
78
78
|
declare function serveAcpAgentOnStdio(app: acp.AgentApp): Promise<void>;
|
|
79
79
|
//#endregion
|
|
80
80
|
//#region src/infrastructure/acp/acp-stdio-agent-loop.d.ts
|
|
81
|
+
interface AcpMcpServerEnvironmentVariable {
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly value: string;
|
|
84
|
+
}
|
|
85
|
+
interface AcpMcpServer {
|
|
86
|
+
readonly args: ReadonlyArray<string>;
|
|
87
|
+
readonly command: string;
|
|
88
|
+
readonly env: ReadonlyArray<AcpMcpServerEnvironmentVariable>;
|
|
89
|
+
readonly name: string;
|
|
90
|
+
}
|
|
81
91
|
interface AcpStdioAgentLoopOptions {
|
|
82
92
|
readonly arguments?: ReadonlyArray<string>;
|
|
83
93
|
readonly clientName?: string;
|
|
84
94
|
readonly command: string;
|
|
85
95
|
readonly environment?: Readonly<Record<string, string>>;
|
|
86
96
|
readonly initializationTimeoutMs?: number;
|
|
97
|
+
readonly mcpServers?: (input: AgentLoopInput) => ReadonlyArray<AcpMcpServer>;
|
|
87
98
|
readonly onStderr?: (text: string) => void;
|
|
88
99
|
readonly permissionPolicy?: AcpSessionPermissionPolicy;
|
|
89
100
|
readonly terminationTimeoutMs?: number;
|
package/dist/acp.js
CHANGED
|
@@ -251,6 +251,19 @@ async function decideAcpPermission(request, policy) {
|
|
|
251
251
|
}
|
|
252
252
|
//#endregion
|
|
253
253
|
//#region src/infrastructure/acp/acp-stdio-agent-loop.ts
|
|
254
|
+
async function buildAcpSession(processConnection, options, input) {
|
|
255
|
+
const builder = processConnection.connection.agent.buildSession(options.workingDirectory);
|
|
256
|
+
for (const server of options.mcpServers?.(input) ?? []) builder.withMcpServer({
|
|
257
|
+
args: [...server.args],
|
|
258
|
+
command: server.command,
|
|
259
|
+
env: server.env.map(({ name, value }) => ({
|
|
260
|
+
name,
|
|
261
|
+
value
|
|
262
|
+
})),
|
|
263
|
+
name: server.name
|
|
264
|
+
});
|
|
265
|
+
return builder.start();
|
|
266
|
+
}
|
|
254
267
|
function createAcpStdioAgentLoop(options) {
|
|
255
268
|
let pendingConnection;
|
|
256
269
|
let activeConnection;
|
|
@@ -317,7 +330,7 @@ function createAcpStdioAgentLoop(options) {
|
|
|
317
330
|
current.dispose();
|
|
318
331
|
processConnection.sessions.delete(input.sessionKey);
|
|
319
332
|
}
|
|
320
|
-
const session = new SdkAcpAgentSession(await processConnection
|
|
333
|
+
const session = new SdkAcpAgentSession(await buildAcpSession(processConnection, options, input), processConnection.connection.agent);
|
|
321
334
|
sessionKeys.set(session.sessionId, input.sessionKey);
|
|
322
335
|
processConnection.sessions.set(input.sessionKey, session);
|
|
323
336
|
return session;
|
package/dist/agent-loop.d.ts
CHANGED
|
@@ -296,7 +296,16 @@ interface AutomationAgentInvocationOrigin {
|
|
|
296
296
|
readonly tenantKey: "automation";
|
|
297
297
|
readonly tickId: string;
|
|
298
298
|
}
|
|
299
|
-
|
|
299
|
+
interface BackgroundSessionAgentInvocationOrigin {
|
|
300
|
+
readonly allowedActorOpenIds: ReadonlyArray<string>;
|
|
301
|
+
readonly endpointId: string;
|
|
302
|
+
readonly kind: "background-session";
|
|
303
|
+
readonly memory?: AgentMemoryInvocationIdentity;
|
|
304
|
+
readonly sessionId: string;
|
|
305
|
+
readonly sourceMessageId: string;
|
|
306
|
+
readonly tenantKey: string;
|
|
307
|
+
}
|
|
308
|
+
type AgentInvocationOrigin = FeishuAgentInvocationOrigin | LocalCliAgentInvocationOrigin | AutomationAgentInvocationOrigin | BackgroundSessionAgentInvocationOrigin;
|
|
300
309
|
//#endregion
|
|
301
310
|
//#region src/application/agent/agent-loop.d.ts
|
|
302
311
|
interface AgentLoopInput {
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
//#region src/application/background-session/background-session-authority.ts
|
|
3
|
+
const BACKGROUND_SESSION_TOOL_IDS = [
|
|
4
|
+
"background.start",
|
|
5
|
+
"background.wait",
|
|
6
|
+
"background.list",
|
|
7
|
+
"background.status",
|
|
8
|
+
"background.send",
|
|
9
|
+
"background.stop"
|
|
10
|
+
];
|
|
11
|
+
const BACKGROUND_SESSION_START_TOOL_ID = "background.start";
|
|
12
|
+
const BACKGROUND_SESSION_TOOL_PLUGIN_ID = "rivus-core";
|
|
13
|
+
const BACKGROUND_SESSION_TOOL_VERSION = "1.0.0";
|
|
14
|
+
const BACKGROUND_SESSION_SESSION_KEY_PREFIX = "background";
|
|
15
|
+
function createBackgroundSessionKey(sessionId) {
|
|
16
|
+
return `${BACKGROUND_SESSION_SESSION_KEY_PREFIX}:${sessionId}`;
|
|
17
|
+
}
|
|
18
|
+
function createBackgroundSessionStepSourceMessageId(sessionId, stepCount) {
|
|
19
|
+
return `bg:${sessionId}:step:${stepCount}`;
|
|
20
|
+
}
|
|
21
|
+
function createBackgroundSessionToolContracts() {
|
|
22
|
+
return [
|
|
23
|
+
Object.freeze({
|
|
24
|
+
description: "Start a background agent session. Use when the request must wait for external changes, observe over time, or continue working after the foreground run ends. Returns a stable session id immediately; the foreground response can finish here. The detached session continues with the granted Skills, CLI, Tools, Project Space, and Memory of this agent.",
|
|
25
|
+
digest: contractDigest("background.start"),
|
|
26
|
+
id: "background.start",
|
|
27
|
+
idempotency: "supported",
|
|
28
|
+
inputSchema: Object.freeze({
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
properties: Object.freeze({
|
|
31
|
+
displayName: {
|
|
32
|
+
type: "string",
|
|
33
|
+
maxLength: 200
|
|
34
|
+
},
|
|
35
|
+
prompt: {
|
|
36
|
+
type: "string",
|
|
37
|
+
minLength: 1,
|
|
38
|
+
maxLength: 2e4
|
|
39
|
+
}
|
|
40
|
+
}),
|
|
41
|
+
required: ["prompt"],
|
|
42
|
+
type: "object"
|
|
43
|
+
}),
|
|
44
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
45
|
+
risk: "mutate",
|
|
46
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
47
|
+
}),
|
|
48
|
+
Object.freeze({
|
|
49
|
+
description: "Pause the current background session durably and end the current step. Call with delayMs to resume after a delay, with until to resume at an absolute ISO time, or with neither to wait for user input. After this call no further tool calls are accepted in this step.",
|
|
50
|
+
digest: contractDigest("background.wait"),
|
|
51
|
+
id: "background.wait",
|
|
52
|
+
idempotency: "supported",
|
|
53
|
+
inputSchema: Object.freeze({
|
|
54
|
+
additionalProperties: false,
|
|
55
|
+
properties: Object.freeze({
|
|
56
|
+
delayMs: {
|
|
57
|
+
type: "integer",
|
|
58
|
+
minimum: 1e3,
|
|
59
|
+
maximum: 864e5
|
|
60
|
+
},
|
|
61
|
+
reason: {
|
|
62
|
+
type: "string",
|
|
63
|
+
maxLength: 500
|
|
64
|
+
},
|
|
65
|
+
until: {
|
|
66
|
+
type: "string",
|
|
67
|
+
maxLength: 64
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
type: "object"
|
|
71
|
+
}),
|
|
72
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
73
|
+
risk: "mutate",
|
|
74
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
75
|
+
}),
|
|
76
|
+
Object.freeze({
|
|
77
|
+
description: "List background sessions owned by this conversation, newest first. Optionally filter by phase and limit the number of results.",
|
|
78
|
+
digest: contractDigest("background.list"),
|
|
79
|
+
id: "background.list",
|
|
80
|
+
idempotency: "supported",
|
|
81
|
+
inputSchema: Object.freeze({
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
properties: Object.freeze({
|
|
84
|
+
limit: {
|
|
85
|
+
type: "integer",
|
|
86
|
+
minimum: 1,
|
|
87
|
+
maximum: 50
|
|
88
|
+
},
|
|
89
|
+
phase: {
|
|
90
|
+
enum: [
|
|
91
|
+
"queued",
|
|
92
|
+
"running",
|
|
93
|
+
"waiting",
|
|
94
|
+
"input-required",
|
|
95
|
+
"stopping",
|
|
96
|
+
"stopped",
|
|
97
|
+
"completed",
|
|
98
|
+
"failed",
|
|
99
|
+
"reconciliation-required"
|
|
100
|
+
],
|
|
101
|
+
type: "string"
|
|
102
|
+
}
|
|
103
|
+
}),
|
|
104
|
+
type: "object"
|
|
105
|
+
}),
|
|
106
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
107
|
+
risk: "observe",
|
|
108
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
109
|
+
}),
|
|
110
|
+
Object.freeze({
|
|
111
|
+
description: "Return the current phase, step counts, wake time, and result of one background session owned by this conversation.",
|
|
112
|
+
digest: contractDigest("background.status"),
|
|
113
|
+
id: "background.status",
|
|
114
|
+
idempotency: "supported",
|
|
115
|
+
inputSchema: Object.freeze({
|
|
116
|
+
additionalProperties: false,
|
|
117
|
+
properties: Object.freeze({ sessionId: {
|
|
118
|
+
type: "string",
|
|
119
|
+
minLength: 1,
|
|
120
|
+
maxLength: 200
|
|
121
|
+
} }),
|
|
122
|
+
required: ["sessionId"],
|
|
123
|
+
type: "object"
|
|
124
|
+
}),
|
|
125
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
126
|
+
risk: "observe",
|
|
127
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
128
|
+
}),
|
|
129
|
+
Object.freeze({
|
|
130
|
+
description: "Send new user instruction text to a background session owned by this conversation and wake it. The input is delivered exactly once in the next step.",
|
|
131
|
+
digest: contractDigest("background.send"),
|
|
132
|
+
id: "background.send",
|
|
133
|
+
idempotency: "supported",
|
|
134
|
+
inputSchema: Object.freeze({
|
|
135
|
+
additionalProperties: false,
|
|
136
|
+
properties: Object.freeze({
|
|
137
|
+
message: {
|
|
138
|
+
type: "string",
|
|
139
|
+
minLength: 1,
|
|
140
|
+
maxLength: 2e4
|
|
141
|
+
},
|
|
142
|
+
sessionId: {
|
|
143
|
+
type: "string",
|
|
144
|
+
minLength: 1,
|
|
145
|
+
maxLength: 200
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
148
|
+
required: ["message", "sessionId"],
|
|
149
|
+
type: "object"
|
|
150
|
+
}),
|
|
151
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
152
|
+
risk: "mutate",
|
|
153
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
154
|
+
}),
|
|
155
|
+
Object.freeze({
|
|
156
|
+
description: "Stop a background session owned by this conversation. Persists the cancellation, aborts the active step and its owned process, and delivers a terminal notice.",
|
|
157
|
+
digest: contractDigest("background.stop"),
|
|
158
|
+
id: "background.stop",
|
|
159
|
+
idempotency: "supported",
|
|
160
|
+
inputSchema: Object.freeze({
|
|
161
|
+
additionalProperties: false,
|
|
162
|
+
properties: Object.freeze({
|
|
163
|
+
reason: {
|
|
164
|
+
type: "string",
|
|
165
|
+
maxLength: 500
|
|
166
|
+
},
|
|
167
|
+
sessionId: {
|
|
168
|
+
type: "string",
|
|
169
|
+
minLength: 1,
|
|
170
|
+
maxLength: 200
|
|
171
|
+
}
|
|
172
|
+
}),
|
|
173
|
+
required: ["sessionId"],
|
|
174
|
+
type: "object"
|
|
175
|
+
}),
|
|
176
|
+
pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
|
|
177
|
+
risk: "mutate",
|
|
178
|
+
version: BACKGROUND_SESSION_TOOL_VERSION
|
|
179
|
+
})
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
function backgroundSessionToolIds() {
|
|
183
|
+
return [...BACKGROUND_SESSION_TOOL_IDS];
|
|
184
|
+
}
|
|
185
|
+
function isBackgroundSessionToolId(toolId) {
|
|
186
|
+
return BACKGROUND_SESSION_TOOL_IDS.includes(toolId);
|
|
187
|
+
}
|
|
188
|
+
function extendBackgroundSessionDefinition(definition) {
|
|
189
|
+
const contracts = createBackgroundSessionToolContracts();
|
|
190
|
+
const existingIds = new Set(definition.tools.map(({ id }) => id));
|
|
191
|
+
const additions = contracts.filter((contract) => !existingIds.has(contract.id));
|
|
192
|
+
const toolGrantSet = Object.freeze({
|
|
193
|
+
revision: grantRevision(definition.toolGrantSet.revision, additions.map(({ id }) => id)),
|
|
194
|
+
toolIds: Object.freeze([...definition.toolGrantSet.toolIds, ...additions.map(({ id }) => id)].sort())
|
|
195
|
+
});
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
...definition,
|
|
198
|
+
tools: Object.freeze([...definition.tools, ...additions]),
|
|
199
|
+
toolGrantSet
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function narrowBackgroundSessionDefinition(definition) {
|
|
203
|
+
const childToolIds = definition.toolGrantSet.toolIds.filter((id) => id !== BACKGROUND_SESSION_START_TOOL_ID);
|
|
204
|
+
const toolGrantSet = Object.freeze({
|
|
205
|
+
revision: grantRevision(definition.toolGrantSet.revision, childToolIds),
|
|
206
|
+
toolIds: Object.freeze(childToolIds)
|
|
207
|
+
});
|
|
208
|
+
return Object.freeze({
|
|
209
|
+
...definition,
|
|
210
|
+
tools: Object.freeze(definition.tools.filter(({ id }) => id !== BACKGROUND_SESSION_START_TOOL_ID)),
|
|
211
|
+
toolGrantSet
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function grantRevision(parentRevision, toolIds) {
|
|
215
|
+
return `sha256:${createHash("sha256").update(JSON.stringify({
|
|
216
|
+
parentRevision,
|
|
217
|
+
toolIds: [...toolIds].sort()
|
|
218
|
+
})).digest("hex")}`;
|
|
219
|
+
}
|
|
220
|
+
function contractDigest(toolId) {
|
|
221
|
+
return `sha256:${createHash("sha256").update(`background-tool:${toolId}:${BACKGROUND_SESSION_TOOL_VERSION}`).digest("hex")}`;
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { BACKGROUND_SESSION_TOOL_VERSION as a, createBackgroundSessionStepSourceMessageId as c, isBackgroundSessionToolId as d, narrowBackgroundSessionDefinition as f, BACKGROUND_SESSION_TOOL_PLUGIN_ID as i, createBackgroundSessionToolContracts as l, BACKGROUND_SESSION_START_TOOL_ID as n, backgroundSessionToolIds as o, BACKGROUND_SESSION_TOOL_IDS as r, createBackgroundSessionKey as s, BACKGROUND_SESSION_SESSION_KEY_PREFIX as t, extendBackgroundSessionDefinition as u };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/application/background-session/background-session-input.ts
|
|
2
|
+
function readBackgroundSessionObject(input, allowed, error) {
|
|
3
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) throw error("background tool input must be an object");
|
|
4
|
+
const record = input;
|
|
5
|
+
const unknown = Object.keys(record).find((key) => !allowed.includes(key));
|
|
6
|
+
if (unknown) throw error(`field is not allowed: ${unknown}`);
|
|
7
|
+
return record;
|
|
8
|
+
}
|
|
9
|
+
function readBackgroundSessionString(value, name, error) {
|
|
10
|
+
if (typeof value !== "string" || value.trim() === "") throw error(`${name} must be a non-empty string`);
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function readBackgroundSessionInteger(value, name, error) {
|
|
14
|
+
if (!Number.isSafeInteger(value) || value < 1) throw error(`${name} must be a positive integer`);
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
function readBackgroundSessionPhase(value, error) {
|
|
18
|
+
const phases = [
|
|
19
|
+
"queued",
|
|
20
|
+
"running",
|
|
21
|
+
"waiting",
|
|
22
|
+
"input-required",
|
|
23
|
+
"stopping",
|
|
24
|
+
"stopped",
|
|
25
|
+
"completed",
|
|
26
|
+
"failed",
|
|
27
|
+
"reconciliation-required"
|
|
28
|
+
];
|
|
29
|
+
if (typeof value !== "string" || !phases.includes(value)) throw error(`phase must be one of ${phases.join(", ")}`);
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function readBackgroundSessionWaitInput(input, error) {
|
|
33
|
+
const { delayMs, reason, until } = readBackgroundSessionObject(input, [
|
|
34
|
+
"delayMs",
|
|
35
|
+
"reason",
|
|
36
|
+
"until"
|
|
37
|
+
], error);
|
|
38
|
+
const args = {};
|
|
39
|
+
if (delayMs !== void 0) args.delayMs = readBackgroundSessionInteger(delayMs, "delayMs", error);
|
|
40
|
+
if (reason !== void 0) args.reason = readBackgroundSessionString(reason, "reason", error);
|
|
41
|
+
if (until !== void 0) args.until = readBackgroundSessionString(until, "until", error);
|
|
42
|
+
return args;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { readBackgroundSessionWaitInput as a, readBackgroundSessionString as i, readBackgroundSessionObject as n, readBackgroundSessionPhase as r, readBackgroundSessionInteger as t };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { c as MemoryScope, n as AgentMemoryIdentity } from "./agent-memory.js";
|
|
2
|
+
import { b as RivusResolvedToolDescriptor, c as ResolvedRivusAgentDefinition, w as RivusToolExecutionContext } from "./rivus-plugin.js";
|
|
3
|
+
|
|
4
|
+
//#region src/domain/background-agent-session.d.ts
|
|
5
|
+
type BackgroundSessionId = string;
|
|
6
|
+
type BackgroundSessionPhase = "queued" | "running" | "waiting" | "input-required" | "stopping" | "stopped" | "completed" | "failed" | "reconciliation-required";
|
|
7
|
+
declare function isBackgroundSessionTerminalPhase(phase: BackgroundSessionPhase): boolean;
|
|
8
|
+
interface BackgroundSessionLease {
|
|
9
|
+
readonly owner: string;
|
|
10
|
+
readonly epoch: number;
|
|
11
|
+
readonly expiresAt: string;
|
|
12
|
+
}
|
|
13
|
+
interface BackgroundSessionOrigin {
|
|
14
|
+
readonly endpointId: string;
|
|
15
|
+
readonly tenantKey: string;
|
|
16
|
+
readonly conversationId?: string;
|
|
17
|
+
readonly allowedActorOpenIds: ReadonlyArray<string>;
|
|
18
|
+
readonly memory?: AgentMemoryIdentity;
|
|
19
|
+
}
|
|
20
|
+
interface BackgroundSessionAuthority {
|
|
21
|
+
readonly agentId: string;
|
|
22
|
+
readonly profileRevision: string;
|
|
23
|
+
readonly toolGrantRevision: string;
|
|
24
|
+
readonly policyEpoch: number;
|
|
25
|
+
readonly memoryScopes: ReadonlyArray<MemoryScope>;
|
|
26
|
+
readonly projectSpaceId?: string;
|
|
27
|
+
readonly sessionKey: string;
|
|
28
|
+
}
|
|
29
|
+
interface BackgroundSessionTerminalResult {
|
|
30
|
+
readonly text: string;
|
|
31
|
+
readonly stepRunId: string;
|
|
32
|
+
readonly completedAt: string;
|
|
33
|
+
}
|
|
34
|
+
interface BackgroundSessionCancellation {
|
|
35
|
+
readonly reason: string;
|
|
36
|
+
readonly requestedAt: string;
|
|
37
|
+
}
|
|
38
|
+
interface BackgroundSessionState {
|
|
39
|
+
readonly sessionId: BackgroundSessionId;
|
|
40
|
+
readonly displayName: string;
|
|
41
|
+
readonly phase: BackgroundSessionPhase;
|
|
42
|
+
readonly revision: number;
|
|
43
|
+
readonly parentRunId: string;
|
|
44
|
+
readonly sourceMessageId: string;
|
|
45
|
+
readonly origin: BackgroundSessionOrigin;
|
|
46
|
+
readonly authority: BackgroundSessionAuthority;
|
|
47
|
+
readonly prompt: string;
|
|
48
|
+
readonly stepCount: number;
|
|
49
|
+
readonly wakeCount: number;
|
|
50
|
+
readonly currentStepRunId?: string;
|
|
51
|
+
readonly lastWakeText?: string;
|
|
52
|
+
readonly pendingInput: ReadonlyArray<string>;
|
|
53
|
+
readonly wakeAt?: string;
|
|
54
|
+
readonly lease?: BackgroundSessionLease;
|
|
55
|
+
readonly cancellation?: BackgroundSessionCancellation;
|
|
56
|
+
readonly consecutiveFailures: number;
|
|
57
|
+
readonly result?: BackgroundSessionTerminalResult;
|
|
58
|
+
readonly errorMessage?: string;
|
|
59
|
+
readonly reconciliationNote?: string;
|
|
60
|
+
readonly createdAt: string;
|
|
61
|
+
readonly updatedAt: string;
|
|
62
|
+
}
|
|
63
|
+
declare class BackgroundSessionTransitionDenied extends Error {
|
|
64
|
+
readonly sessionId: BackgroundSessionId;
|
|
65
|
+
readonly name = "BackgroundSessionTransitionDenied";
|
|
66
|
+
constructor(sessionId: BackgroundSessionId, message: string);
|
|
67
|
+
}
|
|
68
|
+
interface CreateBackgroundSessionInput {
|
|
69
|
+
readonly sessionId: BackgroundSessionId;
|
|
70
|
+
readonly displayName: string;
|
|
71
|
+
readonly prompt: string;
|
|
72
|
+
readonly parentRunId: string;
|
|
73
|
+
readonly sourceMessageId: string;
|
|
74
|
+
readonly origin: BackgroundSessionOrigin;
|
|
75
|
+
readonly authority: BackgroundSessionAuthority;
|
|
76
|
+
readonly now: string;
|
|
77
|
+
}
|
|
78
|
+
declare function createBackgroundSession(input: CreateBackgroundSessionInput): BackgroundSessionState;
|
|
79
|
+
interface ClaimBackgroundSessionInput {
|
|
80
|
+
readonly lease: BackgroundSessionLease;
|
|
81
|
+
readonly stepRunId: string;
|
|
82
|
+
readonly wakeText: string;
|
|
83
|
+
readonly now: string;
|
|
84
|
+
}
|
|
85
|
+
declare function claimBackgroundSession(state: BackgroundSessionState, input: ClaimBackgroundSessionInput): BackgroundSessionState;
|
|
86
|
+
declare function renewBackgroundSessionLease(state: BackgroundSessionState, lease: BackgroundSessionLease): BackgroundSessionState;
|
|
87
|
+
declare function releaseBackgroundSessionLease(state: BackgroundSessionState): BackgroundSessionState;
|
|
88
|
+
interface SuspendBackgroundSessionInput {
|
|
89
|
+
readonly wakeAt?: string;
|
|
90
|
+
readonly reason?: string;
|
|
91
|
+
readonly now: string;
|
|
92
|
+
}
|
|
93
|
+
declare function suspendBackgroundSession(state: BackgroundSessionState, input: SuspendBackgroundSessionInput): BackgroundSessionState;
|
|
94
|
+
declare function completeBackgroundSessionStep(state: BackgroundSessionState, input: {
|
|
95
|
+
readonly text: string;
|
|
96
|
+
readonly stepRunId: string;
|
|
97
|
+
readonly now: string;
|
|
98
|
+
}): BackgroundSessionState;
|
|
99
|
+
declare function failBackgroundSessionStep(state: BackgroundSessionState, input: {
|
|
100
|
+
readonly errorMessage: string;
|
|
101
|
+
readonly now: string;
|
|
102
|
+
readonly retryable: boolean;
|
|
103
|
+
readonly wakeAt?: string;
|
|
104
|
+
}): BackgroundSessionState;
|
|
105
|
+
declare function requestBackgroundSessionStop(state: BackgroundSessionState, input: {
|
|
106
|
+
readonly reason: string;
|
|
107
|
+
readonly now: string;
|
|
108
|
+
}): BackgroundSessionState;
|
|
109
|
+
declare function completeBackgroundSessionStop(state: BackgroundSessionState, input: {
|
|
110
|
+
readonly now: string;
|
|
111
|
+
}): BackgroundSessionState;
|
|
112
|
+
declare function parkBackgroundSessionForReconciliation(state: BackgroundSessionState, input: {
|
|
113
|
+
readonly reason: string;
|
|
114
|
+
readonly now: string;
|
|
115
|
+
}): BackgroundSessionState;
|
|
116
|
+
declare function resolveBackgroundSessionReconciliation(state: BackgroundSessionState, input: {
|
|
117
|
+
readonly outcome: "continue" | "stop";
|
|
118
|
+
readonly now: string;
|
|
119
|
+
}): BackgroundSessionState;
|
|
120
|
+
declare function appendBackgroundSessionInput(state: BackgroundSessionState, input: {
|
|
121
|
+
readonly message: string;
|
|
122
|
+
readonly now: string;
|
|
123
|
+
}): BackgroundSessionState;
|
|
124
|
+
declare function requeueInterruptedBackgroundSessionStep(state: BackgroundSessionState, input: {
|
|
125
|
+
readonly wakeText: string;
|
|
126
|
+
readonly now: string;
|
|
127
|
+
}): BackgroundSessionState;
|
|
128
|
+
declare function isBackgroundSessionLeaseExpired(state: BackgroundSessionState, now: string): boolean;
|
|
129
|
+
declare function isBackgroundSessionDue(state: BackgroundSessionState, now: string): boolean;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/application/background-session/background-session-repository.d.ts
|
|
132
|
+
interface BackgroundSessionLeasePrecondition {
|
|
133
|
+
readonly kind: "absent";
|
|
134
|
+
}
|
|
135
|
+
interface BackgroundSessionLeaseRequirement {
|
|
136
|
+
readonly kind: "held";
|
|
137
|
+
readonly owner: string;
|
|
138
|
+
readonly epoch: number;
|
|
139
|
+
}
|
|
140
|
+
interface BackgroundSessionLeaseStaleOrAbsent {
|
|
141
|
+
readonly kind: "absent-or-stale";
|
|
142
|
+
}
|
|
143
|
+
interface BackgroundSessionRepository {
|
|
144
|
+
create(state: BackgroundSessionState): Promise<BackgroundSessionState>;
|
|
145
|
+
get(sessionId: string): Promise<BackgroundSessionState | undefined>;
|
|
146
|
+
list(options?: {
|
|
147
|
+
readonly phase?: BackgroundSessionPhase;
|
|
148
|
+
readonly limit?: number;
|
|
149
|
+
}): Promise<ReadonlyArray<BackgroundSessionState>>;
|
|
150
|
+
update(input: {
|
|
151
|
+
readonly sessionId: string;
|
|
152
|
+
readonly expectedRevision: number;
|
|
153
|
+
readonly expectedLease?: BackgroundSessionLeasePrecondition | BackgroundSessionLeaseRequirement | BackgroundSessionLeaseStaleOrAbsent;
|
|
154
|
+
readonly now?: string;
|
|
155
|
+
readonly build: (state: BackgroundSessionState) => BackgroundSessionState;
|
|
156
|
+
}): Promise<BackgroundSessionState | undefined>;
|
|
157
|
+
}
|
|
158
|
+
declare class BackgroundSessionRepositoryConflict extends Error {
|
|
159
|
+
readonly name = "BackgroundSessionRepositoryConflict";
|
|
160
|
+
constructor(sessionId: string, message: string);
|
|
161
|
+
}
|
|
162
|
+
declare class BackgroundSessionRepositoryCorrupted extends Error {
|
|
163
|
+
readonly name = "BackgroundSessionRepositoryCorrupted";
|
|
164
|
+
}
|
|
165
|
+
interface CreateBackgroundSessionRepositoryOptions {
|
|
166
|
+
readonly initial?: ReadonlyArray<BackgroundSessionState>;
|
|
167
|
+
readonly persist?: (state: BackgroundSessionState) => Promise<void>;
|
|
168
|
+
}
|
|
169
|
+
declare function createBackgroundSessionRepository(options?: CreateBackgroundSessionRepositoryOptions): BackgroundSessionRepository;
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/application/background-session/background-session-delivery-store.d.ts
|
|
172
|
+
type BackgroundSessionDeliveryKind = "progress" | "final" | "stopped" | "failed" | "reconciliation";
|
|
173
|
+
interface BackgroundSessionDeliveryRecord {
|
|
174
|
+
readonly deliveryId: string;
|
|
175
|
+
readonly sessionId: string;
|
|
176
|
+
readonly kind: BackgroundSessionDeliveryKind;
|
|
177
|
+
readonly text: string;
|
|
178
|
+
readonly state: "pending" | "delivered";
|
|
179
|
+
readonly revision: number;
|
|
180
|
+
readonly providerMessageId?: string;
|
|
181
|
+
readonly createdAt: string;
|
|
182
|
+
}
|
|
183
|
+
interface BackgroundSessionDeliveryStore {
|
|
184
|
+
enqueue(input: {
|
|
185
|
+
readonly deliveryId: string;
|
|
186
|
+
readonly sessionId: string;
|
|
187
|
+
readonly kind: BackgroundSessionDeliveryKind;
|
|
188
|
+
readonly text: string;
|
|
189
|
+
readonly createdAt: string;
|
|
190
|
+
}): Promise<BackgroundSessionDeliveryRecord>;
|
|
191
|
+
pending(): Promise<ReadonlyArray<BackgroundSessionDeliveryRecord>>;
|
|
192
|
+
markDelivered(deliveryId: string, providerMessageId: string): Promise<BackgroundSessionDeliveryRecord | undefined>;
|
|
193
|
+
}
|
|
194
|
+
declare class BackgroundSessionDeliveryConflict extends Error {
|
|
195
|
+
readonly name = "BackgroundSessionDeliveryConflict";
|
|
196
|
+
constructor(deliveryId: string, message: string);
|
|
197
|
+
}
|
|
198
|
+
interface CreateBackgroundSessionDeliveryStoreOptions {
|
|
199
|
+
readonly initial?: ReadonlyArray<BackgroundSessionDeliveryRecord>;
|
|
200
|
+
readonly persist?: (record: BackgroundSessionDeliveryRecord) => Promise<void>;
|
|
201
|
+
}
|
|
202
|
+
declare function createBackgroundSessionDeliveryStore(options?: CreateBackgroundSessionDeliveryStoreOptions): BackgroundSessionDeliveryStore;
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/application/background-session/background-session-authority.d.ts
|
|
205
|
+
declare const BACKGROUND_SESSION_TOOL_IDS: readonly ["background.start", "background.wait", "background.list", "background.status", "background.send", "background.stop"];
|
|
206
|
+
declare const BACKGROUND_SESSION_START_TOOL_ID = "background.start";
|
|
207
|
+
declare const BACKGROUND_SESSION_TOOL_PLUGIN_ID = "rivus-core";
|
|
208
|
+
declare const BACKGROUND_SESSION_TOOL_VERSION = "1.0.0";
|
|
209
|
+
declare const BACKGROUND_SESSION_SESSION_KEY_PREFIX = "background";
|
|
210
|
+
declare function createBackgroundSessionKey(sessionId: string): string;
|
|
211
|
+
declare function createBackgroundSessionStepSourceMessageId(sessionId: string, stepCount: number): string;
|
|
212
|
+
interface BackgroundSessionToolContract extends RivusResolvedToolDescriptor {}
|
|
213
|
+
declare function createBackgroundSessionToolContracts(): ReadonlyArray<BackgroundSessionToolContract>;
|
|
214
|
+
declare function backgroundSessionToolIds(): ReadonlyArray<string>;
|
|
215
|
+
declare function isBackgroundSessionToolId(toolId: string): boolean;
|
|
216
|
+
declare function extendBackgroundSessionDefinition(definition: ResolvedRivusAgentDefinition): ResolvedRivusAgentDefinition;
|
|
217
|
+
declare function narrowBackgroundSessionDefinition(definition: ResolvedRivusAgentDefinition): ResolvedRivusAgentDefinition;
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/application/background-session/background-session-service.d.ts
|
|
220
|
+
interface BackgroundSessionSummary {
|
|
221
|
+
readonly sessionId: string;
|
|
222
|
+
readonly displayName: string;
|
|
223
|
+
readonly phase: BackgroundSessionPhase;
|
|
224
|
+
readonly stepCount: number;
|
|
225
|
+
readonly wakeAt?: string;
|
|
226
|
+
readonly createdAt: string;
|
|
227
|
+
readonly updatedAt: string;
|
|
228
|
+
}
|
|
229
|
+
interface BackgroundSessionDetail extends BackgroundSessionSummary {
|
|
230
|
+
readonly parentRunId: string;
|
|
231
|
+
readonly pendingInput: ReadonlyArray<string>;
|
|
232
|
+
readonly result?: BackgroundSessionState["result"];
|
|
233
|
+
readonly errorMessage?: string;
|
|
234
|
+
readonly cancellationReason?: string;
|
|
235
|
+
readonly reconciliationNote?: string;
|
|
236
|
+
}
|
|
237
|
+
declare class BackgroundSessionCallerDenied extends Error {
|
|
238
|
+
readonly name = "BackgroundSessionCallerDenied";
|
|
239
|
+
constructor(message: string);
|
|
240
|
+
}
|
|
241
|
+
interface BackgroundSessionServiceOptions {
|
|
242
|
+
readonly clock: {
|
|
243
|
+
now(): string;
|
|
244
|
+
};
|
|
245
|
+
readonly deliveries: BackgroundSessionDeliveryStore;
|
|
246
|
+
readonly repository: BackgroundSessionRepository;
|
|
247
|
+
}
|
|
248
|
+
interface BackgroundSessionService {
|
|
249
|
+
list(input: {
|
|
250
|
+
readonly context: RivusToolExecutionContext;
|
|
251
|
+
readonly limit?: number;
|
|
252
|
+
readonly phase?: BackgroundSessionPhase;
|
|
253
|
+
}): Promise<ReadonlyArray<BackgroundSessionSummary>>;
|
|
254
|
+
resolveReconciliation(input: {
|
|
255
|
+
readonly outcome: "continue" | "stop";
|
|
256
|
+
readonly sessionId: string;
|
|
257
|
+
}): Promise<BackgroundSessionSummary>;
|
|
258
|
+
send(input: {
|
|
259
|
+
readonly context: RivusToolExecutionContext;
|
|
260
|
+
readonly message: string;
|
|
261
|
+
readonly sessionId: string;
|
|
262
|
+
}): Promise<BackgroundSessionSummary>;
|
|
263
|
+
start(input: {
|
|
264
|
+
readonly authority: BackgroundSessionAuthority;
|
|
265
|
+
readonly context: RivusToolExecutionContext;
|
|
266
|
+
readonly displayName?: string;
|
|
267
|
+
readonly prompt: string;
|
|
268
|
+
readonly sessionId: string;
|
|
269
|
+
}): Promise<BackgroundSessionSummary>;
|
|
270
|
+
status(input: {
|
|
271
|
+
readonly context: RivusToolExecutionContext;
|
|
272
|
+
readonly sessionId: string;
|
|
273
|
+
}): Promise<BackgroundSessionDetail>;
|
|
274
|
+
stop(input: {
|
|
275
|
+
readonly context: RivusToolExecutionContext;
|
|
276
|
+
readonly reason?: string;
|
|
277
|
+
readonly sessionId: string;
|
|
278
|
+
}): Promise<BackgroundSessionSummary>;
|
|
279
|
+
wait(input: {
|
|
280
|
+
readonly context: RivusToolExecutionContext;
|
|
281
|
+
readonly delayMs?: number;
|
|
282
|
+
readonly reason?: string;
|
|
283
|
+
readonly until?: string;
|
|
284
|
+
}): Promise<BackgroundSessionSummary>;
|
|
285
|
+
}
|
|
286
|
+
declare function createBackgroundSessionService(options: BackgroundSessionServiceOptions): BackgroundSessionService;
|
|
287
|
+
declare function sessionIdFromSessionKey(sessionKey: string): string | undefined;
|
|
288
|
+
declare function terminalDeliveryId(sessionId: string, kind: BackgroundSessionDeliveryKind): string;
|
|
289
|
+
declare function progressDeliveryId(sessionId: string, stepCount: number): string;
|
|
290
|
+
//#endregion
|
|
291
|
+
export { suspendBackgroundSession as $, BackgroundSessionCancellation as A, completeBackgroundSessionStep as B, BackgroundSessionDeliveryStore as C, BackgroundSessionRepositoryCorrupted as D, BackgroundSessionRepositoryConflict as E, BackgroundSessionState as F, isBackgroundSessionLeaseExpired as G, createBackgroundSession as H, BackgroundSessionTerminalResult as I, releaseBackgroundSessionLease as J, isBackgroundSessionTerminalPhase as K, BackgroundSessionTransitionDenied as L, BackgroundSessionLease as M, BackgroundSessionOrigin as N, createBackgroundSessionRepository as O, BackgroundSessionPhase as P, resolveBackgroundSessionReconciliation as Q, appendBackgroundSessionInput as R, BackgroundSessionDeliveryRecord as S, BackgroundSessionRepository as T, failBackgroundSessionStep as U, completeBackgroundSessionStop as V, isBackgroundSessionDue as W, requestBackgroundSessionStop as X, renewBackgroundSessionLease as Y, requeueInterruptedBackgroundSessionStep as Z, createBackgroundSessionToolContracts as _, createBackgroundSessionService as a, narrowBackgroundSessionDefinition as b, terminalDeliveryId as c, BACKGROUND_SESSION_TOOL_IDS as d, BACKGROUND_SESSION_TOOL_PLUGIN_ID as f, createBackgroundSessionStepSourceMessageId as g, createBackgroundSessionKey as h, BackgroundSessionSummary as i, BackgroundSessionId as j, BackgroundSessionAuthority as k, BACKGROUND_SESSION_SESSION_KEY_PREFIX as l, backgroundSessionToolIds as m, BackgroundSessionDetail as n, progressDeliveryId as o, BACKGROUND_SESSION_TOOL_VERSION as p, parkBackgroundSessionForReconciliation as q, BackgroundSessionService as r, sessionIdFromSessionKey as s, BackgroundSessionCallerDenied as t, BACKGROUND_SESSION_START_TOOL_ID as u, extendBackgroundSessionDefinition as v, createBackgroundSessionDeliveryStore as w, BackgroundSessionDeliveryConflict as x, isBackgroundSessionToolId as y, claimBackgroundSession as z };
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { D as loadRivusDeploymentManifest,
|
|
2
|
+
import { D as loadRivusDeploymentManifest, T as resolveNodeRivusPluginModulePath, X as resolveFeishuEndpointCredentials, Z as loadMergedLocalEnvFile, et as validateRivusDeploymentManifest, t as runRivusDaemonCli } from "./rivus-daemon-cli.js";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|