@demicodes/provider-codex 0.6.0 → 0.7.0
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.d.mts +0 -2
- package/dist/index.mjs +48 -36
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -95,8 +95,6 @@ interface CodexProviderConfig {
|
|
|
95
95
|
transport?: CodexTransportMode;
|
|
96
96
|
headers?: Record<string, string>;
|
|
97
97
|
userAgent?: string;
|
|
98
|
-
maxRetries?: number;
|
|
99
|
-
retryBaseDelayMs?: number;
|
|
100
98
|
headerTimeoutMs?: number;
|
|
101
99
|
websocketConnectTimeoutMs?: number;
|
|
102
100
|
streamIdleTimeoutMs?: number;
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { Buffer } from "node:buffer";
|
|
|
3
3
|
import { chmod, mkdir, open, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
|
-
import { applyModelPolicy, clampPromptCacheKey, clampUsedPercent, createProviderQuota, defineProvider, httpErrorCode, normalizeErrorCode, numberHeader, redactCredentialText, severityFromUsedPercent, unixSecondsToIso } from "@demicodes/provider";
|
|
6
|
+
import { applyModelPolicy, clampPromptCacheKey, clampUsedPercent, createProviderQuota, defineProvider, httpErrorCode, normalizeErrorCode, numberHeader, redactCredentialText, retryAfterMsFromHeader, severityFromUsedPercent, unixSecondsToIso } from "@demicodes/provider";
|
|
7
7
|
import { FileCredentialPool, credentialIdFromIdentity } from "@demicodes/provider/credentials-pool";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
//#region src/auth.ts
|
|
@@ -1037,10 +1037,18 @@ function* mapCodexResponseEvent(event, state = newStreamState()) {
|
|
|
1037
1037
|
return;
|
|
1038
1038
|
case "error": {
|
|
1039
1039
|
const nested = isRecord(event.error) ? event.error : null;
|
|
1040
|
+
const message = event.message ?? stringOrNull(nested?.message) ?? "Codex stream error";
|
|
1041
|
+
const rawCode = event.code ?? stringOrNull(nested?.code) ?? stringOrNull(nested?.type);
|
|
1042
|
+
const providerRequestId = providerRequestIdFrom(nested, message);
|
|
1040
1043
|
yield {
|
|
1041
1044
|
type: "error",
|
|
1042
|
-
message
|
|
1043
|
-
code:
|
|
1045
|
+
message,
|
|
1046
|
+
code: normalizeErrorCode(rawCode, message),
|
|
1047
|
+
diagnostics: {
|
|
1048
|
+
source: "stream",
|
|
1049
|
+
...rawCode ? { providerCode: rawCode } : {},
|
|
1050
|
+
...providerRequestId ? { providerRequestId } : {}
|
|
1051
|
+
}
|
|
1044
1052
|
};
|
|
1045
1053
|
return;
|
|
1046
1054
|
}
|
|
@@ -1194,12 +1202,26 @@ function reasoningText(item) {
|
|
|
1194
1202
|
function errorEventFromFailedResponse(response) {
|
|
1195
1203
|
const error = isRecord(response) && isRecord(response.error) ? response.error : null;
|
|
1196
1204
|
const message = stringOrNull(error?.message) ?? "Codex response failed";
|
|
1205
|
+
const rawCode = stringOrNull(error?.code) ?? stringOrNull(error?.type);
|
|
1206
|
+
const providerRequestId = providerRequestIdFrom(error, message);
|
|
1207
|
+
const providerResponseId = isRecord(response) ? stringOrNull(response.id) : null;
|
|
1197
1208
|
return {
|
|
1198
1209
|
type: "error",
|
|
1199
1210
|
message,
|
|
1200
|
-
code: normalizeErrorCode(
|
|
1211
|
+
code: normalizeErrorCode(rawCode, message),
|
|
1212
|
+
diagnostics: {
|
|
1213
|
+
source: "stream",
|
|
1214
|
+
...rawCode ? { providerCode: rawCode } : {},
|
|
1215
|
+
...providerRequestId ? { providerRequestId } : {},
|
|
1216
|
+
...providerResponseId ? { providerResponseId } : {}
|
|
1217
|
+
}
|
|
1201
1218
|
};
|
|
1202
1219
|
}
|
|
1220
|
+
function providerRequestIdFrom(value, message) {
|
|
1221
|
+
const explicit = stringOrNull(value?.request_id) ?? stringOrNull(value?.requestId);
|
|
1222
|
+
if (explicit) return explicit;
|
|
1223
|
+
return message.match(/request ID ([A-Za-z0-9-]+)/i)?.[1] ?? null;
|
|
1224
|
+
}
|
|
1203
1225
|
function incompleteReason(response) {
|
|
1204
1226
|
if (isRecord(response) && isRecord(response.incomplete_details) && typeof response.incomplete_details.reason === "string") return response.incomplete_details.reason;
|
|
1205
1227
|
return "unknown";
|
|
@@ -1530,8 +1552,6 @@ function defaultWebSocketConstructor() {
|
|
|
1530
1552
|
//#region src/provider.ts
|
|
1531
1553
|
const DEFAULT_CHATGPT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
1532
1554
|
const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
|
|
1533
|
-
const DEFAULT_MAX_RETRIES = 2;
|
|
1534
|
-
const DEFAULT_RETRY_BASE_DELAY_MS = 250;
|
|
1535
1555
|
const DEFAULT_SSE_HEADER_TIMEOUT_MS = 2e4;
|
|
1536
1556
|
const DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS = 1e4;
|
|
1537
1557
|
var CodexProvider = class {
|
|
@@ -1546,8 +1566,6 @@ var CodexProvider = class {
|
|
|
1546
1566
|
transport: options.transport ?? "auto",
|
|
1547
1567
|
headers: options.headers,
|
|
1548
1568
|
userAgent: options.userAgent ?? defaultUserAgent(),
|
|
1549
|
-
maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
1550
|
-
retryBaseDelayMs: options.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS,
|
|
1551
1569
|
headerTimeoutMs: options.headerTimeoutMs ?? DEFAULT_SSE_HEADER_TIMEOUT_MS,
|
|
1552
1570
|
websocketConnectTimeoutMs: options.websocketConnectTimeoutMs ?? DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS,
|
|
1553
1571
|
streamIdleTimeoutMs: options.streamIdleTimeoutMs ?? 0,
|
|
@@ -1560,8 +1578,7 @@ var CodexProvider = class {
|
|
|
1560
1578
|
async *run(request) {
|
|
1561
1579
|
const body = buildCodexResponsesRequestBody(request);
|
|
1562
1580
|
let forceRefresh = false;
|
|
1563
|
-
|
|
1564
|
-
while (retryAttempt <= this.config.maxRetries) try {
|
|
1581
|
+
while (true) try {
|
|
1565
1582
|
const auth = await this.authStore.resolveAuth({ forceRefresh });
|
|
1566
1583
|
const url = responsesUrlForAuth(auth, this.config.baseUrl);
|
|
1567
1584
|
const headers = buildCodexHeaders(auth, request, this.config);
|
|
@@ -1595,11 +1612,6 @@ var CodexProvider = class {
|
|
|
1595
1612
|
forceRefresh = true;
|
|
1596
1613
|
continue;
|
|
1597
1614
|
}
|
|
1598
|
-
if (error instanceof CodexHttpError && isRetryableHttpStatus(error.status) && retryAttempt < this.config.maxRetries) {
|
|
1599
|
-
await sleep(this.config.retryBaseDelayMs * 2 ** retryAttempt, request.cancel);
|
|
1600
|
-
retryAttempt += 1;
|
|
1601
|
-
continue;
|
|
1602
|
-
}
|
|
1603
1615
|
yield providerErrorFromUnknown(error);
|
|
1604
1616
|
return;
|
|
1605
1617
|
}
|
|
@@ -1623,8 +1635,6 @@ function createCodexProvider(options = {}) {
|
|
|
1623
1635
|
transport: options.transport,
|
|
1624
1636
|
headers: options.headers,
|
|
1625
1637
|
userAgent: options.userAgent,
|
|
1626
|
-
maxRetries: options.maxRetries,
|
|
1627
|
-
retryBaseDelayMs: options.retryBaseDelayMs,
|
|
1628
1638
|
headerTimeoutMs: options.headerTimeoutMs,
|
|
1629
1639
|
websocketConnectTimeoutMs: options.websocketConnectTimeoutMs,
|
|
1630
1640
|
streamIdleTimeoutMs: options.streamIdleTimeoutMs,
|
|
@@ -1688,33 +1698,35 @@ function providerErrorFromUnknown(error) {
|
|
|
1688
1698
|
message: redactCodexSecretText(error.message),
|
|
1689
1699
|
code: error.code
|
|
1690
1700
|
};
|
|
1691
|
-
if (error instanceof CodexHttpError)
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
code
|
|
1695
|
-
|
|
1701
|
+
if (error instanceof CodexHttpError) {
|
|
1702
|
+
const body = parseJsonObject(error.responseText);
|
|
1703
|
+
const bodyError = isRecord(body?.error) ? body.error : null;
|
|
1704
|
+
const providerCode = stringOrNull(bodyError?.code) ?? stringOrNull(bodyError?.type);
|
|
1705
|
+
const providerRequestId = error.headers.get("x-request-id") ?? stringOrNull(body?.request_id);
|
|
1706
|
+
const retryAfterMs = retryAfterMsFromHeader(error.headers.get("retry-after"));
|
|
1707
|
+
return {
|
|
1708
|
+
type: "error",
|
|
1709
|
+
message: redactCodexSecretText(error.message),
|
|
1710
|
+
code: httpErrorCode(error.status, error.message),
|
|
1711
|
+
...retryAfterMs !== void 0 ? { retryAfterMs } : {},
|
|
1712
|
+
diagnostics: {
|
|
1713
|
+
source: "http",
|
|
1714
|
+
httpStatus: error.status,
|
|
1715
|
+
...providerCode ? { providerCode } : {},
|
|
1716
|
+
...providerRequestId ? { providerRequestId } : {}
|
|
1717
|
+
}
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1696
1720
|
const message = error instanceof Error ? error.message : String(error);
|
|
1697
1721
|
return {
|
|
1698
1722
|
type: "error",
|
|
1699
1723
|
message: redactCodexSecretText(message),
|
|
1700
|
-
code: normalizeErrorCode(null, message)
|
|
1724
|
+
code: normalizeErrorCode(null, message),
|
|
1725
|
+
diagnostics: { source: "transport" }
|
|
1701
1726
|
};
|
|
1702
1727
|
}
|
|
1703
|
-
function isRetryableHttpStatus(status) {
|
|
1704
|
-
return status === 408 || status === 409 || status === 425 || status === 429 || status === 500 || status === 502 || status === 503 || status === 504;
|
|
1705
|
-
}
|
|
1706
1728
|
function defaultUserAgent() {
|
|
1707
1729
|
return `demi-codex-provider/0.0.0 (${process.platform}; ${process.arch})`;
|
|
1708
1730
|
}
|
|
1709
|
-
function sleep(ms, signal) {
|
|
1710
|
-
if (signal.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
1711
|
-
return new Promise((resolve, reject) => {
|
|
1712
|
-
const timeout = setTimeout(resolve, ms);
|
|
1713
|
-
signal.addEventListener("abort", () => {
|
|
1714
|
-
clearTimeout(timeout);
|
|
1715
|
-
reject(new DOMException("Aborted", "AbortError"));
|
|
1716
|
-
}, { once: true });
|
|
1717
|
-
});
|
|
1718
|
-
}
|
|
1719
1731
|
//#endregion
|
|
1720
1732
|
export { PoolAwareCodexAuthStore, codexAuthStatus, createCodexCredentials, createCodexProvider, createCodexQuota, listCodexModels, mapCodexRateLimitHeaders, openCodexCredentialPool, runCodexDeviceLogin };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@demicodes/provider-codex",
|
|
3
3
|
"description": "Codex provider adapter for Demi.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@demicodes/core": "^0.
|
|
15
|
-
"@demicodes/provider": "^0.
|
|
16
|
-
"@demicodes/utils": "^0.
|
|
14
|
+
"@demicodes/core": "^0.7.0",
|
|
15
|
+
"@demicodes/provider": "^0.7.0",
|
|
16
|
+
"@demicodes/utils": "^0.7.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@demicodes/agent": "^0.
|
|
20
|
-
"@demicodes/shell": "^0.
|
|
19
|
+
"@demicodes/agent": "^0.7.0",
|
|
20
|
+
"@demicodes/shell": "^0.7.0"
|
|
21
21
|
},
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"main": "./dist/index.mjs",
|