fix(agent): restore active-task routing and active-mode validation observation
Memind CI / Test, build, and release guards (push) Successful in 5m23s

Keep correction follow-ups on Agent using session transcript and active task
context, and let Page Data validation reach Orchestrator when mode is active
instead of requiring shadowEngine.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-27 12:15:15 +08:00
parent f95d766f69
commit aecde46ff6
6 changed files with 662 additions and 20 deletions
+72 -1
View File
@@ -3,7 +3,7 @@ import test from 'node:test';
import { MemorySaver } from '@langchain/langgraph';
import { createOrchestratorApp } from './app.mjs';
import { createLangGraphOrchestratorRuntime } from './runtime.mjs';
import { createWorkflowShadowObserver } from './shadow-observer.mjs';
import { createWorkflowShadowObserver, resolveValidationEngineSelection } from './shadow-observer.mjs';
function jsonResponse(body, status = 200) {
return new Response(JSON.stringify(body), {
@@ -25,6 +25,77 @@ async function listen(app) {
};
}
test('resolveValidationEngineSelection accepts active-mode LangGraph engine', () => {
assert.ok(resolveValidationEngineSelection({
engine: 'langgraph',
shadowEngine: null,
mode: 'active',
reason: 'active',
}));
assert.equal(resolveValidationEngineSelection({
engine: 'native',
shadowEngine: null,
mode: 'active',
reason: 'active',
}), null);
});
test('validation observer records observations in active mode without shadowEngine', async () => {
let capturedUrl = null;
const observer = createWorkflowShadowObserver({
configService: {
async selectEngine() {
return {
engine: 'langgraph',
candidateEngine: 'langgraph',
shadowEngine: null,
fallbackEngine: 'native',
reason: 'active',
candidateReason: 'active',
mode: 'active',
configVersion: 6,
dryRun: false,
};
},
async getRuntimeState() {
return {
config: {
serviceUrl: 'http://orchestrator.internal:8093',
requestTimeoutMs: 1200,
},
};
},
},
serviceToken: 'internal-token',
fetchImpl: async (url) => {
capturedUrl = url;
return jsonResponse({
runId: 'run-active-1',
validation: { verdict: 'passed', kind: 'page-data-delivery' },
});
},
});
const result = await observer.observeValidation({
runId: 'run-active-1',
requestId: 'request-active-1',
userId: 'user-1',
observation: {
idempotencyKey: 'run-active-1:page-data-delivery:v1',
taskType: 'page_data_dev',
required: true,
checks: [{ id: 'page_data_binding', status: 'passed' }],
source: 'portal-agent-run',
observedAt: 123,
},
});
assert.equal(result.observed, true);
assert.equal(result.mode, 'active');
assert.equal(result.validation.verdict, 'passed');
assert.match(String(capturedUrl), /\/v1\/runs\/run-active-1\/validation-observations$/);
});
test('shadow observer skips without creating a remote client when mode does not select shadow', async () => {
let fetchCalls = 0;
const observer = createWorkflowShadowObserver({