vigthoria-cli 1.8.8 → 1.8.9
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 +5 -2
- package/dist/utils/api.d.ts +2 -0
- package/dist/utils/api.js +41 -6
- package/package.json +1 -1
package/dist/commands/chat.js
CHANGED
|
@@ -1773,13 +1773,16 @@ class ChatCommand {
|
|
|
1773
1773
|
spinner.stop();
|
|
1774
1774
|
}
|
|
1775
1775
|
this.logger.warn('Falling back to legacy CLI agent loop');
|
|
1776
|
-
this.logger.debug(`V3 agent workflow unavailable: ${error.message}`);
|
|
1776
|
+
this.logger.debug(`V3 agent workflow unavailable: ${(0, api_js_1.sanitizeUserFacingErrorText)(error.message || '')}`);
|
|
1777
1777
|
return false;
|
|
1778
1778
|
}
|
|
1779
1779
|
if (spinner) {
|
|
1780
1780
|
spinner.stop();
|
|
1781
1781
|
}
|
|
1782
|
-
const
|
|
1782
|
+
const safeDetail = (0, api_js_1.sanitizeUserFacingErrorText)(error.message || '');
|
|
1783
|
+
const errorMessage = safeDetail
|
|
1784
|
+
? `Agent mode is unavailable right now. ${safeDetail}`
|
|
1785
|
+
: 'Agent mode is unavailable right now. Please retry shortly or run vigthoria login if the issue persists.';
|
|
1783
1786
|
this.logger.error(errorMessage);
|
|
1784
1787
|
this.messages.push({ role: 'assistant', content: errorMessage });
|
|
1785
1788
|
if (this.jsonOutput) {
|
package/dist/utils/api.d.ts
CHANGED
|
@@ -186,6 +186,8 @@ export interface VigthoriUser {
|
|
|
186
186
|
adminAccess: boolean;
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
|
+
export declare function sanitizeUserFacingErrorText(input: string): string;
|
|
190
|
+
export declare function describeUpstreamStatus(status: number): string;
|
|
189
191
|
export declare class APIClient {
|
|
190
192
|
private client;
|
|
191
193
|
private modelRouterClient;
|
package/dist/utils/api.js
CHANGED
|
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.APIClient = exports.CLIError = void 0;
|
|
11
11
|
exports.classifyError = classifyError;
|
|
12
12
|
exports.formatCLIError = formatCLIError;
|
|
13
|
+
exports.sanitizeUserFacingErrorText = sanitizeUserFacingErrorText;
|
|
14
|
+
exports.describeUpstreamStatus = describeUpstreamStatus;
|
|
13
15
|
const axios_1 = __importDefault(require("axios"));
|
|
14
16
|
const crypto_1 = require("crypto");
|
|
15
17
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -116,6 +118,39 @@ const DEFAULT_OPERATOR_TIMEOUT_MS = (() => {
|
|
|
116
118
|
const parsed = Number.parseInt(rawValue, 10);
|
|
117
119
|
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
118
120
|
})();
|
|
121
|
+
// Sanitize an upstream error string before exposing it to the end user.
|
|
122
|
+
// Strips URLs, IPs:ports, absolute server paths, and bare hostnames so the
|
|
123
|
+
// CLI never reveals internal infrastructure to remote users.
|
|
124
|
+
function sanitizeUserFacingErrorText(input) {
|
|
125
|
+
if (!input)
|
|
126
|
+
return '';
|
|
127
|
+
let out = String(input);
|
|
128
|
+
out = out.replace(/https?:\/\/[^\s'"<>)]+/gi, '[redacted-url]');
|
|
129
|
+
out = out.replace(/\b\d{1,3}(?:\.\d{1,3}){3}(?::\d+)?\b/g, '[redacted-host]');
|
|
130
|
+
out = out.replace(/\b(?:localhost|127\.0\.0\.1)(?::\d+)?\b/gi, '[redacted-host]');
|
|
131
|
+
out = out.replace(/\b[a-z0-9.-]+\.vigthoria\.io\b/gi, '[redacted-host]');
|
|
132
|
+
out = out.replace(/(?:[A-Za-z]:)?[\\/](?:var|opt|tmp|home|root|etc|usr)[\\/][^\s'"<>)]*/gi, '[redacted-path]');
|
|
133
|
+
out = out.replace(/\{\s*"detail"\s*:\s*"[^"]*"\s*\}/g, '');
|
|
134
|
+
out = out.replace(/\s+/g, ' ').trim();
|
|
135
|
+
if (out.length > 160)
|
|
136
|
+
out = out.slice(0, 160) + '...';
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
function describeUpstreamStatus(status) {
|
|
140
|
+
if (status === 401 || status === 403)
|
|
141
|
+
return 'Authentication failed. Please run vigthoria login.';
|
|
142
|
+
if (status === 404)
|
|
143
|
+
return 'Requested service endpoint was not found.';
|
|
144
|
+
if (status === 408 || status === 504)
|
|
145
|
+
return 'Upstream service timed out.';
|
|
146
|
+
if (status === 429)
|
|
147
|
+
return 'Rate limit reached. Please retry shortly.';
|
|
148
|
+
if (status >= 500)
|
|
149
|
+
return 'Upstream service is temporarily unavailable.';
|
|
150
|
+
if (status >= 400)
|
|
151
|
+
return 'Request was rejected by the service.';
|
|
152
|
+
return 'Unexpected response from service.';
|
|
153
|
+
}
|
|
119
154
|
class APIClient {
|
|
120
155
|
client;
|
|
121
156
|
modelRouterClient;
|
|
@@ -805,7 +840,7 @@ class APIClient {
|
|
|
805
840
|
});
|
|
806
841
|
if (!response.ok) {
|
|
807
842
|
const errorText = await response.text().catch(() => '');
|
|
808
|
-
throw new Error(`Template preview proof ${response.status}: ${
|
|
843
|
+
throw new Error(`Template preview proof ${response.status}: ${describeUpstreamStatus(response.status)}`);
|
|
809
844
|
}
|
|
810
845
|
const payload = await response.json();
|
|
811
846
|
const modes = payload?.modes || {};
|
|
@@ -1746,7 +1781,7 @@ menu {
|
|
|
1746
1781
|
});
|
|
1747
1782
|
if (!response.ok) {
|
|
1748
1783
|
const errorText = await response.text().catch(() => '');
|
|
1749
|
-
throw new Error(`MCP context update ${response.status}: ${
|
|
1784
|
+
throw new Error(`MCP context update ${response.status}: ${describeUpstreamStatus(response.status)}`);
|
|
1750
1785
|
}
|
|
1751
1786
|
return {
|
|
1752
1787
|
...executionContext,
|
|
@@ -1777,7 +1812,7 @@ menu {
|
|
|
1777
1812
|
});
|
|
1778
1813
|
if (!createResponse.ok) {
|
|
1779
1814
|
const errorText = await createResponse.text().catch(() => '');
|
|
1780
|
-
throw new Error(`MCP context create ${createResponse.status}: ${
|
|
1815
|
+
throw new Error(`MCP context create ${createResponse.status}: ${describeUpstreamStatus(createResponse.status)}`);
|
|
1781
1816
|
}
|
|
1782
1817
|
const payload = await createResponse.json();
|
|
1783
1818
|
const mcpContextId = String(payload.contextId || '').trim();
|
|
@@ -2723,7 +2758,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2723
2758
|
partial: true,
|
|
2724
2759
|
};
|
|
2725
2760
|
}
|
|
2726
|
-
throw new Error(event.message || '
|
|
2761
|
+
throw new Error(`V3 agent: ${sanitizeUserFacingErrorText(event.message || '') || 'returned an error'}`);
|
|
2727
2762
|
}
|
|
2728
2763
|
if (event.type === 'complete' || event.type === 'message') {
|
|
2729
2764
|
final = event;
|
|
@@ -2786,7 +2821,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2786
2821
|
const response = await this.executeV3AgentRunRequest(baseUrl, requestBody, requestExecutionContext, controller.signal);
|
|
2787
2822
|
if (!response.ok) {
|
|
2788
2823
|
const errorText = await response.text().catch(() => '');
|
|
2789
|
-
throw new Error(`V3 agent ${response.status}: ${
|
|
2824
|
+
throw new Error(`V3 agent ${response.status}: ${describeUpstreamStatus(response.status)}`);
|
|
2790
2825
|
}
|
|
2791
2826
|
const data = await this.collectV3AgentStream(response, requestExecutionContext);
|
|
2792
2827
|
// Auto-continuation: if the agent checkpointed (budget exceeded), continue automatically
|
|
@@ -3013,7 +3048,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
3013
3048
|
});
|
|
3014
3049
|
if (!response.ok) {
|
|
3015
3050
|
const errorText = await response.text().catch(() => '');
|
|
3016
|
-
throw new Error(`Operator stream ${response.status}: ${
|
|
3051
|
+
throw new Error(`Operator stream ${response.status}: ${describeUpstreamStatus(response.status)}`);
|
|
3017
3052
|
}
|
|
3018
3053
|
if (!response.body || typeof response.body.getReader !== 'function') {
|
|
3019
3054
|
const fallbackData = await response.json();
|