@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.
- package/README.md +18 -220
- package/dist/cli.d.ts +20 -22
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +183 -154
- package/dist/cli.js.map +1 -1
- package/dist/routing/render-provider-routing-matrix.d.ts +1 -1
- package/dist/routing/render-provider-routing-matrix.d.ts.map +1 -1
- package/dist/routing/render-provider-routing-matrix.js +38 -67
- package/dist/routing/render-provider-routing-matrix.js.map +1 -1
- package/dist/tools/audit-document.d.ts +37 -0
- package/dist/tools/audit-document.d.ts.map +1 -0
- package/dist/tools/audit-document.js +76 -0
- package/dist/tools/audit-document.js.map +1 -0
- package/dist/tools/batch-response.d.ts +21 -0
- package/dist/tools/batch-response.d.ts.map +1 -0
- package/dist/tools/batch-response.js +78 -0
- package/dist/tools/batch-response.js.map +1 -0
- package/dist/tools/debug-task.d.ts +23 -0
- package/dist/tools/debug-task.d.ts.map +1 -0
- package/dist/tools/debug-task.js +38 -0
- package/dist/tools/debug-task.js.map +1 -0
- package/dist/tools/review-code.d.ts +31 -0
- package/dist/tools/review-code.d.ts.map +1 -0
- package/dist/tools/review-code.js +65 -0
- package/dist/tools/review-code.js.map +1 -0
- package/dist/tools/shared.d.ts +31 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +72 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/verify-work.d.ts +22 -0
- package/dist/tools/verify-work.d.ts.map +1 -0
- package/dist/tools/verify-work.js +57 -0
- package/dist/tools/verify-work.js.map +1 -0
- package/package.json +19 -3
|
@@ -1,26 +1,19 @@
|
|
|
1
|
-
import {
|
|
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.
|
|
5
|
-
2.
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
- '
|
|
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
|
|
19
|
-
- Use 'high' for
|
|
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
|
|
22
|
-
|
|
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
|
-
|
|
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 '
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
per-task 'escalationLog' shows every attempt.
|
|
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' =
|
|
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 (
|
|
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
|
|
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 +
|
|
72
|
-
hint — fetch individual outputs with
|
|
73
|
-
or per-task
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
125
|
-
summary mode).`;
|
|
126
|
-
function
|
|
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
|
-
`
|
|
133
|
-
`
|
|
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
|
|
115
|
+
* Helps the consuming LLM understand agent capabilities and routing rules.
|
|
147
116
|
*/
|
|
148
117
|
export function renderProviderRoutingMatrix(config) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
|
127
|
+
'Delegate tasks to sub-agents running on different LLM models.',
|
|
157
128
|
'All tasks execute concurrently.',
|
|
158
129
|
'',
|
|
159
|
-
'Available
|
|
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,
|
|
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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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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"}
|