@pure01fx/dsh-openai-codex-auth 0.5.0 → 0.6.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/CHANGELOG.md +42 -0
- package/README.md +33 -5
- package/client.js +186 -16
- package/cordis.patch.yml +2 -6
- package/lib/catalog.d.ts +77 -0
- package/lib/catalog.js +383 -0
- package/lib/endpoint.d.ts +2 -0
- package/lib/endpoint.js +38 -0
- package/lib/index.d.ts +63 -17
- package/lib/index.js +535 -130
- package/lib/native-adapter.d.ts +43 -0
- package/lib/native-adapter.js +246 -0
- package/lib/native-http.d.ts +61 -0
- package/lib/native-http.js +602 -0
- package/lib/native-websocket-session.d.ts +14 -0
- package/lib/native-websocket-session.js +109 -0
- package/lib/native-websocket-socket.d.ts +28 -0
- package/lib/native-websocket-socket.js +215 -0
- package/lib/native-websocket.d.ts +45 -0
- package/lib/native-websocket.js +615 -0
- package/lib/rate-limits.d.ts +35 -0
- package/lib/rate-limits.js +189 -0
- package/lib/replay.d.ts +49 -0
- package/lib/replay.js +240 -0
- package/lib/response-usage.d.ts +14 -0
- package/lib/response-usage.js +35 -0
- package/lib/responses.d.ts +126 -0
- package/lib/responses.js +572 -0
- package/lib/sse.d.ts +13 -0
- package/lib/sse.js +81 -0
- package/lib/upstream.d.ts +6 -0
- package/lib/upstream.js +6 -0
- package/lib/usage.d.ts +29 -0
- package/lib/usage.js +160 -0
- package/package.json +47 -11
package/lib/usage.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Account-scoped subscription quota projection and reconciliation. */
|
|
2
|
+
import { type CodexRateLimitCredits, type CodexRateLimitUpdate } from './rate-limits.js';
|
|
3
|
+
export interface UsageWindow {
|
|
4
|
+
usedPercent: number;
|
|
5
|
+
windowSeconds?: number;
|
|
6
|
+
resetAt?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface UsageLimitSummary {
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
primary?: UsageWindow;
|
|
12
|
+
secondary?: UsageWindow;
|
|
13
|
+
limitReached?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface UsageSummary {
|
|
16
|
+
planType?: string;
|
|
17
|
+
primary?: UsageWindow;
|
|
18
|
+
secondary?: UsageWindow;
|
|
19
|
+
limitReached?: boolean;
|
|
20
|
+
resetCredits?: number;
|
|
21
|
+
credits?: CodexRateLimitCredits;
|
|
22
|
+
limits?: UsageLimitSummary[];
|
|
23
|
+
source: 'response' | 'endpoint';
|
|
24
|
+
fetchedAt: number;
|
|
25
|
+
}
|
|
26
|
+
/** Reduce a full `wham/usage` payload to bounded fields displayed by the Web card. */
|
|
27
|
+
export declare function normalizeUsage(value: unknown): UsageSummary;
|
|
28
|
+
/** Merge sparse direct transport observations while retaining endpoint-only metadata. */
|
|
29
|
+
export declare function mergeDirectUsage(previous: UsageSummary | undefined, updates: readonly CodexRateLimitUpdate[]): UsageSummary;
|
package/lib/usage.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/** Account-scoped subscription quota projection and reconciliation. */
|
|
2
|
+
import { parseCodexRateLimitCredits, } from './rate-limits.js';
|
|
3
|
+
function optionalNumber(value) {
|
|
4
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
function usageWindow(value) {
|
|
7
|
+
if (value === null || typeof value !== 'object')
|
|
8
|
+
return undefined;
|
|
9
|
+
const row = value;
|
|
10
|
+
const usedPercent = optionalNumber(row.used_percent ?? row.usedPercent);
|
|
11
|
+
if (usedPercent === undefined)
|
|
12
|
+
return undefined;
|
|
13
|
+
const windowSeconds = optionalNumber(row.limit_window_seconds ?? row.windowDurationSecs);
|
|
14
|
+
const resetAt = optionalNumber(row.reset_at ?? row.resetsAt);
|
|
15
|
+
return {
|
|
16
|
+
usedPercent: Math.max(0, Math.min(100, usedPercent)),
|
|
17
|
+
...windowSeconds === undefined ? {} : { windowSeconds },
|
|
18
|
+
...resetAt === undefined ? {} : { resetAt },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function boundedUsageText(value) {
|
|
22
|
+
if (typeof value !== 'string')
|
|
23
|
+
return undefined;
|
|
24
|
+
const text = value.trim();
|
|
25
|
+
return text.length > 0 && text.length <= 128 ? text : undefined;
|
|
26
|
+
}
|
|
27
|
+
function normalizedUsageLimitId(value) {
|
|
28
|
+
return boundedUsageText(value)?.toLowerCase().replaceAll('-', '_');
|
|
29
|
+
}
|
|
30
|
+
function usageLimit(id, name, value) {
|
|
31
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
32
|
+
return undefined;
|
|
33
|
+
const row = value;
|
|
34
|
+
const primary = usageWindow(row.primary_window ?? row.primary);
|
|
35
|
+
const secondary = usageWindow(row.secondary_window ?? row.secondary);
|
|
36
|
+
const limitReached = typeof row.limit_reached === 'boolean'
|
|
37
|
+
? row.limit_reached
|
|
38
|
+
: typeof row.limitReached === 'boolean' ? row.limitReached : undefined;
|
|
39
|
+
if (primary === undefined && secondary === undefined && limitReached === undefined)
|
|
40
|
+
return undefined;
|
|
41
|
+
return {
|
|
42
|
+
id,
|
|
43
|
+
...name === undefined ? {} : { name },
|
|
44
|
+
...primary === undefined ? {} : { primary },
|
|
45
|
+
...secondary === undefined ? {} : { secondary },
|
|
46
|
+
...limitReached === undefined ? {} : { limitReached },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function sortedUsageLimits(limits) {
|
|
50
|
+
return [...limits].sort((left, right) => {
|
|
51
|
+
if (left.id === 'codex')
|
|
52
|
+
return right.id === 'codex' ? 0 : -1;
|
|
53
|
+
if (right.id === 'codex')
|
|
54
|
+
return 1;
|
|
55
|
+
return left.id.localeCompare(right.id);
|
|
56
|
+
}).slice(0, 32);
|
|
57
|
+
}
|
|
58
|
+
/** Reduce a full `wham/usage` payload to bounded fields displayed by the Web card. */
|
|
59
|
+
export function normalizeUsage(value) {
|
|
60
|
+
const root = value !== null && typeof value === 'object' ? value : {};
|
|
61
|
+
const defaultValue = root.rate_limit ?? root.rateLimits;
|
|
62
|
+
const defaultLimit = usageLimit('codex', undefined, defaultValue);
|
|
63
|
+
const limits = defaultLimit === undefined ? [] : [defaultLimit];
|
|
64
|
+
const additional = root.additional_rate_limits ?? root.additionalRateLimits;
|
|
65
|
+
if (Array.isArray(additional)) {
|
|
66
|
+
for (const value of additional.slice(0, 31)) {
|
|
67
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
68
|
+
continue;
|
|
69
|
+
const row = value;
|
|
70
|
+
const id = normalizedUsageLimitId(row.metered_feature ?? row.meteredFeature);
|
|
71
|
+
if (id === undefined || id === 'codex' || limits.some(limit => limit.id === id))
|
|
72
|
+
continue;
|
|
73
|
+
const extra = usageLimit(id, boundedUsageText(row.limit_name ?? row.limitName), row.rate_limit ?? row.rateLimit);
|
|
74
|
+
if (extra !== undefined)
|
|
75
|
+
limits.push(extra);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const sortedLimits = sortedUsageLimits(limits);
|
|
79
|
+
const projected = sortedLimits.find(limit => limit.id === 'codex') ?? sortedLimits[0];
|
|
80
|
+
const resetCreditValue = root.rate_limit_reset_credits ?? root.rateLimitResetCredits;
|
|
81
|
+
const resetCreditRow = resetCreditValue !== null && typeof resetCreditValue === 'object'
|
|
82
|
+
? resetCreditValue : undefined;
|
|
83
|
+
const resetCredits = optionalNumber(resetCreditRow?.available_count ?? resetCreditRow?.availableCount);
|
|
84
|
+
const planType = boundedUsageText(root.plan_type ?? root.planType);
|
|
85
|
+
const parsedCredits = parseCodexRateLimitCredits(root.credits);
|
|
86
|
+
return {
|
|
87
|
+
...planType === undefined ? {} : { planType },
|
|
88
|
+
...projected?.primary === undefined ? {} : { primary: projected.primary },
|
|
89
|
+
...projected?.secondary === undefined ? {} : { secondary: projected.secondary },
|
|
90
|
+
...projected?.limitReached === undefined ? {} : { limitReached: projected.limitReached },
|
|
91
|
+
...resetCredits === undefined ? {} : { resetCredits },
|
|
92
|
+
...parsedCredits === undefined ? {} : { credits: parsedCredits },
|
|
93
|
+
...sortedLimits.length === 0 ? {} : { limits: sortedLimits },
|
|
94
|
+
source: 'endpoint',
|
|
95
|
+
fetchedAt: Date.now(),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function mergeUsageWindow(previous, update) {
|
|
99
|
+
return {
|
|
100
|
+
usedPercent: update.usedPercent,
|
|
101
|
+
...update.windowSeconds === undefined
|
|
102
|
+
? previous?.windowSeconds === undefined ? {} : { windowSeconds: previous.windowSeconds }
|
|
103
|
+
: { windowSeconds: update.windowSeconds },
|
|
104
|
+
...update.resetAt === undefined
|
|
105
|
+
? previous?.resetAt === undefined ? {} : { resetAt: previous.resetAt }
|
|
106
|
+
: { resetAt: update.resetAt },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function mergeUsageLimit(previous, update) {
|
|
110
|
+
const primary = update.primary === undefined ? previous?.primary
|
|
111
|
+
: update.primary === null ? undefined : mergeUsageWindow(previous?.primary, update.primary);
|
|
112
|
+
const secondary = update.secondary === undefined ? previous?.secondary
|
|
113
|
+
: update.secondary === null ? undefined : mergeUsageWindow(previous?.secondary, update.secondary);
|
|
114
|
+
const name = update.limitName ?? previous?.name;
|
|
115
|
+
const limitReached = update.limitReached ?? previous?.limitReached;
|
|
116
|
+
return {
|
|
117
|
+
id: update.limitId,
|
|
118
|
+
...name === undefined ? {} : { name },
|
|
119
|
+
...primary === undefined ? {} : { primary },
|
|
120
|
+
...secondary === undefined ? {} : { secondary },
|
|
121
|
+
...limitReached === undefined ? {} : { limitReached },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** Merge sparse direct transport observations while retaining endpoint-only metadata. */
|
|
125
|
+
export function mergeDirectUsage(previous, updates) {
|
|
126
|
+
const byId = new Map((previous?.limits ?? []).map(limit => [limit.id, limit]));
|
|
127
|
+
if (byId.size === 0 && previous !== undefined
|
|
128
|
+
&& (previous.primary !== undefined || previous.secondary !== undefined
|
|
129
|
+
|| previous.limitReached !== undefined)) {
|
|
130
|
+
byId.set('codex', {
|
|
131
|
+
id: 'codex',
|
|
132
|
+
...previous.primary === undefined ? {} : { primary: previous.primary },
|
|
133
|
+
...previous.secondary === undefined ? {} : { secondary: previous.secondary },
|
|
134
|
+
...previous.limitReached === undefined ? {} : { limitReached: previous.limitReached },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
for (const update of updates.slice(0, 32)) {
|
|
138
|
+
byId.set(update.limitId, mergeUsageLimit(byId.get(update.limitId), update));
|
|
139
|
+
}
|
|
140
|
+
const limits = sortedUsageLimits(byId.values());
|
|
141
|
+
const projected = limits.find(limit => limit.id === 'codex') ?? limits[0];
|
|
142
|
+
const planType = updates.find(update => update.planType !== undefined)?.planType ?? previous?.planType;
|
|
143
|
+
const parsedCredits = updates.find(update => update.credits !== undefined)?.credits ?? previous?.credits;
|
|
144
|
+
const resetCredits = previous?.resetCredits;
|
|
145
|
+
const hasDirectDefault = updates.some(update => update.limitId === 'codex'
|
|
146
|
+
&& (update.primary !== undefined || update.secondary !== undefined));
|
|
147
|
+
const source = hasDirectDefault ? 'response' : previous?.source ?? 'response';
|
|
148
|
+
const fetchedAt = hasDirectDefault ? Date.now() : previous?.fetchedAt ?? Date.now();
|
|
149
|
+
return {
|
|
150
|
+
...planType === undefined ? {} : { planType },
|
|
151
|
+
...projected?.primary === undefined ? {} : { primary: projected.primary },
|
|
152
|
+
...projected?.secondary === undefined ? {} : { secondary: projected.secondary },
|
|
153
|
+
...projected?.limitReached === undefined ? {} : { limitReached: projected.limitReached },
|
|
154
|
+
...resetCredits === undefined ? {} : { resetCredits },
|
|
155
|
+
...parsedCredits === undefined ? {} : { credits: parsedCredits },
|
|
156
|
+
...limits.length === 0 ? {} : { limits },
|
|
157
|
+
source,
|
|
158
|
+
fetchedAt,
|
|
159
|
+
};
|
|
160
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pure01fx/dsh-openai-codex-auth",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Native ChatGPT Codex provider, device-code-first login, and same-origin Web integration for DeepSeek Harness",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
11
|
"url": "git+https://github.com/pure01fx/dsh-openai-codex-auth.git"
|
|
@@ -30,16 +33,46 @@
|
|
|
30
33
|
"files": [
|
|
31
34
|
"lib/index.js",
|
|
32
35
|
"lib/index.d.ts",
|
|
36
|
+
"lib/catalog.js",
|
|
37
|
+
"lib/catalog.d.ts",
|
|
38
|
+
"lib/endpoint.js",
|
|
39
|
+
"lib/endpoint.d.ts",
|
|
40
|
+
"lib/native-adapter.js",
|
|
41
|
+
"lib/native-adapter.d.ts",
|
|
42
|
+
"lib/native-http.js",
|
|
43
|
+
"lib/native-http.d.ts",
|
|
44
|
+
"lib/native-websocket.js",
|
|
45
|
+
"lib/native-websocket.d.ts",
|
|
46
|
+
"lib/native-websocket-session.js",
|
|
47
|
+
"lib/native-websocket-session.d.ts",
|
|
48
|
+
"lib/native-websocket-socket.js",
|
|
49
|
+
"lib/native-websocket-socket.d.ts",
|
|
50
|
+
"lib/responses.js",
|
|
51
|
+
"lib/responses.d.ts",
|
|
52
|
+
"lib/replay.js",
|
|
53
|
+
"lib/replay.d.ts",
|
|
54
|
+
"lib/rate-limits.js",
|
|
55
|
+
"lib/rate-limits.d.ts",
|
|
56
|
+
"lib/response-usage.js",
|
|
57
|
+
"lib/response-usage.d.ts",
|
|
58
|
+
"lib/upstream.js",
|
|
59
|
+
"lib/upstream.d.ts",
|
|
60
|
+
"lib/sse.js",
|
|
61
|
+
"lib/sse.d.ts",
|
|
62
|
+
"lib/usage.js",
|
|
63
|
+
"lib/usage.d.ts",
|
|
33
64
|
"client.js",
|
|
34
65
|
"cordis.patch.yml",
|
|
35
66
|
"assets/readme/hero.svg",
|
|
36
67
|
"assets/readme/workflow.svg",
|
|
37
68
|
"README.md",
|
|
69
|
+
"CHANGELOG.md",
|
|
38
70
|
"LICENSE"
|
|
39
71
|
],
|
|
40
72
|
"scripts": {
|
|
41
73
|
"build": "tsc",
|
|
42
|
-
"test": "vitest run"
|
|
74
|
+
"test": "vitest run",
|
|
75
|
+
"prepack": "pnpm build"
|
|
43
76
|
},
|
|
44
77
|
"dsh": {
|
|
45
78
|
"bundle": {
|
|
@@ -56,20 +89,23 @@
|
|
|
56
89
|
},
|
|
57
90
|
"peerDependencies": {
|
|
58
91
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
59
|
-
"@deepseek-ai/dsh-credentials": "
|
|
60
|
-
"@deepseek-ai/dsh-host-webserver": "
|
|
92
|
+
"@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
|
|
93
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.0-rc.6",
|
|
94
|
+
"@deepseek-ai/dsh-llm": "0.1.0-rc.6"
|
|
61
95
|
},
|
|
62
96
|
"dependencies": {
|
|
63
|
-
"@deepseek-ai/dsh-atomic-write": "
|
|
64
|
-
"@deepseek-ai/dsh-credentials": "
|
|
65
|
-
"@deepseek-ai/dsh-home-paths": "
|
|
66
|
-
"@deepseek-ai/schemastery": "^3.18.1"
|
|
97
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.0-rc.6",
|
|
98
|
+
"@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
|
|
99
|
+
"@deepseek-ai/dsh-home-paths": "0.1.0-rc.6",
|
|
100
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
101
|
+
"ws": "8.21.3"
|
|
67
102
|
},
|
|
68
103
|
"devDependencies": {
|
|
69
104
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
70
105
|
"@deepseek-ai/dsh-agent": "0.1.0-rc.6",
|
|
71
|
-
"@deepseek-ai/dsh-credentials": "
|
|
72
|
-
"@deepseek-ai/dsh-host-webserver": "
|
|
106
|
+
"@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
|
|
107
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.0-rc.6",
|
|
108
|
+
"@deepseek-ai/dsh-llm": "0.1.0-rc.6",
|
|
73
109
|
"@deepseek-ai/dsh-session": "0.1.0-rc.6",
|
|
74
110
|
"@types/node": "^22.20.0",
|
|
75
111
|
"typescript": "^6.0.3",
|