@ai-setting/roy-agent-core 1.7.53 → 1.7.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/env/agent/index.js +3 -3
  2. package/dist/env/error-reply.d.ts +184 -0
  3. package/dist/env/event-source/event-source-handlers.d.ts +9 -23
  4. package/dist/env/event-source/index.js +6 -6
  5. package/dist/env/index.js +18 -18
  6. package/dist/env/llm/adapter-pi-ai.d.ts +147 -2
  7. package/dist/env/llm/adapter.d.ts +21 -1
  8. package/dist/env/llm/index.js +2 -2
  9. package/dist/env/llm/invoke.d.ts +41 -1
  10. package/dist/env/llm/llm.d.ts +25 -0
  11. package/dist/env/llm/reasoning-defense.d.ts +104 -0
  12. package/dist/env/llm/types.d.ts +26 -0
  13. package/dist/env/prompt/index.js +2 -2
  14. package/dist/env/prompt/prompts-index.d.ts +1 -1
  15. package/dist/env/session/index.js +4 -4
  16. package/dist/env/session/storage/index.js +3 -3
  17. package/dist/env/task/backend/index.js +0 -2
  18. package/dist/env/task/backend/types.d.ts +0 -11
  19. package/dist/env/task/delegate/index.js +2 -2
  20. package/dist/env/task/index.js +3 -3
  21. package/dist/env/task/plugins/card-chat-routing.d.ts +42 -89
  22. package/dist/env/task/plugins/index.js +4 -4
  23. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +0 -51
  24. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +14 -31
  25. package/dist/env/task/plugins/per-task-group-chat-plugin.d.ts +4 -4
  26. package/dist/env/workflow/engine/engine.d.ts +65 -0
  27. package/dist/env/workflow/engine/index.js +2 -2
  28. package/dist/env/workflow/index.js +9 -9
  29. package/dist/env/workflow/nodes/index.js +1 -1
  30. package/dist/env/workflow/nodes/tool-node.d.ts +6 -0
  31. package/dist/env/workflow/plugins/index.js +2 -2
  32. package/dist/env/workflow/tools/index.js +6 -6
  33. package/dist/env/workflow/tools/workflow-validate-tool.d.ts +11 -2
  34. package/dist/env/workflow/types/run.d.ts +19 -0
  35. package/dist/env/workflow/utils/agent-session-metadata.d.ts +13 -0
  36. package/dist/env/workflow/utils/index.js +1 -1
  37. package/dist/env/workflow/utils/redact-command-secrets.d.ts +70 -0
  38. package/dist/env/workflow/utils/shell-dialect-lint.d.ts +75 -0
  39. package/dist/env/workflow/utils/validate-workflow-definition.d.ts +22 -0
  40. package/dist/index.js +20 -20
  41. package/dist/shared/@ai-setting/{roy-agent-core-stnddvx9.js → roy-agent-core-12d2xap8.js} +1 -1
  42. package/dist/shared/@ai-setting/{roy-agent-core-pk1b3kvf.js → roy-agent-core-2b8jtv7m.js} +1 -1
  43. package/dist/shared/@ai-setting/{roy-agent-core-x8n1r7h4.js → roy-agent-core-2bscfrr1.js} +188 -7
  44. package/dist/shared/@ai-setting/{roy-agent-core-gdsqp6j8.js → roy-agent-core-6masakz4.js} +45 -0
  45. package/dist/shared/@ai-setting/{roy-agent-core-vvxb9522.js → roy-agent-core-6qxh4xrm.js} +67 -6
  46. package/dist/shared/@ai-setting/{roy-agent-core-h93v6p6y.js → roy-agent-core-7qy3nffr.js} +2 -2
  47. package/dist/shared/@ai-setting/{roy-agent-core-4vpk40ss.js → roy-agent-core-8eqngasy.js} +2 -2
  48. package/dist/shared/@ai-setting/{roy-agent-core-brwzs8wf.js → roy-agent-core-9h72sk1n.js} +1 -1
  49. package/dist/shared/@ai-setting/{roy-agent-core-na73mym1.js → roy-agent-core-a4vzsn0g.js} +212 -1
  50. package/dist/shared/@ai-setting/{roy-agent-core-35s1w7tc.js → roy-agent-core-aer5kw1j.js} +142 -70
  51. package/dist/shared/@ai-setting/{roy-agent-core-j8e92gj8.js → roy-agent-core-b5ew8t0k.js} +0 -59
  52. package/dist/shared/@ai-setting/{roy-agent-core-4sx6sdb2.js → roy-agent-core-cd62e9p1.js} +1 -1
  53. package/dist/shared/@ai-setting/{roy-agent-core-39xejr39.js → roy-agent-core-e2z1etk4.js} +1 -1
  54. package/dist/shared/@ai-setting/{roy-agent-core-hch2geta.js → roy-agent-core-g36jevrk.js} +14 -183
  55. package/dist/shared/@ai-setting/{roy-agent-core-ph5qbqcx.js → roy-agent-core-j2nvedt6.js} +465 -128
  56. package/dist/shared/@ai-setting/{roy-agent-core-p2r27era.js → roy-agent-core-mxdc756a.js} +1 -1
  57. package/dist/shared/@ai-setting/{roy-agent-core-p8ak03s0.js → roy-agent-core-w527pcpe.js} +293 -42
  58. package/dist/shared/@ai-setting/{roy-agent-core-3tv1q6f2.js → roy-agent-core-ytr2w0vb.js} +2 -2
  59. package/dist/shared/@ai-setting/{roy-agent-core-yd21n6c7.js → roy-agent-core-zvemdfx5.js} +1 -1
  60. package/dist/test-utils/child-process-mock.d.ts +73 -0
  61. package/package.json +2 -2
  62. /package/dist/shared/@ai-setting/{roy-agent-core-zy3hqfwg.js → roy-agent-core-0hq21px2.js} +0 -0
@@ -17,7 +17,7 @@ import {
17
17
  init_skill_node,
18
18
  init_tool_node,
19
19
  init_workflow_node
20
- } from "./roy-agent-core-x8n1r7h4.js";
20
+ } from "./roy-agent-core-2bscfrr1.js";
21
21
  import {
22
22
  WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
23
23
  init_json_schema_to_zod,
@@ -1254,6 +1254,10 @@ ${promptInjection}`;
1254
1254
  workflowName: context.workflowName
1255
1255
  }
1256
1256
  });
1257
+ if (typeof context.registerAgentSubSession === "function") {
1258
+ await context.registerAgentSubSession(this.definition.id, agentSessionId);
1259
+ return agentSessionId;
1260
+ }
1257
1261
  const workflowSession = await sessionComponent.get(context.sessionId);
1258
1262
  if (workflowSession) {
1259
1263
  const metadata = workflowSession.metadata || {};
@@ -1437,6 +1441,20 @@ function updateAgentSessionStatus(agentSessions, nodeId, status) {
1437
1441
  function markAgentSessionCompleted(agentSessions, nodeId) {
1438
1442
  return updateAgentSessionStatus(agentSessions, nodeId, "completed");
1439
1443
  }
1444
+ function upsertAgentSession(agentSessions, nodeId, agentSessionId) {
1445
+ const next = {
1446
+ nodeId,
1447
+ sessionId: agentSessionId,
1448
+ status: "active",
1449
+ createdAt: Date.now()
1450
+ };
1451
+ const list = agentSessions ?? [];
1452
+ const existingIndex = list.findIndex((ref) => ref.nodeId === nodeId);
1453
+ if (existingIndex >= 0) {
1454
+ return list.map((ref, index) => index === existingIndex ? { ...next } : ref);
1455
+ }
1456
+ return [...list, next];
1457
+ }
1440
1458
  function markAgentSessionFailed(agentSessions, nodeId) {
1441
1459
  return updateAgentSessionStatus(agentSessions, nodeId, "failed");
1442
1460
  }
@@ -1903,7 +1921,9 @@ var init_engine = __esm(() => {
1903
1921
  agentSessions: new Map,
1904
1922
  edges: dagManager.buildEdges(definition.edges || []),
1905
1923
  loopIterationCount: 0,
1906
- loopGuardCounters: new Map
1924
+ loopGuardCounters: new Map,
1925
+ inFlight: new Map,
1926
+ sessionMetadataQueue: Promise.resolve()
1907
1927
  };
1908
1928
  this.setupEventHandlers(sessionState);
1909
1929
  return sessionState;
@@ -1995,10 +2015,10 @@ var init_engine = __esm(() => {
1995
2015
  sessionState.abortController.abort();
1996
2016
  sessionState.executor.cancelAll();
1997
2017
  if (this.sessionComponent) {
1998
- const metadata = await this.getSessionMetadata(sessionId);
1999
- await this.sessionComponent.update(sessionId, {
2000
- metadata: { ...metadata, status: "paused" }
2001
- });
2018
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2019
+ ...metadata,
2020
+ status: "paused"
2021
+ }));
2002
2022
  }
2003
2023
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.paused", this.getRunIdFromSessionId(sessionId), {}));
2004
2024
  logger3.info(`[WorkflowEngine] Workflow paused: ${sessionId}`);
@@ -2036,15 +2056,11 @@ var init_engine = __esm(() => {
2036
2056
  }
2037
2057
  sessionState.executor.cancelAll();
2038
2058
  if (this.sessionComponent) {
2039
- const metadata = await this.getSessionMetadata(sessionId);
2040
- const updatedAgentSessions = markAllAgentSessionsStopped(metadata.agentSessions);
2041
- await this.sessionComponent.update(sessionId, {
2042
- metadata: {
2043
- ...metadata,
2044
- status: "stopped",
2045
- agentSessions: updatedAgentSessions
2046
- }
2047
- });
2059
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2060
+ ...metadata,
2061
+ status: "stopped",
2062
+ agentSessions: markAllAgentSessionsStopped(metadata.agentSessions)
2063
+ }));
2048
2064
  await this.propagateStopToChildSessions(sessionId, stopReason);
2049
2065
  }
2050
2066
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.stopped", this.getRunIdFromSessionId(sessionId), {
@@ -2151,28 +2167,18 @@ var init_engine = __esm(() => {
2151
2167
  sessionState.workflowHistory.push(...messages);
2152
2168
  }
2153
2169
  }
2154
- if (this.sessionComponent) {
2155
- const metadata = await this.getSessionMetadata(sessionId);
2156
- await this.sessionComponent.update(sessionId, {
2157
- metadata: {
2158
- ...metadata,
2159
- agentSessions: markAgentSessionCompleted(metadata.agentSessions, event.node_id)
2160
- }
2161
- });
2162
- }
2170
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2171
+ ...metadata,
2172
+ agentSessions: markAgentSessionCompleted(metadata.agentSessions, event.node_id)
2173
+ }));
2163
2174
  });
2164
2175
  eventBus.on("node.failed", async (event) => {
2165
2176
  if (event.type !== "node.failed")
2166
2177
  return;
2167
- if (this.sessionComponent) {
2168
- const metadata = await this.getSessionMetadata(sessionId);
2169
- await this.sessionComponent.update(sessionId, {
2170
- metadata: {
2171
- ...metadata,
2172
- agentSessions: markAgentSessionFailed(metadata.agentSessions, event.node_id)
2173
- }
2174
- });
2175
- }
2178
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2179
+ ...metadata,
2180
+ agentSessions: markAgentSessionFailed(metadata.agentSessions, event.node_id)
2181
+ }));
2176
2182
  scheduler.markFailed(event.node_id);
2177
2183
  await this.failWorkflow(sessionState, new Error(event.error.message));
2178
2184
  });
@@ -2183,10 +2189,9 @@ var init_engine = __esm(() => {
2183
2189
  sessionState.status = "paused";
2184
2190
  sessionState.abortController.abort();
2185
2191
  if (this.sessionComponent) {
2186
- const metadata = await this.getSessionMetadata(sessionId);
2187
- const agentSessions = updateAgentSessionStatus(metadata.agentSessions, event.node_id, "paused");
2188
- await this.sessionComponent.update(sessionId, {
2189
- metadata: {
2192
+ await this.updateSessionMetadata(sessionState, (metadata) => {
2193
+ const agentSessions = updateAgentSessionStatus(metadata.agentSessions, event.node_id, "paused");
2194
+ return {
2190
2195
  ...metadata,
2191
2196
  status: "paused",
2192
2197
  pendingNodeId: event.node_id,
@@ -2194,7 +2199,7 @@ var init_engine = __esm(() => {
2194
2199
  pendingAskUserQuery: event.query,
2195
2200
  pendingAskUserAgentSessionId: event.agent_session_id,
2196
2201
  agentSessions
2197
- }
2202
+ };
2198
2203
  });
2199
2204
  }
2200
2205
  await eventBus.publish(createWorkflowEvent("workflow.paused", runId, {
@@ -2237,14 +2242,16 @@ var init_engine = __esm(() => {
2237
2242
  if (readyNodes.length === 0 || !canStart) {
2238
2243
  return false;
2239
2244
  }
2245
+ const parallelLimit = sessionState.config.parallelLimit ?? Infinity;
2240
2246
  let scheduled = 0;
2241
2247
  for (const nodeId of readyNodes) {
2242
2248
  if (!scheduler.canStartMore())
2243
2249
  break;
2244
- if (scheduled >= (sessionState.config.parallelLimit ?? Infinity))
2250
+ if (scheduled >= parallelLimit)
2245
2251
  break;
2246
- await this.startNode(sessionState, nodeId, sessionState.config.workflowInput);
2247
- scheduled++;
2252
+ if (this.dispatchNode(sessionState, nodeId, sessionState.config.workflowInput)) {
2253
+ scheduled++;
2254
+ }
2248
2255
  }
2249
2256
  return true;
2250
2257
  };
@@ -2258,13 +2265,12 @@ var init_engine = __esm(() => {
2258
2265
  }
2259
2266
  while (sessionState.status === "running" && !abortController.signal.aborted && !sessionState.cancellationScope?.signal.aborted) {
2260
2267
  const state = scheduler.getState();
2261
- if (state.pending.length === 0 && state.running.length === 0) {
2268
+ if (state.pending.length === 0 && state.running.length === 0 && sessionState.inFlight.size === 0) {
2262
2269
  break;
2263
2270
  }
2264
- if (sessionState.config.loopEnabled && sessionState.loopIterationCount >= maxIterations) {
2271
+ if (sessionState.config.loopEnabled && sessionState.loopIterationCount > maxIterations) {
2265
2272
  logger3.error(`[WorkflowEngine] Max loop iterations ${maxIterations} exceeded`);
2266
- sessionState.rejectCompleted(new WorkflowError(`Workflow exceeded maximum loop iterations: ${maxIterations}`));
2267
- await this.stop(sessionState.sessionId, "Max iterations exceeded");
2273
+ await this.failWorkflow(sessionState, new WorkflowError(`Workflow exceeded maximum loop iterations: ${maxIterations}`));
2268
2274
  return;
2269
2275
  }
2270
2276
  try {
@@ -2274,13 +2280,42 @@ var init_engine = __esm(() => {
2274
2280
  }
2275
2281
  await scheduleAvailableNodes();
2276
2282
  }
2283
+ while (sessionState.inFlight.size > 0) {
2284
+ const pending = Array.from(sessionState.inFlight.values());
2285
+ await Promise.allSettled(pending);
2286
+ for (const [nodeId, promise] of Array.from(sessionState.inFlight.entries())) {
2287
+ if (pending.includes(promise)) {
2288
+ sessionState.inFlight.delete(nodeId);
2289
+ }
2290
+ }
2291
+ }
2292
+ }
2293
+ dispatchNode(sessionState, nodeId, input) {
2294
+ const { scheduler } = sessionState;
2295
+ if (scheduler.isRunning(nodeId) || scheduler.isCompleted(nodeId) || scheduler.isFailed(nodeId)) {
2296
+ return false;
2297
+ }
2298
+ const promise = this.startNode(sessionState, nodeId, input).catch((error) => {
2299
+ logger3.error(`[WorkflowEngine] Unhandled dispatch error for node "${nodeId}":`, error);
2300
+ }).finally(() => {
2301
+ if (sessionState.inFlight.get(nodeId) === promise) {
2302
+ sessionState.inFlight.delete(nodeId);
2303
+ }
2304
+ });
2305
+ sessionState.inFlight.set(nodeId, promise);
2306
+ return true;
2277
2307
  }
2278
2308
  waitForNextNodeEvent(sessionState, signal) {
2279
2309
  return new Promise((resolve) => {
2280
2310
  const state = sessionState.scheduler.getState();
2281
2311
  const hasRunningNodes = state.running.length > 0;
2312
+ const hasInFlight = sessionState.inFlight.size > 0;
2313
+ const limit = sessionState.config.parallelLimit ?? Infinity;
2314
+ const atCapacity = sessionState.inFlight.size >= limit;
2315
+ const mayHaveDeferredWork = atCapacity && state.pending.length + state.ready.length > 0;
2316
+ const pureEventDriven = hasRunningNodes && hasInFlight && !mayHaveDeferredWork;
2282
2317
  let timeoutId;
2283
- if (!hasRunningNodes) {
2318
+ if (!pureEventDriven) {
2284
2319
  timeoutId = setTimeout(() => {
2285
2320
  cleanup();
2286
2321
  resolve();
@@ -2291,6 +2326,7 @@ var init_engine = __esm(() => {
2291
2326
  clearTimeout(timeoutId);
2292
2327
  sessionState.eventBus.off("node.completed", onCompleted);
2293
2328
  sessionState.eventBus.off("node.failed", onFailed);
2329
+ sessionState.eventBus.off("node.scheduled", onScheduled);
2294
2330
  };
2295
2331
  const onCompleted = (event) => {
2296
2332
  if (event.type === "node.completed") {
@@ -2304,8 +2340,15 @@ var init_engine = __esm(() => {
2304
2340
  resolve();
2305
2341
  }
2306
2342
  };
2343
+ const onScheduled = (event) => {
2344
+ if (event.type === "node.scheduled") {
2345
+ cleanup();
2346
+ resolve();
2347
+ }
2348
+ };
2307
2349
  sessionState.eventBus.on("node.completed", onCompleted);
2308
2350
  sessionState.eventBus.on("node.failed", onFailed);
2351
+ sessionState.eventBus.on("node.scheduled", onScheduled);
2309
2352
  if (signal.aborted) {
2310
2353
  cleanup();
2311
2354
  resolve();
@@ -2541,6 +2584,9 @@ var init_engine = __esm(() => {
2541
2584
  logger3.debug(`[WorkflowEngine] Processing edges after "${completedNodeId}" completed. edges=${JSON.stringify(sessionState.edges)}`);
2542
2585
  const edgeResult = scheduler.processEdgesAfterCompletion(completedNodeId, sessionState.edges, templateResolver, sessionState.config.loopEnabled);
2543
2586
  logger3.debug(`[WorkflowEngine] Edge processing result: ${JSON.stringify(edgeResult)}`);
2587
+ for (const reEntryId of edgeResult.reEntries) {
2588
+ scheduler.markStarted(reEntryId);
2589
+ }
2544
2590
  const loopGuardSnapshots = new Map;
2545
2591
  for (const reEntryId of edgeResult.reEntries) {
2546
2592
  const guard = sessionState.dagManager.getLoopGuard(reEntryId);
@@ -2609,6 +2655,8 @@ var init_engine = __esm(() => {
2609
2655
  }
2610
2656
  }
2611
2657
  const workflowInput = sessionState.config.workflowInput || {};
2658
+ const parallelLimit = sessionState.config.parallelLimit ?? Infinity;
2659
+ const reEntries = new Set(edgeResult.reEntries);
2612
2660
  for (const targetId of edgeResult.toStart) {
2613
2661
  if (loopGuardTripped.has(targetId)) {
2614
2662
  continue;
@@ -2617,8 +2665,14 @@ var init_engine = __esm(() => {
2617
2665
  logger3.info(`[WorkflowEngine] Workflow terminated via __end__ edge from node "${completedNodeId}"`);
2618
2666
  scheduler.markCompleted("__end__");
2619
2667
  await this.completeWorkflow(sessionState);
2620
- } else {
2668
+ } else if (reEntries.has(targetId)) {
2621
2669
  await this.startNode(sessionState, targetId, workflowInput);
2670
+ } else {
2671
+ if (sessionState.inFlight.size >= parallelLimit) {
2672
+ logger3.debug(`[WorkflowEngine] Deferring edge-triggered node "${targetId}" — in-flight ${sessionState.inFlight.size} >= parallel_limit ${parallelLimit}`);
2673
+ continue;
2674
+ }
2675
+ this.dispatchNode(sessionState, targetId, workflowInput);
2622
2676
  }
2623
2677
  }
2624
2678
  }
@@ -2668,6 +2722,15 @@ var init_engine = __esm(() => {
2668
2722
  attachAgentSessionToLastStart: async (targetNodeId, agentSessionId) => {
2669
2723
  await sessionState.executor.attachAgentSessionToLastStart(sessionState.sessionId, targetNodeId, agentSessionId);
2670
2724
  },
2725
+ registerAgentSubSession: async (targetNodeId, agentSessionId) => {
2726
+ await this.updateSessionMetadata(sessionState, (metadata) => {
2727
+ const existing = Array.isArray(metadata.agentSessions) ? metadata.agentSessions : [];
2728
+ return {
2729
+ ...metadata,
2730
+ agentSessions: upsertAgentSession(existing, targetNodeId, agentSessionId)
2731
+ };
2732
+ });
2733
+ },
2671
2734
  workflowInput,
2672
2735
  templateResolver,
2673
2736
  resolvedConfig: templateResolver.resolveValue(effectiveConfig),
@@ -2703,19 +2766,16 @@ var init_engine = __esm(() => {
2703
2766
  allNodeOutputs[nodeId] = nodeOutput;
2704
2767
  }
2705
2768
  if (this.sessionComponent) {
2706
- const metadata = await this.getSessionMetadata(sessionId);
2707
- await this.sessionComponent.update(sessionId, {
2708
- metadata: {
2709
- ...metadata,
2710
- status: "completed",
2711
- completedAt: Date.now(),
2712
- durationMs,
2713
- output: allNodeOutputs,
2714
- pendingNodeId: undefined,
2715
- pauseReason: undefined,
2716
- agentSessions: markAllAgentSessionsCompleted(metadata.agentSessions)
2717
- }
2718
- });
2769
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2770
+ ...metadata,
2771
+ status: "completed",
2772
+ completedAt: Date.now(),
2773
+ durationMs,
2774
+ output: allNodeOutputs,
2775
+ pendingNodeId: undefined,
2776
+ pauseReason: undefined,
2777
+ agentSessions: markAllAgentSessionsCompleted(metadata.agentSessions)
2778
+ }));
2719
2779
  }
2720
2780
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.completed", runId, {
2721
2781
  result: finalOutput,
@@ -2750,16 +2810,13 @@ var init_engine = __esm(() => {
2750
2810
  const runId = this.getRunIdFromSessionId(sessionId);
2751
2811
  sessionState.executor.cancelAll();
2752
2812
  if (this.sessionComponent) {
2753
- const metadata = await this.getSessionMetadata(sessionId);
2754
- await this.sessionComponent.update(sessionId, {
2755
- metadata: {
2756
- ...metadata,
2757
- status: "failed",
2758
- failedAt: Date.now(),
2759
- durationMs,
2760
- agentSessions: markAllAgentSessionsFailed(metadata.agentSessions)
2761
- }
2762
- });
2813
+ await this.updateSessionMetadata(sessionState, (metadata) => ({
2814
+ ...metadata,
2815
+ status: "failed",
2816
+ failedAt: Date.now(),
2817
+ durationMs,
2818
+ agentSessions: markAllAgentSessionsFailed(metadata.agentSessions)
2819
+ }));
2763
2820
  }
2764
2821
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.failed", runId, {
2765
2822
  error: { message: error.message, stack: error.stack },
@@ -2825,6 +2882,21 @@ var init_engine = __esm(() => {
2825
2882
  const session = await this.sessionComponent.get(sessionId);
2826
2883
  return session?.metadata || { type: "workflow", workflowId: "", workflowName: "", status: "running" };
2827
2884
  }
2885
+ async updateSessionMetadata(sessionState, mutate) {
2886
+ if (!this.sessionComponent)
2887
+ return;
2888
+ const sessionId = sessionState.sessionId;
2889
+ const run = (sessionState.sessionMetadataQueue ?? Promise.resolve()).then(async () => {
2890
+ try {
2891
+ const metadata = await this.getSessionMetadata(sessionId);
2892
+ await this.sessionComponent.update(sessionId, { metadata: mutate(metadata) });
2893
+ } catch (error) {
2894
+ logger3.error(`[WorkflowEngine] Failed to update session metadata for ${sessionId}:`, error);
2895
+ }
2896
+ });
2897
+ sessionState.sessionMetadataQueue = run;
2898
+ await run;
2899
+ }
2828
2900
  findDefinitionForWorkflow(workflowIdOrName) {
2829
2901
  if (!this.workflowRepository) {
2830
2902
  return null;
@@ -287,34 +287,6 @@ function buildChatAppLink(chatId, base = DEFAULT_APP_LINK_BASE) {
287
287
  return `${base}/client/chat/open?openChatId=${chatId}`;
288
288
  }
289
289
  var DEFAULT_APP_LINK_BASE = "https://applink.feishu.cn";
290
- function buildRedirectCard(opts) {
291
- const taskLabel = opts.taskId !== undefined ? `#${opts.taskId}` : "本任务";
292
- const title = opts.taskTitle ? ` ${sanitizeInlineText(opts.taskTitle, 120)}` : "";
293
- const link = buildChatAppLink(opts.targetChatId);
294
- const groupName = opts.targetChatName ? sanitizeInlineText(opts.targetChatName, 60) : "专属群";
295
- return {
296
- schema: "2.0",
297
- header: {
298
- title: { tag: "plain_text", content: "\uD83D\uDCC2 任务卡片已改投专属群" },
299
- subtitle: { tag: "plain_text", content: "这里不是本任务的群,进展请看专属群" },
300
- template: "grey"
301
- },
302
- body: {
303
- elements: [
304
- {
305
- tag: "markdown",
306
- content: [
307
- `- **任务**:${taskLabel}${title}`,
308
- `- **专属群**:[${groupName}](${link})`,
309
- `- **群 ID**:\`${opts.targetChatId}\`(搜群名也能进)`,
310
- opts.reason ? `- **原因**:${sanitizeInlineText(opts.reason, 280)}` : ""
311
- ].filter(Boolean).join(`
312
- `)
313
- }
314
- ]
315
- }
316
- };
317
- }
318
290
  var WORKFLOW_STATUS_LABEL = {
319
291
  running: "\uD83D\uDD04 运行中",
320
292
  completed: "✅ 已完成",
@@ -449,7 +421,6 @@ class LarkCardPatchNotifier {
449
421
  mutexes = new Map;
450
422
  states = new Map;
451
423
  workflowStates = new Map;
452
- redirectsSent = new Set;
453
424
  constructor(options = {}) {
454
425
  this.options = {
455
426
  pinOnStart: true,
@@ -505,36 +476,6 @@ class LarkCardPatchNotifier {
505
476
  }
506
477
  return { messageId, pinned, pinError };
507
478
  }
508
- async sendRedirectNotice(opts) {
509
- const redirectKey = opts.taskId !== undefined ? `${opts.taskId}:${opts.targetChatId}` : undefined;
510
- if (redirectKey) {
511
- if (this.redirectsSent.has(redirectKey)) {
512
- logger.debug(`sendRedirectNotice: 已发过改投卡片(${redirectKey})→ 跳过重复发送`);
513
- return false;
514
- }
515
- this.redirectsSent.add(redirectKey);
516
- }
517
- const card = buildRedirectCard({
518
- taskId: opts.taskId,
519
- taskTitle: opts.taskTitle,
520
- targetChatId: opts.targetChatId,
521
- targetChatName: opts.targetChatName,
522
- reason: opts.reason
523
- });
524
- try {
525
- await this.runLarkCli(this.buildSendCardArgs({
526
- chatId: opts.chatId,
527
- profile: opts.profile,
528
- card
529
- }), "send-redirect");
530
- return true;
531
- } catch (err) {
532
- if (redirectKey)
533
- this.redirectsSent.delete(redirectKey);
534
- logger.warn(`sendRedirectNotice failed (non-fatal) for chat ${opts.chatId}: ${err.message}`);
535
- return false;
536
- }
537
- }
538
479
  async updateTask(opts) {
539
480
  await this.mutexFor(opts.messageId).run(async () => {
540
481
  const state = this.states.get(opts.messageId) ?? {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAutoTaskPlugin
3
- } from "./roy-agent-core-hch2geta.js";
3
+ } from "./roy-agent-core-g36jevrk.js";
4
4
  import {
5
5
  ContextError,
6
6
  ErrorCodes
@@ -31,7 +31,7 @@ import {
31
31
  BackgroundTaskManager,
32
32
  createDelegateTool,
33
33
  createStopTool
34
- } from "./roy-agent-core-p2r27era.js";
34
+ } from "./roy-agent-core-mxdc756a.js";
35
35
  import {
36
36
  TaskHookPoints
37
37
  } from "./roy-agent-core-1pg0fepg.js";