vigthoria-cli 1.11.0 → 1.11.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/dist/commands/chat.js
CHANGED
|
@@ -13,7 +13,7 @@ import { TaskDisplay } from '../utils/task-display.js';
|
|
|
13
13
|
import { ProjectMemoryService } from '../utils/project-memory.js';
|
|
14
14
|
import { buildPersonaOverlay, normalizePersonaMode } from '../utils/persona.js';
|
|
15
15
|
import { runAgentSessionMenu, shouldShowAgentSessionMenu } from './agent-session-menu.js';
|
|
16
|
-
import { evaluateExecutorSuccess, handleTaskEvent, noteAnalysisToolUse, } from '../utils/agentRunOutcome.js';
|
|
16
|
+
import { createLiveOutcome, evaluateExecutorSuccess, handleTaskEvent, noteAnalysisToolUse, } from '../utils/agentRunOutcome.js';
|
|
17
17
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
18
18
|
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS;
|
|
19
19
|
if (!rawValue) {
|
|
@@ -2368,20 +2368,11 @@ export class ChatCommand {
|
|
|
2368
2368
|
}).start();
|
|
2369
2369
|
// Live run telemetry, used both for the final summary block and for /retry, /continue.
|
|
2370
2370
|
const liveOutcome = {
|
|
2371
|
-
|
|
2372
|
-
tasksTotal: 0,
|
|
2373
|
-
failedTaskIds: new Set(),
|
|
2371
|
+
...createLiveOutcome(),
|
|
2374
2372
|
unfinishedTaskIds: new Set(),
|
|
2375
2373
|
qualityScore: null,
|
|
2376
2374
|
qualityMissing: [],
|
|
2377
2375
|
qualityBlockers: [],
|
|
2378
|
-
plannerError: null,
|
|
2379
|
-
executorError: null,
|
|
2380
|
-
executorFailed: false,
|
|
2381
|
-
analysisToolsUsed: 0,
|
|
2382
|
-
changedFileCount: 0,
|
|
2383
|
-
requiresWorkspaceChanges: false,
|
|
2384
|
-
workspaceHasOutput: false,
|
|
2385
2376
|
};
|
|
2386
2377
|
const parsePlannerSummary = (raw) => {
|
|
2387
2378
|
if (!raw || typeof raw !== 'string')
|
|
@@ -2498,7 +2489,7 @@ export class ChatCommand {
|
|
|
2498
2489
|
else if (event.type === 'executor_complete') {
|
|
2499
2490
|
const summary = event.summary || {};
|
|
2500
2491
|
handleTaskEvent(summary, liveOutcome);
|
|
2501
|
-
if (summary.status === 'failed') {
|
|
2492
|
+
if (summary.status === 'failed' || summary.status === 'stalled_error') {
|
|
2502
2493
|
const err = typeof summary.error === 'string' ? summary.error.trim() : '';
|
|
2503
2494
|
if (err && !liveOutcome.executorError)
|
|
2504
2495
|
liveOutcome.executorError = err;
|
|
@@ -2510,6 +2501,10 @@ export class ChatCommand {
|
|
|
2510
2501
|
noteAnalysisToolUse(toolName, liveOutcome);
|
|
2511
2502
|
}
|
|
2512
2503
|
else if (event.type === 'complete') {
|
|
2504
|
+
const tt = Number(event.tasks_total);
|
|
2505
|
+
if (Number.isFinite(tt) && tt > 0) {
|
|
2506
|
+
liveOutcome.tasksTotal = tt;
|
|
2507
|
+
}
|
|
2513
2508
|
if (Number(event.discovery_tools_used) > 0) {
|
|
2514
2509
|
liveOutcome.analysisToolsUsed = Math.max(liveOutcome.analysisToolsUsed, Number(event.discovery_tools_used));
|
|
2515
2510
|
}
|
|
@@ -2589,20 +2584,7 @@ export class ChatCommand {
|
|
|
2589
2584
|
if (!this.jsonOutput && previewGate?.required && previewGate?.passed !== true && workspaceHasOutput) {
|
|
2590
2585
|
console.log(chalk.yellow(`Template Service preview gate did not fully validate this output, but generated workspace files were preserved${previewGate?.error ? `: ${previewGate.error}` : '.'}`));
|
|
2591
2586
|
}
|
|
2592
|
-
if (this.
|
|
2593
|
-
console.log(JSON.stringify({
|
|
2594
|
-
success,
|
|
2595
|
-
mode: 'agent',
|
|
2596
|
-
model: routingPolicy.selectedModel,
|
|
2597
|
-
routingPolicy,
|
|
2598
|
-
taskId: response.taskId || null,
|
|
2599
|
-
contextId: response.contextId || null,
|
|
2600
|
-
partial: response.partial === true,
|
|
2601
|
-
content: response.content || 'V3 agent workflow completed.',
|
|
2602
|
-
metadata: response.metadata || {},
|
|
2603
|
-
}, null, 2));
|
|
2604
|
-
}
|
|
2605
|
-
else if (this.v3StreamingStarted) {
|
|
2587
|
+
if (this.v3StreamingStarted) {
|
|
2606
2588
|
// Content was already streamed to stdout in real-time; skip duplicate print.
|
|
2607
2589
|
if (!this.jsonOutput) {
|
|
2608
2590
|
console.log(chalk.gray(`Agent routing: ${routingPolicy.cloudSelected ? 'Vigthoria Cloud' : 'V3 Agent'}`));
|
|
@@ -2720,6 +2702,9 @@ export class ChatCommand {
|
|
|
2720
2702
|
}
|
|
2721
2703
|
taskDisplay.finalize();
|
|
2722
2704
|
// ────────────────────────────────────────────────────────────────
|
|
2705
|
+
if (!executorSucceeded) {
|
|
2706
|
+
process.exitCode = 1;
|
|
2707
|
+
}
|
|
2723
2708
|
this.lastAgentRunOutcome = {
|
|
2724
2709
|
prompt,
|
|
2725
2710
|
taskId: response.taskId || null,
|
|
@@ -2747,7 +2732,35 @@ export class ChatCommand {
|
|
|
2747
2732
|
if (!this.jsonOutput && !this.directPromptMode) {
|
|
2748
2733
|
this.printAgentRunSummary(this.lastAgentRunOutcome, runEvaluation, changedFileCount);
|
|
2749
2734
|
}
|
|
2750
|
-
this.
|
|
2735
|
+
if (this.jsonOutput) {
|
|
2736
|
+
if (!executorSucceeded) {
|
|
2737
|
+
process.exitCode = 1;
|
|
2738
|
+
}
|
|
2739
|
+
console.log(JSON.stringify({
|
|
2740
|
+
success: executorSucceeded,
|
|
2741
|
+
mode: 'agent',
|
|
2742
|
+
model: routingPolicy.selectedModel,
|
|
2743
|
+
routingPolicy,
|
|
2744
|
+
taskId: response.taskId || null,
|
|
2745
|
+
contextId: response.contextId || null,
|
|
2746
|
+
partial: response.partial === true || (!executorSucceeded && liveOutcome.tasksSucceeded > 0),
|
|
2747
|
+
content: response.content || runEvaluation.statusHeadline,
|
|
2748
|
+
statusHeadline: runEvaluation.statusHeadline,
|
|
2749
|
+
tasksSucceeded: liveOutcome.tasksSucceeded,
|
|
2750
|
+
tasksTotal: liveOutcome.tasksTotal,
|
|
2751
|
+
metadata: {
|
|
2752
|
+
...(response.metadata || {}),
|
|
2753
|
+
outcomeTruth: {
|
|
2754
|
+
executorSucceeded,
|
|
2755
|
+
uiTheme: runEvaluation.uiTheme,
|
|
2756
|
+
tasksSucceeded: liveOutcome.tasksSucceeded,
|
|
2757
|
+
tasksTotal: liveOutcome.tasksTotal,
|
|
2758
|
+
},
|
|
2759
|
+
previewGate,
|
|
2760
|
+
},
|
|
2761
|
+
}, null, 2));
|
|
2762
|
+
}
|
|
2763
|
+
this.messages.push({ role: 'assistant', content: response.content || runEvaluation.statusHeadline });
|
|
2751
2764
|
watcher?.stop();
|
|
2752
2765
|
return true;
|
|
2753
2766
|
}
|
|
@@ -2776,6 +2789,10 @@ export class ChatCommand {
|
|
|
2776
2789
|
: 'Agent mode is unavailable right now. Please retry shortly or run vigthoria login if the issue persists.';
|
|
2777
2790
|
this.logger.error(errorMessage);
|
|
2778
2791
|
this.messages.push({ role: 'assistant', content: errorMessage });
|
|
2792
|
+
liveOutcome.streamAborted = true;
|
|
2793
|
+
if (!liveOutcome.executorError) {
|
|
2794
|
+
liveOutcome.executorError = safeDetail || 'Connection aborted';
|
|
2795
|
+
}
|
|
2779
2796
|
// Resolve any half-rendered TaskDisplay spinners before the prompt
|
|
2780
2797
|
// comes back, otherwise the user sees `⟳ Execute tasks` next to `>`.
|
|
2781
2798
|
try {
|
|
@@ -2807,30 +2824,32 @@ export class ChatCommand {
|
|
|
2807
2824
|
workspaceSyncIssue: null,
|
|
2808
2825
|
finishedAt: Date.now(),
|
|
2809
2826
|
};
|
|
2827
|
+
if (!this.jsonOutput) {
|
|
2828
|
+
process.exitCode = 1;
|
|
2829
|
+
}
|
|
2810
2830
|
if (this.jsonOutput) {
|
|
2811
2831
|
process.exitCode = 1;
|
|
2812
2832
|
console.log(JSON.stringify({
|
|
2813
2833
|
success: false,
|
|
2814
2834
|
mode: 'agent',
|
|
2815
2835
|
model: routingPolicy.selectedModel,
|
|
2816
|
-
partial:
|
|
2836
|
+
partial: liveOutcome.tasksSucceeded > 0 && liveOutcome.tasksTotal > 0,
|
|
2817
2837
|
content: '',
|
|
2818
2838
|
error: errorMessage,
|
|
2839
|
+
statusHeadline: evaluateExecutorSuccess(liveOutcome).statusHeadline,
|
|
2840
|
+
tasksSucceeded: liveOutcome.tasksSucceeded,
|
|
2841
|
+
tasksTotal: liveOutcome.tasksTotal,
|
|
2819
2842
|
metadata: { executionPath: 'v3-agent' },
|
|
2820
2843
|
}, null, 2));
|
|
2821
2844
|
}
|
|
2822
2845
|
else if (!this.directPromptMode) {
|
|
2823
2846
|
const failedEval = evaluateExecutorSuccess({
|
|
2847
|
+
...liveOutcome,
|
|
2824
2848
|
executorFailed: true,
|
|
2825
|
-
plannerError: liveOutcome.plannerError,
|
|
2826
2849
|
executorError: liveOutcome.executorError || safeDetail,
|
|
2827
|
-
tasksTotal: liveOutcome.tasksTotal,
|
|
2828
|
-
tasksSucceeded: liveOutcome.tasksSucceeded,
|
|
2829
2850
|
changedFileCount: 0,
|
|
2830
2851
|
requiresWorkspaceChanges: this.taskRequiresWorkspaceChanges(prompt),
|
|
2831
2852
|
workspaceHasOutput: this.api.hasAgentWorkspaceOutput(workspaceContext),
|
|
2832
|
-
failedTaskIds: liveOutcome.failedTaskIds,
|
|
2833
|
-
analysisToolsUsed: liveOutcome.analysisToolsUsed,
|
|
2834
2853
|
});
|
|
2835
2854
|
this.printAgentRunSummary(this.lastAgentRunOutcome, failedEval, 0);
|
|
2836
2855
|
}
|
|
@@ -3312,16 +3331,15 @@ export class ChatCommand {
|
|
|
3312
3331
|
}
|
|
3313
3332
|
const o = this.lastAgentRunOutcome;
|
|
3314
3333
|
const statusEval = evaluateExecutorSuccess({
|
|
3334
|
+
...createLiveOutcome(),
|
|
3315
3335
|
executorFailed: o.failedTaskIds.length > 0,
|
|
3316
3336
|
plannerError: o.plannerError,
|
|
3317
3337
|
executorError: o.executorError,
|
|
3318
3338
|
tasksTotal: o.tasksTotal,
|
|
3319
3339
|
tasksSucceeded: o.tasksSucceeded,
|
|
3320
|
-
changedFileCount: 0,
|
|
3321
3340
|
requiresWorkspaceChanges: this.taskRequiresWorkspaceChanges(o.prompt),
|
|
3322
3341
|
workspaceHasOutput: o.hasOutput,
|
|
3323
3342
|
failedTaskIds: new Set(o.failedTaskIds),
|
|
3324
|
-
analysisToolsUsed: 0,
|
|
3325
3343
|
});
|
|
3326
3344
|
this.printAgentRunSummary(o, statusEval, 0);
|
|
3327
3345
|
}
|
|
@@ -12,7 +12,9 @@ export interface LiveOutcome {
|
|
|
12
12
|
requiresWorkspaceChanges: boolean;
|
|
13
13
|
workspaceHasOutput: boolean;
|
|
14
14
|
failedTaskIds: Set<string>;
|
|
15
|
+
completedTaskIds: Set<string>;
|
|
15
16
|
analysisToolsUsed: number;
|
|
17
|
+
streamAborted?: boolean;
|
|
16
18
|
}
|
|
17
19
|
export interface TaskSummaryEvent {
|
|
18
20
|
status?: string;
|
|
@@ -13,24 +13,36 @@ export function createLiveOutcome() {
|
|
|
13
13
|
requiresWorkspaceChanges: false,
|
|
14
14
|
workspaceHasOutput: false,
|
|
15
15
|
failedTaskIds: new Set(),
|
|
16
|
+
completedTaskIds: new Set(),
|
|
16
17
|
analysisToolsUsed: 0,
|
|
18
|
+
streamAborted: false,
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
/** Process executor_complete / task summary events from the V3 SSE stream. */
|
|
20
22
|
export function handleTaskEvent(summary, liveOutcome) {
|
|
21
23
|
const tid = summary.task_id || summary.id;
|
|
22
24
|
const status = String(summary.status || '').toLowerCase();
|
|
25
|
+
if (!liveOutcome.completedTaskIds) {
|
|
26
|
+
liveOutcome.completedTaskIds = new Set();
|
|
27
|
+
}
|
|
23
28
|
if (status === 'completed' || status === 'success') {
|
|
24
29
|
if (tid) {
|
|
25
|
-
|
|
30
|
+
const id = String(tid);
|
|
31
|
+
if (liveOutcome.completedTaskIds.has(id))
|
|
32
|
+
return;
|
|
33
|
+
liveOutcome.completedTaskIds.add(id);
|
|
34
|
+
liveOutcome.failedTaskIds.delete(id);
|
|
26
35
|
}
|
|
27
36
|
liveOutcome.tasksSucceeded += 1;
|
|
28
37
|
}
|
|
29
|
-
else if (status === 'failed' || status === 'blocked') {
|
|
38
|
+
else if (status === 'failed' || status === 'blocked' || status === 'stalled_error') {
|
|
30
39
|
if (tid) {
|
|
31
40
|
liveOutcome.failedTaskIds.add(String(tid));
|
|
32
41
|
}
|
|
33
42
|
liveOutcome.executorFailed = true;
|
|
43
|
+
if (status === 'stalled_error') {
|
|
44
|
+
liveOutcome.streamAborted = true;
|
|
45
|
+
}
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
48
|
const READ_DISCOVERY_TOOLS = new Set([
|
|
@@ -57,7 +69,18 @@ export function noteAnalysisToolUse(toolName, liveOutcome) {
|
|
|
57
69
|
export function evaluateExecutorSuccess(liveOutcome) {
|
|
58
70
|
const hasFatalError = liveOutcome.executorFailed
|
|
59
71
|
|| Boolean(liveOutcome.plannerError)
|
|
60
|
-
|| Boolean(liveOutcome.executorError)
|
|
72
|
+
|| Boolean(liveOutcome.executorError)
|
|
73
|
+
|| Boolean(liveOutcome.streamAborted);
|
|
74
|
+
if (liveOutcome.streamAborted && liveOutcome.tasksTotal > 0) {
|
|
75
|
+
const partial = liveOutcome.tasksSucceeded > 0;
|
|
76
|
+
return {
|
|
77
|
+
executorSucceeded: false,
|
|
78
|
+
statusHeadline: partial
|
|
79
|
+
? `⚠ ${liveOutcome.tasksSucceeded}/${liveOutcome.tasksTotal} tasks completed — connection aborted`
|
|
80
|
+
: `✕ Connection aborted — 0/${liveOutcome.tasksTotal} tasks completed`,
|
|
81
|
+
uiTheme: 'warning',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
61
84
|
if (hasFatalError && liveOutcome.tasksTotal === 0) {
|
|
62
85
|
return {
|
|
63
86
|
executorSucceeded: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigthoria-cli",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2",
|
|
4
4
|
"description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"start": "node dist/index.js",
|
|
37
37
|
"dev": "ts-node src/index.ts",
|
|
38
38
|
"test": "npm run test:cli",
|
|
39
|
-
"test:
|
|
39
|
+
"test:agent:outcome": "npm run build && node scripts/test-agent-run-outcome.js",
|
|
40
|
+
"test:cli": "npm run build && npm run precheck:services && node scripts/test-cli-suite.js && npm run test:agent:outcome",
|
|
40
41
|
"test:regression": "npm run build && node scripts/test-regression-1.6.22.js",
|
|
41
42
|
"test:agent:smoke": "npm run build && node scripts/test-agent-smoke.js",
|
|
42
43
|
"test:agent:routing": "npm run build && node scripts/test-agent-routing-policy.js",
|