fix(agent-run): tolerate goosed stdio MCP listing gaps during session reconcile.
Memind CI / Test, build, and release guards (push) Failing after 4s
Memind CI / Test, build, and release guards (push) Failing after 4s
Skip hot-adding stdio extensions goosed omits from /extensions, stabilize MCP scope during session start, and wire chat intent routing into the agent-run worker. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+102
-56
@@ -3,8 +3,13 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { createAgentRunGateway } from '../agent-run-gateway.mjs';
|
||||
import { createManagedChatIntentRouter } from '../chat-intent-router.mjs';
|
||||
import { createConversationMemoryService } from '../conversation-memory.mjs';
|
||||
import { createDbPool } from '../db.mjs';
|
||||
import { createEpisodicMemoryService } from '../episodic-memory.mjs';
|
||||
import { createLlmProviderService } from '../llm-providers.mjs';
|
||||
import { createMemoryV2AdminConfigService } from '../memory-v2-admin-config.mjs';
|
||||
import { createManagedMemoryV2Runtime } from '../memory-v2-runtime.mjs';
|
||||
import { createTkmindProxy } from '../tkmind-proxy.mjs';
|
||||
import { createToolGateway } from '../tool-gateway.mjs';
|
||||
import { createUserAuth } from '../user-auth.mjs';
|
||||
@@ -94,62 +99,103 @@ if (args.help) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const pool = createDbPool();
|
||||
const workflowShadowEnabled = isEnabledFlag(
|
||||
process.env.MEMIND_ORCHESTRATOR_SHADOW_OBSERVATION_ENABLED,
|
||||
);
|
||||
const workflowShadowObserver = workflowShadowEnabled
|
||||
? createWorkflowShadowObserver({
|
||||
configService: createOrchestratorAdminConfigService(pool),
|
||||
serviceToken: process.env.MEMIND_ORCHESTRATOR_SERVICE_TOKEN,
|
||||
})
|
||||
: null;
|
||||
const baseUserAuth = createUserAuth(pool, {
|
||||
usersRoot: process.env.H5_USERS_ROOT ?? path.join(root, 'users'),
|
||||
h5Root: root,
|
||||
});
|
||||
const overrideWorkingDir = String(process.env.MEMIND_AGENT_RUN_WORKDIR_OVERRIDE ?? '').trim();
|
||||
const overrideWorkingDirUserId = String(process.env.MEMIND_AGENT_RUN_WORKDIR_USER_ID ?? '').trim();
|
||||
const userAuth = overrideWorkingDir
|
||||
? {
|
||||
...baseUserAuth,
|
||||
async resolveWorkingDir(userId) {
|
||||
if (!overrideWorkingDirUserId || overrideWorkingDirUserId === userId) {
|
||||
return path.resolve(overrideWorkingDir);
|
||||
}
|
||||
return baseUserAuth.resolveWorkingDir(userId);
|
||||
},
|
||||
}
|
||||
: baseUserAuth;
|
||||
const llmProviderService = createLlmProviderService(pool, {
|
||||
apiTarget: process.env.TKMIND_API_TARGET ?? 'https://127.0.0.1:18006',
|
||||
apiSecret: process.env.TKMIND_SERVER__SECRET_KEY ?? 'local-dev-secret',
|
||||
});
|
||||
const toolGateway = createToolGateway({ llmProviderService });
|
||||
const apiTargets = parseTargets();
|
||||
const tkmindProxy = createTkmindProxy({
|
||||
apiTarget: apiTargets[0],
|
||||
apiTargets,
|
||||
apiSecret: process.env.TKMIND_SERVER__SECRET_KEY ?? 'local-dev-secret',
|
||||
userAuth,
|
||||
});
|
||||
const gateway = createAgentRunGateway({
|
||||
pool,
|
||||
userAuth,
|
||||
tkmindProxy,
|
||||
toolGateway,
|
||||
autoDispatch: false,
|
||||
maxConcurrentRuns: Number(process.env.MEMIND_AGENT_RUN_QUEUE_CONCURRENCY ?? 1),
|
||||
runTimeoutMs: Number(process.env.MEMIND_AGENT_RUN_TIMEOUT_MS ?? 15 * 60 * 1000),
|
||||
observeWorkflowRun: workflowShadowObserver,
|
||||
observeWorkflowValidation:
|
||||
workflowShadowObserver?.observeValidation ?? null,
|
||||
enforcePageDataWorkflowValidation:
|
||||
workflowShadowEnabled
|
||||
&& isEnabledFlag(
|
||||
process.env.MEMIND_ORCHESTRATOR_PAGE_DATA_VALIDATION_GATE_ENABLED,
|
||||
),
|
||||
});
|
||||
async function bootstrapWorker() {
|
||||
const pool = createDbPool();
|
||||
const workflowShadowEnabled = isEnabledFlag(
|
||||
process.env.MEMIND_ORCHESTRATOR_SHADOW_OBSERVATION_ENABLED,
|
||||
);
|
||||
const workflowShadowObserver = workflowShadowEnabled
|
||||
? createWorkflowShadowObserver({
|
||||
configService: createOrchestratorAdminConfigService(pool),
|
||||
serviceToken: process.env.MEMIND_ORCHESTRATOR_SERVICE_TOKEN,
|
||||
})
|
||||
: null;
|
||||
const baseUserAuth = createUserAuth(pool, {
|
||||
usersRoot: process.env.H5_USERS_ROOT ?? path.join(root, 'users'),
|
||||
h5Root: root,
|
||||
});
|
||||
const overrideWorkingDir = String(process.env.MEMIND_AGENT_RUN_WORKDIR_OVERRIDE ?? '').trim();
|
||||
const overrideWorkingDirUserId = String(process.env.MEMIND_AGENT_RUN_WORKDIR_USER_ID ?? '').trim();
|
||||
const userAuth = overrideWorkingDir
|
||||
? {
|
||||
...baseUserAuth,
|
||||
async resolveWorkingDir(userId) {
|
||||
if (!overrideWorkingDirUserId || overrideWorkingDirUserId === userId) {
|
||||
return path.resolve(overrideWorkingDir);
|
||||
}
|
||||
return baseUserAuth.resolveWorkingDir(userId);
|
||||
},
|
||||
}
|
||||
: baseUserAuth;
|
||||
const llmProviderService = createLlmProviderService(pool, {
|
||||
apiTarget: process.env.TKMIND_API_TARGET ?? 'https://127.0.0.1:18006',
|
||||
apiSecret: process.env.TKMIND_SERVER__SECRET_KEY ?? 'local-dev-secret',
|
||||
});
|
||||
const memoryV2ConfigService = createMemoryV2AdminConfigService(pool);
|
||||
const getEffectiveEnv = async () => {
|
||||
const state = await memoryV2ConfigService.getRuntimeState().catch(() => null);
|
||||
return {
|
||||
...process.env,
|
||||
...(state?.overrides ?? {}),
|
||||
};
|
||||
};
|
||||
const conversationMemoryService = createConversationMemoryService(pool, {
|
||||
llmProviderService,
|
||||
getEffectiveEnv,
|
||||
});
|
||||
const memoryV2 = await createManagedMemoryV2Runtime({
|
||||
legacyMemoryService: conversationMemoryService,
|
||||
configService: memoryV2ConfigService,
|
||||
mysqlPool: pool,
|
||||
});
|
||||
const episodicMemoryService = createEpisodicMemoryService(pool, {
|
||||
getEffectiveEnv,
|
||||
logger: console,
|
||||
});
|
||||
await episodicMemoryService.ensureSchema().catch((err) => {
|
||||
console.warn(
|
||||
'[agent-run-worker] episodic memory schema setup degraded:',
|
||||
err instanceof Error ? err.message : err,
|
||||
);
|
||||
});
|
||||
const chatIntentRouter = createManagedChatIntentRouter({
|
||||
llmProviderService,
|
||||
memoryV2,
|
||||
conversationMemoryService,
|
||||
episodicMemoryService,
|
||||
configService: memoryV2ConfigService,
|
||||
});
|
||||
const toolGateway = createToolGateway({ llmProviderService });
|
||||
const apiTargets = parseTargets();
|
||||
const tkmindProxy = createTkmindProxy({
|
||||
apiTarget: apiTargets[0],
|
||||
apiTargets,
|
||||
apiSecret: process.env.TKMIND_SERVER__SECRET_KEY ?? 'local-dev-secret',
|
||||
userAuth,
|
||||
});
|
||||
const gateway = createAgentRunGateway({
|
||||
pool,
|
||||
userAuth,
|
||||
tkmindProxy,
|
||||
toolGateway,
|
||||
chatIntentRouter,
|
||||
conversationMemoryService,
|
||||
autoDispatch: false,
|
||||
maxConcurrentRuns: Number(process.env.MEMIND_AGENT_RUN_QUEUE_CONCURRENCY ?? 1),
|
||||
runTimeoutMs: Number(process.env.MEMIND_AGENT_RUN_TIMEOUT_MS ?? 15 * 60 * 1000),
|
||||
observeWorkflowRun: workflowShadowObserver,
|
||||
observeWorkflowValidation:
|
||||
workflowShadowObserver?.observeValidation ?? null,
|
||||
enforcePageDataWorkflowValidation:
|
||||
workflowShadowEnabled
|
||||
&& isEnabledFlag(
|
||||
process.env.MEMIND_ORCHESTRATOR_PAGE_DATA_VALIDATION_GATE_ENABLED,
|
||||
),
|
||||
});
|
||||
return { pool, gateway };
|
||||
}
|
||||
|
||||
const { pool, gateway } = await bootstrapWorker();
|
||||
|
||||
let stopping = false;
|
||||
process.on('SIGINT', () => { stopping = true; });
|
||||
|
||||
Reference in New Issue
Block a user