@kenkaiiii/gg-ai 4.3.164 → 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 +214 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -3
- package/dist/index.d.ts +60 -3
- package/dist/index.js +212 -33
- 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);
|
|
@@ -428,8 +574,8 @@ function supportsAdaptiveThinking(model) {
|
|
|
428
574
|
}
|
|
429
575
|
function toAnthropicThinking(level, maxTokens, model) {
|
|
430
576
|
if (supportsAdaptiveThinking(model)) {
|
|
431
|
-
let effort = level;
|
|
432
|
-
if (
|
|
577
|
+
let effort = level === "xhigh" ? "max" : level;
|
|
578
|
+
if (effort === "max" && !model.includes("opus")) {
|
|
433
579
|
effort = "high";
|
|
434
580
|
}
|
|
435
581
|
return {
|
|
@@ -438,7 +584,7 @@ function toAnthropicThinking(level, maxTokens, model) {
|
|
|
438
584
|
outputConfig: { effort }
|
|
439
585
|
};
|
|
440
586
|
}
|
|
441
|
-
const effectiveLevel = level === "
|
|
587
|
+
const effectiveLevel = level === "xhigh" ? "high" : level;
|
|
442
588
|
const budgetMap = {
|
|
443
589
|
low: Math.max(1024, Math.floor(maxTokens * 0.25)),
|
|
444
590
|
medium: Math.max(2048, Math.floor(maxTokens * 0.5)),
|
|
@@ -571,8 +717,12 @@ function toOpenAIToolChoice(choice) {
|
|
|
571
717
|
if (choice === "required") return "required";
|
|
572
718
|
return { type: "function", function: { name: choice.name } };
|
|
573
719
|
}
|
|
574
|
-
function
|
|
575
|
-
return
|
|
720
|
+
function isOpenAIProVariant(model) {
|
|
721
|
+
return /^gpt-5\.\d+-pro$/i.test(model);
|
|
722
|
+
}
|
|
723
|
+
function toOpenAIReasoningEffort(level, model) {
|
|
724
|
+
if (isOpenAIProVariant(model) && level === "low") return "medium";
|
|
725
|
+
return level;
|
|
576
726
|
}
|
|
577
727
|
function normalizeAnthropicStopReason(reason) {
|
|
578
728
|
switch (reason) {
|
|
@@ -995,8 +1145,10 @@ function messageToResponse(message) {
|
|
|
995
1145
|
}
|
|
996
1146
|
function toError(err) {
|
|
997
1147
|
if (err instanceof import_sdk.default.APIError) {
|
|
1148
|
+
const requestId = err.request_id ?? err.error?.request_id;
|
|
998
1149
|
return new ProviderError("anthropic", err.message, {
|
|
999
1150
|
statusCode: err.status,
|
|
1151
|
+
...requestId ? { requestId } : {},
|
|
1000
1152
|
cause: err
|
|
1001
1153
|
});
|
|
1002
1154
|
}
|
|
@@ -1039,7 +1191,7 @@ async function* runStream2(options) {
|
|
|
1039
1191
|
...effectiveTemp != null && !options.thinking ? { temperature: effectiveTemp } : {},
|
|
1040
1192
|
...options.topP != null ? { top_p: options.topP } : {},
|
|
1041
1193
|
...options.stop ? { stop: options.stop } : {},
|
|
1042
|
-
...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking) } : {},
|
|
1194
|
+
...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) } : {},
|
|
1043
1195
|
...options.tools?.length ? { tools: toOpenAITools(options.tools) } : {},
|
|
1044
1196
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
1045
1197
|
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
@@ -1288,19 +1440,19 @@ function completionToResponse(completion) {
|
|
|
1288
1440
|
}
|
|
1289
1441
|
function toError2(err, provider = "openai") {
|
|
1290
1442
|
if (err instanceof import_openai.default.APIError) {
|
|
1291
|
-
let msg = err.message;
|
|
1292
1443
|
const body = err.error;
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
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, {
|
|
1303
1453
|
statusCode: err.status,
|
|
1454
|
+
...requestId ? { requestId } : {},
|
|
1455
|
+
...hint ? { hint } : {},
|
|
1304
1456
|
cause: err
|
|
1305
1457
|
});
|
|
1306
1458
|
}
|
|
@@ -1362,19 +1514,19 @@ async function* runStream3(options) {
|
|
|
1362
1514
|
});
|
|
1363
1515
|
if (!response.ok) {
|
|
1364
1516
|
const text = await response.text().catch(() => "");
|
|
1365
|
-
|
|
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;
|
|
1366
1521
|
if (response.status === 400 && text.includes("not supported")) {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
}
|
|
1371
|
-
if (response.status === 404 && text.includes("does not exist")) {
|
|
1372
|
-
message += `
|
|
1373
|
-
|
|
1374
|
-
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.";
|
|
1375
1525
|
}
|
|
1376
1526
|
throw new ProviderError("openai", message, {
|
|
1377
|
-
statusCode: response.status
|
|
1527
|
+
statusCode: response.status,
|
|
1528
|
+
...requestId ? { requestId } : {},
|
|
1529
|
+
...hint ? { hint } : {}
|
|
1378
1530
|
});
|
|
1379
1531
|
}
|
|
1380
1532
|
if (!response.body) {
|
|
@@ -1389,12 +1541,22 @@ Hint: codex-mini-latest requires an OpenAI Pro ($200/mo) or Max subscription. GP
|
|
|
1389
1541
|
const type = event.type;
|
|
1390
1542
|
if (!type) continue;
|
|
1391
1543
|
if (type === "error") {
|
|
1392
|
-
const
|
|
1393
|
-
|
|
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
|
+
});
|
|
1394
1552
|
}
|
|
1395
1553
|
if (type === "response.failed") {
|
|
1396
|
-
const
|
|
1397
|
-
|
|
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
|
+
});
|
|
1398
1560
|
}
|
|
1399
1561
|
if (type === "response.output_text.delta") {
|
|
1400
1562
|
const delta = event.delta;
|
|
@@ -1639,6 +1801,23 @@ function toCodexTools(tools) {
|
|
|
1639
1801
|
strict: null
|
|
1640
1802
|
}));
|
|
1641
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
|
+
}
|
|
1642
1821
|
|
|
1643
1822
|
// src/provider-registry.ts
|
|
1644
1823
|
var ProviderRegistryImpl = class {
|
|
@@ -1899,6 +2078,8 @@ function registerPalsuProvider(config) {
|
|
|
1899
2078
|
GGAIError,
|
|
1900
2079
|
ProviderError,
|
|
1901
2080
|
StreamResult,
|
|
2081
|
+
formatError,
|
|
2082
|
+
formatErrorForDisplay,
|
|
1902
2083
|
palsuAssistantMessage,
|
|
1903
2084
|
palsuText,
|
|
1904
2085
|
palsuThinking,
|