@pure01fx/dsh-openai-codex-auth 0.6.0 → 0.6.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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.6.1
6
+
7
+ ### WebSocket reliability
8
+
9
+ - Cancels image and attachment request preparation when the transport is disposed, preserving the `DISPOSED` lifecycle result before a WebSocket session becomes active.
10
+ - Stops same-stream reconnect and replay after any output has been emitted; retryable interruptions now cross the durable failed-step recovery boundary without duplicating visible chunks.
11
+ - Keeps credential-backed connection failures on the bounded reconnect and HTTP fallback path instead of treating every low-level network error as an indefinite pre-credential outage.
12
+
5
13
  ## 0.6.0
6
14
 
7
15
  ### Native Codex transport
@@ -25,6 +25,7 @@ export declare class NativeCodexWebSocketTransport implements NativeCodexTranspo
25
25
  private readonly maxReconnects;
26
26
  private readonly initialRetryDelayMs;
27
27
  private readonly maxRetryDelayMs;
28
+ private readonly preparing;
28
29
  private readonly active;
29
30
  private disposed;
30
31
  constructor(options: NativeCodexWebSocketTransportOptions);
@@ -212,6 +212,7 @@ export class NativeCodexWebSocketTransport {
212
212
  maxReconnects;
213
213
  initialRetryDelayMs;
214
214
  maxRetryDelayMs;
215
+ preparing = new Set();
215
216
  active = new Map();
216
217
  disposed = false;
217
218
  constructor(options) {
@@ -469,7 +470,18 @@ export class NativeCodexWebSocketTransport {
469
470
  async *stream(generation, mode = {}) {
470
471
  if (this.disposed)
471
472
  throw failure('native Codex WebSocket transport was disposed', 'DISPOSED');
472
- const prepared = await this.http.prepare(generation, mode);
473
+ const lifecycle = new AbortController();
474
+ const signal = generation.signal === undefined
475
+ ? lifecycle.signal : AbortSignal.any([generation.signal, lifecycle.signal]);
476
+ const activeGeneration = { ...generation, signal };
477
+ this.preparing.add(lifecycle);
478
+ let prepared;
479
+ try {
480
+ prepared = await this.http.prepare(activeGeneration, mode);
481
+ }
482
+ finally {
483
+ this.preparing.delete(lifecycle);
484
+ }
473
485
  if (this.disposed)
474
486
  throw failure('native Codex WebSocket transport was disposed', 'DISPOSED');
475
487
  const key = sessionKey(generation, prepared.routingId);
@@ -480,11 +492,7 @@ export class NativeCodexWebSocketTransport {
480
492
  throw failure('native Codex WebSocket active session limit was reached', 'WS_SESSION_LIMIT');
481
493
  }
482
494
  entry.busy = true;
483
- const lifecycle = new AbortController();
484
495
  this.active.set(entry, lifecycle);
485
- const signal = generation.signal === undefined
486
- ? lifecycle.signal : AbortSignal.any([generation.signal, lifecycle.signal]);
487
- const activeGeneration = { ...generation, signal };
488
496
  const currentTurn = turnKey(generation);
489
497
  if (entry.turnKey !== currentTurn) {
490
498
  entry.turnKey = currentTurn;
@@ -531,17 +539,18 @@ export class NativeCodexWebSocketTransport {
531
539
  throw failure('native Codex WebSocket transport was disposed', 'DISPOSED');
532
540
  if (generation.signal?.aborted || failureValue.code === 'ABORTED')
533
541
  throw failureValue;
534
- if (failureValue.code === NATIVE_CODEX_CONNECTION_FAILED_CODE
535
- || isNativeCodexConnectionFailure(failureValue)) {
536
- await this.waitForConnection(connectionRetryDelayMs, signal);
537
- connectionRetryDelayMs = Math.min(connectionRetryDelayMs * 2, MAX_CONNECTION_RETRY_DELAY_MS);
538
- continue;
539
- }
540
542
  if (emitted) {
541
543
  if (failedStepRetryable(failureValue.code))
542
544
  throw failedStepRetry(failureValue);
543
545
  throw failureValue;
544
546
  }
547
+ if (failureValue.code === NATIVE_CODEX_CONNECTION_FAILED_CODE
548
+ || (attemptedCredential === undefined
549
+ && isNativeCodexConnectionFailure(failureValue))) {
550
+ await this.waitForConnection(connectionRetryDelayMs, signal);
551
+ connectionRetryDelayMs = Math.min(connectionRetryDelayMs * 2, MAX_CONNECTION_RETRY_DELAY_MS);
552
+ continue;
553
+ }
545
554
  if (failureValue.code === 'WS_AUTH' && !recovered
546
555
  && attemptedCredential !== undefined
547
556
  && this.options.recoverCredential !== undefined) {
@@ -603,6 +612,10 @@ export class NativeCodexWebSocketTransport {
603
612
  if (this.disposed)
604
613
  return;
605
614
  this.disposed = true;
615
+ for (const controller of this.preparing) {
616
+ controller.abort(failure('native Codex WebSocket transport was disposed', 'DISPOSED'));
617
+ }
618
+ this.preparing.clear();
606
619
  for (const [entry, controller] of this.active) {
607
620
  controller.abort(failure('native Codex WebSocket transport was disposed', 'DISPOSED'));
608
621
  this.closeEntry(entry);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pure01fx/dsh-openai-codex-auth",
3
- "version": "0.6.0",
3
+ "version": "0.6.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": {
@@ -69,11 +69,6 @@
69
69
  "CHANGELOG.md",
70
70
  "LICENSE"
71
71
  ],
72
- "scripts": {
73
- "build": "tsc",
74
- "test": "vitest run",
75
- "prepack": "pnpm build"
76
- },
77
72
  "dsh": {
78
73
  "bundle": {
79
74
  "patch": "./cordis.patch.yml"
@@ -110,5 +105,9 @@
110
105
  "@types/node": "^22.20.0",
111
106
  "typescript": "^6.0.3",
112
107
  "vitest": "^4.1.8"
108
+ },
109
+ "scripts": {
110
+ "build": "tsc",
111
+ "test": "vitest run"
113
112
  }
114
- }
113
+ }