@j0hanz/code-review-analyst-mcp 1.4.4 → 1.5.1
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 +23 -19
- package/dist/lib/diff-parser.js +33 -13
- package/dist/lib/diff-store.d.ts +2 -0
- package/dist/lib/gemini.d.ts +4 -0
- package/dist/lib/gemini.js +308 -26
- package/dist/lib/model-config.d.ts +33 -38
- package/dist/lib/model-config.js +55 -88
- package/dist/lib/tool-contracts.d.ts +31 -22
- package/dist/lib/tool-contracts.js +15 -8
- package/dist/lib/tool-factory.d.ts +8 -3
- package/dist/lib/tool-factory.js +53 -5
- package/dist/lib/types.d.ts +7 -1
- package/dist/prompts/index.js +3 -3
- package/dist/resources/instructions.js +3 -3
- package/dist/resources/server-config.js +19 -4
- package/dist/resources/tool-info.js +4 -4
- package/dist/schemas/outputs.d.ts +7 -7
- package/dist/tools/analyze-complexity.js +6 -3
- package/dist/tools/analyze-pr-impact.js +9 -4
- package/dist/tools/detect-api-breaking.js +6 -3
- package/dist/tools/generate-diff.js +1 -1
- package/dist/tools/generate-review-summary.js +17 -6
- package/dist/tools/generate-test-plan.js +9 -4
- package/dist/tools/inspect-code-quality.js +9 -4
- package/dist/tools/suggest-search-replace.js +9 -4
- package/package.json +1 -1
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
/** Fast, cost-effective model for summarization and light analysis. */
|
|
2
|
-
export declare const FLASH_MODEL = "gemini-
|
|
2
|
+
export declare const FLASH_MODEL = "gemini-3-flash-preview";
|
|
3
3
|
/** High-capability model for deep reasoning, quality inspection, and reliable code generation. */
|
|
4
|
-
export declare const PRO_MODEL = "gemini-
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export declare const FLASH_TRIAGE_THINKING_BUDGET: 0;
|
|
12
|
-
/** Thinking budget (tokens) for Flash analysis tasks (test plans, complexity). */
|
|
13
|
-
export declare const FLASH_THINKING_BUDGET: 16384;
|
|
14
|
-
/** Thinking budget (tokens) for Pro model deep-analysis tasks (quality, patches). */
|
|
15
|
-
export declare const PRO_THINKING_BUDGET: 24576;
|
|
16
|
-
/** Output cap for Flash triage tools (impact, summary). */
|
|
17
|
-
export declare const FLASH_TRIAGE_MAX_OUTPUT_TOKENS: 4096;
|
|
18
|
-
/** Output cap for API breaking-change detection (migration guidance needs room). */
|
|
19
|
-
export declare const FLASH_API_BREAKING_MAX_OUTPUT_TOKENS: 4096;
|
|
20
|
-
/** Output cap for test-plan generation (includes pseudocode snippets). */
|
|
21
|
-
export declare const FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS: 8192;
|
|
22
|
-
/** Output cap for Pro deep review findings. */
|
|
23
|
-
export declare const PRO_REVIEW_MAX_OUTPUT_TOKENS: 12288;
|
|
24
|
-
/** Output cap for Pro search/replace remediation blocks. */
|
|
25
|
-
export declare const PRO_PATCH_MAX_OUTPUT_TOKENS: 8192;
|
|
26
|
-
/** Output cap for Flash complexity analysis reports. */
|
|
27
|
-
export declare const FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS: 2048;
|
|
28
|
-
/** Extended timeout for Pro model calls (ms). Pro thinks longer than Flash. */
|
|
4
|
+
export declare const PRO_MODEL = "gemini-3-pro-preview";
|
|
5
|
+
/** Default language hint. */
|
|
6
|
+
export declare const DEFAULT_LANGUAGE = "detect";
|
|
7
|
+
/** Default test-framework hint. */
|
|
8
|
+
export declare const DEFAULT_FRAMEWORK = "detect";
|
|
9
|
+
/** Extended timeout for Pro model calls (ms). */
|
|
29
10
|
export declare const DEFAULT_TIMEOUT_PRO_MS = 120000;
|
|
30
|
-
/** Temperature for triage/classification tools (deterministic structured extraction). */
|
|
31
|
-
export declare const TRIAGE_TEMPERATURE: 0.1;
|
|
32
|
-
/** Temperature for analytical tools (consistent algorithmic reasoning). */
|
|
33
|
-
export declare const ANALYSIS_TEMPERATURE: 0.1;
|
|
34
|
-
/** Temperature for code patch generation (maximum precision for search blocks). */
|
|
35
|
-
export declare const PATCH_TEMPERATURE: 0;
|
|
36
|
-
/** Temperature for creative synthesis tools (test plan generation). */
|
|
37
|
-
export declare const CREATIVE_TEMPERATURE: 0.2;
|
|
38
11
|
export declare const MODEL_TIMEOUT_MS: {
|
|
39
12
|
readonly defaultPro: 120000;
|
|
40
13
|
};
|
|
41
|
-
/**
|
|
42
|
-
export declare const
|
|
43
|
-
/**
|
|
44
|
-
export declare const
|
|
14
|
+
/** Thinking level for Flash triage. */
|
|
15
|
+
export declare const FLASH_TRIAGE_THINKING_LEVEL: "minimal";
|
|
16
|
+
/** Thinking level for Flash analysis. */
|
|
17
|
+
export declare const FLASH_THINKING_LEVEL: "medium";
|
|
18
|
+
/** Thinking level for Pro deep analysis. */
|
|
19
|
+
export declare const PRO_THINKING_LEVEL: "high";
|
|
20
|
+
/** Output cap for Flash API breaking-change detection. */
|
|
21
|
+
export declare const FLASH_API_BREAKING_MAX_OUTPUT_TOKENS: 4096;
|
|
22
|
+
/** Output cap for Flash complexity analysis. */
|
|
23
|
+
export declare const FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS: 2048;
|
|
24
|
+
/** Output cap for Flash test-plan generation. */
|
|
25
|
+
export declare const FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS: 8192;
|
|
26
|
+
/** Output cap for Flash triage tools. */
|
|
27
|
+
export declare const FLASH_TRIAGE_MAX_OUTPUT_TOKENS: 4096;
|
|
28
|
+
/** Output cap for Pro patch generation. */
|
|
29
|
+
export declare const PRO_PATCH_MAX_OUTPUT_TOKENS: 8192;
|
|
30
|
+
/** Output cap for Pro deep review findings. */
|
|
31
|
+
export declare const PRO_REVIEW_MAX_OUTPUT_TOKENS: 12288;
|
|
32
|
+
/** Temperature for analytical tools. */
|
|
33
|
+
export declare const ANALYSIS_TEMPERATURE: 1;
|
|
34
|
+
/** Temperature for creative synthesis (test plans). */
|
|
35
|
+
export declare const CREATIVE_TEMPERATURE: 1;
|
|
36
|
+
/** Temperature for code patch generation. */
|
|
37
|
+
export declare const PATCH_TEMPERATURE: 1;
|
|
38
|
+
/** Temperature for triage/classification tools. */
|
|
39
|
+
export declare const TRIAGE_TEMPERATURE: 1;
|
package/dist/lib/model-config.js
CHANGED
|
@@ -1,104 +1,71 @@
|
|
|
1
1
|
/** Fast, cost-effective model for summarization and light analysis. */
|
|
2
|
-
export const FLASH_MODEL = 'gemini-
|
|
2
|
+
export const FLASH_MODEL = 'gemini-3-flash-preview';
|
|
3
3
|
/** High-capability model for deep reasoning, quality inspection, and reliable code generation. */
|
|
4
|
-
export const PRO_MODEL = 'gemini-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
export const PRO_MODEL = 'gemini-3-pro-preview';
|
|
5
|
+
/** Default hint for auto-detection. */
|
|
6
|
+
const DEFAULT_DETECT_HINT = 'detect';
|
|
7
|
+
/** Default language hint. */
|
|
8
|
+
export const DEFAULT_LANGUAGE = DEFAULT_DETECT_HINT;
|
|
9
|
+
/** Default test-framework hint. */
|
|
10
|
+
export const DEFAULT_FRAMEWORK = DEFAULT_DETECT_HINT;
|
|
11
|
+
/** Extended timeout for Pro model calls (ms). */
|
|
12
|
+
export const DEFAULT_TIMEOUT_PRO_MS = 120_000;
|
|
13
|
+
export const MODEL_TIMEOUT_MS = {
|
|
14
|
+
defaultPro: DEFAULT_TIMEOUT_PRO_MS,
|
|
15
|
+
};
|
|
16
|
+
Object.freeze(MODEL_TIMEOUT_MS);
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Budgets (Thinking & Output)
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
const THINKING_LEVELS = {
|
|
21
|
+
/** Minimal thinking for triage/classification. */
|
|
22
|
+
flashTriage: 'minimal',
|
|
23
|
+
/** Medium thinking for analysis tasks. */
|
|
24
|
+
flash: 'medium',
|
|
25
|
+
/** High thinking for deep review and patches. */
|
|
26
|
+
pro: 'high',
|
|
23
27
|
};
|
|
28
|
+
// Thinking budget in tokens for Flash and Pro tools. Note that these are not hard limits, but rather guidelines to encourage concise responses and manage latency/cost.
|
|
24
29
|
const OUTPUT_TOKEN_BUDGET = {
|
|
25
|
-
flashTriage: 4_096,
|
|
26
|
-
/**
|
|
27
|
-
* Raised from 4_096: 15 test cases × pseudoCode@2_000 chars ≈ 7_500 tokens;
|
|
28
|
-
* staying at 4_096 risked MAX_TOKENS truncation on moderate test plans.
|
|
29
|
-
*/
|
|
30
|
-
flashTestPlan: 8_192,
|
|
31
30
|
flashApiBreaking: 4_096,
|
|
32
31
|
flashComplexity: 2_048,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* exceed 8_192 tokens for rich, high-finding-count reviews.
|
|
36
|
-
*/
|
|
37
|
-
proReview: 12_288,
|
|
38
|
-
/**
|
|
39
|
-
* Raised from 4_096: 10 search/replace blocks with multi-line code context
|
|
40
|
-
* can exceed the previous cap and cause MAX_TOKENS truncation.
|
|
41
|
-
*/
|
|
32
|
+
flashTestPlan: 8_192,
|
|
33
|
+
flashTriage: 4_096,
|
|
42
34
|
proPatch: 8_192,
|
|
35
|
+
proReview: 12_288,
|
|
43
36
|
};
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
/** Triage/classification tasks — deterministic structured extraction. */
|
|
52
|
-
triage: 0.1,
|
|
53
|
-
/** Analytical reasoning — consistent algorithmic analysis. */
|
|
54
|
-
analysis: 0.1,
|
|
55
|
-
/** Code patch generation — maximum precision for exact-match search blocks. */
|
|
56
|
-
patch: 0.0,
|
|
57
|
-
/** Test plan generation — allow modest diversity in test-case synthesis. */
|
|
58
|
-
creative: 0.2,
|
|
59
|
-
};
|
|
60
|
-
const DEFAULT_DETECT_HINT = 'detect';
|
|
61
|
-
/**
|
|
62
|
-
* Thinking budget (tokens) for Flash triage tools (impact, summary, API-breaking).
|
|
63
|
-
* Explicitly disabled (0) — these are classification/extraction tasks that do not
|
|
64
|
-
* benefit from a reasoning chain. Avoids default dynamic-thinking overhead.
|
|
65
|
-
* Flash 2.5 range: 0–24_576.
|
|
66
|
-
*/
|
|
67
|
-
export const FLASH_TRIAGE_THINKING_BUDGET = THINKING_BUDGET_TOKENS.flashTriage;
|
|
68
|
-
/** Thinking budget (tokens) for Flash analysis tasks (test plans, complexity). */
|
|
69
|
-
export const FLASH_THINKING_BUDGET = THINKING_BUDGET_TOKENS.flash;
|
|
70
|
-
/** Thinking budget (tokens) for Pro model deep-analysis tasks (quality, patches). */
|
|
71
|
-
export const PRO_THINKING_BUDGET = THINKING_BUDGET_TOKENS.pro;
|
|
72
|
-
/** Output cap for Flash triage tools (impact, summary). */
|
|
73
|
-
export const FLASH_TRIAGE_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashTriage;
|
|
74
|
-
/** Output cap for API breaking-change detection (migration guidance needs room). */
|
|
37
|
+
/** Thinking level for Flash triage. */
|
|
38
|
+
export const FLASH_TRIAGE_THINKING_LEVEL = THINKING_LEVELS.flashTriage;
|
|
39
|
+
/** Thinking level for Flash analysis. */
|
|
40
|
+
export const FLASH_THINKING_LEVEL = THINKING_LEVELS.flash;
|
|
41
|
+
/** Thinking level for Pro deep analysis. */
|
|
42
|
+
export const PRO_THINKING_LEVEL = THINKING_LEVELS.pro;
|
|
43
|
+
/** Output cap for Flash API breaking-change detection. */
|
|
75
44
|
export const FLASH_API_BREAKING_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashApiBreaking;
|
|
76
|
-
/** Output cap for
|
|
45
|
+
/** Output cap for Flash complexity analysis. */
|
|
46
|
+
export const FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashComplexity;
|
|
47
|
+
/** Output cap for Flash test-plan generation. */
|
|
77
48
|
export const FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashTestPlan;
|
|
49
|
+
/** Output cap for Flash triage tools. */
|
|
50
|
+
export const FLASH_TRIAGE_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashTriage;
|
|
51
|
+
/** Output cap for Pro patch generation. */
|
|
52
|
+
export const PRO_PATCH_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.proPatch;
|
|
78
53
|
/** Output cap for Pro deep review findings. */
|
|
79
54
|
export const PRO_REVIEW_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.proReview;
|
|
80
|
-
/** Output cap for Pro search/replace remediation blocks. */
|
|
81
|
-
export const PRO_PATCH_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.proPatch;
|
|
82
|
-
/** Output cap for Flash complexity analysis reports. */
|
|
83
|
-
export const FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS = OUTPUT_TOKEN_BUDGET.flashComplexity;
|
|
84
|
-
/** Extended timeout for Pro model calls (ms). Pro thinks longer than Flash. */
|
|
85
|
-
export const DEFAULT_TIMEOUT_PRO_MS = 120_000;
|
|
86
55
|
// ---------------------------------------------------------------------------
|
|
87
|
-
//
|
|
56
|
+
// Temperatures
|
|
88
57
|
// ---------------------------------------------------------------------------
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
58
|
+
const TOOL_TEMPERATURE = {
|
|
59
|
+
analysis: 1.0, // Gemini 3 recommends 1.0 for all tasks
|
|
60
|
+
creative: 1.0, // Gemini 3 recommends 1.0 for all tasks
|
|
61
|
+
patch: 1.0, // Gemini 3 recommends 1.0 for all tasks
|
|
62
|
+
triage: 1.0, // Gemini 3 recommends 1.0 for all tasks
|
|
63
|
+
};
|
|
64
|
+
/** Temperature for analytical tools. */
|
|
92
65
|
export const ANALYSIS_TEMPERATURE = TOOL_TEMPERATURE.analysis;
|
|
93
|
-
/** Temperature for
|
|
94
|
-
export const PATCH_TEMPERATURE = TOOL_TEMPERATURE.patch;
|
|
95
|
-
/** Temperature for creative synthesis tools (test plan generation). */
|
|
66
|
+
/** Temperature for creative synthesis (test plans). */
|
|
96
67
|
export const CREATIVE_TEMPERATURE = TOOL_TEMPERATURE.creative;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
/** Default language hint when not specified by the user. Tells the model to auto-detect. */
|
|
102
|
-
export const DEFAULT_LANGUAGE = DEFAULT_DETECT_HINT;
|
|
103
|
-
/** Default test-framework hint when not specified by the user. Tells the model to auto-detect. */
|
|
104
|
-
export const DEFAULT_FRAMEWORK = DEFAULT_DETECT_HINT;
|
|
68
|
+
/** Temperature for code patch generation. */
|
|
69
|
+
export const PATCH_TEMPERATURE = TOOL_TEMPERATURE.patch;
|
|
70
|
+
/** Temperature for triage/classification tools. */
|
|
71
|
+
export const TRIAGE_TEMPERATURE = TOOL_TEMPERATURE.triage;
|
|
@@ -13,7 +13,7 @@ export interface ToolContract {
|
|
|
13
13
|
model: string;
|
|
14
14
|
/** Set to 0 for synchronous (non-Gemini) tools. */
|
|
15
15
|
timeoutMs: number;
|
|
16
|
-
|
|
16
|
+
thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';
|
|
17
17
|
/** Set to 0 for synchronous (non-Gemini) tools. */
|
|
18
18
|
maxOutputTokens: number;
|
|
19
19
|
/**
|
|
@@ -23,6 +23,8 @@ export interface ToolContract {
|
|
|
23
23
|
* Omit to use the global default (0.2).
|
|
24
24
|
*/
|
|
25
25
|
temperature?: number;
|
|
26
|
+
/** Enables deterministic JSON guidance and schema key ordering. */
|
|
27
|
+
deterministicJson?: boolean;
|
|
26
28
|
params: readonly ToolParameterContract[];
|
|
27
29
|
outputShape: string;
|
|
28
30
|
gotchas: readonly string[];
|
|
@@ -48,11 +50,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
48
50
|
}, {
|
|
49
51
|
readonly name: "analyze_pr_impact";
|
|
50
52
|
readonly purpose: "Assess severity, categories, breaking changes, and rollback complexity.";
|
|
51
|
-
readonly model: "gemini-
|
|
53
|
+
readonly model: "gemini-3-flash-preview";
|
|
52
54
|
readonly timeoutMs: 90000;
|
|
53
|
-
readonly
|
|
55
|
+
readonly thinkingLevel: "minimal";
|
|
54
56
|
readonly maxOutputTokens: 4096;
|
|
55
|
-
readonly temperature:
|
|
57
|
+
readonly temperature: 1;
|
|
58
|
+
readonly deterministicJson: true;
|
|
56
59
|
readonly params: readonly [{
|
|
57
60
|
readonly name: "repository";
|
|
58
61
|
readonly type: "string";
|
|
@@ -72,11 +75,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
72
75
|
}, {
|
|
73
76
|
readonly name: "generate_review_summary";
|
|
74
77
|
readonly purpose: "Produce PR summary, risk rating, and merge recommendation.";
|
|
75
|
-
readonly model: "gemini-
|
|
78
|
+
readonly model: "gemini-3-flash-preview";
|
|
76
79
|
readonly timeoutMs: 90000;
|
|
77
|
-
readonly
|
|
80
|
+
readonly thinkingLevel: "minimal";
|
|
78
81
|
readonly maxOutputTokens: 4096;
|
|
79
|
-
readonly temperature:
|
|
82
|
+
readonly temperature: 1;
|
|
83
|
+
readonly deterministicJson: true;
|
|
80
84
|
readonly params: readonly [{
|
|
81
85
|
readonly name: "repository";
|
|
82
86
|
readonly type: "string";
|
|
@@ -96,11 +100,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
96
100
|
}, {
|
|
97
101
|
readonly name: "inspect_code_quality";
|
|
98
102
|
readonly purpose: "Deep code review with optional full-file context.";
|
|
99
|
-
readonly model: "gemini-
|
|
103
|
+
readonly model: "gemini-3-pro-preview";
|
|
100
104
|
readonly timeoutMs: 120000;
|
|
101
|
-
readonly
|
|
105
|
+
readonly thinkingLevel: "high";
|
|
102
106
|
readonly maxOutputTokens: 12288;
|
|
103
|
-
readonly temperature:
|
|
107
|
+
readonly temperature: 1;
|
|
108
|
+
readonly deterministicJson: true;
|
|
104
109
|
readonly params: readonly [{
|
|
105
110
|
readonly name: "repository";
|
|
106
111
|
readonly type: "string";
|
|
@@ -139,11 +144,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
139
144
|
}, {
|
|
140
145
|
readonly name: "suggest_search_replace";
|
|
141
146
|
readonly purpose: "Generate verbatim search/replace fix blocks for one finding.";
|
|
142
|
-
readonly model: "gemini-
|
|
147
|
+
readonly model: "gemini-3-pro-preview";
|
|
143
148
|
readonly timeoutMs: 120000;
|
|
144
|
-
readonly
|
|
149
|
+
readonly thinkingLevel: "high";
|
|
145
150
|
readonly maxOutputTokens: 8192;
|
|
146
|
-
readonly temperature:
|
|
151
|
+
readonly temperature: 1;
|
|
152
|
+
readonly deterministicJson: true;
|
|
147
153
|
readonly params: readonly [{
|
|
148
154
|
readonly name: "findingTitle";
|
|
149
155
|
readonly type: "string";
|
|
@@ -164,11 +170,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
164
170
|
}, {
|
|
165
171
|
readonly name: "generate_test_plan";
|
|
166
172
|
readonly purpose: "Generate prioritized test cases and coverage guidance.";
|
|
167
|
-
readonly model: "gemini-
|
|
173
|
+
readonly model: "gemini-3-flash-preview";
|
|
168
174
|
readonly timeoutMs: 90000;
|
|
169
|
-
readonly
|
|
175
|
+
readonly thinkingLevel: "medium";
|
|
170
176
|
readonly maxOutputTokens: 8192;
|
|
171
|
-
readonly temperature:
|
|
177
|
+
readonly temperature: 1;
|
|
178
|
+
readonly deterministicJson: true;
|
|
172
179
|
readonly params: readonly [{
|
|
173
180
|
readonly name: "repository";
|
|
174
181
|
readonly type: "string";
|
|
@@ -200,11 +207,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
200
207
|
}, {
|
|
201
208
|
readonly name: "analyze_time_space_complexity";
|
|
202
209
|
readonly purpose: "Analyze Big-O complexity and detect degradations in changed code.";
|
|
203
|
-
readonly model: "gemini-
|
|
210
|
+
readonly model: "gemini-3-flash-preview";
|
|
204
211
|
readonly timeoutMs: 90000;
|
|
205
|
-
readonly
|
|
212
|
+
readonly thinkingLevel: "medium";
|
|
206
213
|
readonly maxOutputTokens: 2048;
|
|
207
|
-
readonly temperature:
|
|
214
|
+
readonly temperature: 1;
|
|
215
|
+
readonly deterministicJson: true;
|
|
208
216
|
readonly params: readonly [{
|
|
209
217
|
readonly name: "language";
|
|
210
218
|
readonly type: "string";
|
|
@@ -218,11 +226,12 @@ export declare const TOOL_CONTRACTS: readonly [{
|
|
|
218
226
|
}, {
|
|
219
227
|
readonly name: "detect_api_breaking_changes";
|
|
220
228
|
readonly purpose: "Detect breaking API/interface changes in a diff.";
|
|
221
|
-
readonly model: "gemini-
|
|
229
|
+
readonly model: "gemini-3-flash-preview";
|
|
222
230
|
readonly timeoutMs: 90000;
|
|
223
|
-
readonly
|
|
231
|
+
readonly thinkingLevel: "minimal";
|
|
224
232
|
readonly maxOutputTokens: 4096;
|
|
225
|
-
readonly temperature:
|
|
233
|
+
readonly temperature: 1;
|
|
234
|
+
readonly deterministicJson: true;
|
|
226
235
|
readonly params: readonly [{
|
|
227
236
|
readonly name: "language";
|
|
228
237
|
readonly type: "string";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ANALYSIS_TEMPERATURE, CREATIVE_TEMPERATURE, DEFAULT_TIMEOUT_PRO_MS, FLASH_API_BREAKING_MAX_OUTPUT_TOKENS, FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS, FLASH_MODEL, FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS,
|
|
1
|
+
import { ANALYSIS_TEMPERATURE, CREATIVE_TEMPERATURE, DEFAULT_TIMEOUT_PRO_MS, FLASH_API_BREAKING_MAX_OUTPUT_TOKENS, FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS, FLASH_MODEL, FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS, FLASH_THINKING_LEVEL, FLASH_TRIAGE_MAX_OUTPUT_TOKENS, FLASH_TRIAGE_THINKING_LEVEL, PATCH_TEMPERATURE, PRO_MODEL, PRO_PATCH_MAX_OUTPUT_TOKENS, PRO_REVIEW_MAX_OUTPUT_TOKENS, PRO_THINKING_LEVEL, TRIAGE_TEMPERATURE, } from './model-config.js';
|
|
2
2
|
const DEFAULT_TIMEOUT_FLASH_MS = 90_000;
|
|
3
3
|
export const INSPECTION_FOCUS_AREAS = [
|
|
4
4
|
'security',
|
|
@@ -40,9 +40,10 @@ export const TOOL_CONTRACTS = [
|
|
|
40
40
|
purpose: 'Assess severity, categories, breaking changes, and rollback complexity.',
|
|
41
41
|
model: FLASH_MODEL,
|
|
42
42
|
timeoutMs: DEFAULT_TIMEOUT_FLASH_MS,
|
|
43
|
-
|
|
43
|
+
thinkingLevel: FLASH_TRIAGE_THINKING_LEVEL,
|
|
44
44
|
maxOutputTokens: FLASH_TRIAGE_MAX_OUTPUT_TOKENS,
|
|
45
45
|
temperature: TRIAGE_TEMPERATURE,
|
|
46
|
+
deterministicJson: true,
|
|
46
47
|
params: [
|
|
47
48
|
{
|
|
48
49
|
name: 'repository',
|
|
@@ -73,9 +74,10 @@ export const TOOL_CONTRACTS = [
|
|
|
73
74
|
purpose: 'Produce PR summary, risk rating, and merge recommendation.',
|
|
74
75
|
model: FLASH_MODEL,
|
|
75
76
|
timeoutMs: DEFAULT_TIMEOUT_FLASH_MS,
|
|
76
|
-
|
|
77
|
+
thinkingLevel: FLASH_TRIAGE_THINKING_LEVEL,
|
|
77
78
|
maxOutputTokens: FLASH_TRIAGE_MAX_OUTPUT_TOKENS,
|
|
78
79
|
temperature: TRIAGE_TEMPERATURE,
|
|
80
|
+
deterministicJson: true,
|
|
79
81
|
params: [
|
|
80
82
|
{
|
|
81
83
|
name: 'repository',
|
|
@@ -106,9 +108,10 @@ export const TOOL_CONTRACTS = [
|
|
|
106
108
|
purpose: 'Deep code review with optional full-file context.',
|
|
107
109
|
model: PRO_MODEL,
|
|
108
110
|
timeoutMs: DEFAULT_TIMEOUT_PRO_MS,
|
|
109
|
-
|
|
111
|
+
thinkingLevel: PRO_THINKING_LEVEL,
|
|
110
112
|
maxOutputTokens: PRO_REVIEW_MAX_OUTPUT_TOKENS,
|
|
111
113
|
temperature: ANALYSIS_TEMPERATURE,
|
|
114
|
+
deterministicJson: true,
|
|
112
115
|
params: [
|
|
113
116
|
{
|
|
114
117
|
name: 'repository',
|
|
@@ -163,9 +166,10 @@ export const TOOL_CONTRACTS = [
|
|
|
163
166
|
purpose: 'Generate verbatim search/replace fix blocks for one finding.',
|
|
164
167
|
model: PRO_MODEL,
|
|
165
168
|
timeoutMs: DEFAULT_TIMEOUT_PRO_MS,
|
|
166
|
-
|
|
169
|
+
thinkingLevel: PRO_THINKING_LEVEL,
|
|
167
170
|
maxOutputTokens: PRO_PATCH_MAX_OUTPUT_TOKENS,
|
|
168
171
|
temperature: PATCH_TEMPERATURE,
|
|
172
|
+
deterministicJson: true,
|
|
169
173
|
params: [
|
|
170
174
|
{
|
|
171
175
|
name: 'findingTitle',
|
|
@@ -198,9 +202,10 @@ export const TOOL_CONTRACTS = [
|
|
|
198
202
|
purpose: 'Generate prioritized test cases and coverage guidance.',
|
|
199
203
|
model: FLASH_MODEL,
|
|
200
204
|
timeoutMs: DEFAULT_TIMEOUT_FLASH_MS,
|
|
201
|
-
|
|
205
|
+
thinkingLevel: FLASH_THINKING_LEVEL,
|
|
202
206
|
maxOutputTokens: FLASH_TEST_PLAN_MAX_OUTPUT_TOKENS,
|
|
203
207
|
temperature: CREATIVE_TEMPERATURE,
|
|
208
|
+
deterministicJson: true,
|
|
204
209
|
params: [
|
|
205
210
|
{
|
|
206
211
|
name: 'repository',
|
|
@@ -245,9 +250,10 @@ export const TOOL_CONTRACTS = [
|
|
|
245
250
|
purpose: 'Analyze Big-O complexity and detect degradations in changed code.',
|
|
246
251
|
model: FLASH_MODEL,
|
|
247
252
|
timeoutMs: DEFAULT_TIMEOUT_FLASH_MS,
|
|
248
|
-
|
|
253
|
+
thinkingLevel: FLASH_THINKING_LEVEL,
|
|
249
254
|
maxOutputTokens: FLASH_COMPLEXITY_MAX_OUTPUT_TOKENS,
|
|
250
255
|
temperature: ANALYSIS_TEMPERATURE,
|
|
256
|
+
deterministicJson: true,
|
|
251
257
|
params: [
|
|
252
258
|
{
|
|
253
259
|
name: 'language',
|
|
@@ -269,9 +275,10 @@ export const TOOL_CONTRACTS = [
|
|
|
269
275
|
purpose: 'Detect breaking API/interface changes in a diff.',
|
|
270
276
|
model: FLASH_MODEL,
|
|
271
277
|
timeoutMs: DEFAULT_TIMEOUT_FLASH_MS,
|
|
272
|
-
|
|
278
|
+
thinkingLevel: FLASH_TRIAGE_THINKING_LEVEL,
|
|
273
279
|
maxOutputTokens: FLASH_API_BREAKING_MAX_OUTPUT_TOKENS,
|
|
274
280
|
temperature: TRIAGE_TEMPERATURE,
|
|
281
|
+
deterministicJson: true,
|
|
275
282
|
params: [
|
|
276
283
|
{
|
|
277
284
|
name: 'language',
|
|
@@ -55,10 +55,10 @@ export interface StructuredToolTaskConfig<TInput extends object = Record<string,
|
|
|
55
55
|
transformResult?: (input: TInput, result: TResult, ctx: ToolExecutionContext) => TFinal;
|
|
56
56
|
/** Optional validation hook for input parameters. */
|
|
57
57
|
validateInput?: (input: TInput, ctx: ToolExecutionContext) => Promise<ReturnType<typeof createErrorToolResponse> | undefined> | ReturnType<typeof createErrorToolResponse> | undefined;
|
|
58
|
-
/** Optional Gemini model to use (e.g. 'gemini-
|
|
58
|
+
/** Optional Gemini model to use (e.g. 'gemini-3-pro-preview'). */
|
|
59
59
|
model?: string;
|
|
60
|
-
/** Optional thinking
|
|
61
|
-
|
|
60
|
+
/** Optional thinking level. */
|
|
61
|
+
thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';
|
|
62
62
|
/** Optional timeout in ms for the Gemini call. Defaults to 90,000 ms. Use DEFAULT_TIMEOUT_PRO_MS for Pro model calls. */
|
|
63
63
|
timeoutMs?: number;
|
|
64
64
|
/** Optional max output tokens for Gemini. */
|
|
@@ -72,6 +72,10 @@ export interface StructuredToolTaskConfig<TInput extends object = Record<string,
|
|
|
72
72
|
temperature?: number;
|
|
73
73
|
/** Optional opt-in to Gemini thought output. Defaults to false. */
|
|
74
74
|
includeThoughts?: boolean;
|
|
75
|
+
/** Optional deterministic JSON mode for stricter key ordering and repair prompting. */
|
|
76
|
+
deterministicJson?: boolean;
|
|
77
|
+
/** Optional batch execution mode. Defaults to runtime setting. */
|
|
78
|
+
batchMode?: 'off' | 'inline';
|
|
75
79
|
/** Optional formatter for human-readable text output. */
|
|
76
80
|
formatOutput?: (result: TFinal) => string;
|
|
77
81
|
/** Optional context text used in progress messages. */
|
|
@@ -81,6 +85,7 @@ export interface StructuredToolTaskConfig<TInput extends object = Record<string,
|
|
|
81
85
|
/** Builds the system instruction and user prompt from parsed tool input. */
|
|
82
86
|
buildPrompt: (input: TInput, ctx: ToolExecutionContext) => PromptParts;
|
|
83
87
|
}
|
|
88
|
+
export declare function summarizeSchemaValidationErrorForRetry(errorMessage: string): string;
|
|
84
89
|
export declare function wrapToolHandler<TInput, TResult extends CallToolResult>(options: {
|
|
85
90
|
toolName: string;
|
|
86
91
|
progressContext?: (input: TInput) => string;
|
package/dist/lib/tool-factory.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { DefaultOutputSchema } from '../schemas/outputs.js';
|
|
3
3
|
import { getDiff } from './diff-store.js';
|
|
4
|
+
import { createCachedEnvInt } from './env-config.js';
|
|
4
5
|
import { getErrorMessage, RETRYABLE_UPSTREAM_ERROR_PATTERN } from './errors.js';
|
|
5
6
|
import { stripJsonSchemaConstraints } from './gemini-schema.js';
|
|
6
7
|
import { generateStructuredJson, getCurrentRequestId } from './gemini.js';
|
|
@@ -14,6 +15,9 @@ const TIMEOUT_ERROR_PATTERN = /timed out|timeout/i;
|
|
|
14
15
|
const BUDGET_ERROR_PATTERN = /exceeds limit|max allowed size|input too large/i;
|
|
15
16
|
const BUSY_ERROR_PATTERN = /too many concurrent/i;
|
|
16
17
|
const MAX_SCHEMA_RETRIES = 1;
|
|
18
|
+
const DEFAULT_SCHEMA_RETRY_ERROR_CHARS = 1_500;
|
|
19
|
+
const schemaRetryErrorCharsConfig = createCachedEnvInt('MAX_SCHEMA_RETRY_ERROR_CHARS', DEFAULT_SCHEMA_RETRY_ERROR_CHARS);
|
|
20
|
+
const DETERMINISTIC_JSON_RETRY_NOTE = 'Deterministic JSON mode: keep key names exactly as schema-defined and preserve stable field ordering.';
|
|
17
21
|
function createGeminiResponseSchema(config) {
|
|
18
22
|
const sourceSchema = config.geminiSchema ?? config.resultSchema;
|
|
19
23
|
return stripJsonSchemaConstraints(z.toJSONSchema(sourceSchema));
|
|
@@ -21,6 +25,35 @@ function createGeminiResponseSchema(config) {
|
|
|
21
25
|
function parseToolInput(input, fullInputSchema) {
|
|
22
26
|
return fullInputSchema.parse(input);
|
|
23
27
|
}
|
|
28
|
+
function extractResponseKeyOrdering(responseSchema) {
|
|
29
|
+
const schemaType = responseSchema.type;
|
|
30
|
+
if (schemaType !== 'object') {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const { properties } = responseSchema;
|
|
34
|
+
if (typeof properties !== 'object' || properties === null) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return Object.keys(properties);
|
|
38
|
+
}
|
|
39
|
+
export function summarizeSchemaValidationErrorForRetry(errorMessage) {
|
|
40
|
+
const maxChars = Math.max(200, schemaRetryErrorCharsConfig.get());
|
|
41
|
+
const compact = errorMessage.replace(/\s+/g, ' ').trim();
|
|
42
|
+
if (compact.length <= maxChars) {
|
|
43
|
+
return compact;
|
|
44
|
+
}
|
|
45
|
+
return `${compact.slice(0, maxChars - 3)}...`;
|
|
46
|
+
}
|
|
47
|
+
function createSchemaRetryPrompt(prompt, errorMessage, deterministicJson) {
|
|
48
|
+
const summarizedError = summarizeSchemaValidationErrorForRetry(errorMessage);
|
|
49
|
+
const deterministicNote = deterministicJson
|
|
50
|
+
? `\n${DETERMINISTIC_JSON_RETRY_NOTE}`
|
|
51
|
+
: '';
|
|
52
|
+
return {
|
|
53
|
+
summarizedError,
|
|
54
|
+
prompt: `${prompt}\n\nCRITICAL: The previous response failed schema validation. Error: ${summarizedError}${deterministicNote}`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
24
57
|
function createGenerationRequest(config, promptParts, responseSchema, onLog, signal) {
|
|
25
58
|
const request = {
|
|
26
59
|
systemInstruction: promptParts.systemInstruction,
|
|
@@ -31,8 +64,8 @@ function createGenerationRequest(config, promptParts, responseSchema, onLog, sig
|
|
|
31
64
|
if (config.model !== undefined) {
|
|
32
65
|
request.model = config.model;
|
|
33
66
|
}
|
|
34
|
-
if (config.
|
|
35
|
-
request.
|
|
67
|
+
if (config.thinkingLevel !== undefined) {
|
|
68
|
+
request.thinkingLevel = config.thinkingLevel;
|
|
36
69
|
}
|
|
37
70
|
if (config.timeoutMs !== undefined) {
|
|
38
71
|
request.timeoutMs = config.timeoutMs;
|
|
@@ -46,13 +79,23 @@ function createGenerationRequest(config, promptParts, responseSchema, onLog, sig
|
|
|
46
79
|
if (config.includeThoughts !== undefined) {
|
|
47
80
|
request.includeThoughts = config.includeThoughts;
|
|
48
81
|
}
|
|
82
|
+
if (config.deterministicJson) {
|
|
83
|
+
const responseKeyOrdering = extractResponseKeyOrdering(responseSchema);
|
|
84
|
+
if (responseKeyOrdering !== undefined) {
|
|
85
|
+
request.responseKeyOrdering = responseKeyOrdering;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (config.batchMode !== undefined) {
|
|
89
|
+
request.batchMode = config.batchMode;
|
|
90
|
+
}
|
|
49
91
|
if (signal !== undefined) {
|
|
50
92
|
request.signal = signal;
|
|
51
93
|
}
|
|
52
94
|
return request;
|
|
53
95
|
}
|
|
96
|
+
const VALIDATION_ERROR_PATTERN = /validation/i;
|
|
54
97
|
function classifyErrorMeta(error, message) {
|
|
55
|
-
if (error instanceof z.ZodError ||
|
|
98
|
+
if (error instanceof z.ZodError || VALIDATION_ERROR_PATTERN.test(message)) {
|
|
56
99
|
return {
|
|
57
100
|
kind: 'validation',
|
|
58
101
|
retryable: false,
|
|
@@ -341,11 +384,16 @@ export function registerStructuredToolTask(server, config) {
|
|
|
341
384
|
throw error;
|
|
342
385
|
}
|
|
343
386
|
const errorMessage = getErrorMessage(error);
|
|
387
|
+
const schemaRetryPrompt = createSchemaRetryPrompt(prompt, errorMessage, config.deterministicJson === true);
|
|
344
388
|
await onLog('warning', {
|
|
345
389
|
event: 'schema_validation_failed',
|
|
346
|
-
details: {
|
|
390
|
+
details: {
|
|
391
|
+
attempt,
|
|
392
|
+
error: schemaRetryPrompt.summarizedError,
|
|
393
|
+
originalChars: errorMessage.length,
|
|
394
|
+
},
|
|
347
395
|
});
|
|
348
|
-
retryPrompt =
|
|
396
|
+
retryPrompt = schemaRetryPrompt.prompt;
|
|
349
397
|
}
|
|
350
398
|
}
|
|
351
399
|
if (!parsed) {
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
export type JsonObject = Record<string, unknown>;
|
|
2
2
|
export type GeminiLogHandler = (level: string, data: unknown) => Promise<void>;
|
|
3
|
+
export interface GeminiFunctionCallingContext {
|
|
4
|
+
readonly modelParts: readonly unknown[];
|
|
5
|
+
}
|
|
3
6
|
export interface GeminiRequestExecutionOptions {
|
|
4
7
|
maxRetries?: number;
|
|
5
8
|
timeoutMs?: number;
|
|
6
9
|
temperature?: number;
|
|
7
10
|
maxOutputTokens?: number;
|
|
8
|
-
|
|
11
|
+
thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';
|
|
9
12
|
includeThoughts?: boolean;
|
|
10
13
|
signal?: AbortSignal;
|
|
11
14
|
onLog?: GeminiLogHandler;
|
|
15
|
+
responseKeyOrdering?: readonly string[];
|
|
16
|
+
functionCallingContext?: GeminiFunctionCallingContext;
|
|
17
|
+
batchMode?: 'off' | 'inline';
|
|
12
18
|
}
|
|
13
19
|
export interface GeminiStructuredRequestOptions extends GeminiRequestExecutionOptions {
|
|
14
20
|
model?: string;
|
package/dist/prompts/index.js
CHANGED
|
@@ -43,9 +43,9 @@ function getToolGuide(tool) {
|
|
|
43
43
|
if (!contract) {
|
|
44
44
|
return `Use \`${tool}\` to analyze your code changes.`;
|
|
45
45
|
}
|
|
46
|
-
const {
|
|
47
|
-
const modelLine =
|
|
48
|
-
? `Model: ${contract.model} (thinking
|
|
46
|
+
const { thinkingLevel } = contract;
|
|
47
|
+
const modelLine = thinkingLevel !== undefined
|
|
48
|
+
? `Model: ${contract.model} (thinking level ${thinkingLevel}, output cap ${contract.maxOutputTokens}).`
|
|
49
49
|
: `Model: ${contract.model} (output cap ${contract.maxOutputTokens}).`;
|
|
50
50
|
return `Tool: ${contract.name}\n${modelLine}\nOutput: ${contract.outputShape}\nUse: ${contract.purpose}`;
|
|
51
51
|
}
|
|
@@ -23,9 +23,9 @@ function formatToolSection(contract) {
|
|
|
23
23
|
${parameterLines.join('\n')}
|
|
24
24
|
- Output shape: \`${contract.outputShape}\``;
|
|
25
25
|
}
|
|
26
|
-
const thinkingLine = contract.
|
|
27
|
-
? '- Thinking
|
|
28
|
-
: `- Thinking
|
|
26
|
+
const thinkingLine = contract.thinkingLevel === undefined
|
|
27
|
+
? '- Thinking level: disabled'
|
|
28
|
+
: `- Thinking level: ${contract.thinkingLevel}`;
|
|
29
29
|
return `### \`${contract.name}\`
|
|
30
30
|
- Purpose: ${contract.purpose}
|
|
31
31
|
- Model: \`${contract.model}\`
|