@rivus/agent 0.6.0 → 0.6.2

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/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { a as createAgentLoopSkillExecutionStart, c as createAgentLoopToolExecutionEnd, d as createAsyncIterableAgentLoop, f as createEventAgentLoop, i as createAgentLoopSkillExecutionEnd, l as createAgentLoopToolExecutionStart, m as createTextAgentLoopFromCallback, n as createAgentLoopModelExecutionEnd, o as createAgentLoopTextDelta, p as createTextAgentLoop, r as createAgentLoopModelExecutionStart, s as createAgentLoopThinkingDelta, t as createAgentLoopFromCallback, u as createAgentLoopToolExecutionUpdate } from "./agent-loop.js";
2
- import { a as RIVUS_MEMORY_TOOL_ID, c as createMemoryNamespace, d as InvalidRivusPlugin, f as RIVUS_PLUGIN_API_VERSION, i as MEMORY_SCOPES, l as createRivusMemoryToolContract, m as requiresToolApproval, n as resolveRivusAgentDefinition, o as RIVUS_MEMORY_TOOL_PLUGIN_ID, p as RivusToolInputRejected, s as RIVUS_MEMORY_TOOL_VERSION, t as createRivusPluginCatalog, u as restrictMemoryScopesForAudience } from "./rivus-plugin-registry.js";
2
+ import { a as createMemoryNamespace, c as InvalidRivusPlugin, d as requiresToolApproval, i as RIVUS_MEMORY_TOOL_VERSION, l as RIVUS_PLUGIN_API_VERSION, n as RIVUS_MEMORY_TOOL_ID, o as createRivusMemoryToolContract, r as RIVUS_MEMORY_TOOL_PLUGIN_ID, s as restrictMemoryScopesForAudience, t as MEMORY_SCOPES, u as RivusToolInputRejected } from "./agent-memory.js";
3
+ import { n as resolveRivusAgentDefinition, t as createRivusPluginCatalog } from "./rivus-plugin-registry.js";
3
4
  import { A as CardPresentationTransitionDenied, B as FeishuEndpointCredentialError, C as loadRivusDaemonConfig, D as loadRivusDeploymentManifest, E as RivusDeploymentManifestError, F as completeCardPresentationHandoff, G as validateRivusDeploymentManifest, I as createCardPresentationChain, L as failCardPresentationHandoff, M as activeCardPresentation, N as beginCardPresentationHandoff, O as DEFAULT_CARD_STREAM_LEASE_MS, P as compensateCardPresentationHandoff, R as isCardPresentationHandoffDue, S as RivusDaemonConfigError, U as RivusPluginLoadError, V as resolveFeishuEndpointCredentials, W as loadRivusDeployment, _ as createStableId, a as InvalidRivusProjectSpace, b as createRivusEnvFromOpenClawConfig, c as RivusDeploymentReadinessError, d as createRivusAgentHost, f as AgentInstanceBusy, g as createAgentInstanceRegistry, h as AgentInstanceConflict, i as resolveRivusProjectSpace, j as acceptsCardPresentationProgress, k as createFeishuCardRollover, l as createRivusDeploymentDaemon, m as createAgentRuntimePool, n as createRivusDeploymentCliProcess, o as RivusDeploymentAutomationReadinessError, p as AgentRuntimeDisposed, r as createConfiguredRivusDeploymentDaemon, s as RivusDeploymentDaemonLifecycleError, t as runRivusDaemonCli, u as InvalidRivusEndpointBinding, v as createRivusDaemonShutdownController, w as loadNodeRivusPluginModule, x as formatRivusEnvFile, y as OpenClawEnvImportError, z as markCardPresentationTerminal } from "./rivus-daemon-cli.js";
5
+ import { a as InvalidInvocationAuthority, i as normalizeStableJson, n as InvalidToolInput, o as createInvocationAuthority, r as createToolInputDigest, s as resolveInvocationAuthority, t as InvalidStableJson } from "./tool-input-digest.js";
4
6
  import { n as assertRivusPluginConforms, r as createFakeRivusPlugin, t as RivusPluginConformanceError } from "./rivus-plugin-testkit.js";
5
- import { Cause, Deferred, Effect, Exit, Fiber, Option, Stream } from "effect";
7
+ import { Cause, Deferred, Effect, Either, Exit, Fiber, Option, Stream } from "effect";
6
8
  import { createHash, randomUUID } from "node:crypto";
7
9
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
8
10
  import { appendFile, lstat, mkdir, readFile, readdir, realpath, rename, stat, unlink, writeFile } from "node:fs/promises";
@@ -14,7 +16,6 @@ import { resourceFromAttributes } from "@opentelemetry/resources";
14
16
  import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
15
17
  import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
16
18
  import { ROOT_CONTEXT, SpanStatusCode, trace } from "@opentelemetry/api";
17
- import { Unsafe } from "typebox";
18
19
  //#region src/application/support/serial-executor.ts
19
20
  function createSerialExecutor() {
20
21
  let tail = Promise.resolve();
@@ -1935,6 +1936,9 @@ function encodeSegment(value) {
1935
1936
  }
1936
1937
  //#endregion
1937
1938
  //#region src/application/feishu/feishu-message-intake.ts
1939
+ function readTenantKey(payload) {
1940
+ return payload.event.sender?.tenant_key ?? payload.header?.tenant_key ?? "";
1941
+ }
1938
1942
  var UnsupportedFeishuMessage = class extends Error {
1939
1943
  messageType;
1940
1944
  name = "UnsupportedFeishuMessage";
@@ -2011,7 +2015,7 @@ function toSessionReference(payload, options) {
2011
2015
  return {
2012
2016
  agentId: options.agentId,
2013
2017
  chatId: payload.event.message.chat_id,
2014
- tenantKey: payload.event.sender?.tenant_key ?? payload.header?.tenant_key ?? "",
2018
+ tenantKey: readTenantKey(payload),
2015
2019
  ...payload.event.message.thread_id ? { threadId: payload.event.message.thread_id } : {}
2016
2020
  };
2017
2021
  }
@@ -2092,6 +2096,7 @@ function createFeishuAgentDaemon(options) {
2092
2096
  handleMessage: (payload, handleOptions) => {
2093
2097
  let dedupeMessageId;
2094
2098
  const sideEffectsDisabled = handleOptions?.sideEffects === "disabled";
2099
+ const finalizeRun = options.finalizeRun ?? (() => Effect.void);
2095
2100
  const prepareRun = sideEffectsDisabled ? void 0 : options.prepareRun;
2096
2101
  const publish = sideEffectsDisabled ? () => Effect.void : options.publish;
2097
2102
  const publishRunUpdate = sideEffectsDisabled ? void 0 : options.publishRunUpdate;
@@ -2111,12 +2116,14 @@ function createFeishuAgentDaemon(options) {
2111
2116
  }
2112
2117
  if (inbound.type === "cancel_run") return yield* cancelRun(inbound);
2113
2118
  const projector = createFeishuStreamProjector();
2119
+ const acceptedRunIds = /* @__PURE__ */ new Set();
2114
2120
  const command = {
2115
2121
  ...inbound.command,
2116
2122
  ...options.resolveInvocation ? { invocation: options.resolveInvocation(payload, inbound.conversationId) } : {}
2117
2123
  };
2118
2124
  const result = yield* execution.promptWithUpdates(command, (update) => Effect.gen(function* () {
2119
2125
  const event = update.event;
2126
+ if (event.type === "agent_run_accepted") acceptedRunIds.add(event.runId);
2120
2127
  if (event.type === "agent_run_accepted" && prepareRun) yield* prepareRun({
2121
2128
  messageId: inbound.messageId,
2122
2129
  prompt: event.prompt,
@@ -2126,7 +2133,7 @@ function createFeishuAgentDaemon(options) {
2126
2133
  });
2127
2134
  if (publishRunUpdate) yield* publishRunUpdate(update);
2128
2135
  for (const action of projector.applyUpdate(update)) yield* publish(action);
2129
- }));
2136
+ })).pipe(Effect.ensuring(Effect.forEach(acceptedRunIds, (runId) => finalizeRun(runId), { discard: true })));
2130
2137
  return {
2131
2138
  finalText: result.finalText,
2132
2139
  messageId: inbound.messageId,
@@ -2226,9 +2233,8 @@ function createFeishuMessageQueue(options) {
2226
2233
  };
2227
2234
  }
2228
2235
  function createLaneKey(payload) {
2229
- const tenantKey = payload.event.sender?.tenant_key ?? payload.header?.tenant_key ?? "unknown-tenant";
2230
2236
  const message = payload.event.message;
2231
- return `${tenantKey}:${message.chat_id}:${message.thread_id ?? message.chat_id}`;
2237
+ return `${readTenantKey(payload)}:${message.chat_id}:${message.thread_id ?? message.chat_id}`;
2232
2238
  }
2233
2239
  //#endregion
2234
2240
  //#region src/application/feishu/feishu-group-policy.ts
@@ -2250,7 +2256,10 @@ function createFeishuMessageWorker(options) {
2250
2256
  const results = [];
2251
2257
  while (options.queue.pending() > 0) {
2252
2258
  const batchSize = Math.min(concurrency, options.queue.pending());
2253
- const batch = yield* Effect.all(Array.from({ length: batchSize }, () => options.queue.drainOne()), { concurrency: "unbounded" });
2259
+ const outcomes = yield* Effect.all(Array.from({ length: batchSize }, () => options.queue.drainOne().pipe(Effect.either)), { concurrency: "unbounded" });
2260
+ const failures = outcomes.filter(Either.isLeft).map((outcome) => outcome.left);
2261
+ if (failures.length > 0) yield* Effect.fail(failures.length === 1 ? failures[0] : new AggregateError(failures, "Feishu message batch failed"));
2262
+ const batch = outcomes.filter(Either.isRight).map((outcome) => outcome.right);
2254
2263
  if (batch.every((result) => !result.handled)) break;
2255
2264
  for (const result of batch) if (result.handled) results.push(result);
2256
2265
  }
@@ -2654,6 +2663,7 @@ function createFeishuAgentRuntime(options) {
2654
2663
  const daemon = createFeishuAgentDaemon({
2655
2664
  agentId: options.agentId,
2656
2665
  ...options.botOpenId ? { botOpenId: options.botOpenId } : {},
2666
+ ...options.finalizeRun ? { finalizeRun: options.finalizeRun } : {},
2657
2667
  harness,
2658
2668
  ...options.prepareRun ? { prepareRun: options.prepareRun } : {},
2659
2669
  publish: options.publish
@@ -2720,7 +2730,7 @@ function isRetryableFeishuMessageError(error) {
2720
2730
  return !(error instanceof AgentRunCancelled || error instanceof UnsupportedFeishuMessage || error instanceof InvalidFeishuMessageContent || error instanceof InvalidFeishuSessionReference);
2721
2731
  }
2722
2732
  function summarizeReceiveMessage(payload) {
2723
- const tenantKey = payload.event.sender?.tenant_key ?? payload.header?.tenant_key;
2733
+ const tenantKey = readTenantKey(payload);
2724
2734
  return {
2725
2735
  chatId: payload.event.message.chat_id,
2726
2736
  messageId: payload.event.message.message_id,
@@ -2856,8 +2866,8 @@ function resolveRunPresentation(input) {
2856
2866
  title: input.generation ? "正在处理(续)" : "正在处理"
2857
2867
  };
2858
2868
  case "handoff": return {
2859
- content: "任务仍在后台处理,进度将继续显示在下一条消息。",
2860
- note: "本卡片的流式窗口已交接",
2869
+ content: input.text || "任务仍在后台处理,进度将继续显示在下一条消息。",
2870
+ note: "本卡片已停止更新;后续进度见下一条消息",
2861
2871
  template: "blue",
2862
2872
  title: "已转到新消息"
2863
2873
  };
@@ -2873,14 +2883,35 @@ function resolveRunPresentation(input) {
2873
2883
  template: "red",
2874
2884
  title: "处理失败"
2875
2885
  };
2876
- case "cancelled": return {
2877
- content: "已停止生成。",
2878
- note: "本次运行已取消",
2879
- template: "grey",
2880
- title: "已取消"
2881
- };
2886
+ case "cancelled": return resolveCancellationPresentation(input.reason, input.text);
2882
2887
  }
2883
2888
  }
2889
+ function resolveCancellationPresentation(reason, text) {
2890
+ const timeoutMs = readRunTimeoutMs(reason);
2891
+ if (timeoutMs !== void 0) return {
2892
+ content: text || `任务执行超过 ${formatDuration(timeoutMs)},已停止。本次没有形成最终结论。`,
2893
+ note: `达到 ${formatDuration(timeoutMs)}运行时限;以上是超时前进度,不是最终结论`,
2894
+ template: "orange",
2895
+ title: "执行超时"
2896
+ };
2897
+ return {
2898
+ content: text || "已停止生成。",
2899
+ note: "本次运行已取消",
2900
+ template: "grey",
2901
+ title: "已取消"
2902
+ };
2903
+ }
2904
+ function readRunTimeoutMs(reason) {
2905
+ const match = /^run timed out after (\d+)ms$/.exec(reason ?? "");
2906
+ if (!match) return void 0;
2907
+ const milliseconds = Number(match[1]);
2908
+ return Number.isSafeInteger(milliseconds) && milliseconds > 0 ? milliseconds : void 0;
2909
+ }
2910
+ function formatDuration(milliseconds) {
2911
+ if (milliseconds % 36e5 === 0) return `${milliseconds / 36e5} 小时`;
2912
+ if (milliseconds % 6e4 === 0) return `${milliseconds / 6e4} 分钟`;
2913
+ return `${Math.ceil(milliseconds / 1e3)} 秒`;
2914
+ }
2884
2915
  //#endregion
2885
2916
  //#region src/infrastructure/feishu/feishu-tenant-token-provider.ts
2886
2917
  var FeishuTenantAccessTokenError = class {
@@ -2994,10 +3025,20 @@ function isStreamingClosed(error) {
2994
3025
  return error instanceof FeishuOpenApiError && (error.code === 200850 || error.code === 300309);
2995
3026
  }
2996
3027
  function updateWholeCard(baseUrl, agentName, request, status, call) {
3028
+ const requestText = "text" in request ? request.text : void 0;
2997
3029
  const card = status === "completed" ? createFeishuAgentRunCard({
2998
3030
  agentName,
2999
3031
  status,
3000
- text: "text" in request ? request.text : ""
3032
+ text: requestText ?? ""
3033
+ }) : status === "cancelled" ? createFeishuAgentRunCard({
3034
+ agentName,
3035
+ ..."reason" in request && request.reason ? { reason: request.reason } : {},
3036
+ status,
3037
+ ...requestText === void 0 ? {} : { text: requestText }
3038
+ }) : status === "handoff" ? createFeishuAgentRunCard({
3039
+ agentName,
3040
+ status,
3041
+ ...requestText === void 0 ? {} : { text: requestText }
3001
3042
  }) : createFeishuAgentRunCard({
3002
3043
  agentName,
3003
3044
  status
@@ -3030,7 +3071,8 @@ function createFeishuCardKitPublisher(options) {
3030
3071
  });
3031
3072
  case "handoff": return yield* options.client.handoff({
3032
3073
  cardId: target.cardId,
3033
- sequence
3074
+ sequence,
3075
+ ...action.text === void 0 ? {} : { text: action.text }
3034
3076
  });
3035
3077
  case "finish":
3036
3078
  yield* options.client.finish({
@@ -3050,7 +3092,8 @@ function createFeishuCardKitPublisher(options) {
3050
3092
  yield* options.client.cancel({
3051
3093
  cardId: target.cardId,
3052
3094
  ...action.reason ? { reason: action.reason } : {},
3053
- sequence
3095
+ sequence,
3096
+ ...action.text === void 0 ? {} : { text: action.text }
3054
3097
  });
3055
3098
  return yield* ledger.markTerminal(action.runId);
3056
3099
  }
@@ -3135,13 +3178,6 @@ function createFeishuCardTargetPreparation(options) {
3135
3178
  yield* options.presentations.bindRun(run, target);
3136
3179
  });
3137
3180
  }
3138
- function createConfiguredFeishuCardKitTargetPreparation(options) {
3139
- const creator = createConfiguredFeishuCardKitTargetCreator(options);
3140
- return createFeishuCardTargetPreparation({
3141
- createTarget: (run) => creator.createTarget(run),
3142
- presentations: options.presentations
3143
- });
3144
- }
3145
3181
  function createConfiguredFeishuCardKitTargetCreator(options) {
3146
3182
  return createFeishuCardKitOpenApiTargetCreator({
3147
3183
  baseUrl: options.config.feishu.baseUrl,
@@ -3165,7 +3201,7 @@ function createFeishuCardKitOpenApiTargetCreator(options) {
3165
3201
  runId: run.runId,
3166
3202
  sessionKey: run.sessionKey,
3167
3203
  status: "running",
3168
- text: initialContent
3204
+ text: createOptions?.initialContent ?? initialContent
3169
3205
  })),
3170
3206
  type: "card_json"
3171
3207
  },
@@ -3222,7 +3258,10 @@ function createConfiguredFeishuCardRolloverRuntime(options) {
3222
3258
  });
3223
3259
  const cardRollover = createFeishuCardRollover({
3224
3260
  clock: options.clock,
3225
- createSuccessor: ({ generation, run }) => creator.createTarget(run, { generation }),
3261
+ createSuccessor: ({ generation, run, text }) => creator.createTarget(run, {
3262
+ generation,
3263
+ ...text === void 0 ? {} : { initialContent: text }
3264
+ }),
3226
3265
  leaseMs,
3227
3266
  ...options.observe ? { observe: options.observe } : {},
3228
3267
  publisher,
@@ -3293,6 +3332,7 @@ function createConfiguredRivusDaemonBootstrap(options) {
3293
3332
  ...options.botOpenId ? { botOpenId: options.botOpenId } : {},
3294
3333
  clock: options.clock,
3295
3334
  eventSinks: [options.eventLog],
3335
+ finalizeRun: (runId) => cardRollover.rollover.releaseRun(runId),
3296
3336
  ...options.inboxRepository ? { inboxRepository: options.inboxRepository } : {},
3297
3337
  ...options.initialEvents ? { initialEvents: options.initialEvents } : {},
3298
3338
  ...options.initialRunStates ? { initialRunStates: options.initialRunStates } : {},
@@ -4081,62 +4121,6 @@ function resolveContentMode(value) {
4081
4121
  throw new LangfuseTelemetryConfigError("RIVUS_TELEMETRY_CONTENT must be either \"metadata-only\" or \"redacted\"");
4082
4122
  }
4083
4123
  //#endregion
4084
- //#region src/infrastructure/pi/pi-skill-tool.ts
4085
- const PI_SKILL_READER_TOOL_NAME = "rivus_read_skill";
4086
- function createPiSkillRuntime(skills) {
4087
- if (skills.length === 0) return Object.freeze({ prompt: "" });
4088
- const skillsById = new Map(skills.map((skill) => [skill.id, skill]));
4089
- const prompt = [
4090
- "Granted Skills are versioned instructions loaded on demand.",
4091
- `Before following a Skill, call ${PI_SKILL_READER_TOOL_NAME} with its exact ID and follow the returned content.`,
4092
- "Granted Skill catalog:",
4093
- ...skills.map((skill) => `- ${skill.id} | ${skill.title} | v${skill.version} | ${skill.digest}`)
4094
- ].join("\n");
4095
- const tool = {
4096
- description: "Read the full versioned instructions for one Skill granted to this Agent Runtime.",
4097
- execute: async (_callId, input) => {
4098
- const skillId = readSkillId$1(input);
4099
- const skill = skillsById.get(skillId);
4100
- if (!skill) throw new Error(`Skill is not granted: ${skillId}`);
4101
- const details = {
4102
- contentLength: skill.content.length,
4103
- digest: skill.digest,
4104
- skillId: skill.id,
4105
- title: skill.title,
4106
- version: skill.version
4107
- };
4108
- return {
4109
- content: [{
4110
- text: skill.content,
4111
- type: "text"
4112
- }],
4113
- details
4114
- };
4115
- },
4116
- executionMode: "sequential",
4117
- label: "Read granted Skill",
4118
- name: PI_SKILL_READER_TOOL_NAME,
4119
- parameters: Unsafe({
4120
- additionalProperties: false,
4121
- properties: { skillId: {
4122
- description: "Exact Skill ID from the granted Skill catalog.",
4123
- type: "string"
4124
- } },
4125
- required: ["skillId"],
4126
- type: "object"
4127
- }),
4128
- promptSnippet: `${PI_SKILL_READER_TOOL_NAME}: read one granted Skill by exact ID`
4129
- };
4130
- return Object.freeze({
4131
- prompt,
4132
- tool
4133
- });
4134
- }
4135
- function readSkillId$1(input) {
4136
- if (input === null || typeof input !== "object" || Array.isArray(input) || typeof input.skillId !== "string") throw new Error("Skill reader input requires a string skillId");
4137
- return input.skillId;
4138
- }
4139
- //#endregion
4140
4124
  //#region src/infrastructure/pi/pi-agent-loop.ts
4141
4125
  function createPiAgentLoop(options) {
4142
4126
  return createAsyncIterableAgentLoop({ run: (input) => runPiSession(input, options) });
@@ -5029,6 +5013,15 @@ function readRedactedString(serialized) {
5029
5013
  function createFixedClock(now) {
5030
5014
  return { now: Effect.succeed(now) };
5031
5015
  }
5016
+ function createTestClock(initial) {
5017
+ let now = initial;
5018
+ return {
5019
+ advance: (ms) => {
5020
+ now = new Date(now.getTime() + ms);
5021
+ },
5022
+ now: Effect.suspend(() => Effect.succeed(now))
5023
+ };
5024
+ }
5032
5025
  function createSequenceRunIds(runIds) {
5033
5026
  let index = 0;
5034
5027
  return { next: Effect.sync(() => {
@@ -5202,72 +5195,6 @@ function freezeView(view) {
5202
5195
  return Object.freeze(view);
5203
5196
  }
5204
5197
  //#endregion
5205
- //#region src/application/delegation/tool-authority.ts
5206
- const authorities = /* @__PURE__ */ new WeakMap();
5207
- var InvalidInvocationAuthority = class extends Error {
5208
- name = "InvalidInvocationAuthority";
5209
- };
5210
- function createInvocationAuthority(authority) {
5211
- if (!authority.sourceMessageId.trim()) throw new InvalidInvocationAuthority("invocation authority requires a trusted source message id");
5212
- const reference = Object.freeze({ id: `authority:${randomUUID()}` });
5213
- const memory = authority.memory ? Object.freeze({
5214
- ...authority.memory,
5215
- scopes: Object.freeze(restrictMemoryScopesForAudience(authority.memory.scopes, authority.memory.audience))
5216
- }) : void 0;
5217
- authorities.set(reference, Object.freeze({
5218
- ...authority,
5219
- ...memory ? { memory } : {}
5220
- }));
5221
- return reference;
5222
- }
5223
- function resolveInvocationAuthority(reference) {
5224
- const authority = authorities.get(reference);
5225
- if (!authority) throw new InvalidInvocationAuthority("invocation authority was not issued by this host");
5226
- return authority;
5227
- }
5228
- //#endregion
5229
- //#region src/application/delegation/tool-input-digest.ts
5230
- var InvalidStableJson = class extends Error {
5231
- name = "InvalidStableJson";
5232
- };
5233
- var InvalidToolInput = class extends InvalidStableJson {
5234
- name = "InvalidToolInput";
5235
- };
5236
- function createToolInputDigest(input) {
5237
- let canonical;
5238
- try {
5239
- canonical = normalizeStableJson(input);
5240
- } catch (error) {
5241
- if (error instanceof InvalidStableJson) throw new InvalidToolInput(error.message);
5242
- throw error;
5243
- }
5244
- return `sha256:${createHash("sha256").update(JSON.stringify(canonical)).digest("hex")}`;
5245
- }
5246
- function normalizeStableJson(value) {
5247
- return canonicalize(value, /* @__PURE__ */ new Set());
5248
- }
5249
- function canonicalize(value, ancestors) {
5250
- if (value === null || typeof value === "string" || typeof value === "boolean") return value;
5251
- if (typeof value === "number") {
5252
- if (!Number.isFinite(value)) throw new InvalidStableJson("stable JSON numbers must be finite");
5253
- return Object.is(value, -0) ? 0 : value;
5254
- }
5255
- if (typeof value !== "object") throw new InvalidStableJson("value must contain only stable JSON values");
5256
- if (ancestors.has(value)) throw new InvalidStableJson("stable JSON must not contain cycles");
5257
- ancestors.add(value);
5258
- try {
5259
- if (Array.isArray(value)) return Array.from({ length: value.length }, (_, index) => {
5260
- if (!Object.hasOwn(value, index)) throw new InvalidStableJson("stable JSON arrays must not contain holes");
5261
- return canonicalize(value[index], ancestors);
5262
- });
5263
- const prototype = Object.getPrototypeOf(value);
5264
- if (prototype !== Object.prototype && prototype !== null) throw new InvalidStableJson("stable JSON objects must be plain objects");
5265
- return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => [key, canonicalize(entry, ancestors)]));
5266
- } finally {
5267
- ancestors.delete(value);
5268
- }
5269
- }
5270
- //#endregion
5271
5198
  //#region src/application/delegation/tool-operation-ledger.ts
5272
5199
  function createToolOperationLedger(options = {}) {
5273
5200
  const records = new Map(options.initial?.map((record) => [record.operationId, structuredClone(record)]) ?? []);
@@ -5618,6 +5545,7 @@ function createFeishuDeploymentEndpoint(options) {
5618
5545
  agentId: options.agentId,
5619
5546
  botOpenId: options.botOpenId,
5620
5547
  execution: execution.port,
5548
+ ...options.finalizeRun ? { finalizeRun: options.finalizeRun } : {},
5621
5549
  ...options.interactions ? { interactions: options.interactions } : {},
5622
5550
  ...options.prepareRun ? { prepareRun: options.prepareRun } : {},
5623
5551
  publish: options.publish,
@@ -5791,7 +5719,7 @@ function createInvocation(payload, endpointId, memoryTenantId, conversationId, p
5791
5719
  tenantId: memoryTenantId
5792
5720
  } } : {},
5793
5721
  sourceMessageId: payload.event.message.message_id,
5794
- tenantKey: payload.event.sender?.tenant_key ?? payload.header?.tenant_key ?? ""
5722
+ tenantKey: readTenantKey(payload)
5795
5723
  };
5796
5724
  }
5797
5725
  function namespaceSessionKey(namespace, sessionKey) {
@@ -7018,112 +6946,6 @@ function assertTimestamp(value, label) {
7018
6946
  if (!Number.isFinite(Date.parse(value))) throw new HumanInteractionTransitionDenied(`${label} must be an ISO timestamp`);
7019
6947
  }
7020
6948
  //#endregion
7021
- //#region src/infrastructure/pi/pi-tool-proxy.ts
7022
- function createPiToolProxyDefinitions(options) {
7023
- const names = /* @__PURE__ */ new Set();
7024
- return options.tools.map((tool) => {
7025
- const name = toPiToolName(tool.id);
7026
- if (names.has(name)) throw new Error(`Pi tool name collision: ${name}`);
7027
- names.add(name);
7028
- return {
7029
- description: tool.description,
7030
- execute: async (callId, input, signal) => {
7031
- const activeInput = options.getActiveInput();
7032
- const invocation = activeInput?.invocation;
7033
- if (!activeInput || !invocation) throw new Error(`tool ${tool.id} requires an active agent run with a trusted invocation`);
7034
- if (!invocation.tenantKey) throw new Error(`tool ${tool.id} requires a trusted tenant identity`);
7035
- throwIfAborted(signal ?? activeInput.abortSignal);
7036
- const inputDigest = createToolInputDigest(input);
7037
- const operationId = createBoundId("operation", {
7038
- agentId: options.agentId,
7039
- inputDigest,
7040
- instanceId: options.instanceId,
7041
- sourceMessageId: invocation.sourceMessageId,
7042
- toolId: tool.id,
7043
- toolVersion: tool.version
7044
- });
7045
- const approvalId = createBoundId("approval", {
7046
- callId,
7047
- operationId,
7048
- runId: activeInput.runId
7049
- });
7050
- if (requiresToolApproval(tool.risk)) {
7051
- if (invocation.allowedActorOpenIds.length === 0) throw new Error(`tool ${tool.id} requires at least one trusted approval actor`);
7052
- await options.approvals.requestApproval({
7053
- agentId: options.agentId,
7054
- allowedActorOpenIds: invocation.allowedActorOpenIds,
7055
- approvalId,
7056
- callId,
7057
- endpointId: invocation.endpointId,
7058
- inputDigest,
7059
- instanceId: options.instanceId,
7060
- operationId,
7061
- risk: tool.risk,
7062
- runId: activeInput.runId,
7063
- sessionKey: activeInput.sessionKey,
7064
- signal: signal ?? activeInput.abortSignal,
7065
- sourceMessageId: invocation.sourceMessageId,
7066
- tenantKey: invocation.tenantKey,
7067
- toolId: tool.id,
7068
- toolVersion: tool.version
7069
- });
7070
- throwIfAborted(signal ?? activeInput.abortSignal);
7071
- }
7072
- const result = await options.broker.execute({
7073
- authority: createInvocationAuthority({
7074
- agentId: options.agentId,
7075
- instanceId: options.instanceId,
7076
- ...invocation.memory ? { memory: {
7077
- ...invocation.memory,
7078
- scopes: options.memoryScopes ?? []
7079
- } } : {},
7080
- runId: activeInput.runId,
7081
- sessionKey: activeInput.sessionKey,
7082
- sourceMessageId: invocation.sourceMessageId,
7083
- tenantKey: invocation.tenantKey,
7084
- toolGrantSet: options.toolGrantSet
7085
- }),
7086
- callId,
7087
- input,
7088
- operationId,
7089
- ...requiresToolApproval(tool.risk) ? { approvalId } : {},
7090
- toolId: tool.id,
7091
- version: tool.version
7092
- });
7093
- return {
7094
- content: [{
7095
- text: stringifyToolResult(result),
7096
- type: "text"
7097
- }],
7098
- details: result
7099
- };
7100
- },
7101
- executionMode: "sequential",
7102
- label: tool.id,
7103
- name,
7104
- parameters: Unsafe(tool.inputSchema),
7105
- promptSnippet: `${name}: ${tool.description}`
7106
- };
7107
- });
7108
- }
7109
- function createPiToolNameResolver(tools) {
7110
- const toolIdsByPiName = new Map(tools.map((tool) => [toPiToolName(tool.id), tool.id]));
7111
- return (toolName) => toolIdsByPiName.get(toolName) ?? toolName;
7112
- }
7113
- function toPiToolName(toolId) {
7114
- return `rivus_${toolId.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
7115
- }
7116
- function createBoundId(kind, binding) {
7117
- return `${kind}:${createHash("sha256").update(JSON.stringify(binding)).digest("hex")}`;
7118
- }
7119
- function throwIfAborted(signal) {
7120
- if (signal.aborted) throw signal.reason ?? /* @__PURE__ */ new Error("tool execution was aborted");
7121
- }
7122
- function stringifyToolResult(result) {
7123
- if (typeof result === "string") return result;
7124
- return JSON.stringify(result ?? null);
7125
- }
7126
- //#endregion
7127
6949
  //#region src/composition/human-interaction-tool-approval-gateway.ts
7128
6950
  function createHumanInteractionEndpointRegistry() {
7129
6951
  const services = /* @__PURE__ */ new Map();
@@ -7640,4 +7462,4 @@ function validateDecisionInput(input) {
7640
7462
  if (input.recommendedOptionId && !optionIds.includes(input.recommendedOptionId)) throw new Error("recommended user decision option must be available");
7641
7463
  }
7642
7464
  //#endregion
7643
- export { AgentContextBudgetExceeded, AgentEventHandlerFailed, AgentEventLogStoreError, AgentEventSinkFailed, AgentHarnessBusy, AgentInstanceBusy, AgentInstanceConflict, AgentLoopFailed, AgentMemoryError, AgentRunCancelled, AgentRuntimeDisposed, AutomationMandateError, CardPresentationTransitionDenied, CompactionError, DEFAULT_CARD_STREAM_LEASE_MS, DelegationDenied, DeliveryOutboxError, FeishuCardPresentationNotFound, FeishuCardTargetNotFound, FeishuCardTargetRegistryStoreError, FeishuCotProtocolError, FeishuEndpointCredentialError, FeishuOpenApiError, FeishuTenantAccessTokenError, HumanInteractionRepositoryError, HumanInteractionTransitionDenied, InvalidFeishuCardAction, InvalidFeishuMessageContent, InvalidFeishuSessionReference, InvalidInvocationAuthority, InvalidProjectSkillCatalog, InvalidRecoveryAction, InvalidRivusEndpointBinding, InvalidRivusPlugin, InvalidRivusProjectSpace, InvalidStableJson, InvalidToolInput, InvalidWorkspaceRoot, LangfuseTelemetryConfigError, MEMORY_SCOPES, OpenClawEnvImportError, PluginStateConflict, RIVUS_MEMORY_TOOL_ID, RIVUS_MEMORY_TOOL_PLUGIN_ID, RIVUS_MEMORY_TOOL_VERSION, RIVUS_PLUGIN_API_VERSION, RivusDaemonConfigError, RivusDeploymentAutomationReadinessError, RivusDeploymentDaemonLifecycleError, RivusDeploymentManifestError, RivusDeploymentReadinessError, RivusPluginConformanceError, RivusPluginLoadError, RivusToolInputRejected, SessionSchedulerCapacityExceeded, SessionSchedulerDisposed, ToolInvocationDenied, UnsupportedFeishuCardAction, UnsupportedFeishuMessage, WorkspaceInstructionsSourceError, acceptsCardPresentationProgress, activeCardPresentation, assembleAgentContext, assertRivusPluginConforms, commitAutomationOutcome, createAgentCommandFromFeishuCardAction, createAgentCommandFromFeishuMessage, createAgentConversationMessages, createAgentDomainEventHandler, createAgentDomainEventSink, createAgentDomainEventSinkFromCallback, createAgentHarness, createAgentHarnessClient, createAgentHarnessPooledRuntime, createAgentInstanceRegistry, createAgentLoopFromCallback, createAgentLoopModelExecutionEnd, createAgentLoopModelExecutionStart, createAgentLoopPromptTransformer, createAgentLoopSkillExecutionEnd, createAgentLoopSkillExecutionStart, createAgentLoopTextDelta, createAgentLoopThinkingDelta, createAgentLoopToolExecutionEnd, createAgentLoopToolExecutionStart, createAgentLoopToolExecutionUpdate, createAgentMemoryService, createAgentRunUpdateHandler, createAgentRuntime, createAgentRuntimePool, createAgentTranscriptMessages, createAgentTranscriptTurn, createAgentsMdInstructionsProvider, createAsyncIterableAgentLoop, createAutomationMandateStore, createCoalescingFeishuPublisher, createCompactionService, createCompositeRivusDaemonTransport, createConfiguredFeishuAutomationCardSender, createConfiguredFeishuCardKitPublisher, createConfiguredFeishuCardKitTargetCreator, createConfiguredFeishuCardKitTargetPreparation, createConfiguredFeishuCardRolloverRuntime, createConfiguredFeishuHumanInteractionPresenter, createConfiguredFeishuOpenApiClient, createConfiguredFeishuTextReplySender, createConfiguredRivusDaemonBootstrap, createConfiguredRivusDeploymentDaemon, createDailyAutomationSchedule, createDefaultAgentHarness, createDefaultAgentHarnessClient, createDefaultAgentHarnessClientFromCallback, createDefaultAgentHarnessClientFromTextCallback, createDefaultAgentHarnessFromCallback, createDefaultAgentHarnessFromTextCallback, createDefaultAgentRuntime, createDefaultAgentRuntimeFromCallback, createDefaultAgentRuntimeFromTextCallback, createDelegationService, createDeliveryOutbox, createEventAgentLoop, createFakeRivusPlugin, createFeishuAgentDaemon, createFeishuAgentRunCard, createFeishuAgentRuntime, createFeishuCardActionCallbackResponse, createFeishuCardActionErrorResponse, createFeishuCardDeliveryLedger, createFeishuCardDeliveryReconciler, createFeishuCardKitOpenApiClient, createFeishuCardKitOpenApiTargetCreator, createFeishuCardKitPublisher, createFeishuCardPresentationStore, createFeishuCardRollover, createFeishuCardRolloverSupervisor, createFeishuCardTargetPreparation, createFeishuConversationId, createFeishuCotPublisher, createFeishuDeploymentEndpoint, createFeishuEventHandlers, createFeishuHumanInteractionCard, createFeishuHumanInteractionPresenter, createFeishuInboxRepository, createFeishuMessageQueue, createFeishuMessageWorker, createFeishuOpenApiClient, createFeishuPeriodicFlush, createFeishuPresentationPreparation, createFeishuSessionKey, createFeishuStreamProjector, createFeishuTenantAccessTokenProvider, createFeishuWebSocketDaemon, createFeishuWorkerLoop, createFixedClock, createHumanInteractionEndpointRegistry, createHumanInteractionService, createHumanInteractionToolApprovalGateway, createInMemoryFeishuCardTargetRegistry, createInMemoryHumanInteractionRepository, createInvocationAuthority, createJsonFetchRequest, createJsonFileFeishuCardTargetRegistry, createJsonlAgentEventLog, createJsonlHumanInteractionRepository, createLangfuseAgentTelemetry, createLazyFeishuWebSocketEventDispatcher, createMemoryNamespace, createOpenTelemetryAgentEventSink, createOpenTelemetryAgentTelemetry, createPiAgentLoop, createPiSdkAgentLoop, createPiSessionRegistry, createPiSkillRuntime, createPiToolNameResolver, createPiToolProxyDefinitions, createPluginStateStore, createProjectMemoryPromptPreparer, createRateLimitedFeishuPublisher, createRecoveryAction, createRecoveryControl, createRivusAgentHost, createRivusDaemonProcess, createRivusDaemonShutdownController, createRivusDaemonStatusHttpServer, createRivusDaemonStatusReporter, createRivusDeploymentCliProcess, createRivusDeploymentDaemon, createRivusEnvFromOpenClawConfig, createRivusMemoryTool, createRivusMemoryToolContract, createRivusMemoryToolDescriptor, createRivusPluginCatalog, createRoutedHumanInteractionToolApprovalService, createScheduledAutomation, createSequenceRunIds, createSessionScheduler, createSubagentCoordinator, createSystemClock, createTelemetryContentRedactor, createTextAgentLoop, createTextAgentLoopFromCallback, createToolBroker, createToolInputDigest, createToolOperationLedger, createUuidRunIds, createWorkspaceRootHandle, describeFeishuMessageIntake, evolveAgentRun, formatRivusEnvFile, initialAgentRunState, intersectToolIds, isAgentToolExecutionEvent, isAssistantTextDeltaEvent, isAssistantThinkingDeltaEvent, isCardPresentationHandoffDue, isTerminalAgentDomainEvent, isTerminalAgentRunPhase, loadNodeRivusPluginModule, loadRivusDaemonConfig, loadRivusDeployment, loadRivusDeploymentManifest, normalizeStableJson, openJsonAutomationTickRepository, openJsonlAgentMemoryService, openJsonlFeishuCardDeliveryLedger, openJsonlFeishuInboxRepository, openJsonlRecoveryControl, openJsonlToolOperationLedger, replayAgentHistory, replayAgentTranscript, requiresToolApproval, resolveFeishuEndpointCredentials, resolveLangfuseTelemetryConfig, resolveRivusAgentDefinition, resolveRivusProjectSpace, restoreAgentHistory, restoreConfiguredRivusDaemonBootstrap, restrictMemoryScopesForAudience, runRivusDaemonCli, shouldAcceptFeishuEndpointMessage, transitionHumanInteraction, validateProjectSkillCatalog, validateProjectSkillCommand, validateRivusDeploymentManifest };
7465
+ export { AgentContextBudgetExceeded, AgentEventHandlerFailed, AgentEventLogStoreError, AgentEventSinkFailed, AgentHarnessBusy, AgentInstanceBusy, AgentInstanceConflict, AgentLoopFailed, AgentMemoryError, AgentRunCancelled, AgentRuntimeDisposed, AutomationMandateError, CardPresentationTransitionDenied, CompactionError, DEFAULT_CARD_STREAM_LEASE_MS, DelegationDenied, DeliveryOutboxError, FeishuCardPresentationNotFound, FeishuCardTargetNotFound, FeishuCardTargetRegistryStoreError, FeishuCotProtocolError, FeishuEndpointCredentialError, FeishuOpenApiError, FeishuTenantAccessTokenError, HumanInteractionRepositoryError, HumanInteractionTransitionDenied, InvalidFeishuCardAction, InvalidFeishuMessageContent, InvalidFeishuSessionReference, InvalidInvocationAuthority, InvalidProjectSkillCatalog, InvalidRecoveryAction, InvalidRivusEndpointBinding, InvalidRivusPlugin, InvalidRivusProjectSpace, InvalidStableJson, InvalidToolInput, InvalidWorkspaceRoot, LangfuseTelemetryConfigError, MEMORY_SCOPES, OpenClawEnvImportError, PluginStateConflict, RIVUS_MEMORY_TOOL_ID, RIVUS_MEMORY_TOOL_PLUGIN_ID, RIVUS_MEMORY_TOOL_VERSION, RIVUS_PLUGIN_API_VERSION, RivusDaemonConfigError, RivusDeploymentAutomationReadinessError, RivusDeploymentDaemonLifecycleError, RivusDeploymentManifestError, RivusDeploymentReadinessError, RivusPluginConformanceError, RivusPluginLoadError, RivusToolInputRejected, SessionSchedulerCapacityExceeded, SessionSchedulerDisposed, ToolInvocationDenied, UnsupportedFeishuCardAction, UnsupportedFeishuMessage, WorkspaceInstructionsSourceError, acceptsCardPresentationProgress, activeCardPresentation, assembleAgentContext, assertRivusPluginConforms, commitAutomationOutcome, createAgentCommandFromFeishuCardAction, createAgentCommandFromFeishuMessage, createAgentConversationMessages, createAgentDomainEventHandler, createAgentDomainEventSink, createAgentDomainEventSinkFromCallback, createAgentHarness, createAgentHarnessClient, createAgentHarnessPooledRuntime, createAgentInstanceRegistry, createAgentLoopFromCallback, createAgentLoopModelExecutionEnd, createAgentLoopModelExecutionStart, createAgentLoopPromptTransformer, createAgentLoopSkillExecutionEnd, createAgentLoopSkillExecutionStart, createAgentLoopTextDelta, createAgentLoopThinkingDelta, createAgentLoopToolExecutionEnd, createAgentLoopToolExecutionStart, createAgentLoopToolExecutionUpdate, createAgentMemoryService, createAgentRunUpdateHandler, createAgentRuntime, createAgentRuntimePool, createAgentTranscriptMessages, createAgentTranscriptTurn, createAgentsMdInstructionsProvider, createAsyncIterableAgentLoop, createAutomationMandateStore, createCoalescingFeishuPublisher, createCompactionService, createCompositeRivusDaemonTransport, createConfiguredFeishuAutomationCardSender, createConfiguredFeishuCardKitPublisher, createConfiguredFeishuCardKitTargetCreator, createConfiguredFeishuCardRolloverRuntime, createConfiguredFeishuHumanInteractionPresenter, createConfiguredFeishuOpenApiClient, createConfiguredFeishuTextReplySender, createConfiguredRivusDaemonBootstrap, createConfiguredRivusDeploymentDaemon, createDailyAutomationSchedule, createDefaultAgentHarness, createDefaultAgentHarnessClient, createDefaultAgentHarnessClientFromCallback, createDefaultAgentHarnessClientFromTextCallback, createDefaultAgentHarnessFromCallback, createDefaultAgentHarnessFromTextCallback, createDefaultAgentRuntime, createDefaultAgentRuntimeFromCallback, createDefaultAgentRuntimeFromTextCallback, createDelegationService, createDeliveryOutbox, createEventAgentLoop, createFakeRivusPlugin, createFeishuAgentDaemon, createFeishuAgentRunCard, createFeishuAgentRuntime, createFeishuCardActionCallbackResponse, createFeishuCardActionErrorResponse, createFeishuCardDeliveryLedger, createFeishuCardDeliveryReconciler, createFeishuCardKitOpenApiClient, createFeishuCardKitOpenApiTargetCreator, createFeishuCardKitPublisher, createFeishuCardPresentationStore, createFeishuCardRollover, createFeishuCardRolloverSupervisor, createFeishuCardTargetPreparation, createFeishuConversationId, createFeishuCotPublisher, createFeishuDeploymentEndpoint, createFeishuEventHandlers, createFeishuHumanInteractionCard, createFeishuHumanInteractionPresenter, createFeishuInboxRepository, createFeishuMessageQueue, createFeishuMessageWorker, createFeishuOpenApiClient, createFeishuPeriodicFlush, createFeishuPresentationPreparation, createFeishuSessionKey, createFeishuStreamProjector, createFeishuTenantAccessTokenProvider, createFeishuWebSocketDaemon, createFeishuWorkerLoop, createFixedClock, createHumanInteractionEndpointRegistry, createHumanInteractionService, createHumanInteractionToolApprovalGateway, createInMemoryFeishuCardTargetRegistry, createInMemoryHumanInteractionRepository, createInvocationAuthority, createJsonFetchRequest, createJsonFileFeishuCardTargetRegistry, createJsonlAgentEventLog, createJsonlHumanInteractionRepository, createLangfuseAgentTelemetry, createLazyFeishuWebSocketEventDispatcher, createMemoryNamespace, createOpenTelemetryAgentEventSink, createOpenTelemetryAgentTelemetry, createPiAgentLoop, createPiSdkAgentLoop, createPiSessionRegistry, createPluginStateStore, createProjectMemoryPromptPreparer, createRateLimitedFeishuPublisher, createRecoveryAction, createRecoveryControl, createRivusAgentHost, createRivusDaemonProcess, createRivusDaemonShutdownController, createRivusDaemonStatusHttpServer, createRivusDaemonStatusReporter, createRivusDeploymentCliProcess, createRivusDeploymentDaemon, createRivusEnvFromOpenClawConfig, createRivusMemoryTool, createRivusMemoryToolContract, createRivusMemoryToolDescriptor, createRivusPluginCatalog, createRoutedHumanInteractionToolApprovalService, createScheduledAutomation, createSequenceRunIds, createSessionScheduler, createSubagentCoordinator, createSystemClock, createTelemetryContentRedactor, createTestClock, createTextAgentLoop, createTextAgentLoopFromCallback, createToolBroker, createToolInputDigest, createToolOperationLedger, createUuidRunIds, createWorkspaceRootHandle, describeFeishuMessageIntake, evolveAgentRun, formatRivusEnvFile, initialAgentRunState, intersectToolIds, isAgentToolExecutionEvent, isAssistantTextDeltaEvent, isAssistantThinkingDeltaEvent, isCardPresentationHandoffDue, isTerminalAgentDomainEvent, isTerminalAgentRunPhase, loadNodeRivusPluginModule, loadRivusDaemonConfig, loadRivusDeployment, loadRivusDeploymentManifest, normalizeStableJson, openJsonAutomationTickRepository, openJsonlAgentMemoryService, openJsonlFeishuCardDeliveryLedger, openJsonlFeishuInboxRepository, openJsonlRecoveryControl, openJsonlToolOperationLedger, replayAgentHistory, replayAgentTranscript, requiresToolApproval, resolveFeishuEndpointCredentials, resolveLangfuseTelemetryConfig, resolveRivusAgentDefinition, resolveRivusProjectSpace, restoreAgentHistory, restoreConfiguredRivusDaemonBootstrap, restrictMemoryScopesForAudience, runRivusDaemonCli, shouldAcceptFeishuEndpointMessage, transitionHumanInteraction, validateProjectSkillCatalog, validateProjectSkillCommand, validateRivusDeploymentManifest };