@pure01fx/dsh-openai-codex-auth 0.10.0 → 0.10.1
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 +7 -0
- package/CODEX-COMPATIBILITY.md +7 -1
- package/README.md +3 -1
- package/client.js +23 -2
- package/lib/native-websocket-socket.js +7 -3
- package/lib/responses.d.ts +2 -2
- package/lib/responses.js +4 -4
- package/package.json +38 -33
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.10.1
|
|
6
|
+
|
|
7
|
+
- Targets DSH 0.1.5-rc.1 with exact SDK peers and runtime helpers; migrates Responses tool calls to ToolCallId.
|
|
8
|
+
- Keeps browser-local model hiding active during catalog, selection projection, and reconnection updates, filtering before subscribers receive snapshots.
|
|
9
|
+
- Accepts the real Node/ws successful send callback (`null`), avoiding false WebSocket send failures and unintended HTTP fallback; replaces the local ws declaration with official types and handles bounded RawData variants.
|
|
10
|
+
- Adds actual target directory and LLM/tools service protocol regression coverage. Older DSH releases are not claimed by this candidate.
|
|
11
|
+
|
|
5
12
|
## 0.10.0
|
|
6
13
|
|
|
7
14
|
### Codex cloud tools
|
package/CODEX-COMPATIBILITY.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Codex 云端能力兼容性跟踪
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## DSH 0.1.5-rc.1 版本适配
|
|
4
|
+
|
|
5
|
+
`0.10.1` 迁移 ToolCallId、精确 SDK 依赖和客户端服务提供包,隐藏策略在目录发布投影之前执行。`tests/target-directory.spec.ts` 执行官方 shell 的真实 store/Zustand/Immer 与目标目录/catalog 类,使用合成 Remote 响应和投影输入;这不是浏览器联合验收。`tests/target-services.spec.ts` 使用真实 Cordis/LlmRuntime/ToolRuntime、真实 loopback HTTP/SSE/WebSocket,验证工具 ID、工具执行、含加密 reasoning 的历史回放、永久错误和取消,并确认 WS 没有偷偷回退 HTTP。实际 socket 测试也修复了 ws 成功回调为 null 时的误判。
|
|
6
|
+
|
|
7
|
+
该版本不运行真实 OAuth、账号刷新或付费请求,不改写既有用户数据;旧版兼容性不在声明范围。下面的线上账号结果来自原 0.10.0 验证,不能视作本版本的新验证。升级/回滚建议见 README。
|
|
8
|
+
|
|
9
|
+
## 原 0.10.0 实现与验证边界
|
|
4
10
|
|
|
5
11
|
本次范围为已确认的非语音 Codex 云端服务。参考上游 b348fc26674189f758d5941cdab3f78f258b2aa7(cloud 专用跟踪常量在 src/upstream.ts);原 Provider 协议基线仍单独保留。四个工具是普通 DSH function 工具,不依赖专用模式,不覆盖现有工具。
|
|
6
12
|
|
package/README.md
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
## 快速开始
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
版本 `0.10.1` 明确适配 DeepSeek Harness `0.1.5-rc.1`,SDK peers/runtime helpers 精确锁定该版本;不声明兼容旧 SDK。旧 DSH `0.1.1-rc.2` profile 应保留原插件 `0.10.0`,升级时在独立 profile 安装新版插件并保留原 profile/锁文件以便回滚。无需迁移账号文件或浏览器隐藏列表;`dsh.engines` 仅作兼容性说明,不当作宿主硬门禁。
|
|
21
|
+
|
|
22
|
+
本版本通过真实目标 LLM/tools 服务与本地 HTTP/SSE/WebSocket 回放、错误/取消回归;模型隐藏覆盖真实目录/catalog/store 的投影更新、重连和重新加载。验证命令为 `pnpm typecheck && pnpm build && pnpm test`;当前版本未执行线上 OAuth/付费模型验收。
|
|
21
23
|
|
|
22
24
|
将插件安装到 DSH 的 `web` profile:
|
|
23
25
|
|
package/client.js
CHANGED
|
@@ -112,6 +112,9 @@ window.__ModuleLoader__.load({
|
|
|
112
112
|
dispose: directory.dispose,
|
|
113
113
|
wrappedLoad: undefined,
|
|
114
114
|
wrappedDispose: undefined,
|
|
115
|
+
set: directory.store && directory.store.set,
|
|
116
|
+
wrappedSet: undefined,
|
|
117
|
+
visibleGroups: undefined,
|
|
115
118
|
generation: 0,
|
|
116
119
|
rawGroups: directory.store && typeof directory.store.getSnapshot === 'function'
|
|
117
120
|
? directory.store.getSnapshot().groups : [],
|
|
@@ -124,15 +127,30 @@ window.__ModuleLoader__.load({
|
|
|
124
127
|
const groups = visibleModelGroups(rawGroups)
|
|
125
128
|
return value && typeof value === 'object' ? { ...value, groups } : value
|
|
126
129
|
}
|
|
127
|
-
record.rawGroups = rawGroups
|
|
130
|
+
if (rawGroups !== record.visibleGroups) record.rawGroups = rawGroups
|
|
128
131
|
const groups = render(directory, record.rawGroups)
|
|
132
|
+
record.visibleGroups = groups
|
|
129
133
|
return value && typeof value === 'object' ? { ...value, groups } : value
|
|
130
134
|
}
|
|
131
135
|
record.wrappedDispose = function (...args) {
|
|
132
136
|
++record.generation
|
|
133
137
|
tracked.delete(directory)
|
|
138
|
+
if (directory.store.set === record.wrappedSet) directory.store.set = record.set
|
|
134
139
|
return record.dispose.apply(this, args)
|
|
135
140
|
}
|
|
141
|
+
// Target ModelDirectory publishes catalog/selection/reconnect snapshots through set.
|
|
142
|
+
// Filter before publication so no subscriber can observe a hidden row.
|
|
143
|
+
if (typeof record.set === 'function') {
|
|
144
|
+
record.wrappedSet = function (state) {
|
|
145
|
+
if (state.groups !== record.visibleGroups) record.rawGroups = state.groups
|
|
146
|
+
const available = codexModels(record.rawGroups)
|
|
147
|
+
if (available.length > 0) writeAvailableModels(available)
|
|
148
|
+
const groups = visibleModelGroups(record.rawGroups)
|
|
149
|
+
record.visibleGroups = groups
|
|
150
|
+
return record.set.call(this, { ...state, groups })
|
|
151
|
+
}
|
|
152
|
+
directory.store.set = record.wrappedSet
|
|
153
|
+
}
|
|
136
154
|
directory.load = record.wrappedLoad
|
|
137
155
|
directory.dispose = record.wrappedDispose
|
|
138
156
|
tracked.set(directory, record)
|
|
@@ -148,7 +166,9 @@ window.__ModuleLoader__.load({
|
|
|
148
166
|
for (const directory of resolver.live.directories.values()) track(directory)
|
|
149
167
|
}
|
|
150
168
|
const refresh = () => {
|
|
151
|
-
for (const [directory, record] of tracked)
|
|
169
|
+
for (const [directory, record] of tracked) {
|
|
170
|
+
record.visibleGroups = render(directory, record.rawGroups)
|
|
171
|
+
}
|
|
152
172
|
}
|
|
153
173
|
window.addEventListener(MODEL_VISIBILITY_EVENT, refresh)
|
|
154
174
|
|
|
@@ -159,6 +179,7 @@ window.__ModuleLoader__.load({
|
|
|
159
179
|
++record.generation
|
|
160
180
|
if (directory.load === record.wrappedLoad) directory.load = record.load
|
|
161
181
|
if (directory.dispose === record.wrappedDispose) directory.dispose = record.dispose
|
|
182
|
+
if (directory.store.set === record.wrappedSet) directory.store.set = record.set
|
|
162
183
|
}
|
|
163
184
|
tracked.clear()
|
|
164
185
|
}
|
|
@@ -68,11 +68,15 @@ class NodeNativeCodexWebSocket {
|
|
|
68
68
|
this.fail(failure('native Codex WebSocket returned a binary frame', 'WS_PROTOCOL_ERROR'));
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
const bytes = Array.isArray(data)
|
|
72
|
+
? data.reduce((total, chunk) => total + chunk.byteLength, 0) : data.byteLength;
|
|
73
|
+
if (bytes > maxFrameBytes) {
|
|
72
74
|
this.fail(failure('native Codex WebSocket frame exceeded the size limit', 'WS_FRAME_TOO_LARGE'));
|
|
73
75
|
return;
|
|
74
76
|
}
|
|
75
|
-
|
|
77
|
+
const buffer = Array.isArray(data) ? Buffer.concat(data, bytes)
|
|
78
|
+
: Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
79
|
+
this.push({ type: 'text', text: buffer.toString('utf8') }, bytes);
|
|
76
80
|
});
|
|
77
81
|
socket.on('close', (code, reason) => {
|
|
78
82
|
this.ended = true;
|
|
@@ -124,7 +128,7 @@ class NodeNativeCodexWebSocket {
|
|
|
124
128
|
signal?.addEventListener('abort', abort, { once: true });
|
|
125
129
|
this.socket.send(text, (error) => {
|
|
126
130
|
signal?.removeEventListener('abort', abort);
|
|
127
|
-
if (error === undefined)
|
|
131
|
+
if (error === undefined || error === null)
|
|
128
132
|
resolve();
|
|
129
133
|
else
|
|
130
134
|
reject(failure('native Codex WebSocket send failed', 'WS_RETRYABLE', error));
|
package/lib/responses.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ToolCallId, LlmError, type ContentBlock, type GenerateOptions, type StreamChunk, type TokenUsage, type ToolSchema } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
import { type ParseSseOptions } from './sse.js';
|
|
3
3
|
import { type NativeCodexReplaySource } from './replay.js';
|
|
4
4
|
export declare const DEFAULT_CODEX_INSTRUCTIONS = "You are Codex, an AI coding agent. Help the user with software engineering tasks.";
|
|
@@ -11,7 +11,7 @@ export interface ResolvedImagePart {
|
|
|
11
11
|
}
|
|
12
12
|
export interface ResolvedToolResultPart {
|
|
13
13
|
type: 'tool-result';
|
|
14
|
-
toolCallId:
|
|
14
|
+
toolCallId: ToolCallId;
|
|
15
15
|
content: readonly ResolvedContentPart[];
|
|
16
16
|
isError?: boolean;
|
|
17
17
|
}
|
package/lib/responses.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Pure DSH-to-Codex Responses request and stream translation. */
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import {
|
|
3
|
+
import { ToolCallId, CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, isContextWindowExceededError, isQuotaExceededError, LlmError, QUOTA_EXCEEDED_CODE, } from '@deepseek-ai/dsh-llm';
|
|
4
4
|
import { parseSse } from './sse.js';
|
|
5
5
|
import { NativeCodexReplayCapture, replayAssistantInput, replayableItemId, } from './replay.js';
|
|
6
6
|
export const DEFAULT_CODEX_INSTRUCTIONS = 'You are Codex, an AI coding agent. Help the user with software engineering tasks.';
|
|
@@ -312,7 +312,7 @@ function closeBlock(block) {
|
|
|
312
312
|
return { type: 'text', text: block.text };
|
|
313
313
|
if (block.kind === 'reasoning')
|
|
314
314
|
return { type: 'reasoning', text: block.text };
|
|
315
|
-
return { type: 'tool-call', id:
|
|
315
|
+
return { type: 'tool-call', id: ToolCallId(block.callId), name: block.name ?? '', arguments: block.text };
|
|
316
316
|
}
|
|
317
317
|
/** Stateful, transport-free Responses event to DSH chunk translator. */
|
|
318
318
|
export class ResponsesStreamTranslator {
|
|
@@ -398,7 +398,7 @@ export class ResponsesStreamTranslator {
|
|
|
398
398
|
this.sawToolCall = true;
|
|
399
399
|
const block = this.open(`${item.id}:call`, 'tool-call', chunks, item.call_id, item.name);
|
|
400
400
|
chunks.push({
|
|
401
|
-
type: 'tool-call-delta', index: block.index, id:
|
|
401
|
+
type: 'tool-call-delta', index: block.index, id: ToolCallId(block.callId),
|
|
402
402
|
name: item.name, argumentsDelta: '',
|
|
403
403
|
});
|
|
404
404
|
return chunks;
|
|
@@ -430,7 +430,7 @@ export class ResponsesStreamTranslator {
|
|
|
430
430
|
const delta = eventDelta(event);
|
|
431
431
|
this.append(block, delta);
|
|
432
432
|
chunks.push({
|
|
433
|
-
type: 'tool-call-delta', index: block.index, id:
|
|
433
|
+
type: 'tool-call-delta', index: block.index, id: ToolCallId(block.callId),
|
|
434
434
|
...block.name === undefined ? {} : { name: block.name }, argumentsDelta: delta,
|
|
435
435
|
});
|
|
436
436
|
return chunks;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pure01fx/dsh-openai-codex-auth",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Native ChatGPT Codex provider, device-code-first login, and same-origin Web integration for DeepSeek Harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -86,16 +86,22 @@
|
|
|
86
86
|
"LICENSE",
|
|
87
87
|
"CODEX-COMPATIBILITY.md"
|
|
88
88
|
],
|
|
89
|
+
"scripts": {
|
|
90
|
+
"build": "tsc",
|
|
91
|
+
"typecheck": "tsc --noEmit",
|
|
92
|
+
"test": "vitest run",
|
|
93
|
+
"prepack": "pnpm build"
|
|
94
|
+
},
|
|
89
95
|
"dsh": {
|
|
90
96
|
"engines": {
|
|
91
|
-
"dsh": "0.1.
|
|
97
|
+
"dsh": "0.1.5-rc.1"
|
|
92
98
|
},
|
|
93
99
|
"bundle": {
|
|
94
100
|
"patch": "./cordis.patch.yml"
|
|
95
101
|
},
|
|
96
102
|
"client": {
|
|
97
103
|
"inject": [
|
|
98
|
-
"@deepseek-ai/dsh-client-
|
|
104
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
99
105
|
"@deepseek-ai/dsh-client-ui-model-selection",
|
|
100
106
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
101
107
|
"@deepseek-ai/dsh-client-ui-settings"
|
|
@@ -105,19 +111,19 @@
|
|
|
105
111
|
},
|
|
106
112
|
"peerDependencies": {
|
|
107
113
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
108
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
109
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
110
|
-
"@deepseek-ai/dsh-fs": "0.1.
|
|
111
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.
|
|
112
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
113
|
-
"@deepseek-ai/dsh-sandbox": "0.1.
|
|
114
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.1.
|
|
115
|
-
"@deepseek-ai/dsh-shell": "0.1.
|
|
116
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
114
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
|
|
115
|
+
"@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
|
|
116
|
+
"@deepseek-ai/dsh-fs": "0.1.5-rc.1",
|
|
117
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-rc.1",
|
|
118
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
119
|
+
"@deepseek-ai/dsh-sandbox": "0.1.5-rc.1",
|
|
120
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.5-rc.1",
|
|
121
|
+
"@deepseek-ai/dsh-shell": "0.1.5-rc.1",
|
|
122
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1"
|
|
117
123
|
},
|
|
118
124
|
"dependencies": {
|
|
119
|
-
"@deepseek-ai/dsh-atomic-write": "0.1.
|
|
120
|
-
"@deepseek-ai/dsh-home-paths": "0.1.
|
|
125
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.5-rc.1",
|
|
126
|
+
"@deepseek-ai/dsh-home-paths": "0.1.5-rc.1",
|
|
121
127
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
122
128
|
"https-proxy-agent": "7.0.6",
|
|
123
129
|
"image-size": "^2.0.2",
|
|
@@ -125,23 +131,26 @@
|
|
|
125
131
|
"ws": "8.21.3"
|
|
126
132
|
},
|
|
127
133
|
"devDependencies": {
|
|
134
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.1",
|
|
135
|
+
"@deepseek-ai/dsh-web-frontend": "0.1.5-rc.1",
|
|
128
136
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
129
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
130
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
131
|
-
"@deepseek-ai/dsh-attachment-local": "0.1.
|
|
132
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
133
|
-
"@deepseek-ai/dsh-fs": "0.1.
|
|
134
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.
|
|
135
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
136
|
-
"@deepseek-ai/dsh-sandbox": "0.1.
|
|
137
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.1.
|
|
138
|
-
"@deepseek-ai/dsh-scope": "0.1.
|
|
139
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
140
|
-
"@deepseek-ai/dsh-shell": "0.1.
|
|
141
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.
|
|
142
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
137
|
+
"@deepseek-ai/dsh-agent": "0.1.5-rc.1",
|
|
138
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
|
|
139
|
+
"@deepseek-ai/dsh-attachment-local": "0.1.5-rc.1",
|
|
140
|
+
"@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
|
|
141
|
+
"@deepseek-ai/dsh-fs": "0.1.5-rc.1",
|
|
142
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-rc.1",
|
|
143
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
144
|
+
"@deepseek-ai/dsh-sandbox": "0.1.5-rc.1",
|
|
145
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.5-rc.1",
|
|
146
|
+
"@deepseek-ai/dsh-scope": "0.1.5-rc.1",
|
|
147
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.1",
|
|
148
|
+
"@deepseek-ai/dsh-shell": "0.1.5-rc.1",
|
|
149
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
|
|
150
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1",
|
|
143
151
|
"@types/node": "^22.20.0",
|
|
144
152
|
"@types/proxy-from-env": "1.0.4",
|
|
153
|
+
"@types/ws": "8.18.1",
|
|
145
154
|
"sharp": "^0.35.4",
|
|
146
155
|
"typescript": "^6.0.3",
|
|
147
156
|
"vitest": "^4.1.8"
|
|
@@ -165,9 +174,5 @@
|
|
|
165
174
|
"@deepseek-ai/dsh-sandbox-policy": {
|
|
166
175
|
"optional": true
|
|
167
176
|
}
|
|
168
|
-
},
|
|
169
|
-
"scripts": {
|
|
170
|
-
"build": "tsc",
|
|
171
|
-
"test": "vitest run"
|
|
172
177
|
}
|
|
173
|
-
}
|
|
178
|
+
}
|