@zhixuan92/multi-model-agent-mcp 0.4.0 → 1.1.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 (34) hide show
  1. package/README.md +18 -220
  2. package/dist/cli.d.ts +20 -22
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +183 -154
  5. package/dist/cli.js.map +1 -1
  6. package/dist/routing/render-provider-routing-matrix.d.ts +1 -1
  7. package/dist/routing/render-provider-routing-matrix.d.ts.map +1 -1
  8. package/dist/routing/render-provider-routing-matrix.js +38 -67
  9. package/dist/routing/render-provider-routing-matrix.js.map +1 -1
  10. package/dist/tools/audit-document.d.ts +37 -0
  11. package/dist/tools/audit-document.d.ts.map +1 -0
  12. package/dist/tools/audit-document.js +76 -0
  13. package/dist/tools/audit-document.js.map +1 -0
  14. package/dist/tools/batch-response.d.ts +21 -0
  15. package/dist/tools/batch-response.d.ts.map +1 -0
  16. package/dist/tools/batch-response.js +78 -0
  17. package/dist/tools/batch-response.js.map +1 -0
  18. package/dist/tools/debug-task.d.ts +23 -0
  19. package/dist/tools/debug-task.d.ts.map +1 -0
  20. package/dist/tools/debug-task.js +38 -0
  21. package/dist/tools/debug-task.js.map +1 -0
  22. package/dist/tools/review-code.d.ts +31 -0
  23. package/dist/tools/review-code.d.ts.map +1 -0
  24. package/dist/tools/review-code.js +65 -0
  25. package/dist/tools/review-code.js.map +1 -0
  26. package/dist/tools/shared.d.ts +31 -0
  27. package/dist/tools/shared.d.ts.map +1 -0
  28. package/dist/tools/shared.js +72 -0
  29. package/dist/tools/shared.js.map +1 -0
  30. package/dist/tools/verify-work.d.ts +22 -0
  31. package/dist/tools/verify-work.d.ts.map +1 -0
  32. package/dist/tools/verify-work.js +57 -0
  33. package/dist/tools/verify-work.js.map +1 -0
  34. package/package.json +19 -3
@@ -1,26 +1,19 @@
1
- import { getBaseCapabilities } from '@zhixuan92/multi-model-agent-core/routing/capabilities';
2
- import { findModelProfile, getEffectiveCostTier } from '@zhixuan92/multi-model-agent-core/routing/model-profiles';
1
+ import { findModelCapabilities, findModelProfile } from '@zhixuan92/multi-model-agent-core/routing/model-profiles';
3
2
  const ROUTING_RECIPE = `How to route a task:
4
- 1. Capability filter (HARD): exclude providers missing any required capability.
5
- 2. Quality filter: exclude providers whose tier is below the task's tier.
6
- Tier ordering: trivial < standard < reasoning.
7
- 3. Cost preference (STRONG): among the remainder, prefer the cheapest tier.
8
- If a 'free' provider qualifies, pick it. Only escalate to paid tiers when
9
- the task tier or required capabilities demand it.
3
+ 1. Select the agent type based on required capabilities.
4
+ 2. If the selected agent lacks required capabilities, auto-escalate to the other agent type.
5
+ 3. Among available agents, prefer the one that meets capability requirements.
10
6
 
11
- Tier guidance for the consumer LLM:
12
- - 'trivial' — well-defined edits, lookups, formatting. One obvious answer.
7
+ Agent guidance:
13
8
  - 'standard' — most code work. Clear spec, multiple valid approaches.
14
- - 'reasoning' — ambiguous, architectural, research, or high-stakes.
15
- Use when requirements are unclear or judgment is required.
9
+ - 'complex' — ambiguous, architectural, research, or high-stakes tasks requiring more reasoning.
16
10
 
17
11
  Optional 'effort' knob (per task):
18
- - Only providers marked 'effort: supported' in the matrix honor this field.
19
- - Use 'high' for reasoning-tier tasks when you want maximum depth,
12
+ - Only agents marked 'effort: supported' in the matrix honor this field.
13
+ - Use 'high' for complex tasks when you want maximum depth,
20
14
  'medium' for balanced, 'low' for fast-but-shallow, 'none' to disable
21
- thinking entirely on providers that default it on. Omit the field on
22
- providers that do not support it.`;
23
- const TOOL_NOTES = `Sub-agent tool notes (apply to every provider):
15
+ thinking entirely on agents that default it on.`;
16
+ const TOOL_NOTES = `Sub-agent tool notes (apply to every agent):
24
17
  - 'grep' accepts a file OR a directory. When given a directory it searches
25
18
  recursively (output is prefixed file:line). Prefer one recursive grep over
26
19
  many readFile calls when the worker needs to find usages or patterns.
@@ -28,19 +21,18 @@ const TOOL_NOTES = `Sub-agent tool notes (apply to every provider):
28
21
  otherwise salvaged from a running scratchpad. You ALWAYS get text back,
29
22
  even on 'incomplete' / 'timeout' / 'api_error' / 'network_error' paths.
30
23
  - Tasks that need shell ('pnpm', 'pytest', 'tsc', 'git') only work on
31
- providers configured with sandboxPolicy: 'none'. Otherwise keep shell
24
+ agents configured with sandboxPolicy: 'none'. Otherwise keep shell
32
25
  work on the parent session, not in a delegated sub-agent.
33
26
 
34
27
  Escalation, statuses, streaming, and batch helpers:
35
- - Auto-routed tasks (no 'provider' set) walk the full capability+tier
36
- chain cheapest-first on failure. The chain stops at the first 'ok'.
37
- If every provider fails, the best salvage is returned and the
38
- per-task 'escalationLog' shows every attempt. Explicit pins
39
- ('provider' set) run as a single attempt — pinning opts out.
28
+ - Auto-routed tasks (no 'agentType' set) use 'standard' agent.
29
+ - If the selected agent lacks required capabilities, auto-escalate to 'complex'.
30
+ - If every agent fails, the best salvage is returned and the
31
+ per-task 'escalationLog' shows every attempt.
40
32
  - Status values: 'ok', 'incomplete', 'max_turns', 'timeout',
41
33
  'api_aborted', 'api_error', 'network_error', 'error'.
42
34
  'incomplete' = scratchpad salvage after a degenerate completion;
43
- 'api_aborted' = provider-side abort; 'api_error' = HTTP error with
35
+ 'api_aborted' = agent-side abort; 'api_error' = HTTP error with
44
36
  a numeric .status; 'network_error' = transport failure
45
37
  (ECONNREFUSED / ENOTFOUND / /network/i).
46
38
  - Streaming: if your MCP client passes '_meta.progressToken' on the
@@ -59,22 +51,21 @@ Escalation, statuses, streaming, and batch helpers:
59
51
  shared across multiple tasks are sent to the parent session only
60
52
  once.
61
53
 
62
- RESPONSE SHAPE (v0.3+): Every delegate_tasks response includes a top-level
54
+ RESPONSE SHAPE (v1.0+): Every delegate_tasks response includes a top-level
63
55
  batchId, mode ('full' or 'summary'), timings ({wallClockMs, sumOfTaskMs,
64
56
  estimatedParallelSavingsMs}), batchProgress ({totalTasks, completedTasks,
65
57
  incompleteTasks, failedTasks, successPercent}), and aggregateCost
66
- ({totalActualCostUSD, totalSavedCostUSD, actualCostUnavailableTasks,
67
- savedCostUnavailableTasks}). If the combined output across tasks is small,
58
+ ({totalActualCostUSD, totalSavedCostUSD}). If the combined output across tasks is small,
68
59
  mode: 'full' with inline outputs; if it exceeds the server's threshold
69
60
  (default 64 KB, configurable via env MULTI_MODEL_LARGE_RESPONSE_THRESHOLD_CHARS
70
61
  / config defaults.largeResponseThresholdChars / buildMcpServer option),
71
- mode: 'summary' with per-task outputLength + outputSha256 + _fetchOutputWith
72
- hint — fetch individual outputs with get_task_output({ batchId, taskIndex }),
73
- or per-task metadata with get_task_detail({ batchId, taskIndex }).
62
+ mode: 'summary' with per-task outputLength + outputSha256 + _fetchWith
63
+ hint — fetch individual outputs with get_batch_slice({ batchId, slice: 'output', taskIndex }),
64
+ or per-task details with get_batch_slice({ batchId, slice: 'detail', taskIndex }).
74
65
  Set responseMode: 'full' to force inline, 'summary' to force summary, or
75
66
  omit for auto-escape.
76
67
 
77
- COVERAGE DECLARATION (v0.3+): For tasks with enumerable deliverables
68
+ COVERAGE DECLARATION (v1.0+): For tasks with enumerable deliverables
78
69
  (multi-file refactors, test generation across many functions, multi-PR
79
70
  review, per-endpoint reports, per-function test stubs, audit checklists),
80
71
  set expectedCoverage on the task spec with either minSections: N,
@@ -86,7 +77,7 @@ Do NOT set expectedCoverage for one-shot tasks (bug fixes, single
86
77
  implementations, prose, creative writing) — the field is opt-in and has
87
78
  no meaning for deliverables you can't enumerate ahead of time.
88
79
 
89
- COST + TIME VISIBILITY (v0.3+): Set parentModel on the task spec (e.g.
80
+ COST + TIME VISIBILITY (v1.0+): Set parentModel on the task spec (e.g.
90
81
  'claude-opus-4-6') to get usage.savedCostUSD — the ESTIMATED cost
91
82
  difference vs running the same token volume on that parent model.
92
83
  Positive means delegation was cheaper. Both usage.costUSD (actual) and
@@ -98,39 +89,17 @@ serial for-loop. batchProgress.successPercent is a clean-success rate
98
89
  (the batch is always 100% done by the time you see the response —
99
90
  successPercent measures how many finished cleanly, NOT progress).
100
91
 
101
- PROGRESS TRACE (v0.3+): Set includeProgressTrace: true on the task spec
102
- to receive a bounded, priority-trimmed trace of the execution timeline
103
- in the final RunResult.progressTrace. Useful for post-hoc debugging of
104
- long-running tasks — did the worker loop through supervision retries,
105
- where did it stall, did it escalate across providers. The trace is
106
- trimmed at 80 events and 16 KB; text_emission and tool_call events are
107
- dropped first under pressure (their content is already in output /
108
- toolCalls). Boundary events (turn_start, turn_complete, escalation_start,
109
- injection, done) are never dropped. If trimming fired, a synthetic
110
- _trimmed marker at the end of the trace reports the dropped count and
111
- per-kind histogram.
112
-
113
- NOTE: progress-events at the MCP protocol level (notifications/progress)
114
- are emitted correctly by the server and delivered to the MCP client.
115
- Whether your client renders them live depends on the client — some
116
- render them as in-flight tool-call status lines, others don't surface
117
- them to the calling LLM at all. includeProgressTrace gives you the
118
- full timeline post-hoc regardless of your client's live-rendering
119
- behavior.
120
-
121
92
  AVAILABLE TOOLS: delegate_tasks (this one), register_context_block
122
93
  (stash reusable brief content referenced via TaskSpec.contextBlockIds),
123
94
  retry_tasks (re-dispatch specific indices from a previous batch),
124
- get_task_output (fetch individual task outputs when a response was in
125
- summary mode).`;
126
- function renderProviderBlock(name, config, capabilities, profile, costSource) {
127
- const cost = getEffectiveCostTier(config);
128
- const costSuffix = costSource === 'config' ? ' (from config)' : '';
95
+ get_batch_slice (fetch outputs/details/telemetry when a response was in
96
+ summary mode or for per-task introspection).`;
97
+ function renderAgentBlock(name, config, capabilities, profile) {
129
98
  const effortLabel = profile.supportsEffort ? 'supported' : 'not supported';
130
99
  const lines = [
131
100
  `${name} (${config.model})`,
132
- ` tools: ${capabilities.join(', ')}`,
133
- ` tier: ${profile.tier} | cost: ${cost}${costSuffix} | effort: ${effortLabel}`,
101
+ ` capabilities: ${capabilities.join(', ') || '(none)'}`,
102
+ ` cost: ${profile.defaultCost} | effort: ${effortLabel}`,
134
103
  ` best for: ${profile.bestFor}`,
135
104
  ];
136
105
  if (profile.notes) {
@@ -143,20 +112,22 @@ function renderProviderBlock(name, config, capabilities, profile, costSource) {
143
112
  }
144
113
  /**
145
114
  * Renders the full routing matrix for the MCP tool description.
146
- * Helps the consuming LLM understand provider capabilities and routing rules.
115
+ * Helps the consuming LLM understand agent capabilities and routing rules.
147
116
  */
148
117
  export function renderProviderRoutingMatrix(config) {
149
- const blocks = Object.entries(config.providers).map(([name, providerConfig]) => {
150
- const capabilities = getBaseCapabilities(providerConfig);
151
- const profile = findModelProfile(providerConfig.model);
152
- const costSource = providerConfig.costTier ? 'config' : 'default';
153
- return renderProviderBlock(name, providerConfig, capabilities, profile, costSource);
118
+ if (!config.agents) {
119
+ return 'No agents configured.';
120
+ }
121
+ const blocks = Object.entries(config.agents).map(([name, agentConfig]) => {
122
+ const capabilities = agentConfig.capabilities ?? findModelCapabilities(agentConfig.model);
123
+ const profile = findModelProfile(agentConfig.model);
124
+ return renderAgentBlock(name, agentConfig, capabilities, profile);
154
125
  });
155
126
  return [
156
- 'Delegate tasks to sub-agents running on different LLM providers.',
127
+ 'Delegate tasks to sub-agents running on different LLM models.',
157
128
  'All tasks execute concurrently.',
158
129
  '',
159
- 'Available providers:',
130
+ 'Available agents:',
160
131
  '',
161
132
  blocks.join('\n\n'),
162
133
  '',
@@ -1 +1 @@
1
- {"version":3,"file":"render-provider-routing-matrix.js","sourceRoot":"","sources":["../../src/routing/render-provider-routing-matrix.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,0DAA0D,CAAC;AAGlH,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;oCAmBa,CAAC;AAErC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAsGJ,CAAC;AAEhB,SAAS,mBAAmB,CAC1B,IAAY,EACZ,MAAsB,EACtB,YAA0B,EAC1B,OAAqB,EACrB,UAAgC;IAEhC,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC;IAC3E,MAAM,KAAK,GAAG;QACZ,GAAG,IAAI,KAAK,MAAM,CAAC,KAAK,GAAG;QAC3B,YAAY,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACrC,WAAW,OAAO,CAAC,IAAI,YAAY,IAAI,GAAG,UAAU,cAAc,WAAW,EAAE;QAC/E,eAAe,OAAO,CAAC,OAAO,EAAE;KACjC,CAAC;IACF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAwB;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,EAAE;QAC7E,MAAM,YAAY,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,UAAU,GAAyB,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACxF,OAAO,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,kEAAkE;QAClE,iCAAiC;QACjC,EAAE;QACF,sBAAsB;QACtB,EAAE;QACF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACnB,EAAE;QACF,cAAc;QACd,EAAE;QACF,UAAU;KACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"render-provider-routing-matrix.js","sourceRoot":"","sources":["../../src/routing/render-provider-routing-matrix.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,0DAA0D,CAAC;AAGnH,MAAM,cAAc,GAAG;;;;;;;;;;;;;kDAa2B,CAAC;AAEnD,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAgF0B,CAAC;AAE9C,SAAS,gBAAgB,CACvB,IAAY,EACZ,MAAmB,EACnB,YAA4C,EAC5C,OAAqB;IAErB,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC;IAC3E,MAAM,KAAK,GAAG;QACZ,GAAG,IAAI,KAAK,MAAM,CAAC,KAAK,GAAG;QAC3B,mBAAmB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE;QACxD,WAAW,OAAO,CAAC,WAAW,cAAc,WAAW,EAAE;QACzD,eAAe,OAAO,CAAC,OAAO,EAAE;KACjC,CAAC;IACF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAwB;IAClE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE;QACvE,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,IAAI,qBAAqB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC1F,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,+DAA+D;QAC/D,iCAAiC;QACjC,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACnB,EAAE;QACF,cAAc;QACd,EAAE;QACF,UAAU;KACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { z } from 'zod';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import type { MultiModelConfig } from '@zhixuan92/multi-model-agent-core';
4
+ export declare const auditDocumentSchema: z.ZodObject<{
5
+ filePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
+ cwd: z.ZodOptional<z.ZodString>;
7
+ contextBlockIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
8
+ tools: z.ZodOptional<z.ZodEnum<{
9
+ readonly: "readonly";
10
+ none: "none";
11
+ full: "full";
12
+ }>>;
13
+ document: z.ZodOptional<z.ZodString>;
14
+ auditType: z.ZodUnion<readonly [z.ZodEnum<{
15
+ security: "security";
16
+ performance: "performance";
17
+ correctness: "correctness";
18
+ style: "style";
19
+ general: "general";
20
+ }>, z.ZodArray<z.ZodEnum<{
21
+ security: "security";
22
+ performance: "performance";
23
+ correctness: "correctness";
24
+ style: "style";
25
+ }>>]>;
26
+ outputFormat: z.ZodOptional<z.ZodEnum<{
27
+ json: "json";
28
+ markdown: "markdown";
29
+ }>>;
30
+ agentType: z.ZodOptional<z.ZodEnum<{
31
+ standard: "standard";
32
+ complex: "complex";
33
+ }>>;
34
+ }, z.core.$strip>;
35
+ export type AuditDocumentParams = z.infer<typeof auditDocumentSchema>;
36
+ export declare function registerAuditDocument(server: McpServer, config: MultiModelConfig): void;
37
+ //# sourceMappingURL=audit-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-document.d.ts","sourceRoot":"","sources":["../../src/tools/audit-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAY,MAAM,mCAAmC,CAAC;AAapF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAU9B,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAyBtE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,QAmDhF"}
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ import { runTasks } from '@zhixuan92/multi-model-agent-core/run-tasks';
3
+ import { commonToolFields, validateInput, resolveDispatchMode, buildMetadataBlock, buildFilePathsPrompt, buildPerFilePrompt, applyCommonFields, } from './shared.js';
4
+ import { buildFanOutResponse } from './batch-response.js';
5
+ export const auditDocumentSchema = z.object({
6
+ document: z.string().optional().describe('Inline document content to audit'),
7
+ auditType: z.union([
8
+ z.enum(['security', 'performance', 'correctness', 'style', 'general']),
9
+ z.array(z.enum(['security', 'performance', 'correctness', 'style'])).min(1),
10
+ ]).describe('Audit focus. Single string or array of types. "general" = all four categories.'),
11
+ outputFormat: z.enum(['json', 'markdown']).optional()
12
+ .describe('Output format. json returns structured findings array.'),
13
+ agentType: z.enum(['standard', 'complex']).optional(),
14
+ ...commonToolFields,
15
+ });
16
+ function resolveAuditTypeText(auditType) {
17
+ if (auditType === 'general')
18
+ return 'security, performance, correctness, and style';
19
+ if (Array.isArray(auditType))
20
+ return auditType.join(', ');
21
+ return auditType;
22
+ }
23
+ function buildAuditPrompt(auditTypeText, document, filePaths, outputFormat) {
24
+ const parts = [`Audit for ${auditTypeText} issues.`];
25
+ if (outputFormat === 'json') {
26
+ parts.push('Return findings as a JSON array of objects with keys: severity, category, finding, recommendation.');
27
+ }
28
+ if (document)
29
+ parts.push(`Document:\n\n${document}`);
30
+ const fileSection = buildFilePathsPrompt(filePaths);
31
+ if (fileSection)
32
+ parts.push(fileSection);
33
+ parts.push('Provide a structured audit report with findings and severity.');
34
+ return parts.join('\n\n');
35
+ }
36
+ export function registerAuditDocument(server, config) {
37
+ server.tool('audit_document', 'Audit documents or files for issues. Accepts inline content or file paths \u2014 multiple files are audited in parallel, each as a separate task. Preset: complex agent, no review pipeline. Use this for any audit task. Use delegate_tasks only for custom pipeline config or tasks that don\'t match a specialized tool.', auditDocumentSchema.shape, async (params) => {
38
+ const validation = validateInput(params.document, params.filePaths);
39
+ if (!validation.valid) {
40
+ return { content: [{ type: 'text', text: `Error: ${validation.message}` }], isError: true };
41
+ }
42
+ const agentType = params.agentType ?? 'complex';
43
+ const auditTypeText = resolveAuditTypeText(params.auditType);
44
+ const baseTaskSpec = applyCommonFields({
45
+ agentType,
46
+ reviewPolicy: 'off',
47
+ ...(params.outputFormat && { formatConstraints: { outputFormat: params.outputFormat } }),
48
+ }, params);
49
+ try {
50
+ const mode = resolveDispatchMode(params.document, params.filePaths);
51
+ if (mode === 'fan_out') {
52
+ const validPaths = params.filePaths.filter(p => p.trim().length > 0);
53
+ const promptTemplate = buildAuditPrompt(auditTypeText, undefined, undefined, params.outputFormat);
54
+ const tasks = validPaths.map(fp => ({
55
+ ...baseTaskSpec,
56
+ prompt: buildPerFilePrompt(fp, promptTemplate),
57
+ }));
58
+ const startMs = Date.now();
59
+ const results = await runTasks(tasks, config);
60
+ return { content: [buildFanOutResponse(results, tasks, Date.now() - startMs)] };
61
+ }
62
+ // Single-task mode
63
+ const prompt = buildAuditPrompt(auditTypeText, params.document, params.filePaths, params.outputFormat);
64
+ const results = await runTasks([{ ...baseTaskSpec, prompt }], config);
65
+ const result = results[0];
66
+ return { content: [{ type: 'text', text: result.output }, buildMetadataBlock(result)] };
67
+ }
68
+ catch (err) {
69
+ return {
70
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
71
+ isError: true,
72
+ };
73
+ }
74
+ });
75
+ }
76
+ //# sourceMappingURL=audit-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-document.js","sourceRoot":"","sources":["../../src/tools/audit-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AACvE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC5E,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;KAC5E,CAAC,CAAC,QAAQ,CAAC,gFAAgF,CAAC;IAC7F,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;SAClD,QAAQ,CAAC,wDAAwD,CAAC;IACrE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrD,GAAG,gBAAgB;CACpB,CAAC,CAAC;AAIH,SAAS,oBAAoB,CAAC,SAA2C;IACvE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,+CAA+C,CAAC;IACpF,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,aAAqB,EACrB,QAA4B,EAC5B,SAA+B,EAC/B,YAAgC;IAEhC,MAAM,KAAK,GAAa,CAAC,aAAa,aAAa,UAAU,CAAC,CAAC;IAC/D,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,oGAAoG,CAAC,CAAC;IACnH,CAAC;IACD,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAC5E,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAwB;IAC/E,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,6TAA6T,EAC7T,mBAAmB,CAAC,KAAK,EACzB,KAAK,EAAE,MAA2B,EAAE,EAAE;QACpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvG,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;QAChD,MAAM,aAAa,GAAG,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAsB,iBAAiB,CACvD;YACE,SAAS;YACT,YAAY,EAAE,KAAc;YAC5B,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,iBAAiB,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;SACzF,EACD,MAAM,CACP,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YAEpE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,UAAU,GAAG,MAAM,CAAC,SAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACtE,MAAM,cAAc,GAAG,gBAAgB,CAAC,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;gBAClG,MAAM,KAAK,GAAe,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBAC9C,GAAG,YAAY;oBACf,MAAM,EAAE,kBAAkB,CAAC,EAAE,EAAE,cAAc,CAAC;iBAClC,CAAA,CAAC,CAAC;gBAEhB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;YAClF,CAAC;YAED,mBAAmB;YACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;YACvG,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAc,CAAC,EAAE,MAAM,CAAC,CAAC;YAClF,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACxG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { RunResult, TaskSpec, BatchTimings, BatchProgress, BatchAggregateCost } from '@zhixuan92/multi-model-agent-core';
2
+ /**
3
+ * Compute per-batch timing metrics.
4
+ */
5
+ export declare function computeTimings(wallClockMs: number, results: RunResult[]): BatchTimings;
6
+ /**
7
+ * Compute per-batch progress summary.
8
+ */
9
+ export declare function computeBatchProgress(results: RunResult[]): BatchProgress;
10
+ /**
11
+ * Compute aggregate cost across all tasks.
12
+ */
13
+ export declare function computeAggregateCost(results: RunResult[]): BatchAggregateCost;
14
+ /**
15
+ * Build a fan-out response for specialized tools. No batchId (not cache-backed).
16
+ */
17
+ export declare function buildFanOutResponse(results: RunResult[], tasks: TaskSpec[], wallClockMs: number): {
18
+ type: 'text';
19
+ text: string;
20
+ };
21
+ //# sourceMappingURL=batch-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-response.d.ts","sourceRoot":"","sources":["../../src/tools/batch-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,kBAAkB,EACnB,MAAM,mCAAmC,CAAC;AAE3C;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,YAAY,CAItF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,aAAa,CAgBxE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAiB7E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,EAAE,EACpB,KAAK,EAAE,QAAQ,EAAE,EACjB,WAAW,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiChC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Compute per-batch timing metrics.
3
+ */
4
+ export function computeTimings(wallClockMs, results) {
5
+ const sumOfTaskMs = results.reduce((sum, r) => sum + (r.durationMs ?? 0), 0);
6
+ const estimatedParallelSavingsMs = Math.max(0, sumOfTaskMs - wallClockMs);
7
+ return { wallClockMs, sumOfTaskMs, estimatedParallelSavingsMs };
8
+ }
9
+ /**
10
+ * Compute per-batch progress summary.
11
+ */
12
+ export function computeBatchProgress(results) {
13
+ const totalTasks = results.length;
14
+ const completedTasks = results.filter((r) => r.status === 'ok').length;
15
+ const incompleteTasks = results.filter((r) => r.status === 'incomplete' || r.status === 'max_turns' || r.status === 'timeout').length;
16
+ const failedTasks = results.filter((r) => r.status === 'error' ||
17
+ r.status === 'api_aborted' ||
18
+ r.status === 'api_error' ||
19
+ r.status === 'network_error').length;
20
+ const successPercent = totalTasks === 0 ? 0 : Math.round((completedTasks / totalTasks) * 1000) / 10;
21
+ return { totalTasks, completedTasks, incompleteTasks, failedTasks, successPercent };
22
+ }
23
+ /**
24
+ * Compute aggregate cost across all tasks.
25
+ */
26
+ export function computeAggregateCost(results) {
27
+ let totalActualCostUSD = 0;
28
+ let totalSavedCostUSD = 0;
29
+ for (const r of results) {
30
+ if (r.usage.costUSD !== null && r.usage.costUSD !== undefined) {
31
+ totalActualCostUSD += r.usage.costUSD;
32
+ }
33
+ if (r.usage.savedCostUSD !== null && r.usage.savedCostUSD !== undefined) {
34
+ totalSavedCostUSD += r.usage.savedCostUSD;
35
+ }
36
+ }
37
+ return {
38
+ totalActualCostUSD,
39
+ totalSavedCostUSD,
40
+ };
41
+ }
42
+ /**
43
+ * Build a fan-out response for specialized tools. No batchId (not cache-backed).
44
+ */
45
+ export function buildFanOutResponse(results, tasks, wallClockMs) {
46
+ const timings = computeTimings(wallClockMs, results);
47
+ const batchProgress = computeBatchProgress(results);
48
+ const aggregateCost = computeAggregateCost(results);
49
+ return {
50
+ type: 'text',
51
+ text: JSON.stringify({
52
+ schemaVersion: '1.0.0',
53
+ mode: 'fan_out',
54
+ timings,
55
+ batchProgress,
56
+ aggregateCost,
57
+ results: results.map((r, i) => ({
58
+ agentType: tasks[i]?.agentType ?? '(auto)',
59
+ status: r.status,
60
+ output: r.output,
61
+ turns: r.turns,
62
+ durationMs: r.durationMs,
63
+ filesRead: r.filesRead,
64
+ filesWritten: r.filesWritten,
65
+ directoriesListed: r.directoriesListed,
66
+ toolCalls: r.toolCalls,
67
+ escalationLog: r.escalationLog,
68
+ usage: r.usage,
69
+ workerStatus: r.workerStatus,
70
+ specReviewStatus: r.specReviewStatus,
71
+ qualityReviewStatus: r.qualityReviewStatus,
72
+ agents: r.agents,
73
+ ...(r.error && { error: r.error }),
74
+ })),
75
+ }, null, 2),
76
+ };
77
+ }
78
+ //# sourceMappingURL=batch-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-response.js","sourceRoot":"","sources":["../../src/tools/batch-response.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,OAAoB;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,MAAM,0BAA0B,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC,CAAC;IAC1E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAoB;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAClC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CACvF,CAAC,MAAM,CAAC;IACT,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,KAAK,OAAO;QACpB,CAAC,CAAC,MAAM,KAAK,aAAa;QAC1B,CAAC,CAAC,MAAM,KAAK,WAAW;QACxB,CAAC,CAAC,MAAM,KAAK,eAAe,CAC/B,CAAC,MAAM,CAAC;IACT,MAAM,cAAc,GAClB,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/E,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AACtF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAoB;IACvD,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAE1B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9D,kBAAkB,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,CAAC,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACxE,iBAAiB,IAAI,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO;QACL,kBAAkB;QAClB,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAoB,EACpB,KAAiB,EACjB,WAAmB;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,MAAe;QACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,aAAa,EAAE,OAAO;YACtB,IAAI,EAAE,SAAS;YACf,OAAO;YACP,aAAa;YACb,aAAa;YACb,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,QAAQ;gBAC1C,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;gBACtC,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,mBAAmB,EAAE,CAAC,CAAC,mBAAmB;gBAC1C,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;aACnC,CAAC,CAAC;SACJ,EAAE,IAAI,EAAE,CAAC,CAAC;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import type { MultiModelConfig } from '@zhixuan92/multi-model-agent-core';
4
+ export declare const debugTaskSchema: z.ZodObject<{
5
+ filePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
+ cwd: z.ZodOptional<z.ZodString>;
7
+ contextBlockIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
8
+ tools: z.ZodOptional<z.ZodEnum<{
9
+ readonly: "readonly";
10
+ none: "none";
11
+ full: "full";
12
+ }>>;
13
+ problem: z.ZodString;
14
+ context: z.ZodOptional<z.ZodString>;
15
+ hypothesis: z.ZodOptional<z.ZodString>;
16
+ agentType: z.ZodOptional<z.ZodEnum<{
17
+ standard: "standard";
18
+ complex: "complex";
19
+ }>>;
20
+ }, z.core.$strip>;
21
+ export type DebugTaskParams = z.infer<typeof debugTaskSchema>;
22
+ export declare function registerDebugTask(server: McpServer, config: MultiModelConfig): void;
23
+ //# sourceMappingURL=debug-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-task.d.ts","sourceRoot":"","sources":["../../src/tools/debug-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAY,MAAM,mCAAmC,CAAC;AASpF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;iBAM1B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,QAgC5E"}
@@ -0,0 +1,38 @@
1
+ import { z } from 'zod';
2
+ import { runTasks } from '@zhixuan92/multi-model-agent-core/run-tasks';
3
+ import { commonToolFields, buildMetadataBlock, buildFilePathsPrompt, applyCommonFields, } from './shared.js';
4
+ export const debugTaskSchema = z.object({
5
+ problem: z.string().describe('Description of the problem to debug'),
6
+ context: z.string().optional().describe('Additional context about the problem'),
7
+ hypothesis: z.string().optional().describe('Initial hypothesis about the cause'),
8
+ agentType: z.enum(['standard', 'complex']).optional(),
9
+ ...commonToolFields,
10
+ });
11
+ export function registerDebugTask(server, config) {
12
+ server.tool('debug_task', 'Debug a problem using hypothesis-driven investigation. Always single-task \u2014 file paths provide context for the investigation. Preset: complex agent, 1 review round. Use delegate_tasks only for custom pipeline config.', debugTaskSchema.shape, async (params) => {
13
+ const agentType = params.agentType ?? 'complex';
14
+ const parts = [`Debug this problem:\n\n${params.problem}`];
15
+ if (params.context)
16
+ parts.push(`Context: ${params.context}`);
17
+ if (params.hypothesis)
18
+ parts.push(`Initial hypothesis: ${params.hypothesis}`);
19
+ const fileSection = buildFilePathsPrompt(params.filePaths);
20
+ if (fileSection)
21
+ parts.push(fileSection);
22
+ parts.push('Use hypothesis-driven debugging: identify root cause, propose fix, verify.');
23
+ const prompt = parts.join('\n\n');
24
+ const taskSpec = applyCommonFields({ agentType, reviewPolicy: 'full', maxReviewRounds: 1 }, params);
25
+ try {
26
+ const results = await runTasks([{ ...taskSpec, prompt }], config);
27
+ const result = results[0];
28
+ return { content: [{ type: 'text', text: result.output }, buildMetadataBlock(result)] };
29
+ }
30
+ catch (err) {
31
+ return {
32
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
33
+ isError: true,
34
+ };
35
+ }
36
+ });
37
+ }
38
+ //# sourceMappingURL=debug-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-task.js","sourceRoot":"","sources":["../../src/tools/debug-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AACvE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACnE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC/E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IAChF,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrD,GAAG,gBAAgB;CACpB,CAAC,CAAC;AAIH,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAwB;IAC3E,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,+NAA+N,EAC/N,eAAe,CAAC,KAAK,EACrB,KAAK,EAAE,MAAuB,EAAE,EAAE;QAChC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;QAChD,MAAM,KAAK,GAAa,CAAC,0BAA0B,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,IAAI,MAAM,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9E,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3D,IAAI,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;QACzF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAElC,MAAM,QAAQ,GAAsB,iBAAiB,CACnD,EAAE,SAAS,EAAE,YAAY,EAAE,MAAe,EAAE,eAAe,EAAE,CAAC,EAAE,EAChE,MAAM,CACP,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAc,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACxG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import type { MultiModelConfig } from '@zhixuan92/multi-model-agent-core';
4
+ export declare const reviewCodeSchema: z.ZodObject<{
5
+ filePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
+ cwd: z.ZodOptional<z.ZodString>;
7
+ contextBlockIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
8
+ tools: z.ZodOptional<z.ZodEnum<{
9
+ readonly: "readonly";
10
+ none: "none";
11
+ full: "full";
12
+ }>>;
13
+ code: z.ZodOptional<z.ZodString>;
14
+ focus: z.ZodOptional<z.ZodArray<z.ZodEnum<{
15
+ security: "security";
16
+ performance: "performance";
17
+ correctness: "correctness";
18
+ style: "style";
19
+ }>>>;
20
+ outputFormat: z.ZodOptional<z.ZodEnum<{
21
+ json: "json";
22
+ markdown: "markdown";
23
+ }>>;
24
+ agentType: z.ZodOptional<z.ZodEnum<{
25
+ standard: "standard";
26
+ complex: "complex";
27
+ }>>;
28
+ }, z.core.$strip>;
29
+ export type ReviewCodeParams = z.infer<typeof reviewCodeSchema>;
30
+ export declare function registerReviewCode(server: McpServer, config: MultiModelConfig): void;
31
+ //# sourceMappingURL=review-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-code.d.ts","sourceRoot":"","sources":["../../src/tools/review-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAY,MAAM,mCAAmC,CAAC;AAapF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;iBAM3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAoBhE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,QAiD7E"}
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+ import { runTasks } from '@zhixuan92/multi-model-agent-core/run-tasks';
3
+ import { commonToolFields, validateInput, resolveDispatchMode, buildMetadataBlock, buildFilePathsPrompt, buildPerFilePrompt, applyCommonFields, } from './shared.js';
4
+ import { buildFanOutResponse } from './batch-response.js';
5
+ export const reviewCodeSchema = z.object({
6
+ code: z.string().optional().describe('Inline code to review'),
7
+ focus: z.array(z.enum(['security', 'performance', 'correctness', 'style'])).optional(),
8
+ outputFormat: z.enum(['json', 'markdown']).optional(),
9
+ agentType: z.enum(['standard', 'complex']).optional(),
10
+ ...commonToolFields,
11
+ });
12
+ function buildReviewPrompt(code, filePaths, focus, outputFormat) {
13
+ const parts = ['Review this code:'];
14
+ if (code)
15
+ parts.push(`\`\`\`\n${code}\n\`\`\``);
16
+ const fileSection = buildFilePathsPrompt(filePaths);
17
+ if (fileSection)
18
+ parts.push(fileSection);
19
+ if (focus && focus.length > 0)
20
+ parts.push(`Focus areas: ${focus.join(', ')}.`);
21
+ if (outputFormat === 'json') {
22
+ parts.push('Return findings as a JSON array of objects with keys: severity, category, file, line, finding, recommendation.');
23
+ }
24
+ parts.push('Provide a structured review with findings and recommendations.');
25
+ return parts.join('\n\n');
26
+ }
27
+ export function registerReviewCode(server, config) {
28
+ server.tool('review_code', 'Review code with the full quality pipeline (spec review + quality review). Accepts inline code or file paths \u2014 multiple files are reviewed in parallel. Preset: complex agent, full review. Use this when code needs thorough review. Use delegate_tasks only for custom pipeline config.', reviewCodeSchema.shape, async (params) => {
29
+ const validation = validateInput(params.code, params.filePaths);
30
+ if (!validation.valid) {
31
+ return { content: [{ type: 'text', text: `Error: ${validation.message}` }], isError: true };
32
+ }
33
+ const agentType = params.agentType ?? 'complex';
34
+ const baseTaskSpec = applyCommonFields({
35
+ agentType,
36
+ reviewPolicy: 'full',
37
+ ...(params.outputFormat && { formatConstraints: { outputFormat: params.outputFormat } }),
38
+ }, params);
39
+ try {
40
+ const mode = resolveDispatchMode(params.code, params.filePaths);
41
+ if (mode === 'fan_out') {
42
+ const validPaths = params.filePaths.filter(p => p.trim().length > 0);
43
+ const promptTemplate = buildReviewPrompt(undefined, undefined, params.focus, params.outputFormat);
44
+ const tasks = validPaths.map(fp => ({
45
+ ...baseTaskSpec,
46
+ prompt: buildPerFilePrompt(fp, promptTemplate),
47
+ }));
48
+ const startMs = Date.now();
49
+ const results = await runTasks(tasks, config);
50
+ return { content: [buildFanOutResponse(results, tasks, Date.now() - startMs)] };
51
+ }
52
+ const prompt = buildReviewPrompt(params.code, params.filePaths, params.focus, params.outputFormat);
53
+ const results = await runTasks([{ ...baseTaskSpec, prompt }], config);
54
+ const result = results[0];
55
+ return { content: [{ type: 'text', text: result.output }, buildMetadataBlock(result)] };
56
+ }
57
+ catch (err) {
58
+ return {
59
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
60
+ isError: true,
61
+ };
62
+ }
63
+ });
64
+ }
65
+ //# sourceMappingURL=review-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-code.js","sourceRoot":"","sources":["../../src/tools/review-code.ts"],"names":[],"mappings":"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"}