@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.
- package/dist/env/agent/index.js +3 -3
- package/dist/env/error-reply.d.ts +184 -0
- package/dist/env/event-source/event-source-handlers.d.ts +9 -23
- package/dist/env/event-source/index.js +6 -6
- package/dist/env/index.js +18 -18
- package/dist/env/llm/adapter-pi-ai.d.ts +147 -2
- package/dist/env/llm/adapter.d.ts +21 -1
- package/dist/env/llm/index.js +2 -2
- package/dist/env/llm/invoke.d.ts +41 -1
- package/dist/env/llm/llm.d.ts +25 -0
- package/dist/env/llm/reasoning-defense.d.ts +104 -0
- package/dist/env/llm/types.d.ts +26 -0
- package/dist/env/prompt/index.js +2 -2
- package/dist/env/prompt/prompts-index.d.ts +1 -1
- package/dist/env/session/index.js +4 -4
- package/dist/env/session/storage/index.js +3 -3
- package/dist/env/task/backend/index.js +0 -2
- package/dist/env/task/backend/types.d.ts +0 -11
- package/dist/env/task/delegate/index.js +2 -2
- package/dist/env/task/index.js +3 -3
- package/dist/env/task/plugins/card-chat-routing.d.ts +42 -89
- package/dist/env/task/plugins/index.js +4 -4
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +0 -51
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +14 -31
- package/dist/env/task/plugins/per-task-group-chat-plugin.d.ts +4 -4
- package/dist/env/workflow/engine/engine.d.ts +65 -0
- package/dist/env/workflow/engine/index.js +2 -2
- package/dist/env/workflow/index.js +9 -9
- package/dist/env/workflow/nodes/index.js +1 -1
- package/dist/env/workflow/nodes/tool-node.d.ts +6 -0
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/tools/index.js +6 -6
- package/dist/env/workflow/tools/workflow-validate-tool.d.ts +11 -2
- package/dist/env/workflow/types/run.d.ts +19 -0
- package/dist/env/workflow/utils/agent-session-metadata.d.ts +13 -0
- package/dist/env/workflow/utils/index.js +1 -1
- package/dist/env/workflow/utils/redact-command-secrets.d.ts +70 -0
- package/dist/env/workflow/utils/shell-dialect-lint.d.ts +75 -0
- package/dist/env/workflow/utils/validate-workflow-definition.d.ts +22 -0
- package/dist/index.js +20 -20
- package/dist/shared/@ai-setting/{roy-agent-core-stnddvx9.js → roy-agent-core-12d2xap8.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-pk1b3kvf.js → roy-agent-core-2b8jtv7m.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-x8n1r7h4.js → roy-agent-core-2bscfrr1.js} +188 -7
- package/dist/shared/@ai-setting/{roy-agent-core-gdsqp6j8.js → roy-agent-core-6masakz4.js} +45 -0
- package/dist/shared/@ai-setting/{roy-agent-core-vvxb9522.js → roy-agent-core-6qxh4xrm.js} +67 -6
- package/dist/shared/@ai-setting/{roy-agent-core-h93v6p6y.js → roy-agent-core-7qy3nffr.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-4vpk40ss.js → roy-agent-core-8eqngasy.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-brwzs8wf.js → roy-agent-core-9h72sk1n.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-na73mym1.js → roy-agent-core-a4vzsn0g.js} +212 -1
- package/dist/shared/@ai-setting/{roy-agent-core-35s1w7tc.js → roy-agent-core-aer5kw1j.js} +142 -70
- package/dist/shared/@ai-setting/{roy-agent-core-j8e92gj8.js → roy-agent-core-b5ew8t0k.js} +0 -59
- package/dist/shared/@ai-setting/{roy-agent-core-4sx6sdb2.js → roy-agent-core-cd62e9p1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-39xejr39.js → roy-agent-core-e2z1etk4.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-hch2geta.js → roy-agent-core-g36jevrk.js} +14 -183
- package/dist/shared/@ai-setting/{roy-agent-core-ph5qbqcx.js → roy-agent-core-j2nvedt6.js} +465 -128
- package/dist/shared/@ai-setting/{roy-agent-core-p2r27era.js → roy-agent-core-mxdc756a.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-p8ak03s0.js → roy-agent-core-w527pcpe.js} +293 -42
- package/dist/shared/@ai-setting/{roy-agent-core-3tv1q6f2.js → roy-agent-core-ytr2w0vb.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-yd21n6c7.js → roy-agent-core-zvemdfx5.js} +1 -1
- package/dist/test-utils/child-process-mock.d.ts +73 -0
- package/package.json +2 -2
- /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-
|
|
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
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
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
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
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
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
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
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
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
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
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 >=
|
|
2250
|
+
if (scheduled >= parallelLimit)
|
|
2245
2251
|
break;
|
|
2246
|
-
|
|
2247
|
-
|
|
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
|
|
2271
|
+
if (sessionState.config.loopEnabled && sessionState.loopIterationCount > maxIterations) {
|
|
2265
2272
|
logger3.error(`[WorkflowEngine] Max loop iterations ${maxIterations} exceeded`);
|
|
2266
|
-
|
|
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 (!
|
|
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
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
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
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
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) ?? {
|