@agile-vibe-coding/avc 0.2.3 → 0.3.2
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 +475 -3
- package/cli/agents/agent-selector.md +23 -0
- package/cli/agents/code-implementer.md +117 -0
- package/cli/agents/code-validator.md +80 -0
- package/cli/agents/context-reviewer-epic.md +101 -0
- package/cli/agents/context-reviewer-story.md +92 -0
- package/cli/agents/context-writer-epic.md +145 -0
- package/cli/agents/context-writer-story.md +111 -0
- package/cli/agents/doc-writer-epic.md +42 -0
- package/cli/agents/doc-writer-story.md +43 -0
- package/cli/agents/duplicate-detector.md +110 -0
- package/cli/agents/epic-story-decomposer.md +318 -39
- package/cli/agents/mission-scope-generator.md +68 -4
- package/cli/agents/mission-scope-validator.md +40 -6
- package/cli/agents/project-context-extractor.md +21 -6
- package/cli/agents/scaffolding-generator.md +99 -0
- package/cli/agents/seed-validator.md +71 -0
- package/cli/agents/story-scope-reviewer.md +147 -0
- package/cli/agents/story-splitter.md +83 -0
- package/cli/agents/validator-documentation.json +31 -0
- package/cli/agents/validator-documentation.md +3 -1
- package/cli/api-reference-tool.js +368 -0
- package/cli/checks/catalog.json +76 -0
- package/cli/checks/code/quality.json +26 -0
- package/cli/checks/code/testing.json +14 -0
- package/cli/checks/code/traceability.json +26 -0
- package/cli/checks/cross-refs/epic.json +171 -0
- package/cli/checks/cross-refs/story.json +149 -0
- package/cli/checks/epic/api.json +114 -0
- package/cli/checks/epic/backend.json +126 -0
- package/cli/checks/epic/cloud.json +126 -0
- package/cli/checks/epic/data.json +102 -0
- package/cli/checks/epic/database.json +114 -0
- package/cli/checks/epic/developer.json +182 -0
- package/cli/checks/epic/devops.json +174 -0
- package/cli/checks/epic/frontend.json +162 -0
- package/cli/checks/epic/mobile.json +102 -0
- package/cli/checks/epic/qa.json +90 -0
- package/cli/checks/epic/security.json +184 -0
- package/cli/checks/epic/solution-architect.json +192 -0
- package/cli/checks/epic/test-architect.json +90 -0
- package/cli/checks/epic/ui.json +102 -0
- package/cli/checks/epic/ux.json +90 -0
- package/cli/checks/fixes/epic-fix-template.md +10 -0
- package/cli/checks/fixes/story-fix-template.md +10 -0
- package/cli/checks/story/api.json +186 -0
- package/cli/checks/story/backend.json +102 -0
- package/cli/checks/story/cloud.json +102 -0
- package/cli/checks/story/data.json +210 -0
- package/cli/checks/story/database.json +102 -0
- package/cli/checks/story/developer.json +168 -0
- package/cli/checks/story/devops.json +102 -0
- package/cli/checks/story/frontend.json +174 -0
- package/cli/checks/story/mobile.json +102 -0
- package/cli/checks/story/qa.json +210 -0
- package/cli/checks/story/security.json +198 -0
- package/cli/checks/story/solution-architect.json +230 -0
- package/cli/checks/story/test-architect.json +210 -0
- package/cli/checks/story/ui.json +102 -0
- package/cli/checks/story/ux.json +102 -0
- package/cli/coding-order.js +401 -0
- package/cli/dependency-checker.js +72 -0
- package/cli/epic-story-validator.js +284 -799
- package/cli/index.js +0 -0
- package/cli/init-model-config.js +17 -10
- package/cli/init.js +514 -92
- package/cli/kanban-server-manager.js +1 -2
- package/cli/llm-claude.js +98 -31
- package/cli/llm-gemini.js +29 -5
- package/cli/llm-local.js +493 -0
- package/cli/llm-openai.js +262 -41
- package/cli/llm-provider.js +147 -8
- package/cli/llm-token-limits.js +113 -4
- package/cli/llm-verifier.js +209 -1
- package/cli/llm-xiaomi.js +143 -0
- package/cli/message-constants.js +3 -12
- package/cli/messaging-api.js +6 -12
- package/cli/micro-check-fixer.js +335 -0
- package/cli/micro-check-runner.js +449 -0
- package/cli/micro-check-scorer.js +148 -0
- package/cli/micro-check-validator.js +538 -0
- package/cli/model-pricing.js +23 -0
- package/cli/model-selector.js +3 -2
- package/cli/prompt-logger.js +57 -0
- package/cli/repl-ink.js +106 -346
- package/cli/repl-old.js +1 -2
- package/cli/seed-processor.js +194 -24
- package/cli/sprint-planning-processor.js +2638 -289
- package/cli/template-processor.js +50 -3
- package/cli/token-tracker.js +50 -23
- package/cli/tools/generate-story-validators.js +1 -1
- package/cli/validation-router.js +70 -8
- package/cli/worktree-runner.js +654 -0
- package/kanban/client/dist/assets/index-D_KC5EQT.css +1 -0
- package/kanban/client/dist/assets/index-DjY5zqW7.js +351 -0
- package/kanban/client/dist/index.html +2 -2
- package/kanban/client/src/App.jsx +43 -14
- package/kanban/client/src/components/ceremony/AskArchPopup.jsx +7 -3
- package/kanban/client/src/components/ceremony/AskModelPopup.jsx +23 -10
- package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +320 -133
- package/kanban/client/src/components/ceremony/ProviderSwitcherButton.jsx +290 -0
- package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +80 -13
- package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +156 -22
- package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +11 -11
- package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +3 -21
- package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +214 -10
- package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +23 -2
- package/kanban/client/src/components/kanban/CardDetailModal.jsx +97 -10
- package/kanban/client/src/components/kanban/GroupingSelector.jsx +7 -1
- package/kanban/client/src/components/kanban/KanbanCard.jsx +23 -14
- package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +9 -14
- package/kanban/client/src/components/kanban/RunButton.jsx +162 -0
- package/kanban/client/src/components/kanban/SeedButton.jsx +176 -0
- package/kanban/client/src/components/settings/AgentsTab.jsx +103 -75
- package/kanban/client/src/components/settings/ApiKeysTab.jsx +31 -2
- package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +9 -2
- package/kanban/client/src/components/settings/CheckEditorPopup.jsx +507 -0
- package/kanban/client/src/components/settings/CostThresholdsTab.jsx +3 -2
- package/kanban/client/src/components/settings/ModelPricingTab.jsx +72 -7
- package/kanban/client/src/components/settings/OpenAIAuthSection.jsx +412 -0
- package/kanban/client/src/components/settings/SettingsModal.jsx +4 -4
- package/kanban/client/src/components/stats/CostModal.jsx +34 -3
- package/kanban/client/src/hooks/useGrouping.js +59 -0
- package/kanban/client/src/lib/api.js +118 -4
- package/kanban/client/src/lib/status-grouping.js +10 -0
- package/kanban/client/src/store/kanbanStore.js +8 -0
- package/kanban/server/index.js +23 -2
- package/kanban/server/routes/ceremony.js +153 -4
- package/kanban/server/routes/costs.js +9 -3
- package/kanban/server/routes/openai-oauth.js +366 -0
- package/kanban/server/routes/settings.js +447 -14
- package/kanban/server/routes/websocket.js +7 -2
- package/kanban/server/routes/work-items.js +141 -1
- package/kanban/server/services/CeremonyService.js +275 -24
- package/kanban/server/services/TaskRunnerService.js +261 -0
- package/kanban/server/workers/run-task-worker.js +121 -0
- package/kanban/server/workers/seed-worker.js +94 -0
- package/kanban/server/workers/sponsor-call-worker.js +14 -6
- package/kanban/server/workers/sprint-planning-worker.js +94 -12
- package/package.json +2 -3
- package/cli/agents/solver-epic-api.json +0 -15
- package/cli/agents/solver-epic-api.md +0 -39
- package/cli/agents/solver-epic-backend.json +0 -15
- package/cli/agents/solver-epic-backend.md +0 -39
- package/cli/agents/solver-epic-cloud.json +0 -15
- package/cli/agents/solver-epic-cloud.md +0 -39
- package/cli/agents/solver-epic-data.json +0 -15
- package/cli/agents/solver-epic-data.md +0 -39
- package/cli/agents/solver-epic-database.json +0 -15
- package/cli/agents/solver-epic-database.md +0 -39
- package/cli/agents/solver-epic-developer.json +0 -15
- package/cli/agents/solver-epic-developer.md +0 -39
- package/cli/agents/solver-epic-devops.json +0 -15
- package/cli/agents/solver-epic-devops.md +0 -39
- package/cli/agents/solver-epic-frontend.json +0 -15
- package/cli/agents/solver-epic-frontend.md +0 -39
- package/cli/agents/solver-epic-mobile.json +0 -15
- package/cli/agents/solver-epic-mobile.md +0 -39
- package/cli/agents/solver-epic-qa.json +0 -15
- package/cli/agents/solver-epic-qa.md +0 -39
- package/cli/agents/solver-epic-security.json +0 -15
- package/cli/agents/solver-epic-security.md +0 -39
- package/cli/agents/solver-epic-solution-architect.json +0 -15
- package/cli/agents/solver-epic-solution-architect.md +0 -39
- package/cli/agents/solver-epic-test-architect.json +0 -15
- package/cli/agents/solver-epic-test-architect.md +0 -39
- package/cli/agents/solver-epic-ui.json +0 -15
- package/cli/agents/solver-epic-ui.md +0 -39
- package/cli/agents/solver-epic-ux.json +0 -15
- package/cli/agents/solver-epic-ux.md +0 -39
- package/cli/agents/solver-story-api.json +0 -15
- package/cli/agents/solver-story-api.md +0 -39
- package/cli/agents/solver-story-backend.json +0 -15
- package/cli/agents/solver-story-backend.md +0 -39
- package/cli/agents/solver-story-cloud.json +0 -15
- package/cli/agents/solver-story-cloud.md +0 -39
- package/cli/agents/solver-story-data.json +0 -15
- package/cli/agents/solver-story-data.md +0 -39
- package/cli/agents/solver-story-database.json +0 -15
- package/cli/agents/solver-story-database.md +0 -39
- package/cli/agents/solver-story-developer.json +0 -15
- package/cli/agents/solver-story-developer.md +0 -39
- package/cli/agents/solver-story-devops.json +0 -15
- package/cli/agents/solver-story-devops.md +0 -39
- package/cli/agents/solver-story-frontend.json +0 -15
- package/cli/agents/solver-story-frontend.md +0 -39
- package/cli/agents/solver-story-mobile.json +0 -15
- package/cli/agents/solver-story-mobile.md +0 -39
- package/cli/agents/solver-story-qa.json +0 -15
- package/cli/agents/solver-story-qa.md +0 -39
- package/cli/agents/solver-story-security.json +0 -15
- package/cli/agents/solver-story-security.md +0 -39
- package/cli/agents/solver-story-solution-architect.json +0 -15
- package/cli/agents/solver-story-solution-architect.md +0 -39
- package/cli/agents/solver-story-test-architect.json +0 -15
- package/cli/agents/solver-story-test-architect.md +0 -39
- package/cli/agents/solver-story-ui.json +0 -15
- package/cli/agents/solver-story-ui.md +0 -39
- package/cli/agents/solver-story-ux.json +0 -15
- package/cli/agents/solver-story-ux.md +0 -39
- package/cli/agents/validator-epic-api.json +0 -93
- package/cli/agents/validator-epic-api.md +0 -137
- package/cli/agents/validator-epic-backend.json +0 -93
- package/cli/agents/validator-epic-backend.md +0 -130
- package/cli/agents/validator-epic-cloud.json +0 -93
- package/cli/agents/validator-epic-cloud.md +0 -137
- package/cli/agents/validator-epic-data.json +0 -93
- package/cli/agents/validator-epic-data.md +0 -130
- package/cli/agents/validator-epic-database.json +0 -93
- package/cli/agents/validator-epic-database.md +0 -137
- package/cli/agents/validator-epic-developer.json +0 -74
- package/cli/agents/validator-epic-developer.md +0 -153
- package/cli/agents/validator-epic-devops.json +0 -74
- package/cli/agents/validator-epic-devops.md +0 -153
- package/cli/agents/validator-epic-frontend.json +0 -74
- package/cli/agents/validator-epic-frontend.md +0 -153
- package/cli/agents/validator-epic-mobile.json +0 -93
- package/cli/agents/validator-epic-mobile.md +0 -130
- package/cli/agents/validator-epic-qa.json +0 -93
- package/cli/agents/validator-epic-qa.md +0 -130
- package/cli/agents/validator-epic-security.json +0 -74
- package/cli/agents/validator-epic-security.md +0 -154
- package/cli/agents/validator-epic-solution-architect.json +0 -74
- package/cli/agents/validator-epic-solution-architect.md +0 -156
- package/cli/agents/validator-epic-test-architect.json +0 -93
- package/cli/agents/validator-epic-test-architect.md +0 -130
- package/cli/agents/validator-epic-ui.json +0 -93
- package/cli/agents/validator-epic-ui.md +0 -130
- package/cli/agents/validator-epic-ux.json +0 -93
- package/cli/agents/validator-epic-ux.md +0 -130
- package/cli/agents/validator-story-api.json +0 -104
- package/cli/agents/validator-story-api.md +0 -152
- package/cli/agents/validator-story-backend.json +0 -104
- package/cli/agents/validator-story-backend.md +0 -152
- package/cli/agents/validator-story-cloud.json +0 -104
- package/cli/agents/validator-story-cloud.md +0 -152
- package/cli/agents/validator-story-data.json +0 -104
- package/cli/agents/validator-story-data.md +0 -152
- package/cli/agents/validator-story-database.json +0 -104
- package/cli/agents/validator-story-database.md +0 -152
- package/cli/agents/validator-story-developer.json +0 -104
- package/cli/agents/validator-story-developer.md +0 -152
- package/cli/agents/validator-story-devops.json +0 -104
- package/cli/agents/validator-story-devops.md +0 -152
- package/cli/agents/validator-story-frontend.json +0 -104
- package/cli/agents/validator-story-frontend.md +0 -152
- package/cli/agents/validator-story-mobile.json +0 -104
- package/cli/agents/validator-story-mobile.md +0 -152
- package/cli/agents/validator-story-qa.json +0 -104
- package/cli/agents/validator-story-qa.md +0 -152
- package/cli/agents/validator-story-security.json +0 -104
- package/cli/agents/validator-story-security.md +0 -152
- package/cli/agents/validator-story-solution-architect.json +0 -104
- package/cli/agents/validator-story-solution-architect.md +0 -152
- package/cli/agents/validator-story-test-architect.json +0 -104
- package/cli/agents/validator-story-test-architect.md +0 -152
- package/cli/agents/validator-story-ui.json +0 -104
- package/cli/agents/validator-story-ui.md +0 -152
- package/cli/agents/validator-story-ux.json +0 -104
- package/cli/agents/validator-story-ux.md +0 -152
- package/kanban/client/dist/assets/index-CiD8PS2e.js +0 -306
- package/kanban/client/dist/assets/index-nLh0m82Q.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { exec } from 'child_process';
|
|
1
|
+
import { exec, execSync } from 'child_process';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
@@ -150,7 +150,6 @@ export class KanbanServerManager {
|
|
|
150
150
|
if (pid && !isNaN(pid)) {
|
|
151
151
|
// Try to get process name
|
|
152
152
|
try {
|
|
153
|
-
const { execSync } = require('child_process');
|
|
154
153
|
const psOutput = execSync(`ps -p ${pid} -o comm=`, { encoding: 'utf8' });
|
|
155
154
|
return { pid, command: psOutput.trim() };
|
|
156
155
|
} catch {
|
package/cli/llm-claude.js
CHANGED
|
@@ -30,43 +30,86 @@ export class ClaudeProvider extends LLMProvider {
|
|
|
30
30
|
return response.content[0].text;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
async generateJSON(prompt, agentInstructions = null) {
|
|
33
|
+
async generateJSON(prompt, agentInstructions = null, cachedContext = null) {
|
|
34
34
|
if (!this._client) {
|
|
35
35
|
this._client = this._createClient();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const fullPrompt = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
39
|
-
|
|
40
38
|
// Use model-specific maximum tokens
|
|
41
39
|
const maxTokens = getMaxTokensForModel(this.model);
|
|
42
40
|
|
|
41
|
+
const JSON_SYSTEM = 'You are a helpful assistant that always returns valid JSON. Your response must be a valid JSON object or array, nothing else.';
|
|
42
|
+
|
|
43
|
+
let systemParam;
|
|
44
|
+
let userContent;
|
|
45
|
+
|
|
46
|
+
if (cachedContext) {
|
|
47
|
+
// Structured content blocks: cache_control on agentInstructions (system) and
|
|
48
|
+
// cachedContext (first user block) — both stay stable across multiple calls
|
|
49
|
+
// in the same ceremony, hitting the 5-min cache on subsequent validators.
|
|
50
|
+
systemParam = agentInstructions
|
|
51
|
+
? [
|
|
52
|
+
{ type: 'text', text: JSON_SYSTEM },
|
|
53
|
+
{ type: 'text', text: agentInstructions, cache_control: { type: 'ephemeral' } },
|
|
54
|
+
]
|
|
55
|
+
: [{ type: 'text', text: JSON_SYSTEM }];
|
|
56
|
+
|
|
57
|
+
userContent = [
|
|
58
|
+
{ type: 'text', text: cachedContext, cache_control: { type: 'ephemeral' } },
|
|
59
|
+
{ type: 'text', text: prompt },
|
|
60
|
+
];
|
|
61
|
+
} else {
|
|
62
|
+
systemParam = JSON_SYSTEM;
|
|
63
|
+
userContent = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const requestParams = {
|
|
67
|
+
model: this.model,
|
|
68
|
+
max_tokens: maxTokens,
|
|
69
|
+
system: systemParam,
|
|
70
|
+
messages: [{ role: 'user', content: userContent }],
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const fullPrompt = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
74
|
+
|
|
75
|
+
const _t0Json = Date.now();
|
|
43
76
|
const response = await this._withRetry(
|
|
44
|
-
() => this._client.messages.create(
|
|
45
|
-
model: this.model,
|
|
46
|
-
max_tokens: maxTokens,
|
|
47
|
-
messages: [{
|
|
48
|
-
role: 'user',
|
|
49
|
-
content: fullPrompt
|
|
50
|
-
}],
|
|
51
|
-
system: 'You are a helpful assistant that always returns valid JSON. Your response must be a valid JSON object or array, nothing else.'
|
|
52
|
-
}),
|
|
77
|
+
() => this._client.messages.create(requestParams),
|
|
53
78
|
'JSON generation (Claude)'
|
|
54
79
|
);
|
|
55
80
|
|
|
56
|
-
this._trackTokens(response.usage);
|
|
57
81
|
const content = response.content[0].text;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
this._trackTokens(response.usage, {
|
|
83
|
+
prompt: fullPrompt,
|
|
84
|
+
agentInstructions: agentInstructions ?? null,
|
|
85
|
+
response: content,
|
|
86
|
+
elapsed: Date.now() - _t0Json,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Extract JSON from response (handle markdown code blocks and preamble text)
|
|
61
90
|
let jsonStr = content.trim();
|
|
91
|
+
|
|
92
|
+
// Strip markdown code fences if the response starts with one
|
|
62
93
|
if (jsonStr.startsWith('```')) {
|
|
63
|
-
// Remove opening fence (```json or ```)
|
|
64
94
|
jsonStr = jsonStr.replace(/^```(?:json)?\s*\n?/, '');
|
|
65
|
-
// Remove closing fence
|
|
66
95
|
jsonStr = jsonStr.replace(/\n?\s*```\s*$/, '');
|
|
67
96
|
jsonStr = jsonStr.trim();
|
|
68
97
|
}
|
|
69
98
|
|
|
99
|
+
// If model added reasoning preamble before JSON, find the first { or [ and extract from there.
|
|
100
|
+
// This handles Claude responses like "I'll analyze...\n\n```json\n{...}\n```" or "Here is the JSON:\n{...}"
|
|
101
|
+
if (!jsonStr.startsWith('{') && !jsonStr.startsWith('[')) {
|
|
102
|
+
const firstBrace = jsonStr.indexOf('{');
|
|
103
|
+
const firstBracket = jsonStr.indexOf('[');
|
|
104
|
+
const jsonStart = firstBrace === -1 ? firstBracket
|
|
105
|
+
: firstBracket === -1 ? firstBrace
|
|
106
|
+
: Math.min(firstBrace, firstBracket);
|
|
107
|
+
if (jsonStart > 0) {
|
|
108
|
+
// Also strip trailing markdown fences that may follow the JSON block
|
|
109
|
+
jsonStr = jsonStr.slice(jsonStart).replace(/\n?\s*```\s*$/, '').trim();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
70
113
|
try {
|
|
71
114
|
return JSON.parse(jsonStr);
|
|
72
115
|
} catch (firstError) {
|
|
@@ -81,29 +124,53 @@ export class ClaudeProvider extends LLMProvider {
|
|
|
81
124
|
}
|
|
82
125
|
}
|
|
83
126
|
|
|
84
|
-
async generateText(prompt, agentInstructions = null) {
|
|
127
|
+
async generateText(prompt, agentInstructions = null, cachedContext = null) {
|
|
85
128
|
if (!this._client) {
|
|
86
129
|
this._client = this._createClient();
|
|
87
130
|
}
|
|
88
131
|
|
|
89
|
-
const fullPrompt = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
90
|
-
|
|
91
132
|
// Use model-specific maximum tokens
|
|
92
133
|
const maxTokens = getMaxTokensForModel(this.model);
|
|
93
134
|
|
|
135
|
+
let systemParam;
|
|
136
|
+
let userContent;
|
|
137
|
+
|
|
138
|
+
if (cachedContext) {
|
|
139
|
+
systemParam = agentInstructions
|
|
140
|
+
? [
|
|
141
|
+
{ type: 'text', text: agentInstructions, cache_control: { type: 'ephemeral' } },
|
|
142
|
+
]
|
|
143
|
+
: undefined;
|
|
144
|
+
userContent = [
|
|
145
|
+
{ type: 'text', text: cachedContext, cache_control: { type: 'ephemeral' } },
|
|
146
|
+
{ type: 'text', text: prompt },
|
|
147
|
+
];
|
|
148
|
+
} else {
|
|
149
|
+
userContent = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const requestParams = {
|
|
153
|
+
model: this.model,
|
|
154
|
+
max_tokens: maxTokens,
|
|
155
|
+
messages: [{ role: 'user', content: userContent }],
|
|
156
|
+
};
|
|
157
|
+
if (systemParam) requestParams.system = systemParam;
|
|
158
|
+
|
|
159
|
+
const fullPrompt = agentInstructions ? `${agentInstructions}\n\n${prompt}` : prompt;
|
|
160
|
+
|
|
161
|
+
const _t0Text = Date.now();
|
|
94
162
|
const response = await this._withRetry(
|
|
95
|
-
() => this._client.messages.create(
|
|
96
|
-
model: this.model,
|
|
97
|
-
max_tokens: maxTokens,
|
|
98
|
-
messages: [{
|
|
99
|
-
role: 'user',
|
|
100
|
-
content: fullPrompt
|
|
101
|
-
}]
|
|
102
|
-
}),
|
|
163
|
+
() => this._client.messages.create(requestParams),
|
|
103
164
|
'Text generation (Claude)'
|
|
104
165
|
);
|
|
105
166
|
|
|
106
|
-
|
|
107
|
-
|
|
167
|
+
const text = response.content[0].text;
|
|
168
|
+
this._trackTokens(response.usage, {
|
|
169
|
+
prompt: fullPrompt,
|
|
170
|
+
agentInstructions: agentInstructions ?? null,
|
|
171
|
+
response: text,
|
|
172
|
+
elapsed: Date.now() - _t0Text,
|
|
173
|
+
});
|
|
174
|
+
return text;
|
|
108
175
|
}
|
|
109
176
|
}
|
package/cli/llm-gemini.js
CHANGED
|
@@ -31,7 +31,7 @@ export class GeminiProvider extends LLMProvider {
|
|
|
31
31
|
return response.text;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
async generateJSON(prompt, agentInstructions = null) {
|
|
34
|
+
async generateJSON(prompt, agentInstructions = null, cachedContext = null) {
|
|
35
35
|
if (!this._client) {
|
|
36
36
|
this._client = this._createClient();
|
|
37
37
|
}
|
|
@@ -50,6 +50,14 @@ export class GeminiProvider extends LLMProvider {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
// When cachedContext is provided (e.g. project rootContextMd), set it as the
|
|
54
|
+
// systemInstruction — Gemini's implicit caching targets system instructions and
|
|
55
|
+
// stable prefix content, giving a best-effort discount with no extra setup.
|
|
56
|
+
if (cachedContext) {
|
|
57
|
+
params.systemInstruction = cachedContext;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const _t0Json = Date.now();
|
|
53
61
|
const response = await this._withRetry(
|
|
54
62
|
() => this._client.models.generateContent(params),
|
|
55
63
|
'JSON generation (Gemini)'
|
|
@@ -58,8 +66,13 @@ export class GeminiProvider extends LLMProvider {
|
|
|
58
66
|
throw new Error('Gemini returned no text (possible safety filter block).');
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
this._trackTokens(response.usageMetadata);
|
|
62
69
|
const content = response.text;
|
|
70
|
+
this._trackTokens(response.usageMetadata, {
|
|
71
|
+
prompt: fullPrompt,
|
|
72
|
+
agentInstructions: agentInstructions ?? null,
|
|
73
|
+
response: content,
|
|
74
|
+
elapsed: Date.now() - _t0Json,
|
|
75
|
+
});
|
|
63
76
|
|
|
64
77
|
// Strip markdown code fences if present (more robust)
|
|
65
78
|
let jsonStr = content.trim();
|
|
@@ -83,7 +96,7 @@ export class GeminiProvider extends LLMProvider {
|
|
|
83
96
|
}
|
|
84
97
|
}
|
|
85
98
|
|
|
86
|
-
async generateText(prompt, agentInstructions = null) {
|
|
99
|
+
async generateText(prompt, agentInstructions = null, cachedContext = null) {
|
|
87
100
|
if (!this._client) {
|
|
88
101
|
this._client = this._createClient();
|
|
89
102
|
}
|
|
@@ -101,6 +114,11 @@ export class GeminiProvider extends LLMProvider {
|
|
|
101
114
|
}
|
|
102
115
|
};
|
|
103
116
|
|
|
117
|
+
if (cachedContext) {
|
|
118
|
+
params.systemInstruction = cachedContext;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const _t0Text = Date.now();
|
|
104
122
|
const response = await this._withRetry(
|
|
105
123
|
() => this._client.models.generateContent(params),
|
|
106
124
|
'Text generation (Gemini)'
|
|
@@ -109,7 +127,13 @@ export class GeminiProvider extends LLMProvider {
|
|
|
109
127
|
throw new Error('Gemini returned no text (possible safety filter block).');
|
|
110
128
|
}
|
|
111
129
|
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
const text = response.text;
|
|
131
|
+
this._trackTokens(response.usageMetadata, {
|
|
132
|
+
prompt: fullPrompt,
|
|
133
|
+
agentInstructions: agentInstructions ?? null,
|
|
134
|
+
response: text,
|
|
135
|
+
elapsed: Date.now() - _t0Text,
|
|
136
|
+
});
|
|
137
|
+
return text;
|
|
114
138
|
}
|
|
115
139
|
}
|