feat: add shadow LangGraph orchestrator runtime

This commit is contained in:
john
2026-07-24 21:25:40 +08:00
parent 46ea22b342
commit 24336d0178
29 changed files with 3247 additions and 25 deletions
+46 -1
View File
@@ -289,6 +289,7 @@ export function createAgentRunGateway({
conversationMemoryService = null,
syncUserPagesOnSuccess = null,
observePersonalMemoryOnSuccess = null,
observeWorkflowRun = null,
isSessionExternallyBusy = null,
validateRunDeliverables = null,
retryDelaysMs = DEFAULT_RUN_RETRY_DELAYS_MS,
@@ -338,6 +339,39 @@ export function createAgentRunGateway({
);
}
function dispatchShadowObservation(input) {
if (typeof observeWorkflowRun !== 'function' || input.toolMode !== 'code') return;
setImmediate(() => {
void Promise.resolve()
.then(() => observeWorkflowRun(input))
.then(async (result) => {
if (!result?.observed) return;
await appendEvent(input.runId, 'workflow_shadow_completed', {
engine: result.engine ?? 'langgraph',
mode: result.mode ?? 'shadow',
configVersion: result.configVersion ?? null,
status: result.shadowRun?.status ?? null,
phase: result.shadowRun?.phase ?? null,
});
})
.catch(async (error) => {
console.warn(
'[AgentRun] workflow shadow observation failed:',
error instanceof Error ? error.message : error,
);
await appendEvent(input.runId, 'workflow_shadow_failed', {
code: String(error?.code ?? 'WORKFLOW_SHADOW_FAILED').slice(0, 128),
message: String(error instanceof Error ? error.message : error).slice(0, 1000),
}).catch((appendError) => {
console.warn(
'[AgentRun] workflow shadow failure event skipped:',
appendError instanceof Error ? appendError.message : appendError,
);
});
});
});
}
async function appendRunSnapshot(runId) {
if (!isRunStreamReplayEnabled()) return;
const row = await getRunById(runId);
@@ -443,8 +477,19 @@ export function createAgentRunGateway({
taskType: normalizedTaskType,
forceDeepReasoning: Boolean(forceDeepReasoning),
});
const createdRun = projectRun(await getRunById(runId));
dispatchShadowObservation({
runId,
requestId: normalizedRequestId,
userId,
sessionId: sessionId || null,
workflowName: 'code-run-v1',
userMessage: runMessage,
toolMode: normalizedToolMode,
taskType: normalizedTaskType,
});
if (autoDispatch) dispatchRun(runId);
return projectRun(await getRunById(runId));
return createdRun;
}
async function prepareRunDeliverables({ userId, sessionId, runId, runStartedAtMs = null }) {