vigthoria-cli 1.8.2 → 1.8.4
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 +3 -8
- package/dist/utils/api.js +16 -23
- package/package.json +1 -1
package/dist/commands/chat.js
CHANGED
|
@@ -1616,14 +1616,9 @@ class ChatCommand {
|
|
|
1616
1616
|
...runtimeContext,
|
|
1617
1617
|
onStreamEvent: spinner ? (event) => this.updateV3AgentSpinner(spinner, event) : undefined,
|
|
1618
1618
|
});
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
new Promise((_, reject) => {
|
|
1623
|
-
setTimeout(() => reject(new Error('V3_SAAS_SOFT_TIMEOUT')), 3600000);
|
|
1624
|
-
}),
|
|
1625
|
-
])
|
|
1626
|
-
: workflowPromise);
|
|
1619
|
+
// No hard timeout — SSE stream stays open until the server
|
|
1620
|
+
// sends complete/error/[DONE]. We never cut off a working workflow.
|
|
1621
|
+
const response = await workflowPromise;
|
|
1627
1622
|
if (spinner) {
|
|
1628
1623
|
spinner.stop();
|
|
1629
1624
|
}
|
package/dist/utils/api.js
CHANGED
|
@@ -89,20 +89,24 @@ function formatCLIError(err) {
|
|
|
89
89
|
return `${tag} ${err.message}`;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
// SSE-based architecture: NO hard timeouts. Streams stay open until
|
|
93
|
+
// complete/error/disconnect. Liveness is checked via heartbeat events.
|
|
94
|
+
// Set to 0 (disabled) by default. Only use a timeout as an emergency
|
|
95
|
+
// safety net when explicitly configured via env vars.
|
|
92
96
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
93
|
-
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS || '
|
|
97
|
+
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS || '0';
|
|
94
98
|
const parsed = Number.parseInt(rawValue, 10);
|
|
95
|
-
return Number.isFinite(parsed) && parsed
|
|
99
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
96
100
|
})();
|
|
97
101
|
const DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS = (() => {
|
|
98
|
-
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS || '
|
|
102
|
+
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS || '0';
|
|
99
103
|
const parsed = Number.parseInt(rawValue, 10);
|
|
100
|
-
return Number.isFinite(parsed) && parsed
|
|
104
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
101
105
|
})();
|
|
102
106
|
const DEFAULT_OPERATOR_TIMEOUT_MS = (() => {
|
|
103
|
-
const rawValue = process.env.VIGTHORIA_OPERATOR_TIMEOUT_MS || process.env.OPERATOR_TIMEOUT_MS || '
|
|
107
|
+
const rawValue = process.env.VIGTHORIA_OPERATOR_TIMEOUT_MS || process.env.OPERATOR_TIMEOUT_MS || '0';
|
|
104
108
|
const parsed = Number.parseInt(rawValue, 10);
|
|
105
|
-
return Number.isFinite(parsed) && parsed
|
|
109
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
106
110
|
})();
|
|
107
111
|
class APIClient {
|
|
108
112
|
client;
|
|
@@ -2732,7 +2736,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2732
2736
|
&& context.localMachineCapable !== false;
|
|
2733
2737
|
const rescueEligibleSaaS = preferLocalV3
|
|
2734
2738
|
&& /(saas|dashboard|analytics|billing|team management|activity feed|login screen)/i.test(message);
|
|
2735
|
-
const timeoutMs = rescueEligibleSaaS ? Math.min(baseTimeoutMs, 3600000) : baseTimeoutMs;
|
|
2736
2739
|
const maxAttempts = preferLocalV3 ? 2 : 1;
|
|
2737
2740
|
let lastErrors = [];
|
|
2738
2741
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
@@ -2765,8 +2768,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2765
2768
|
stream: true,
|
|
2766
2769
|
};
|
|
2767
2770
|
for (const baseUrl of this.getV3AgentBaseUrls(preferLocalV3)) {
|
|
2771
|
+
// No hard timeout — SSE stream stays alive until server sends
|
|
2772
|
+
// complete/error/[DONE] or the TCP connection drops.
|
|
2768
2773
|
const controller = new AbortController();
|
|
2769
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2770
2774
|
try {
|
|
2771
2775
|
const response = await this.executeV3AgentRunRequest(baseUrl, requestBody, requestExecutionContext, controller.signal);
|
|
2772
2776
|
if (!response.ok) {
|
|
@@ -2798,7 +2802,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2798
2802
|
stream: true,
|
|
2799
2803
|
};
|
|
2800
2804
|
const continueController = new AbortController();
|
|
2801
|
-
const continueTimeoutId = setTimeout(() => continueController.abort(), timeoutMs);
|
|
2802
2805
|
try {
|
|
2803
2806
|
const continueHeaders = await this.getV3AgentHeaders();
|
|
2804
2807
|
const continueResponse = await fetch(this.getV3AgentContinueUrl(baseUrl), {
|
|
@@ -2816,7 +2819,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2816
2819
|
break; // Fall through to normal completion with partial data
|
|
2817
2820
|
}
|
|
2818
2821
|
finally {
|
|
2819
|
-
|
|
2822
|
+
// no timeout to clear — SSE stream ends naturally
|
|
2820
2823
|
}
|
|
2821
2824
|
}
|
|
2822
2825
|
// Use the final continuation data for workspace recovery
|
|
@@ -2872,9 +2875,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2872
2875
|
}
|
|
2873
2876
|
errors.push(`${baseUrl}: ${error?.message || String(error)}`);
|
|
2874
2877
|
}
|
|
2875
|
-
finally {
|
|
2876
|
-
clearTimeout(timeoutId);
|
|
2877
|
-
}
|
|
2878
2878
|
}
|
|
2879
2879
|
lastErrors = errors;
|
|
2880
2880
|
const shouldRetry = attempt < maxAttempts
|
|
@@ -2940,7 +2940,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2940
2940
|
}
|
|
2941
2941
|
async runOperatorWorkflow(message, context = {}) {
|
|
2942
2942
|
const executionContext = await this.bindExecutionContext(context);
|
|
2943
|
-
const timeoutMs = context.operatorTimeoutMs || DEFAULT_OPERATOR_TIMEOUT_MS;
|
|
2944
2943
|
const errors = [];
|
|
2945
2944
|
const authToken = this.config.get('authToken');
|
|
2946
2945
|
// Collect a lightweight workspace file listing so the operator can
|
|
@@ -2948,8 +2947,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2948
2947
|
const workspacePath = executionContext.workspacePath || executionContext.projectPath || executionContext.targetPath || process.cwd();
|
|
2949
2948
|
const workspaceSummary = this.buildLocalWorkspaceSummary(workspacePath);
|
|
2950
2949
|
for (const baseUrl of this.getOperatorBaseUrls()) {
|
|
2950
|
+
// No hard timeout — SSE stream stays open until result/error/disconnect.
|
|
2951
|
+
// BMAD sends heartbeat events every 15s; if the TCP connection drops,
|
|
2952
|
+
// the fetch will throw naturally.
|
|
2951
2953
|
const controller = new AbortController();
|
|
2952
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2953
2954
|
try {
|
|
2954
2955
|
const response = await fetch(this.getOperatorStreamUrl(baseUrl), {
|
|
2955
2956
|
method: 'POST',
|
|
@@ -3088,16 +3089,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
3088
3089
|
};
|
|
3089
3090
|
}
|
|
3090
3091
|
catch (error) {
|
|
3091
|
-
const isAbort = error?.name === 'AbortError' || error?.code === 'ABORT_ERR';
|
|
3092
|
-
if (isAbort) {
|
|
3093
|
-
const mins = Math.round(timeoutMs / 60000);
|
|
3094
|
-
throw new CLIError(`Operator workflow timed out after ${mins} minute(s). You can increase the timeout with VIGTHORIA_OPERATOR_TIMEOUT_MS.`, 'timeout', error);
|
|
3095
|
-
}
|
|
3096
3092
|
errors.push(`${baseUrl}: ${error?.message || String(error)}`);
|
|
3097
3093
|
}
|
|
3098
|
-
finally {
|
|
3099
|
-
clearTimeout(timeoutId);
|
|
3100
|
-
}
|
|
3101
3094
|
}
|
|
3102
3095
|
throw new CLIError(`Operator workflow failed on all endpoints: ${errors.join(' | ')}`, 'model_backend');
|
|
3103
3096
|
}
|