@rivus/agent 0.6.2 → 0.7.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.
@@ -94,6 +94,9 @@ interface InvocationAuthorityRef {
94
94
  }
95
95
  interface InvocationAuthority {
96
96
  readonly agentId: string;
97
+ readonly allowedActorOpenIds?: ReadonlyArray<string>;
98
+ readonly conversationId?: string;
99
+ readonly endpointId?: string;
97
100
  readonly instanceId: string;
98
101
  readonly memory?: AgentMemoryAuthority;
99
102
  readonly runId: string;
package/dist/pi.js CHANGED
@@ -88,6 +88,9 @@ function createPiToolProxyDefinitions(options) {
88
88
  const result = await options.broker.execute({
89
89
  authority: createInvocationAuthority({
90
90
  agentId: options.agentId,
91
+ allowedActorOpenIds: invocation.allowedActorOpenIds,
92
+ ...invocation.memory?.conversationId ? { conversationId: invocation.memory.conversationId } : {},
93
+ endpointId: invocation.endpointId,
91
94
  instanceId: options.instanceId,
92
95
  ...invocation.memory ? { memory: {
93
96
  ...invocation.memory,
@@ -1,5 +1,5 @@
1
1
  import { t as MEMORY_SCOPES } from "./agent-memory.js";
2
- import { n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
2
+ import { h as narrowBackgroundSessionDefinition, n as resolveRivusAgentDefinition, r as deepFreeze, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { Effect } from "effect";
5
5
  import { createHash, randomUUID } from "node:crypto";
@@ -109,7 +109,7 @@ async function loadRivusDeployment(options) {
109
109
  continue;
110
110
  }
111
111
  try {
112
- const baseDefinition = resolveRivusAgentDefinition(catalog, agent);
112
+ const baseDefinition = resolveRivusAgentDefinition(catalog, agent, { backgroundSessions: options.manifest.backgroundSessions?.enabled === true });
113
113
  const projectSpace = agent.projectSpaceId ? options.manifest.projectSpaces?.find(({ id }) => id === agent.projectSpaceId) : void 0;
114
114
  const definition = projectSpace ? deepFreeze({
115
115
  ...baseDefinition,
@@ -224,6 +224,13 @@ function validateRivusDeploymentManifest(manifest) {
224
224
  if (!defaultEndpoint) throw new Error(`default endpoint does not exist: ${manifest.defaultEndpointId}`);
225
225
  if (defaultEndpoint.agentId !== defaultAgent.agentId) throw new Error("default endpoint is not bound to the default agent");
226
226
  if (!defaultEndpoint.enabled) throw new Error("default endpoint must be enabled");
227
+ if (manifest.backgroundSessions) validateBackgroundSessions(manifest.backgroundSessions);
228
+ }
229
+ function validateBackgroundSessions(config) {
230
+ if (config.required && !config.enabled) throw new Error("backgroundSessions.required requires backgroundSessions.enabled");
231
+ if (config.leaseRenewalIntervalMs >= config.leaseMs) throw new Error("backgroundSessions.leaseRenewalIntervalMs must be shorter than leaseMs");
232
+ if (config.stepTimeoutMs <= 0 || config.maxConcurrentSessions <= 0 || config.leaseMs <= 0) throw new Error("backgroundSessions durations and concurrency must be positive");
233
+ if (config.retryBackoffMs <= 0 || config.sessionLifetimeMs <= 0 || config.maxConsecutiveFailures <= 0) throw new Error("backgroundSessions retry and lifetime limits must be positive");
227
234
  }
228
235
  function validateRelativeProjectPath(value, owner) {
229
236
  if (value.trim() === "" || isAbsolute(value) || value.includes("\0")) throw new Error(`${owner} must be a non-empty relative path`);
@@ -656,6 +663,19 @@ function createCounters() {
656
663
  };
657
664
  }
658
665
  //#endregion
666
+ //#region src/application/background-session/background-session-config.ts
667
+ const DEFAULT_BACKGROUND_SESSION_STEP_TIMEOUT_MS = 300 * 1e3;
668
+ const DEFAULT_BACKGROUND_SESSION_MAX_CONCURRENT_SESSIONS = 4;
669
+ const DEFAULT_BACKGROUND_SESSION_LEASE_MS = 3e4;
670
+ const DEFAULT_BACKGROUND_SESSION_LEASE_RENEWAL_INTERVAL_MS = 1e4;
671
+ const DEFAULT_BACKGROUND_SESSION_MAX_CONSECUTIVE_FAILURES = 3;
672
+ const DEFAULT_BACKGROUND_SESSION_RETRY_BACKOFF_MS = 3e4;
673
+ const DEFAULT_BACKGROUND_SESSION_LIFETIME_MS = 1440 * 60 * 1e3;
674
+ const DEFAULT_BACKGROUND_SESSION_SUPERVISOR_INTERVAL_MS = 1e3;
675
+ function resolveBackgroundSessionSupervisorIntervalMs(leaseMs) {
676
+ return Math.min(5e3, Math.max(200, Math.floor(leaseMs / 10)));
677
+ }
678
+ //#endregion
659
679
  //#region src/infrastructure/config/rivus-deployment-manifest.ts
660
680
  var RivusDeploymentManifestError = class extends Error {
661
681
  manifestPath;
@@ -684,12 +704,17 @@ function parseManifest(value) {
684
704
  exactKeys(root, [
685
705
  "agents",
686
706
  "automations",
707
+ "backgroundSessions",
687
708
  "defaultAgentId",
688
709
  "defaultEndpointId",
689
710
  "endpoints",
690
711
  "plugins",
691
712
  "projectSpaces"
692
- ], "manifest", ["automations", "projectSpaces"]);
713
+ ], "manifest", [
714
+ "automations",
715
+ "backgroundSessions",
716
+ "projectSpaces"
717
+ ]);
693
718
  const plugins = array(root.plugins, "manifest.plugins").map((entry, index) => {
694
719
  const plugin = record(entry, `manifest.plugins[${index}]`);
695
720
  exactKeys(plugin, [
@@ -816,9 +841,11 @@ function parseManifest(value) {
816
841
  workingDirectory: string(projectSpace.workingDirectory, `manifest.projectSpaces[${index}].workingDirectory`)
817
842
  });
818
843
  });
844
+ const backgroundSessions = root.backgroundSessions === void 0 ? void 0 : parseBackgroundSessions(record(root.backgroundSessions, "manifest.backgroundSessions"));
819
845
  return Object.freeze({
820
846
  agents: Object.freeze(agents),
821
847
  automations: Object.freeze(automations),
848
+ ...backgroundSessions ? { backgroundSessions } : {},
822
849
  defaultAgentId: string(root.defaultAgentId, "manifest.defaultAgentId"),
823
850
  defaultEndpointId: string(root.defaultEndpointId, "manifest.defaultEndpointId"),
824
851
  endpoints: Object.freeze(endpoints),
@@ -826,6 +853,38 @@ function parseManifest(value) {
826
853
  projectSpaces: Object.freeze(projectSpaces)
827
854
  });
828
855
  }
856
+ function parseBackgroundSessions(value) {
857
+ exactKeys(value, [
858
+ "enabled",
859
+ "leaseMs",
860
+ "leaseRenewalIntervalMs",
861
+ "maxConsecutiveFailures",
862
+ "maxConcurrentSessions",
863
+ "required",
864
+ "retryBackoffMs",
865
+ "sessionLifetimeMs",
866
+ "stepTimeoutMs"
867
+ ], "manifest.backgroundSessions", [
868
+ "leaseMs",
869
+ "leaseRenewalIntervalMs",
870
+ "maxConsecutiveFailures",
871
+ "maxConcurrentSessions",
872
+ "retryBackoffMs",
873
+ "sessionLifetimeMs",
874
+ "stepTimeoutMs"
875
+ ]);
876
+ return Object.freeze({
877
+ enabled: boolean(value.enabled, "manifest.backgroundSessions.enabled"),
878
+ required: boolean(value.required, "manifest.backgroundSessions.required"),
879
+ stepTimeoutMs: positiveInteger(value.stepTimeoutMs ?? 3e5, "manifest.backgroundSessions.stepTimeoutMs"),
880
+ maxConcurrentSessions: positiveInteger(value.maxConcurrentSessions ?? 4, "manifest.backgroundSessions.maxConcurrentSessions"),
881
+ leaseMs: positiveInteger(value.leaseMs ?? 3e4, "manifest.backgroundSessions.leaseMs"),
882
+ leaseRenewalIntervalMs: positiveInteger(value.leaseRenewalIntervalMs ?? 1e4, "manifest.backgroundSessions.leaseRenewalIntervalMs"),
883
+ maxConsecutiveFailures: positiveInteger(value.maxConsecutiveFailures ?? 3, "manifest.backgroundSessions.maxConsecutiveFailures"),
884
+ retryBackoffMs: positiveInteger(value.retryBackoffMs ?? 3e4, "manifest.backgroundSessions.retryBackoffMs"),
885
+ sessionLifetimeMs: positiveInteger(value.sessionLifetimeMs ?? 864e5, "manifest.backgroundSessions.sessionLifetimeMs")
886
+ });
887
+ }
829
888
  function record(value, path) {
830
889
  if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error(`${path} must be an object`);
831
890
  return value;
@@ -1192,7 +1251,7 @@ function createAgentInstanceRegistry(options = {}) {
1192
1251
  skillGrantRevision: definition.skillGrantSet.revision,
1193
1252
  toolGrantRevision: definition.toolGrantSet.revision
1194
1253
  });
1195
- const bindingId = binding.kind === "endpoint" ? binding.endpointId : binding.automationId;
1254
+ const bindingId = binding.kind === "endpoint" ? binding.endpointId : binding.kind === "automation" ? binding.automationId : binding.agentId;
1196
1255
  const bindingKey = `${binding.kind}:${bindingId}:${definition.agentId}`;
1197
1256
  const existing = records.get(bindingKey);
1198
1257
  if (existing) {
@@ -1217,6 +1276,10 @@ function createAgentInstanceRegistry(options = {}) {
1217
1276
  automationId,
1218
1277
  kind: "automation"
1219
1278
  }, definition),
1279
+ resolveBackgroundSession: (agentId, definition) => resolveBinding({
1280
+ agentId,
1281
+ kind: "background-session"
1282
+ }, definition),
1220
1283
  resolveEndpoint: (endpointId, definition) => resolveBinding({
1221
1284
  endpointId,
1222
1285
  kind: "endpoint"
@@ -1296,6 +1359,7 @@ function createRivusAgentHost(options) {
1296
1359
  const definitions = new Map(options.definitions.map((definition) => [definition.agentId, definition]));
1297
1360
  const endpoints = /* @__PURE__ */ new Map();
1298
1361
  const automations = /* @__PURE__ */ new Map();
1362
+ const backgroundSessions = /* @__PURE__ */ new Map();
1299
1363
  for (const endpoint of options.endpoints) {
1300
1364
  if (endpoints.has(endpoint.id)) throw new InvalidRivusEndpointBinding(`duplicate endpoint: ${endpoint.id}`);
1301
1365
  const definition = definitions.get(endpoint.agentId);
@@ -1308,6 +1372,11 @@ function createRivusAgentHost(options) {
1308
1372
  if (!definitions.has(automation.definition.agentId)) throw new InvalidRivusEndpointBinding(`unknown automation agent: ${automation.definition.agentId}`);
1309
1373
  automations.set(automation.id, options.runtimePool.registry.resolveAutomation(automation.id, automation.definition));
1310
1374
  }
1375
+ for (const backgroundSession of options.backgroundSessions ?? []) {
1376
+ if (backgroundSessions.has(backgroundSession.agentId)) throw new InvalidRivusEndpointBinding(`duplicate background session agent: ${backgroundSession.agentId}`);
1377
+ if (!definitions.has(backgroundSession.agentId)) throw new InvalidRivusEndpointBinding(`unknown background session agent: ${backgroundSession.agentId}`);
1378
+ backgroundSessions.set(backgroundSession.agentId, options.runtimePool.registry.resolveBackgroundSession(backgroundSession.agentId, backgroundSession.definition));
1379
+ }
1311
1380
  const resolveEndpoint = (endpointId) => {
1312
1381
  const instance = endpoints.get(endpointId);
1313
1382
  if (!instance) throw new InvalidRivusEndpointBinding(`unknown endpoint: ${endpointId}`);
@@ -1318,11 +1387,19 @@ function createRivusAgentHost(options) {
1318
1387
  if (!instance) throw new InvalidRivusEndpointBinding(`unknown automation: ${automationId}`);
1319
1388
  return instance;
1320
1389
  };
1390
+ const resolveBackgroundSession = (agentId) => {
1391
+ const instance = backgroundSessions.get(agentId);
1392
+ if (!instance) throw new InvalidRivusEndpointBinding(`unknown background session agent: ${agentId}`);
1393
+ return instance;
1394
+ };
1321
1395
  return {
1396
+ cancelBackgroundSession: (agentId, input) => options.runtimePool.cancel(resolveBackgroundSession(agentId), input),
1322
1397
  cancelEndpoint: (endpointId, input) => options.runtimePool.cancel(resolveEndpoint(endpointId), input),
1323
1398
  handleAutomation: (automationId, input) => options.runtimePool.run(resolveAutomation(automationId), input),
1399
+ handleBackgroundSession: (agentId, input) => options.runtimePool.run(resolveBackgroundSession(agentId), input),
1324
1400
  handleEndpoint: (endpointId, input) => options.runtimePool.run(resolveEndpoint(endpointId), input),
1325
1401
  resolveAutomation,
1402
+ resolveBackgroundSession,
1326
1403
  resolveEndpoint
1327
1404
  };
1328
1405
  }
@@ -1359,9 +1436,15 @@ async function createRivusDeploymentDaemon(options) {
1359
1436
  })));
1360
1437
  const definitions = new Map(deployment.definitions.map((definition) => [definition.agentId, definition]));
1361
1438
  const automationDefinitions = new Map(deployment.automationDefinitions.map((definition) => [definition.id, definition]));
1439
+ const backgroundSessionsConfig = deployment.manifest.backgroundSessions;
1440
+ const backgroundDefinitions = /* @__PURE__ */ new Map();
1441
+ if (backgroundSessionsConfig?.enabled) for (const agent of deployment.agents) {
1442
+ if (agent.status !== "enabled" || !agent.definition) continue;
1443
+ backgroundDefinitions.set(agent.agentId, narrowBackgroundSessionDefinition(agent.definition));
1444
+ }
1362
1445
  const runtimePool = createAgentRuntimePool({
1363
1446
  createRuntime: (instance) => {
1364
- const definition = instance.binding.kind === "automation" ? automationDefinitions.get(instance.binding.automationId)?.runtimeDefinition : definitions.get(instance.agentId);
1447
+ const definition = instance.binding.kind === "automation" ? automationDefinitions.get(instance.binding.automationId)?.runtimeDefinition : instance.binding.kind === "background-session" ? backgroundDefinitions.get(instance.agentId) : definitions.get(instance.agentId);
1365
1448
  if (!definition) throw new RivusDeploymentDaemonLifecycleError(`runtime instance references unknown agent: ${instance.agentId}`);
1366
1449
  const projectSpace = definition.projectSpaceId ? projectSpaces.get(definition.projectSpaceId) : void 0;
1367
1450
  return options.createRuntime({
@@ -1392,11 +1475,20 @@ async function createRivusDeploymentDaemon(options) {
1392
1475
  lifecycle: definition.enabled && agentEnabled ? "stopped" : "disabled"
1393
1476
  };
1394
1477
  });
1478
+ const backgroundSessionSlot = backgroundSessionsConfig ? {
1479
+ agentEnabled: backgroundDefinitions.size > 0,
1480
+ definition: backgroundSessionsConfig,
1481
+ lifecycle: backgroundSessionsConfig.enabled && backgroundDefinitions.size > 0 ? "stopped" : "disabled"
1482
+ } : void 0;
1395
1483
  const host = createRivusAgentHost({
1396
1484
  automations: automationSlots.filter((slot) => slot.definition.enabled && slot.agentEnabled && slot.resolvedDefinition !== void 0).map((slot) => ({
1397
1485
  definition: slot.resolvedDefinition.runtimeDefinition,
1398
1486
  id: slot.definition.id
1399
1487
  })),
1488
+ ...backgroundSessionSlot ? { backgroundSessions: [...backgroundDefinitions].map(([agentId, definition]) => ({
1489
+ agentId,
1490
+ definition
1491
+ })) } : {},
1400
1492
  definitions: deployment.definitions,
1401
1493
  endpoints: slots.filter((slot) => slot.definition.enabled && slot.agentEnabled).map((slot) => ({
1402
1494
  agentId: slot.definition.agentId,
@@ -1424,7 +1516,15 @@ async function createRivusDeploymentDaemon(options) {
1424
1516
  agentId: slot.definition.agentId,
1425
1517
  automationId: slot.definition.id
1426
1518
  });
1427
- const allSlots = [...slots, ...automationSlots];
1519
+ const backgroundSessionStatus = (slot) => Object.freeze({
1520
+ ...componentStatus(slot),
1521
+ ...slot.adapter?.status ? { supervisor: slot.adapter.status() } : {}
1522
+ });
1523
+ const allSlots = [
1524
+ ...slots,
1525
+ ...automationSlots,
1526
+ ...backgroundSessionSlot ? [backgroundSessionSlot] : []
1527
+ ];
1428
1528
  const isReady = () => allSlots.every(isSlotReady);
1429
1529
  const failedRequiredEndpointIds = () => slots.filter((slot) => slot.definition.enabled && slot.definition.required && slot.lifecycle !== "running").map((slot) => slot.definition.id);
1430
1530
  const failedRequiredAutomationIds = () => automationSlots.filter((slot) => slot.definition.enabled && slot.definition.required && slot.lifecycle !== "running").map((slot) => slot.definition.id);
@@ -1437,6 +1537,7 @@ async function createRivusDeploymentDaemon(options) {
1437
1537
  const status = () => Object.freeze({
1438
1538
  agents: deployment.agents,
1439
1539
  automations: Object.freeze(automationSlots.map(automationStatus)),
1540
+ ...backgroundSessionSlot ? { backgroundSessions: backgroundSessionStatus(backgroundSessionSlot) } : {},
1440
1541
  defaultAgentId: deployment.manifest.defaultAgentId,
1441
1542
  defaultEndpointId: deployment.manifest.defaultEndpointId,
1442
1543
  endpoints: Object.freeze(slots.map(endpointStatus)),
@@ -1501,6 +1602,18 @@ async function createRivusDeploymentDaemon(options) {
1501
1602
  });
1502
1603
  degraded ||= slotDegraded;
1503
1604
  }
1605
+ if (backgroundSessionSlot) {
1606
+ const slotDegraded = await startSlot(backgroundSessionSlot, true, async () => {
1607
+ if (!options.createBackgroundSession) throw new RivusDeploymentDaemonLifecycleError("deployment bootstrap does not provide Background Session adapters");
1608
+ return options.createBackgroundSession({
1609
+ agentIds: [...backgroundDefinitions.keys()],
1610
+ cancel: (input) => host.cancelBackgroundSession(input.agentId, input),
1611
+ config: backgroundSessionSlot.definition,
1612
+ run: (input) => host.handleBackgroundSession(input.agentId, input)
1613
+ });
1614
+ });
1615
+ degraded ||= slotDegraded;
1616
+ }
1504
1617
  lifecycle = degraded ? "degraded" : "running";
1505
1618
  assertRequiredReadiness();
1506
1619
  },
@@ -1514,6 +1627,7 @@ async function createRivusDeploymentDaemon(options) {
1514
1627
  lifecycle = "stopping";
1515
1628
  const errors = [];
1516
1629
  await stopSlots(automationSlots, errors);
1630
+ if (backgroundSessionSlot) await stopSlots([backgroundSessionSlot], errors);
1517
1631
  await stopSlots(slots, errors);
1518
1632
  try {
1519
1633
  await runtimePool.disposeAll();
@@ -1654,6 +1768,7 @@ async function createConfiguredRivusDeploymentDaemon(options) {
1654
1768
  const manifest = await loadRivusDeploymentManifest(options.manifestPath, options.manifestOptions);
1655
1769
  return createRivusDeploymentDaemon({
1656
1770
  ...options.createAutomation ? { createAutomation: options.createAutomation } : {},
1771
+ ...options.createBackgroundSession ? { createBackgroundSession: options.createBackgroundSession } : {},
1657
1772
  createEndpoint: options.createEndpoint,
1658
1773
  createRuntime: options.createRuntime,
1659
1774
  deploymentRoot: dirname(options.manifestPath),
@@ -2968,6 +3083,17 @@ function toRedactedDeploymentManifest(manifest) {
2968
3083
  templateId,
2969
3084
  timeZone
2970
3085
  })),
3086
+ ...manifest.backgroundSessions ? { backgroundSessions: {
3087
+ enabled: manifest.backgroundSessions.enabled,
3088
+ leaseMs: manifest.backgroundSessions.leaseMs,
3089
+ leaseRenewalIntervalMs: manifest.backgroundSessions.leaseRenewalIntervalMs,
3090
+ maxConsecutiveFailures: manifest.backgroundSessions.maxConsecutiveFailures,
3091
+ maxConcurrentSessions: manifest.backgroundSessions.maxConcurrentSessions,
3092
+ required: manifest.backgroundSessions.required,
3093
+ retryBackoffMs: manifest.backgroundSessions.retryBackoffMs,
3094
+ sessionLifetimeMs: manifest.backgroundSessions.sessionLifetimeMs,
3095
+ stepTimeoutMs: manifest.backgroundSessions.stepTimeoutMs
3096
+ } } : {},
2971
3097
  defaultAgentId: manifest.defaultAgentId,
2972
3098
  defaultEndpointId: manifest.defaultEndpointId,
2973
3099
  endpoints: manifest.endpoints.map(({ agentId, credentialRef, enabled, id, required, sessionNamespace }) => ({
@@ -3109,4 +3235,4 @@ function hasRecoveryRunner(daemon) {
3109
3235
  return typeof daemon.openRecoveryControl === "function";
3110
3236
  }
3111
3237
  //#endregion
3112
- export { CardPresentationTransitionDenied as A, FeishuEndpointCredentialError as B, loadRivusDaemonConfig as C, loadRivusDeploymentManifest as D, RivusDeploymentManifestError as E, completeCardPresentationHandoff as F, validateRivusDeploymentManifest as G, loadMergedLocalEnvFile as H, createCardPresentationChain as I, failCardPresentationHandoff as L, activeCardPresentation as M, beginCardPresentationHandoff as N, DEFAULT_CARD_STREAM_LEASE_MS as O, compensateCardPresentationHandoff as P, isCardPresentationHandoffDue as R, RivusDaemonConfigError as S, resolveNodeRivusPluginModulePath as T, RivusPluginLoadError as U, resolveFeishuEndpointCredentials as V, loadRivusDeployment as W, createStableId as _, InvalidRivusProjectSpace as a, createRivusEnvFromOpenClawConfig as b, RivusDeploymentReadinessError as c, createRivusAgentHost as d, AgentInstanceBusy as f, createAgentInstanceRegistry as g, AgentInstanceConflict as h, resolveRivusProjectSpace as i, acceptsCardPresentationProgress as j, createFeishuCardRollover as k, createRivusDeploymentDaemon as l, createAgentRuntimePool as m, createRivusDeploymentCliProcess as n, RivusDeploymentAutomationReadinessError as o, AgentRuntimeDisposed as p, createConfiguredRivusDeploymentDaemon as r, RivusDeploymentDaemonLifecycleError as s, runRivusDaemonCli as t, InvalidRivusEndpointBinding as u, createRivusDaemonShutdownController as v, loadNodeRivusPluginModule as w, formatRivusEnvFile as x, OpenClawEnvImportError as y, markCardPresentationTerminal as z };
3238
+ export { loadRivusDeployment as $, DEFAULT_BACKGROUND_SESSION_LIFETIME_MS as A, acceptsCardPresentationProgress as B, loadRivusDaemonConfig as C, loadRivusDeploymentManifest as D, RivusDeploymentManifestError as E, DEFAULT_BACKGROUND_SESSION_SUPERVISOR_INTERVAL_MS as F, createCardPresentationChain as G, beginCardPresentationHandoff as H, resolveBackgroundSessionSupervisorIntervalMs as I, markCardPresentationTerminal as J, failCardPresentationHandoff as K, DEFAULT_CARD_STREAM_LEASE_MS as L, DEFAULT_BACKGROUND_SESSION_MAX_CONSECUTIVE_FAILURES as M, DEFAULT_BACKGROUND_SESSION_RETRY_BACKOFF_MS as N, DEFAULT_BACKGROUND_SESSION_LEASE_MS as O, DEFAULT_BACKGROUND_SESSION_STEP_TIMEOUT_MS as P, RivusPluginLoadError as Q, createFeishuCardRollover as R, RivusDaemonConfigError as S, resolveNodeRivusPluginModulePath as T, compensateCardPresentationHandoff as U, activeCardPresentation as V, completeCardPresentationHandoff as W, resolveFeishuEndpointCredentials as X, FeishuEndpointCredentialError as Y, loadMergedLocalEnvFile as Z, createStableId as _, InvalidRivusProjectSpace as a, createRivusEnvFromOpenClawConfig as b, RivusDeploymentReadinessError as c, createRivusAgentHost as d, validateRivusDeploymentManifest as et, AgentInstanceBusy as f, createAgentInstanceRegistry as g, AgentInstanceConflict as h, resolveRivusProjectSpace as i, DEFAULT_BACKGROUND_SESSION_MAX_CONCURRENT_SESSIONS as j, DEFAULT_BACKGROUND_SESSION_LEASE_RENEWAL_INTERVAL_MS as k, createRivusDeploymentDaemon as l, createAgentRuntimePool as m, createRivusDeploymentCliProcess as n, RivusDeploymentAutomationReadinessError as o, AgentRuntimeDisposed as p, isCardPresentationHandoffDue as q, createConfiguredRivusDeploymentDaemon as r, RivusDeploymentDaemonLifecycleError as s, runRivusDaemonCli as t, InvalidRivusEndpointBinding as u, createRivusDaemonShutdownController as v, loadNodeRivusPluginModule as w, formatRivusEnvFile as x, OpenClawEnvImportError as y, CardPresentationTransitionDenied as z };
@@ -1,5 +1,227 @@
1
1
  import { c as InvalidRivusPlugin, o as createRivusMemoryToolContract, r as RIVUS_MEMORY_TOOL_PLUGIN_ID, t as MEMORY_SCOPES } from "./agent-memory.js";
2
2
  import { createHash } from "node:crypto";
3
+ //#region src/application/background-session/background-session-authority.ts
4
+ const BACKGROUND_SESSION_TOOL_IDS = [
5
+ "background.start",
6
+ "background.wait",
7
+ "background.list",
8
+ "background.status",
9
+ "background.send",
10
+ "background.stop"
11
+ ];
12
+ const BACKGROUND_SESSION_START_TOOL_ID = "background.start";
13
+ const BACKGROUND_SESSION_TOOL_PLUGIN_ID = "rivus-core";
14
+ const BACKGROUND_SESSION_TOOL_VERSION = "1.0.0";
15
+ const BACKGROUND_SESSION_SESSION_KEY_PREFIX = "background";
16
+ function createBackgroundSessionKey(sessionId) {
17
+ return `${BACKGROUND_SESSION_SESSION_KEY_PREFIX}:${sessionId}`;
18
+ }
19
+ function createBackgroundSessionStepSourceMessageId(sessionId, stepCount) {
20
+ return `bg:${sessionId}:step:${stepCount}`;
21
+ }
22
+ function createBackgroundSessionToolContracts() {
23
+ return [
24
+ Object.freeze({
25
+ 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.",
26
+ digest: contractDigest("background.start"),
27
+ id: "background.start",
28
+ idempotency: "supported",
29
+ inputSchema: Object.freeze({
30
+ additionalProperties: false,
31
+ properties: Object.freeze({
32
+ displayName: {
33
+ type: "string",
34
+ maxLength: 200
35
+ },
36
+ prompt: {
37
+ type: "string",
38
+ minLength: 1,
39
+ maxLength: 2e4
40
+ }
41
+ }),
42
+ required: ["prompt"],
43
+ type: "object"
44
+ }),
45
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
46
+ risk: "mutate",
47
+ version: BACKGROUND_SESSION_TOOL_VERSION
48
+ }),
49
+ Object.freeze({
50
+ 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.",
51
+ digest: contractDigest("background.wait"),
52
+ id: "background.wait",
53
+ idempotency: "supported",
54
+ inputSchema: Object.freeze({
55
+ additionalProperties: false,
56
+ properties: Object.freeze({
57
+ delayMs: {
58
+ type: "integer",
59
+ minimum: 1e3,
60
+ maximum: 864e5
61
+ },
62
+ reason: {
63
+ type: "string",
64
+ maxLength: 500
65
+ },
66
+ until: {
67
+ type: "string",
68
+ maxLength: 64
69
+ }
70
+ }),
71
+ type: "object"
72
+ }),
73
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
74
+ risk: "mutate",
75
+ version: BACKGROUND_SESSION_TOOL_VERSION
76
+ }),
77
+ Object.freeze({
78
+ description: "List background sessions owned by this conversation, newest first. Optionally filter by phase and limit the number of results.",
79
+ digest: contractDigest("background.list"),
80
+ id: "background.list",
81
+ idempotency: "supported",
82
+ inputSchema: Object.freeze({
83
+ additionalProperties: false,
84
+ properties: Object.freeze({
85
+ limit: {
86
+ type: "integer",
87
+ minimum: 1,
88
+ maximum: 50
89
+ },
90
+ phase: {
91
+ enum: [
92
+ "queued",
93
+ "running",
94
+ "waiting",
95
+ "input-required",
96
+ "stopping",
97
+ "stopped",
98
+ "completed",
99
+ "failed",
100
+ "reconciliation-required"
101
+ ],
102
+ type: "string"
103
+ }
104
+ }),
105
+ type: "object"
106
+ }),
107
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
108
+ risk: "observe",
109
+ version: BACKGROUND_SESSION_TOOL_VERSION
110
+ }),
111
+ Object.freeze({
112
+ description: "Return the current phase, step counts, wake time, and result of one background session owned by this conversation.",
113
+ digest: contractDigest("background.status"),
114
+ id: "background.status",
115
+ idempotency: "supported",
116
+ inputSchema: Object.freeze({
117
+ additionalProperties: false,
118
+ properties: Object.freeze({ sessionId: {
119
+ type: "string",
120
+ minLength: 1,
121
+ maxLength: 200
122
+ } }),
123
+ required: ["sessionId"],
124
+ type: "object"
125
+ }),
126
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
127
+ risk: "observe",
128
+ version: BACKGROUND_SESSION_TOOL_VERSION
129
+ }),
130
+ Object.freeze({
131
+ 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.",
132
+ digest: contractDigest("background.send"),
133
+ id: "background.send",
134
+ idempotency: "supported",
135
+ inputSchema: Object.freeze({
136
+ additionalProperties: false,
137
+ properties: Object.freeze({
138
+ message: {
139
+ type: "string",
140
+ minLength: 1,
141
+ maxLength: 2e4
142
+ },
143
+ sessionId: {
144
+ type: "string",
145
+ minLength: 1,
146
+ maxLength: 200
147
+ }
148
+ }),
149
+ required: ["message", "sessionId"],
150
+ type: "object"
151
+ }),
152
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
153
+ risk: "mutate",
154
+ version: BACKGROUND_SESSION_TOOL_VERSION
155
+ }),
156
+ Object.freeze({
157
+ 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.",
158
+ digest: contractDigest("background.stop"),
159
+ id: "background.stop",
160
+ idempotency: "supported",
161
+ inputSchema: Object.freeze({
162
+ additionalProperties: false,
163
+ properties: Object.freeze({
164
+ reason: {
165
+ type: "string",
166
+ maxLength: 500
167
+ },
168
+ sessionId: {
169
+ type: "string",
170
+ minLength: 1,
171
+ maxLength: 200
172
+ }
173
+ }),
174
+ required: ["sessionId"],
175
+ type: "object"
176
+ }),
177
+ pluginId: BACKGROUND_SESSION_TOOL_PLUGIN_ID,
178
+ risk: "mutate",
179
+ version: BACKGROUND_SESSION_TOOL_VERSION
180
+ })
181
+ ];
182
+ }
183
+ function backgroundSessionToolIds() {
184
+ return [...BACKGROUND_SESSION_TOOL_IDS];
185
+ }
186
+ function isBackgroundSessionToolId(toolId) {
187
+ return BACKGROUND_SESSION_TOOL_IDS.includes(toolId);
188
+ }
189
+ function extendBackgroundSessionDefinition(definition) {
190
+ const contracts = createBackgroundSessionToolContracts();
191
+ const existingIds = new Set(definition.tools.map(({ id }) => id));
192
+ const additions = contracts.filter((contract) => !existingIds.has(contract.id));
193
+ const toolGrantSet = Object.freeze({
194
+ revision: grantRevision(definition.toolGrantSet.revision, additions.map(({ id }) => id)),
195
+ toolIds: Object.freeze([...definition.toolGrantSet.toolIds, ...additions.map(({ id }) => id)].sort())
196
+ });
197
+ return Object.freeze({
198
+ ...definition,
199
+ tools: Object.freeze([...definition.tools, ...additions]),
200
+ toolGrantSet
201
+ });
202
+ }
203
+ function narrowBackgroundSessionDefinition(definition) {
204
+ const childToolIds = definition.toolGrantSet.toolIds.filter((id) => id !== BACKGROUND_SESSION_START_TOOL_ID);
205
+ const toolGrantSet = Object.freeze({
206
+ revision: grantRevision(definition.toolGrantSet.revision, childToolIds),
207
+ toolIds: Object.freeze(childToolIds)
208
+ });
209
+ return Object.freeze({
210
+ ...definition,
211
+ tools: Object.freeze(definition.tools.filter(({ id }) => id !== BACKGROUND_SESSION_START_TOOL_ID)),
212
+ toolGrantSet
213
+ });
214
+ }
215
+ function grantRevision(parentRevision, toolIds) {
216
+ return `sha256:${createHash("sha256").update(JSON.stringify({
217
+ parentRevision,
218
+ toolIds: [...toolIds].sort()
219
+ })).digest("hex")}`;
220
+ }
221
+ function contractDigest(toolId) {
222
+ return `sha256:${createHash("sha256").update(`background-tool:${toolId}:${BACKGROUND_SESSION_TOOL_VERSION}`).digest("hex")}`;
223
+ }
224
+ //#endregion
3
225
  //#region src/application/plugin/deep-freeze.ts
4
226
  function deepFreeze(value) {
5
227
  if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
@@ -70,7 +292,7 @@ function createRivusPluginCatalog() {
70
292
  })
71
293
  };
72
294
  }
73
- function resolveRivusAgentDefinition(catalog, deployment) {
295
+ function resolveRivusAgentDefinition(catalog, deployment, options = {}) {
74
296
  const snapshot = catalog.snapshot();
75
297
  const plugin = snapshot.plugins.find((candidate) => candidate.id === deployment.pluginId);
76
298
  if (!plugin) throw new InvalidRivusPlugin(`unknown deployment plugin: ${deployment.pluginId}`);
@@ -135,7 +357,7 @@ function resolveRivusAgentDefinition(catalog, deployment) {
135
357
  }),
136
358
  skillIds
137
359
  });
138
- return deepFreeze({
360
+ const definition = deepFreeze({
139
361
  agentId: deployment.agentId,
140
362
  endpointIds: [...deployment.endpointIds],
141
363
  memory: {
@@ -153,6 +375,8 @@ function resolveRivusAgentDefinition(catalog, deployment) {
153
375
  toolGrantSet,
154
376
  tools
155
377
  });
378
+ if (options.backgroundSessions === true) return extendBackgroundSessionDefinition(definition);
379
+ return definition;
156
380
  }
157
381
  function validateMemoryScopes(scopes, owner) {
158
382
  const result = /* @__PURE__ */ new Set();
@@ -209,4 +433,4 @@ function stableJson(value) {
209
433
  return JSON.stringify(value);
210
434
  }
211
435
  //#endregion
212
- export { resolveRivusAgentDefinition as n, deepFreeze as r, createRivusPluginCatalog as t };
436
+ export { BACKGROUND_SESSION_START_TOOL_ID as a, BACKGROUND_SESSION_TOOL_VERSION as c, createBackgroundSessionStepSourceMessageId as d, createBackgroundSessionToolContracts as f, narrowBackgroundSessionDefinition as h, BACKGROUND_SESSION_SESSION_KEY_PREFIX as i, backgroundSessionToolIds as l, isBackgroundSessionToolId as m, resolveRivusAgentDefinition as n, BACKGROUND_SESSION_TOOL_IDS as o, extendBackgroundSessionDefinition as p, deepFreeze as r, BACKGROUND_SESSION_TOOL_PLUGIN_ID as s, createRivusPluginCatalog as t, createBackgroundSessionKey as u };
@@ -16,6 +16,12 @@ interface RivusPluginManifest {
16
16
  interface RivusToolExecutor {
17
17
  execute(input: unknown, context: RivusToolExecutionContext): unknown;
18
18
  }
19
+ interface RivusToolExecutionOrigin {
20
+ readonly endpointId: string;
21
+ readonly tenantKey: string;
22
+ readonly conversationId?: string;
23
+ readonly allowedActorOpenIds: ReadonlyArray<string>;
24
+ }
19
25
  interface RivusToolExecutionContext {
20
26
  readonly agentId: string;
21
27
  readonly instanceId: string;
@@ -27,6 +33,8 @@ interface RivusToolExecutionContext {
27
33
  readonly toolId: string;
28
34
  readonly toolVersion: string;
29
35
  readonly sessionKey: string;
36
+ readonly origin?: RivusToolExecutionOrigin;
37
+ readonly sourceMessageId?: string;
30
38
  }
31
39
  interface RivusToolFactoryContext {
32
40
  readonly toolId: string;
@@ -64,6 +64,7 @@ var InvalidInvocationAuthority = class extends Error {
64
64
  };
65
65
  function createInvocationAuthority(authority) {
66
66
  if (!authority.sourceMessageId.trim()) throw new InvalidInvocationAuthority("invocation authority requires a trusted source message id");
67
+ if (authority.endpointId !== void 0 && !authority.endpointId.trim()) throw new InvalidInvocationAuthority("invocation authority requires a trusted endpoint id");
67
68
  const reference = Object.freeze({ id: `authority:${randomUUID()}` });
68
69
  const memory = authority.memory ? Object.freeze({
69
70
  ...authority.memory,
@@ -71,6 +72,7 @@ function createInvocationAuthority(authority) {
71
72
  }) : void 0;
72
73
  authorities.set(reference, Object.freeze({
73
74
  ...authority,
75
+ ...authority.allowedActorOpenIds ? { allowedActorOpenIds: Object.freeze([...authority.allowedActorOpenIds]) } : {},
74
76
  ...memory ? { memory } : {}
75
77
  }));
76
78
  return reference;