@kenkaiiii/gg-ai 4.3.165 → 4.3.166
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/index.cjs +204 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.js +202 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,8 @@ __export(index_exports, {
|
|
|
34
34
|
GGAIError: () => GGAIError,
|
|
35
35
|
ProviderError: () => ProviderError,
|
|
36
36
|
StreamResult: () => StreamResult,
|
|
37
|
+
formatError: () => formatError,
|
|
38
|
+
formatErrorForDisplay: () => formatErrorForDisplay,
|
|
37
39
|
palsuAssistantMessage: () => palsuAssistantMessage,
|
|
38
40
|
palsuText: () => palsuText,
|
|
39
41
|
palsuThinking: () => palsuThinking,
|
|
@@ -46,21 +48,165 @@ module.exports = __toCommonJS(index_exports);
|
|
|
46
48
|
|
|
47
49
|
// src/errors.ts
|
|
48
50
|
var GGAIError = class extends Error {
|
|
51
|
+
source;
|
|
52
|
+
requestId;
|
|
53
|
+
hint;
|
|
49
54
|
constructor(message, options) {
|
|
50
|
-
super(message, options);
|
|
55
|
+
super(message, { cause: options?.cause });
|
|
51
56
|
this.name = "GGAIError";
|
|
57
|
+
this.source = options?.source ?? "ggcoder";
|
|
58
|
+
this.requestId = options?.requestId;
|
|
59
|
+
this.hint = options?.hint;
|
|
52
60
|
}
|
|
53
61
|
};
|
|
54
62
|
var ProviderError = class extends GGAIError {
|
|
55
63
|
provider;
|
|
56
64
|
statusCode;
|
|
57
65
|
constructor(provider, message, options) {
|
|
58
|
-
super(
|
|
66
|
+
super(message, {
|
|
67
|
+
source: "provider",
|
|
68
|
+
requestId: options?.requestId,
|
|
69
|
+
hint: options?.hint,
|
|
70
|
+
cause: options?.cause
|
|
71
|
+
});
|
|
59
72
|
this.name = "ProviderError";
|
|
60
73
|
this.provider = provider;
|
|
61
74
|
this.statusCode = options?.statusCode;
|
|
62
75
|
}
|
|
63
76
|
};
|
|
77
|
+
var PROVIDER_DISPLAY = {
|
|
78
|
+
openai: "OpenAI",
|
|
79
|
+
anthropic: "Anthropic",
|
|
80
|
+
glm: "Z.AI (GLM)",
|
|
81
|
+
moonshot: "Moonshot",
|
|
82
|
+
deepseek: "DeepSeek",
|
|
83
|
+
openrouter: "OpenRouter",
|
|
84
|
+
xiaomi: "Xiaomi (MiMo)",
|
|
85
|
+
minimax: "MiniMax"
|
|
86
|
+
};
|
|
87
|
+
var PROVIDER_STATUS_URL = {
|
|
88
|
+
openai: "status.openai.com",
|
|
89
|
+
anthropic: "status.anthropic.com"
|
|
90
|
+
};
|
|
91
|
+
function providerDisplayName(provider) {
|
|
92
|
+
return PROVIDER_DISPLAY[provider] ?? provider;
|
|
93
|
+
}
|
|
94
|
+
function formatError(err) {
|
|
95
|
+
if (err instanceof ProviderError) {
|
|
96
|
+
const name = providerDisplayName(err.provider);
|
|
97
|
+
const cleanMessage = cleanProviderMessage(err.message);
|
|
98
|
+
return {
|
|
99
|
+
headline: `${name} returned an error.`,
|
|
100
|
+
source: "provider",
|
|
101
|
+
message: cleanMessage,
|
|
102
|
+
provider: err.provider,
|
|
103
|
+
statusCode: err.statusCode,
|
|
104
|
+
requestId: err.requestId,
|
|
105
|
+
guidance: err.hint ?? providerGuidance(err.provider, cleanMessage, err.statusCode)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (err instanceof GGAIError) {
|
|
109
|
+
return finaliseBySource(err.source, err.message, err.requestId, err.hint);
|
|
110
|
+
}
|
|
111
|
+
if (err instanceof Error) {
|
|
112
|
+
const source = inferSource(err);
|
|
113
|
+
return finaliseBySource(source, err.message, void 0, void 0);
|
|
114
|
+
}
|
|
115
|
+
return finaliseBySource("ggcoder", String(err), void 0, void 0);
|
|
116
|
+
}
|
|
117
|
+
function finaliseBySource(source, message, requestId, hint) {
|
|
118
|
+
switch (source) {
|
|
119
|
+
case "network":
|
|
120
|
+
return {
|
|
121
|
+
headline: "Network error \u2014 couldn't reach the provider.",
|
|
122
|
+
source,
|
|
123
|
+
message,
|
|
124
|
+
guidance: hint ?? "Check your internet connection. Not a ggcoder issue \u2014 retry shortly.",
|
|
125
|
+
...requestId ? { requestId } : {}
|
|
126
|
+
};
|
|
127
|
+
case "auth":
|
|
128
|
+
return {
|
|
129
|
+
headline: "Authentication issue.",
|
|
130
|
+
source,
|
|
131
|
+
message,
|
|
132
|
+
guidance: hint ?? "Run `ggcoder login` to refresh your credentials.",
|
|
133
|
+
...requestId ? { requestId } : {}
|
|
134
|
+
};
|
|
135
|
+
case "provider":
|
|
136
|
+
return {
|
|
137
|
+
headline: "Provider returned an error.",
|
|
138
|
+
source,
|
|
139
|
+
message,
|
|
140
|
+
guidance: hint ?? providerGuidance(void 0, message, void 0),
|
|
141
|
+
...requestId ? { requestId } : {}
|
|
142
|
+
};
|
|
143
|
+
case "ggcoder":
|
|
144
|
+
return {
|
|
145
|
+
headline: "ggcoder hit an unexpected error.",
|
|
146
|
+
source,
|
|
147
|
+
message,
|
|
148
|
+
guidance: hint ?? "This looks like a ggcoder bug \u2014 please report it to the developer (see /help).",
|
|
149
|
+
...requestId ? { requestId } : {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function formatErrorForDisplay(err) {
|
|
154
|
+
const f = formatError(err);
|
|
155
|
+
const lines = [f.headline];
|
|
156
|
+
if (f.message && f.message !== f.headline) lines.push(` ${f.message}`);
|
|
157
|
+
lines.push(` \u2192 ${f.guidance}`);
|
|
158
|
+
return lines.join("\n");
|
|
159
|
+
}
|
|
160
|
+
function cleanProviderMessage(message) {
|
|
161
|
+
return message.replace(/^\[[^\]]+\]\s*/, "").trim();
|
|
162
|
+
}
|
|
163
|
+
function inferSource(err) {
|
|
164
|
+
const msg = err.message.toLowerCase();
|
|
165
|
+
const code = err.code ?? "";
|
|
166
|
+
if (code === "ECONNREFUSED" || code === "ETIMEDOUT" || code === "ENOTFOUND" || code === "ECONNRESET" || msg.includes("fetch failed") || msg.includes("network request failed")) {
|
|
167
|
+
return "network";
|
|
168
|
+
}
|
|
169
|
+
if (msg.includes("not logged in") || msg.includes("token exchange failed") || msg.includes("token refresh failed") || msg.includes("invalid_grant")) {
|
|
170
|
+
return "auth";
|
|
171
|
+
}
|
|
172
|
+
return "ggcoder";
|
|
173
|
+
}
|
|
174
|
+
function providerGuidance(provider, message, statusCode) {
|
|
175
|
+
const name = provider ? providerDisplayName(provider) : "the provider";
|
|
176
|
+
const status = provider ? PROVIDER_STATUS_URL[provider] : void 0;
|
|
177
|
+
const lower = message.toLowerCase();
|
|
178
|
+
if (statusCode === 401 || lower.includes("unauthorized") || lower.includes("invalid api key")) {
|
|
179
|
+
return `Authentication failed with ${name}. Run \`ggcoder login\` to refresh your credentials.`;
|
|
180
|
+
}
|
|
181
|
+
if (lower.includes("overloaded") || lower.includes("engine_overloaded")) {
|
|
182
|
+
return `${name}'s servers are overloaded right now. Retry in a moment \u2014 not a ggcoder issue.`;
|
|
183
|
+
}
|
|
184
|
+
if (lower.includes("insufficient balance") || lower.includes("quota exceeded") || lower.includes("recharge") || lower.includes("no resource package")) {
|
|
185
|
+
return `Your ${name} account has a billing or quota issue \u2014 check your balance. Not a ggcoder issue.`;
|
|
186
|
+
}
|
|
187
|
+
if (statusCode === 429 || lower.includes("rate limit") || lower.includes("too many requests")) {
|
|
188
|
+
return `${name} rate limit hit. Wait a moment then retry \u2014 not a ggcoder issue.`;
|
|
189
|
+
}
|
|
190
|
+
if (statusCode === 502 || lower.includes("bad gateway")) {
|
|
191
|
+
return `${name} returned a bad gateway. Retry \u2014 this is on their side, not ggcoder.`;
|
|
192
|
+
}
|
|
193
|
+
if (statusCode === 503 || lower.includes("service unavailable")) {
|
|
194
|
+
return `${name} is temporarily unavailable. Retry shortly \u2014 not a ggcoder issue.`;
|
|
195
|
+
}
|
|
196
|
+
if (statusCode === 500 || lower.includes("server_error") || lower.includes("500") && lower.includes("internal server error")) {
|
|
197
|
+
return status ? `This is an error from ${name}, not ggcoder. Retry \u2014 if it keeps happening, check ${status}.` : `This is an error from ${name}, not ggcoder. Retry \u2014 if it keeps happening, try a different model with /model.`;
|
|
198
|
+
}
|
|
199
|
+
if (lower.includes("timeout") || lower.includes("timed out")) {
|
|
200
|
+
return `Request to ${name} timed out. Their servers may be slow \u2014 retry. Not a ggcoder issue.`;
|
|
201
|
+
}
|
|
202
|
+
if (lower.includes("does not recognize the requested model") || lower.includes("model") && (lower.includes("not exist") || lower.includes("not found") || lower.includes("no access"))) {
|
|
203
|
+
return `${name} doesn't recognise this model on your account. Use /model to switch, or check your subscription tier.`;
|
|
204
|
+
}
|
|
205
|
+
if (lower.includes("context_length_exceeded") || lower.includes("prompt is too long")) {
|
|
206
|
+
return `Context window for this ${name} model is full. Run /compact to shrink history, or start a new session.`;
|
|
207
|
+
}
|
|
208
|
+
return status ? `This is an error from ${name}, not ggcoder. Retry \u2014 if it persists, check ${status}.` : `This is an error from ${name}, not ggcoder. Retry \u2014 if it persists, try a different model with /model.`;
|
|
209
|
+
}
|
|
64
210
|
|
|
65
211
|
// src/providers/anthropic.ts
|
|
66
212
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
|
|
@@ -999,8 +1145,10 @@ function messageToResponse(message) {
|
|
|
999
1145
|
}
|
|
1000
1146
|
function toError(err) {
|
|
1001
1147
|
if (err instanceof import_sdk.default.APIError) {
|
|
1148
|
+
const requestId = err.request_id ?? err.error?.request_id;
|
|
1002
1149
|
return new ProviderError("anthropic", err.message, {
|
|
1003
1150
|
statusCode: err.status,
|
|
1151
|
+
...requestId ? { requestId } : {},
|
|
1004
1152
|
cause: err
|
|
1005
1153
|
});
|
|
1006
1154
|
}
|
|
@@ -1292,19 +1440,19 @@ function completionToResponse(completion) {
|
|
|
1292
1440
|
}
|
|
1293
1441
|
function toError2(err, provider = "openai") {
|
|
1294
1442
|
if (err instanceof import_openai.default.APIError) {
|
|
1295
|
-
let msg = err.message;
|
|
1296
1443
|
const body = err.error;
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
return new ProviderError(provider, msg, {
|
|
1444
|
+
const bodyMessage = typeof body?.message === "string" && body.message.trim() ? body.message.trim() : void 0;
|
|
1445
|
+
const modelName = typeof body?.model === "string" ? body.model : "";
|
|
1446
|
+
const cleanMessage = bodyMessage ?? err.message;
|
|
1447
|
+
let hint;
|
|
1448
|
+
if (modelName === "codex-mini-latest" || cleanMessage.includes("codex-mini-latest")) {
|
|
1449
|
+
hint = "codex-mini-latest requires an OpenAI Pro or Max subscription. Your account currently has access to GPT-5.4 and GPT-5.4 Mini.";
|
|
1450
|
+
}
|
|
1451
|
+
const requestId = err.request_id ?? (typeof body?.request_id === "string" ? body.request_id : void 0);
|
|
1452
|
+
return new ProviderError(provider, cleanMessage, {
|
|
1307
1453
|
statusCode: err.status,
|
|
1454
|
+
...requestId ? { requestId } : {},
|
|
1455
|
+
...hint ? { hint } : {},
|
|
1308
1456
|
cause: err
|
|
1309
1457
|
});
|
|
1310
1458
|
}
|
|
@@ -1366,19 +1514,19 @@ async function* runStream3(options) {
|
|
|
1366
1514
|
});
|
|
1367
1515
|
if (!response.ok) {
|
|
1368
1516
|
const text = await response.text().catch(() => "");
|
|
1369
|
-
|
|
1517
|
+
const parsed = parseCodexErrorBody(text);
|
|
1518
|
+
const message = parsed.message ?? `Codex API returned HTTP ${response.status}.`;
|
|
1519
|
+
const requestId = parsed.requestId ?? response.headers.get("x-request-id") ?? response.headers.get("openai-request-id") ?? void 0;
|
|
1520
|
+
let hint;
|
|
1370
1521
|
if (response.status === 400 && text.includes("not supported")) {
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
}
|
|
1375
|
-
if (response.status === 404 && text.includes("does not exist")) {
|
|
1376
|
-
message += `
|
|
1377
|
-
|
|
1378
|
-
Hint: codex-mini-latest requires an OpenAI Pro ($200/mo) or Max subscription. GPT-5.4 and GPT-5.4 Mini work with any active ChatGPT plan.`;
|
|
1522
|
+
hint = 'Codex models require a ChatGPT Plus ($20/mo) or Pro ($200/mo) subscription. The "codex-spark" variants require ChatGPT Pro. Check your subscription at https://chatgpt.com/settings.';
|
|
1523
|
+
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
1524
|
+
hint = "codex-mini-latest requires an OpenAI Pro ($200/mo) or Max subscription. GPT-5.4 and GPT-5.4 Mini work with any active ChatGPT plan.";
|
|
1379
1525
|
}
|
|
1380
1526
|
throw new ProviderError("openai", message, {
|
|
1381
|
-
statusCode: response.status
|
|
1527
|
+
statusCode: response.status,
|
|
1528
|
+
...requestId ? { requestId } : {},
|
|
1529
|
+
...hint ? { hint } : {}
|
|
1382
1530
|
});
|
|
1383
1531
|
}
|
|
1384
1532
|
if (!response.body) {
|
|
@@ -1393,12 +1541,22 @@ Hint: codex-mini-latest requires an OpenAI Pro ($200/mo) or Max subscription. GP
|
|
|
1393
1541
|
const type = event.type;
|
|
1394
1542
|
if (!type) continue;
|
|
1395
1543
|
if (type === "error") {
|
|
1396
|
-
const
|
|
1397
|
-
|
|
1544
|
+
const nested = event.error ?? void 0;
|
|
1545
|
+
const message = nested?.message ?? event.message ?? "Codex stream emitted an error chunk without a message.";
|
|
1546
|
+
const code = nested?.code ?? nested?.type ?? event.code ?? "server_error";
|
|
1547
|
+
const requestId = extractCodexRequestId(message) ?? event.request_id;
|
|
1548
|
+
throw new ProviderError("openai", message, {
|
|
1549
|
+
...requestId != null ? { requestId } : {},
|
|
1550
|
+
...code === "server_error" ? { statusCode: 500 } : {}
|
|
1551
|
+
});
|
|
1398
1552
|
}
|
|
1399
1553
|
if (type === "response.failed") {
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1554
|
+
const nested = event.error;
|
|
1555
|
+
const message = nested?.message ?? "Codex response failed.";
|
|
1556
|
+
const requestId = extractCodexRequestId(message) ?? event.request_id;
|
|
1557
|
+
throw new ProviderError("openai", message, {
|
|
1558
|
+
...requestId != null ? { requestId } : {}
|
|
1559
|
+
});
|
|
1402
1560
|
}
|
|
1403
1561
|
if (type === "response.output_text.delta") {
|
|
1404
1562
|
const delta = event.delta;
|
|
@@ -1643,6 +1801,23 @@ function toCodexTools(tools) {
|
|
|
1643
1801
|
strict: null
|
|
1644
1802
|
}));
|
|
1645
1803
|
}
|
|
1804
|
+
function extractCodexRequestId(message) {
|
|
1805
|
+
const match = message.match(/request ID ([a-z0-9-]{8,})/i);
|
|
1806
|
+
return match?.[1];
|
|
1807
|
+
}
|
|
1808
|
+
function parseCodexErrorBody(text) {
|
|
1809
|
+
if (!text) return {};
|
|
1810
|
+
try {
|
|
1811
|
+
const parsed = JSON.parse(text);
|
|
1812
|
+
const error = parsed.error;
|
|
1813
|
+
const message = error?.message ?? parsed.message;
|
|
1814
|
+
const requestId = parsed.request_id ?? error?.request_id ?? (message ? extractCodexRequestId(message) : void 0);
|
|
1815
|
+
return { ...message ? { message } : {}, ...requestId ? { requestId } : {} };
|
|
1816
|
+
} catch {
|
|
1817
|
+
const trimmed = text.trim().slice(0, 240);
|
|
1818
|
+
return trimmed ? { message: trimmed } : {};
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1646
1821
|
|
|
1647
1822
|
// src/provider-registry.ts
|
|
1648
1823
|
var ProviderRegistryImpl = class {
|
|
@@ -1903,6 +2078,8 @@ function registerPalsuProvider(config) {
|
|
|
1903
2078
|
GGAIError,
|
|
1904
2079
|
ProviderError,
|
|
1905
2080
|
StreamResult,
|
|
2081
|
+
formatError,
|
|
2082
|
+
formatErrorForDisplay,
|
|
1906
2083
|
palsuAssistantMessage,
|
|
1907
2084
|
palsuText,
|
|
1908
2085
|
palsuThinking,
|