@zhixuan92/multi-model-agent 5.1.0 → 5.2.0

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 (117) hide show
  1. package/dist/cli/serve.d.ts.map +1 -1
  2. package/dist/cli/serve.js +9 -34
  3. package/dist/cli/serve.js.map +1 -1
  4. package/dist/cli/status.js +1 -1
  5. package/dist/cli/status.js.map +1 -1
  6. package/dist/http/handler-deps.d.ts +3 -3
  7. package/dist/http/handler-deps.d.ts.map +1 -1
  8. package/dist/http/handlers/control/context-blocks.d.ts +1 -2
  9. package/dist/http/handlers/control/context-blocks.d.ts.map +1 -1
  10. package/dist/http/handlers/control/context-blocks.js +7 -30
  11. package/dist/http/handlers/control/context-blocks.js.map +1 -1
  12. package/dist/http/handlers/introspection/status.d.ts +3 -3
  13. package/dist/http/handlers/introspection/status.d.ts.map +1 -1
  14. package/dist/http/handlers/introspection/status.js +13 -31
  15. package/dist/http/handlers/introspection/status.js.map +1 -1
  16. package/dist/http/handlers/unified-task.d.ts +5 -0
  17. package/dist/http/handlers/unified-task.d.ts.map +1 -0
  18. package/dist/http/handlers/unified-task.js +520 -0
  19. package/dist/http/handlers/unified-task.js.map +1 -0
  20. package/dist/http/project-registry.d.ts +5 -4
  21. package/dist/http/project-registry.d.ts.map +1 -1
  22. package/dist/http/project-registry.js +5 -7
  23. package/dist/http/project-registry.js.map +1 -1
  24. package/dist/http/server.d.ts +4 -3
  25. package/dist/http/server.d.ts.map +1 -1
  26. package/dist/http/server.js +76 -134
  27. package/dist/http/server.js.map +1 -1
  28. package/dist/skill-install/discover.d.ts +1 -1
  29. package/dist/skill-install/discover.d.ts.map +1 -1
  30. package/dist/skill-install/discover.js +1 -0
  31. package/dist/skill-install/discover.js.map +1 -1
  32. package/dist/skills/_shared/error-handling.md +2 -2
  33. package/dist/skills/_shared/polling.md +7 -7
  34. package/dist/skills/_shared/response-shape.md +8 -8
  35. package/dist/skills/_shared/review-policy.md +1 -3
  36. package/dist/skills/mma-audit/SKILL.md +16 -15
  37. package/dist/skills/mma-context-blocks/SKILL.md +9 -9
  38. package/dist/skills/mma-debug/SKILL.md +9 -13
  39. package/dist/skills/mma-delegate/SKILL.md +14 -13
  40. package/dist/skills/mma-execute-plan/SKILL.md +15 -14
  41. package/dist/skills/mma-explore/SKILL.md +4 -3
  42. package/dist/skills/mma-investigate/SKILL.md +7 -6
  43. package/dist/skills/mma-journal-recall/SKILL.md +7 -6
  44. package/dist/skills/mma-journal-record/SKILL.md +10 -18
  45. package/dist/skills/mma-orchestrate/SKILL.md +74 -0
  46. package/dist/skills/mma-research/SKILL.md +7 -5
  47. package/dist/skills/mma-retry/SKILL.md +38 -37
  48. package/dist/skills/mma-review/SKILL.md +7 -6
  49. package/dist/skills/multi-model-agent/SKILL.md +7 -7
  50. package/dist/telemetry/flusher.d.ts.map +1 -1
  51. package/dist/telemetry/flusher.js +8 -11
  52. package/dist/telemetry/flusher.js.map +1 -1
  53. package/package.json +2 -2
  54. package/dist/http/async-dispatch.d.ts +0 -44
  55. package/dist/http/async-dispatch.d.ts.map +0 -1
  56. package/dist/http/async-dispatch.js +0 -175
  57. package/dist/http/async-dispatch.js.map +0 -1
  58. package/dist/http/canonicalize-file-paths.d.ts +0 -8
  59. package/dist/http/canonicalize-file-paths.d.ts.map +0 -1
  60. package/dist/http/canonicalize-file-paths.js +0 -43
  61. package/dist/http/canonicalize-file-paths.js.map +0 -1
  62. package/dist/http/execution-context.d.ts +0 -18
  63. package/dist/http/execution-context.d.ts.map +0 -1
  64. package/dist/http/execution-context.js +0 -61
  65. package/dist/http/execution-context.js.map +0 -1
  66. package/dist/http/handlers/control/batch-slice.d.ts +0 -4
  67. package/dist/http/handlers/control/batch-slice.d.ts.map +0 -1
  68. package/dist/http/handlers/control/batch-slice.js +0 -40
  69. package/dist/http/handlers/control/batch-slice.js.map +0 -1
  70. package/dist/http/handlers/control/batch.d.ts +0 -23
  71. package/dist/http/handlers/control/batch.d.ts.map +0 -1
  72. package/dist/http/handlers/control/batch.js +0 -332
  73. package/dist/http/handlers/control/batch.js.map +0 -1
  74. package/dist/http/handlers/tools/audit.d.ts +0 -4
  75. package/dist/http/handlers/tools/audit.d.ts.map +0 -1
  76. package/dist/http/handlers/tools/audit.js +0 -43
  77. package/dist/http/handlers/tools/audit.js.map +0 -1
  78. package/dist/http/handlers/tools/debug.d.ts +0 -4
  79. package/dist/http/handlers/tools/debug.d.ts.map +0 -1
  80. package/dist/http/handlers/tools/debug.js +0 -43
  81. package/dist/http/handlers/tools/debug.js.map +0 -1
  82. package/dist/http/handlers/tools/delegate.d.ts +0 -4
  83. package/dist/http/handlers/tools/delegate.d.ts.map +0 -1
  84. package/dist/http/handlers/tools/delegate.js +0 -43
  85. package/dist/http/handlers/tools/delegate.js.map +0 -1
  86. package/dist/http/handlers/tools/execute-plan.d.ts +0 -4
  87. package/dist/http/handlers/tools/execute-plan.d.ts.map +0 -1
  88. package/dist/http/handlers/tools/execute-plan.js +0 -45
  89. package/dist/http/handlers/tools/execute-plan.js.map +0 -1
  90. package/dist/http/handlers/tools/investigate.d.ts +0 -4
  91. package/dist/http/handlers/tools/investigate.d.ts.map +0 -1
  92. package/dist/http/handlers/tools/investigate.js +0 -64
  93. package/dist/http/handlers/tools/investigate.js.map +0 -1
  94. package/dist/http/handlers/tools/journal-recall.d.ts +0 -4
  95. package/dist/http/handlers/tools/journal-recall.d.ts.map +0 -1
  96. package/dist/http/handlers/tools/journal-recall.js +0 -40
  97. package/dist/http/handlers/tools/journal-recall.js.map +0 -1
  98. package/dist/http/handlers/tools/journal-record.d.ts +0 -12
  99. package/dist/http/handlers/tools/journal-record.d.ts.map +0 -1
  100. package/dist/http/handlers/tools/journal-record.js +0 -43
  101. package/dist/http/handlers/tools/journal-record.js.map +0 -1
  102. package/dist/http/handlers/tools/research.d.ts +0 -4
  103. package/dist/http/handlers/tools/research.d.ts.map +0 -1
  104. package/dist/http/handlers/tools/research.js +0 -64
  105. package/dist/http/handlers/tools/research.js.map +0 -1
  106. package/dist/http/handlers/tools/retry.d.ts +0 -4
  107. package/dist/http/handlers/tools/retry.d.ts.map +0 -1
  108. package/dist/http/handlers/tools/retry.js +0 -49
  109. package/dist/http/handlers/tools/retry.js.map +0 -1
  110. package/dist/http/handlers/tools/review.d.ts +0 -4
  111. package/dist/http/handlers/tools/review.d.ts.map +0 -1
  112. package/dist/http/handlers/tools/review.js +0 -43
  113. package/dist/http/handlers/tools/review.js.map +0 -1
  114. package/dist/http/request-observability.d.ts +0 -8
  115. package/dist/http/request-observability.d.ts.map +0 -1
  116. package/dist/http/request-observability.js +0 -20
  117. package/dist/http/request-observability.js.map +0 -1
@@ -0,0 +1,520 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { taskInputSchema, getTypeConfig, oppositeAgent, loadSkill, resolveAgent, runTwoPhasePipeline, } from '@zhixuan92/multi-model-agent-core';
3
+ import { BraveClient, runOrchestrator, parseQueryPlan, serializeEvidencePack, summarizeSourcesUsed, resolveEnabledAdapters, arxivSearch, semanticScholarSearch, githubSearch, } from '@zhixuan92/multi-model-agent-core/research';
4
+ import { sendJson, sendError } from '../errors.js';
5
+ import * as path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ /** Map unified TaskType (underscores) to wire Route (hyphens). */
8
+ function taskTypeToRoute(type) {
9
+ const map = {
10
+ execute_plan: 'execute-plan',
11
+ journal_recall: 'journal-recall',
12
+ journal_record: 'journal-record',
13
+ retry_tasks: 'retry',
14
+ main: 'orchestrate',
15
+ };
16
+ return (map[type] ?? type);
17
+ }
18
+ /**
19
+ * Build a goal condition string for the Stop hook. This keeps the agent
20
+ * working until it has covered all criteria defined in the skill file.
21
+ */
22
+ function buildGoalCondition(type, role, skillContent) {
23
+ if (role === 'reviewer') {
24
+ return [
25
+ 'You have verified every criterion the implementer was supposed to cover.',
26
+ 'You have checked for hallucinated findings (claims without evidence in the source material).',
27
+ 'You have validated evidence quality (every finding cites actual file:line or quoted text).',
28
+ 'You have checked severity calibration against the skill definitions.',
29
+ 'You have produced the required JSON output block with findings, summary, and verdict.',
30
+ ].join(' ');
31
+ }
32
+ switch (type) {
33
+ case 'audit': {
34
+ const countMatch = skillContent.match(/(\d+)\s+(?:Verification Criteria|perspectives|failure modes|Execution Steps)/i);
35
+ const count = countMatch ? countMatch[1] : 'all';
36
+ return [
37
+ `You have evaluated the document against ALL ${count} criteria one by one.`,
38
+ 'For each criterion, you wrote findings to the scratch file before moving to the next.',
39
+ 'Every criterion either has findings with quoted evidence, or an explicit "No findings for this criterion." entry.',
40
+ 'You have read the scratch file and consolidated into the final JSON output block.',
41
+ `The criteriaCovered array in your output lists all ${count} criteria.`,
42
+ ].join(' ');
43
+ }
44
+ case 'investigate':
45
+ return [
46
+ 'You have applied ALL 5 investigation perspectives: direct-symbol-trace, caller-analysis, test-driven, cross-file dependency-map, documentation/comment-lens.',
47
+ 'Every finding cites file:line from files you actually read (no training-data citations).',
48
+ 'Absent things are evidenced with "searched <pattern> in <path>, no matches."',
49
+ 'You have calibrated confidence (high/medium/low) based on evidence strength.',
50
+ 'You have produced the required JSON output block.',
51
+ ].join(' ');
52
+ case 'review':
53
+ return [
54
+ 'You have swept ALL 10 review categories: test gap, cross-file ripple, pre-existing-vs-regression, missing edge case, race/concurrency, resource leak, backward-compat break, security regression, performance regression, implicit-contract assumption.',
55
+ 'Cross-file findings cite both the change site AND the broken caller.',
56
+ 'Pre-existing bugs are separated from new regressions.',
57
+ 'You have produced the required JSON output block.',
58
+ ].join(' ');
59
+ case 'debug':
60
+ return [
61
+ 'You have applied ALL 4 investigation angles: symptom-location, recent-change, test-failure, reproduction.',
62
+ 'Your trace chain has at least 3 evidence points: symptom → intermediate state → cause, each with file:line.',
63
+ 'You have proposed a fix (read-only — describe, do not apply).',
64
+ 'You have stated a falsifier (how the maintainer verifies the fix).',
65
+ 'You have produced the required JSON output block.',
66
+ ].join(' ');
67
+ case 'research':
68
+ return [
69
+ 'You have searched from ALL 5 perspectives: primary-sources, practitioner-consensus, recent-developments, counter-perspectives, cross-domain.',
70
+ 'Every finding cites a real source with URL or identifier.',
71
+ 'Source tier (primary/practitioner/recent) is indicated.',
72
+ 'You have produced the required JSON output block with sources, findings, and synthesis.',
73
+ ].join(' ');
74
+ case 'delegate':
75
+ return [
76
+ 'You have implemented ALL requested changes in the task description.',
77
+ 'Only the declared filePaths were modified (no scope creep).',
78
+ 'If tests exist for the changed area, you have verified they pass.',
79
+ 'You have produced the required JSON output block listing tasks completed and files changed.',
80
+ ].join(' ');
81
+ case 'execute_plan':
82
+ return [
83
+ 'You have followed EVERY step in the plan exactly as written.',
84
+ 'Code blocks in the plan were applied verbatim (no substitution or improvisation).',
85
+ 'If the plan lists verification commands, you ran them.',
86
+ 'No steps were skipped or reordered.',
87
+ 'You have produced the required JSON output block.',
88
+ ].join(' ');
89
+ case 'journal_record':
90
+ return [
91
+ 'You have classified the learning (decision/constraint/pattern/mistake).',
92
+ 'You have checked the existing journal for supersede/refine/merge candidates.',
93
+ 'You have written the node file with proper YAML frontmatter and edges.',
94
+ 'You have updated the journal catalog (log.md and index.md).',
95
+ 'You have produced the required JSON output block.',
96
+ ].join(' ');
97
+ case 'journal_recall':
98
+ return [
99
+ 'You have searched from ALL 3 perspectives: keyword-match, graph-neighborhood, contradiction-and-history.',
100
+ 'Superseded nodes are excluded from results.',
101
+ 'Each result includes the learning, context, and relevance assessment.',
102
+ 'You have produced the required JSON output block.',
103
+ ].join(' ');
104
+ case 'main':
105
+ return [
106
+ 'You have fully processed the prompt and produced the requested output.',
107
+ 'If an output format was specified, your response conforms to that format.',
108
+ 'Your response is the deliverable — no meta-commentary wrapping it.',
109
+ ].join(' ');
110
+ default:
111
+ return 'You have completed the task as specified in the skill instructions and produced the required output.';
112
+ }
113
+ }
114
+ /**
115
+ * Build a minimal TaskEnvelope-compatible snapshot from a PipelineResult
116
+ * so the TelemetryUploader can convert it to a wire record and enqueue it.
117
+ */
118
+ function buildEnvelopeSnapshot(taskId, type, result, implTier, revTier, reviewPolicy, implModel, revModel, mainModel, cwd, durationMs, sourcesUsed = []) {
119
+ const now = new Date().toISOString();
120
+ const route = taskTypeToRoute(type);
121
+ // Build stage records from the pipeline turns.
122
+ const stages = [];
123
+ const implTurn = result.implementerTurn;
124
+ stages.push({
125
+ name: 'implementing',
126
+ round: 1,
127
+ outcome: result.status === 'failed' ? 'fail' : 'advance',
128
+ startedAt: now,
129
+ completedAt: now,
130
+ durationMs: implTurn.durationMs,
131
+ costUSD: implTurn.costUSD,
132
+ model: implModel,
133
+ tier: implTier,
134
+ turnsUsed: implTurn.turns,
135
+ filesWrittenCount: implTurn.filesWritten.length,
136
+ inputTokens: implTurn.usage.inputTokens,
137
+ outputTokens: implTurn.usage.outputTokens,
138
+ cachedReadTokens: implTurn.usage.cachedReadTokens,
139
+ cachedNonReadTokens: implTurn.usage.cachedNonReadTokens,
140
+ });
141
+ if (result.reviewerTurn) {
142
+ const revTurn = result.reviewerTurn;
143
+ stages.push({
144
+ name: 'reviewing',
145
+ round: 1,
146
+ outcome: result.status === 'done_with_concerns' ? 'concern' : 'advance',
147
+ startedAt: now,
148
+ completedAt: now,
149
+ durationMs: revTurn.durationMs,
150
+ costUSD: revTurn.costUSD,
151
+ model: revModel,
152
+ tier: revTier,
153
+ turnsUsed: revTurn.turns,
154
+ filesWrittenCount: 0,
155
+ inputTokens: revTurn.usage.inputTokens,
156
+ outputTokens: revTurn.usage.outputTokens,
157
+ cachedReadTokens: revTurn.usage.cachedReadTokens,
158
+ cachedNonReadTokens: revTurn.usage.cachedNonReadTokens,
159
+ verdict: result.status === 'done_with_concerns' ? 'concerns' : 'approved',
160
+ concernCategories: [],
161
+ });
162
+ }
163
+ const totalInputTokens = stages.reduce((s, st) => s + st.inputTokens, 0);
164
+ const totalOutputTokens = stages.reduce((s, st) => s + st.outputTokens, 0);
165
+ const totalCachedRead = stages.reduce((s, st) => s + (st.cachedReadTokens ?? 0), 0);
166
+ const totalCachedNonRead = stages.reduce((s, st) => s + (st.cachedNonReadTokens ?? 0), 0);
167
+ const totalCostUSD = stages.reduce((s, st) => s + (st.costUSD ?? 0), 0);
168
+ return {
169
+ taskId,
170
+ batchId: taskId,
171
+ taskIndex: 0,
172
+ route,
173
+ agentType: implTier,
174
+ client: 'claude-code',
175
+ mainModel,
176
+ cwd,
177
+ startedAt: now,
178
+ status: result.status,
179
+ terminalAt: now,
180
+ stopReason: null,
181
+ structuredError: result.status === 'failed'
182
+ ? { code: 'pipeline_failed', message: 'Pipeline completed with failed status' }
183
+ : null,
184
+ errorCode: null,
185
+ reviewPolicy: reviewPolicy === 'none' ? 'none' : 'reviewed',
186
+ plannedStageTotal: stages.length,
187
+ stages,
188
+ toolCalls: [],
189
+ filesWritten: implTurn.filesWritten,
190
+ realFilesChanged: implTurn.filesWritten,
191
+ commitSha: null,
192
+ commitMessage: null,
193
+ commitSkipReason: null,
194
+ contextBlockId: null,
195
+ totalCostUSD,
196
+ totalInputTokens,
197
+ totalOutputTokens,
198
+ totalCachedReadTokens: totalCachedRead,
199
+ totalCachedNonReadTokens: totalCachedNonRead,
200
+ totalDurationMs: durationMs,
201
+ turnsUsed: stages.reduce((s, st) => s + st.turnsUsed, 0),
202
+ stallCount: 0,
203
+ sandboxViolationCount: 0,
204
+ taskMaxIdleMs: 0,
205
+ findings: [],
206
+ sourcesUsed,
207
+ escalationLog: [],
208
+ validationWarnings: [],
209
+ headline: { prefix: '', stageLabel: 'done', stageIndex: stages.length, stageTotal: stages.length, toolWrites: 0, toolTotal: 0 },
210
+ };
211
+ }
212
+ const QUERY_PLAN_PROMPT = `You are a research query planner. Given a research question and background, emit ONLY a JSON query plan — no prose, no code fences.
213
+
214
+ The JSON must conform to this shape:
215
+ {
216
+ "braveQueries": ["<search query string>", ...],
217
+ "arxivQueries": ["<search query string>", ...],
218
+ "semanticScholarQueries": ["<search query string>", ...],
219
+ "githubQueries": [{"q": "<search query string>", "kind": "repo|code"}, ...]
220
+ }
221
+
222
+ Rules:
223
+ - Max 8 entries per array, max 200 chars per query string.
224
+ - Phrase queries as topical keywords, NOT full sentences.
225
+ - Empty arrays are allowed for sources you do not need.
226
+ - Emit ONLY the JSON object.`;
227
+ /**
228
+ * Turn 1 + orchestrator: ask the implementer LLM for a QueryPlan, then fan
229
+ * out across real adapters to gather an EvidencePack. Falls back gracefully:
230
+ * - If the LLM output isn't parseable as a QueryPlan, returns null (caller
231
+ * proceeds with LLM-only research).
232
+ * - If the orchestrator throws, returns null.
233
+ */
234
+ async function prepareResearchContext(researchQuestion, background, implProvider, researchCfg, taskId, cwd) {
235
+ // --- Turn 1: generate a query plan via the implementer LLM ---
236
+ const planSession = implProvider.openSession({
237
+ cwd,
238
+ wallClockDeadline: Date.now() + 60_000, // 60s budget for plan generation
239
+ abortSignal: new AbortController().signal,
240
+ taskId,
241
+ taskIndex: 0,
242
+ });
243
+ try {
244
+ const planPrompt = [
245
+ QUERY_PLAN_PROMPT,
246
+ '',
247
+ '## Research Question',
248
+ researchQuestion,
249
+ '',
250
+ '## Background',
251
+ background,
252
+ ].join('\n');
253
+ const planTurn = await planSession.send(planPrompt);
254
+ const planOutput = planTurn.output.trim();
255
+ // Extract JSON from the output — the LLM may wrap it in code fences
256
+ let jsonStr = planOutput;
257
+ const fenceMatch = planOutput.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
258
+ if (fenceMatch) {
259
+ jsonStr = fenceMatch[1].trim();
260
+ }
261
+ const queryPlan = parseQueryPlan(jsonStr);
262
+ // --- Orchestrator: fan out queries against real APIs ---
263
+ const enabledAdapters = resolveEnabledAdapters(researchCfg.builtinAdapters, {
264
+ semanticScholarApiKey: researchCfg.builtinAdapters.semanticScholarApiKey,
265
+ githubPat: researchCfg.builtinAdapters.githubPat,
266
+ });
267
+ // Build BraveClient only if API keys are configured
268
+ const hasBraveKeys = researchCfg.brave.apiKeys.length > 0;
269
+ const braveClient = hasBraveKeys ? new BraveClient(researchCfg.brave) : null;
270
+ const pack = await runOrchestrator(queryPlan, {
271
+ enabledAdapters,
272
+ brave: {
273
+ search: async (query) => {
274
+ if (!braveClient) {
275
+ throw new Error('brave_not_configured: no API keys');
276
+ }
277
+ return braveClient.search(query);
278
+ },
279
+ },
280
+ adapters: {
281
+ arxiv: (q) => arxivSearch(q),
282
+ semanticScholar: (q) => semanticScholarSearch(q, {
283
+ apiKey: researchCfg.builtinAdapters.semanticScholarApiKey,
284
+ }),
285
+ github: (q, kind) => githubSearch(q, {
286
+ kind,
287
+ pat: researchCfg.builtinAdapters.githubPat,
288
+ }),
289
+ },
290
+ perAdapterTimeoutMs: researchCfg.brave.timeoutMs,
291
+ totalDeadlineMs: 30_000,
292
+ concurrencyCap: 4,
293
+ });
294
+ const evidenceMarkdown = serializeEvidencePack(pack);
295
+ const sourcesUsed = summarizeSourcesUsed(pack);
296
+ process.stderr.write(`[mmagent] event=research_evidence_ready ts=${new Date().toISOString()} task=${taskId} sources=${pack.sources.length} failed=${pack.failedAttempts.length}\n`);
297
+ return { evidenceMarkdown, sourcesUsed };
298
+ }
299
+ catch (err) {
300
+ process.stderr.write(`[mmagent] event=research_preprocess_failed ts=${new Date().toISOString()} task=${taskId} error="${((err instanceof Error ? err.message : String(err))).replace(/"/g, '\\"')}"\n`);
301
+ return null;
302
+ }
303
+ finally {
304
+ try {
305
+ await planSession.close();
306
+ }
307
+ catch { /* best-effort */ }
308
+ }
309
+ }
310
+ // ─── Handler helpers ─────────────────────────────────────────────────────
311
+ const thisDir = path.dirname(fileURLToPath(import.meta.url));
312
+ // Navigate from packages/server/src/http/handlers/ -> packages/core/src/skills/
313
+ // 5x .. walks up to the monorepo root; then packages/core/src/skills/ reaches the skill .md files.
314
+ const SKILLS_DIR = path.resolve(thisDir, '..', '..', '..', '..', '..', 'packages', 'core', 'src', 'skills');
315
+ export function buildUnifiedTaskHandler(deps) {
316
+ return async (_req, res, _params, ctx) => {
317
+ const parsed = taskInputSchema.safeParse(ctx.body);
318
+ if (!parsed.success) {
319
+ sendError(res, 400, 'invalid_request', 'Validation failed', {
320
+ fieldErrors: parsed.error.flatten(),
321
+ });
322
+ return;
323
+ }
324
+ const input = parsed.data;
325
+ const cwd = ctx.cwd;
326
+ if (!cwd) {
327
+ sendError(res, 400, 'invalid_cwd', 'cwd query parameter required');
328
+ return;
329
+ }
330
+ const typeConfig = getTypeConfig(input.type);
331
+ const implTier = input.agentTier ?? typeConfig.defaultTier;
332
+ const revTier = oppositeAgent(implTier);
333
+ const reviewPolicy = input.type === 'main' ? 'none' : (input.reviewPolicy ?? 'reviewed');
334
+ let implAgent, revAgent;
335
+ try {
336
+ implAgent = resolveAgent(implTier, deps.config);
337
+ revAgent = resolveAgent(revTier, deps.config);
338
+ }
339
+ catch (err) {
340
+ sendError(res, 503, 'agent_not_configured', err instanceof Error ? err.message : 'Agent resolution failed');
341
+ return;
342
+ }
343
+ let skills;
344
+ try {
345
+ const subtype = input.subtype;
346
+ skills = await loadSkill(input.type, SKILLS_DIR, subtype);
347
+ }
348
+ catch (err) {
349
+ sendError(res, 500, 'skill_load_failed', err instanceof Error ? err.message : 'Skill load failed');
350
+ return;
351
+ }
352
+ const reserveResult = deps.projectRegistry.reserveProject(cwd);
353
+ if (!reserveResult.ok) {
354
+ sendError(res, 503, reserveResult.error, reserveResult.message);
355
+ return;
356
+ }
357
+ const pc = reserveResult.projectContext;
358
+ pc.lastActivityAt = Date.now();
359
+ deps.projectRegistry.cancelReservation(cwd);
360
+ const blockIds = input.contextBlockIds ?? [];
361
+ const contextBlockStore = pc.contextBlocks;
362
+ const { type, agentTier: _at, reviewPolicy: _rp, sessionIds: _si, contextBlockIds: _cbi, ...payload } = input;
363
+ // Register task in TaskRegistry and return 202 immediately
364
+ const taskId = randomUUID();
365
+ deps.taskRegistry.register(taskId, cwd, input.type);
366
+ // Emit task-created diagnostic for observability.
367
+ deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_created', fields: { batch_id: taskId, route: input.type } });
368
+ const statusUrl = `/task/${taskId}`;
369
+ sendJson(res, 202, { taskId, statusUrl });
370
+ // Run the pipeline asynchronously via setImmediate
371
+ const startedAtMs = Date.now();
372
+ setImmediate(() => {
373
+ void (async () => {
374
+ try {
375
+ process.stderr.write(`[mmagent] event=executor_started ts=${new Date().toISOString()} task=${taskId} route=${input.type}\n`);
376
+ const implementerGoal = buildGoalCondition(input.type, 'implementer', skills.implement);
377
+ const reviewerGoal = buildGoalCondition(input.type, 'reviewer', skills.review);
378
+ // ── Research pre-processing: Turn 1 (query plan) + orchestrator ──
379
+ let researchCtx = null;
380
+ let enrichedPayload = JSON.stringify(payload, null, 2);
381
+ if (input.type === 'research') {
382
+ const researchPayload = payload;
383
+ researchCtx = await prepareResearchContext(researchPayload.researchQuestion, researchPayload.background, implAgent.provider, deps.config.research, taskId, cwd);
384
+ if (researchCtx) {
385
+ // Inject the real evidence into the payload so the implementer
386
+ // synthesizes from actual sources, not training-data recall.
387
+ enrichedPayload = [
388
+ enrichedPayload,
389
+ '',
390
+ '---',
391
+ '',
392
+ '## Pre-fetched Evidence (from real API queries)',
393
+ '',
394
+ researchCtx.evidenceMarkdown,
395
+ ].join('\n');
396
+ }
397
+ }
398
+ const result = await runTwoPhasePipeline({
399
+ type: input.type,
400
+ implementerSkill: skills.implement,
401
+ reviewerSkill: skills.review,
402
+ taskPayload: enrichedPayload,
403
+ implementerProvider: implAgent.provider,
404
+ reviewerProvider: revAgent.provider,
405
+ implementerTier: implTier,
406
+ reviewerTier: revTier,
407
+ reviewPolicy,
408
+ cwd,
409
+ sandboxPolicy: typeConfig.sandbox,
410
+ worktreeEnabled: typeConfig.worktree,
411
+ taskId,
412
+ implementerGoal,
413
+ reviewerGoal,
414
+ });
415
+ const durationMs = Date.now() - startedAtMs;
416
+ // Auto-register a terminal context block for read-only routes
417
+ // (investigate, audit, review, debug, research, journal_recall)
418
+ // so callers can reference the output in subsequent dispatches.
419
+ let contextBlockId = null;
420
+ if (typeConfig.sandbox === 'read-only' && result.implementerOutput.trim().length > 0) {
421
+ try {
422
+ const block = contextBlockStore.register(result.implementerOutput);
423
+ contextBlockId = block.id;
424
+ }
425
+ catch { /* best-effort — store may be at capacity */ }
426
+ }
427
+ const resultObj = {
428
+ headline: `${input.type}: ${result.status}`,
429
+ results: [{
430
+ taskId,
431
+ type: input.type,
432
+ status: result.status,
433
+ report: {
434
+ implementer: result.implementerOutput,
435
+ reviewer: result.reviewerOutput,
436
+ reviewerParseError: result.reviewerParseError,
437
+ },
438
+ sessions: result.sessions,
439
+ worktree: result.worktree,
440
+ cost: result.cost,
441
+ contextBlockId,
442
+ error: null,
443
+ }],
444
+ taskTimings: { wallClockMs: durationMs, sumOfTaskMs: durationMs, estimatedParallelSavingsMs: 0 },
445
+ costSummary: {
446
+ totalActualCostUSD: result.cost.implementerUsd + (result.cost.reviewerUsd ?? 0),
447
+ totalCostDeltaVsMainUSD: 0,
448
+ },
449
+ structuredReport: {
450
+ summary: result.reviewerRaw ?? result.implementerOutput,
451
+ workerStatus: result.status,
452
+ filesChanged: result.implementerTurn.filesWritten,
453
+ },
454
+ sourcesUsed: researchCtx?.sourcesUsed ?? [],
455
+ error: result.status === 'failed'
456
+ ? { code: 'pipeline_failed', message: 'Pipeline completed with failed status' }
457
+ : { kind: 'not_applicable', reason: 'task succeeded' },
458
+ };
459
+ // Emit telemetry via the bus — TelemetryUploader picks up the
460
+ // sealed envelope snapshot and enqueues a wire record.
461
+ try {
462
+ const implModelId = deps.config.agents[implTier]?.model ?? 'unknown';
463
+ const revModelId = deps.config.agents[revTier]?.model ?? 'unknown';
464
+ const mainModelId = deps.config.defaults?.mainModel ?? implModelId;
465
+ const envelope = buildEnvelopeSnapshot(taskId, input.type, result, implTier, revTier, reviewPolicy, implModelId, revModelId, mainModelId, cwd, durationMs, researchCtx?.sourcesUsed ?? []);
466
+ deps.bus.emitEnvelopeSnapshot(envelope, 'seal');
467
+ }
468
+ catch (telErr) {
469
+ process.stderr.write(`[mmagent] event=telemetry_emit_error ts=${new Date().toISOString()} task=${taskId} err="${(telErr instanceof Error ? telErr.message : String(telErr)).replace(/"/g, '\\"')}"\n`);
470
+ }
471
+ if (result.status === 'failed') {
472
+ deps.taskRegistry.fail(taskId, resultObj);
473
+ deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_failed', fields: { task_id: taskId, tool: input.type, duration_ms: durationMs, error_code: 'pipeline_failed', error_message: 'Pipeline completed with failed status' } });
474
+ process.stderr.write(`[mmagent] event=task_failed ts=${new Date().toISOString()} task=${taskId} route=${input.type} duration_ms=${durationMs}\n`);
475
+ }
476
+ else {
477
+ deps.taskRegistry.complete(taskId, resultObj);
478
+ deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_completed', fields: { task_id: taskId, tool: input.type, duration_ms: durationMs } });
479
+ process.stderr.write(`[mmagent] event=task_completed ts=${new Date().toISOString()} task=${taskId} route=${input.type} duration_ms=${durationMs}\n`);
480
+ }
481
+ }
482
+ catch (err) {
483
+ const message = err instanceof Error ? err.message : String(err);
484
+ const stack = err instanceof Error ? err.stack : undefined;
485
+ const errObj = {
486
+ code: 'runner_crash',
487
+ message,
488
+ ...(stack !== undefined && { stack }),
489
+ };
490
+ deps.taskRegistry.fail(taskId, errObj);
491
+ const durationMs = Date.now() - startedAtMs;
492
+ deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_failed', fields: { task_id: taskId, tool: input.type, duration_ms: durationMs, error_code: errObj.code, error_message: errObj.message } });
493
+ process.stderr.write(`[mmagent] event=task_failed ts=${new Date().toISOString()} task=${taskId} route=${input.type} duration_ms=${durationMs} error="${message.replace(/"/g, '\\"')}"\n`);
494
+ }
495
+ })();
496
+ });
497
+ };
498
+ }
499
+ export function buildTaskPollHandler(deps) {
500
+ return async (_req, res, params, _ctx) => {
501
+ const taskId = params.taskId;
502
+ if (!taskId) {
503
+ sendError(res, 400, 'missing_task_id', 'taskId required');
504
+ return;
505
+ }
506
+ const entry = deps.taskRegistry.get(taskId);
507
+ if (!entry) {
508
+ sendError(res, 404, 'not_found', `Task ${taskId} not found`);
509
+ return;
510
+ }
511
+ if (deps.taskRegistry.isTerminal(taskId)) {
512
+ sendJson(res, 200, entry.result ?? { taskId, status: entry.state, error: null });
513
+ }
514
+ else {
515
+ res.writeHead(202, { 'content-type': 'text/plain; charset=utf-8' });
516
+ res.end(entry.runningHeadline || 'Running...');
517
+ }
518
+ };
519
+ }
520
+ //# sourceMappingURL=unified-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unified-task.js","sourceRoot":"","sources":["../../../src/http/handlers/unified-task.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { type ProjectContext, BatchRegistry } from '@zhixuan92/multi-model-agent-core';
1
+ import { type ProjectContext } from '@zhixuan92/multi-model-agent-core';
2
+ import type { TaskRegistry } from '@zhixuan92/multi-model-agent-core';
2
3
  export type ReserveError = 'project_cap' | 'invalid_cwd' | 'missing_cwd' | 'cwd_not_dir' | 'forbidden_cwd';
3
4
  export type ReserveResult = {
4
5
  ok: true;
@@ -44,11 +45,11 @@ export declare class ProjectRegistry {
44
45
  entries(): IterableIterator<[string, ProjectContext]>;
45
46
  /**
46
47
  * Returns true if the project context is idle and eligible for eviction.
47
- * Gates on: no active HTTP requests, no active batches in the registry,
48
+ * Gates on: no active HTTP requests, no active tasks in the registry,
48
49
  * no active sessions, no pending reservations, and idle for at least idleTimeoutMs.
49
50
  */
50
- isIdleFor(pc: ProjectContext, now: number, idleTimeoutMs: number, batchRegistry: BatchRegistry): boolean;
51
- evictIdle(batchRegistry?: BatchRegistry): void;
51
+ isIdleFor(pc: ProjectContext, now: number, idleTimeoutMs: number, taskRegistry: TaskRegistry): boolean;
52
+ evictIdle(taskRegistry?: TaskRegistry): void;
52
53
  clear(): void;
53
54
  }
54
55
  //# sourceMappingURL=project-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../src/http/project-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7G,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CAAC;AAE3G,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqC;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwB;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwC;gBAE9D,OAAO,EAAE,sBAAsB;IAQ3C,kBAAkB,IAAI,IAAI;IAM1B,iBAAiB,IAAI,IAAI;IAKzB,oGAAoG;IACpG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IAoB1C;;;OAGG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ5D,0FAA0F;IAC1F,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAO5D,2FAA2F;IAC3F,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAO7C,8CAA8C;IAC9C,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIrD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAItD;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,GAAG,OAAO;IAUxG,SAAS,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI;IAuB9C,KAAK,IAAI,IAAI;CAOd"}
1
+ {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../src/http/project-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAGtE,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CAAC;AAE3G,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqC;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwB;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwC;gBAE9D,OAAO,EAAE,sBAAsB;IAQ3C,kBAAkB,IAAI,IAAI;IAM1B,iBAAiB,IAAI,IAAI;IAKzB,oGAAoG;IACpG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IAoB1C;;;OAGG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ5D,0FAA0F;IAC1F,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAO5D,2FAA2F;IAC3F,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAO7C,8CAA8C;IAC9C,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIrD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAItD;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO;IAUtG,SAAS,CAAC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI;IAsB5C,KAAK,IAAI,IAAI;CAMd"}
@@ -89,24 +89,24 @@ export class ProjectRegistry {
89
89
  }
90
90
  /**
91
91
  * Returns true if the project context is idle and eligible for eviction.
92
- * Gates on: no active HTTP requests, no active batches in the registry,
92
+ * Gates on: no active HTTP requests, no active tasks in the registry,
93
93
  * no active sessions, no pending reservations, and idle for at least idleTimeoutMs.
94
94
  */
95
- isIdleFor(pc, now, idleTimeoutMs, batchRegistry) {
95
+ isIdleFor(pc, now, idleTimeoutMs, taskRegistry) {
96
96
  return (pc.activeRequests === 0 &&
97
- batchRegistry.countActiveForProject(pc.cwd) === 0 &&
97
+ taskRegistry.countActive(pc.cwd) === 0 &&
98
98
  pc.activeSessions.size === 0 &&
99
99
  pc.pendingReservations === 0 &&
100
100
  (now - pc.lastActivityAt) > idleTimeoutMs);
101
101
  }
102
- evictIdle(batchRegistry) {
102
+ evictIdle(taskRegistry) {
103
103
  const now = Date.now();
104
104
  const victims = [];
105
105
  for (const [cwd, pc] of this.map.entries()) {
106
106
  if (pc.activeSessions.size === 0 &&
107
107
  pc.activeRequests === 0 &&
108
108
  pc.pendingReservations === 0 &&
109
- (batchRegistry === undefined || batchRegistry.countActiveForProject(cwd) === 0) &&
109
+ (taskRegistry === undefined || taskRegistry.countActive(cwd) === 0) &&
110
110
  now - pc.lastActivityAt > this.idleEvictionMs) {
111
111
  victims.push(cwd);
112
112
  }
@@ -114,7 +114,6 @@ export class ProjectRegistry {
114
114
  for (const cwd of victims) {
115
115
  const pc = this.map.get(cwd);
116
116
  pc.contextBlocks.clear();
117
- pc.batchCache.clear();
118
117
  this.map.delete(cwd);
119
118
  this.onProjectEvicted?.(cwd, now - pc.lastActivityAt);
120
119
  }
@@ -122,7 +121,6 @@ export class ProjectRegistry {
122
121
  clear() {
123
122
  for (const pc of this.map.values()) {
124
123
  pc.contextBlocks.clear();
125
- pc.batchCache.clear();
126
124
  }
127
125
  this.map.clear();
128
126
  }