@opengeni/codex 0.2.16 → 0.2.17

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.
@@ -53,6 +53,7 @@ export type CodexRequestOpaqueArtifacts = {
53
53
  requestId: string;
54
54
  fingerprints: readonly string[];
55
55
  };
56
+ export type CodexRequestPreparationPhase = "transport_entry" | "credential_ready" | "wire_request_ready";
56
57
  export type CodexRequestContext = {
57
58
  clientVersion: string;
58
59
  /**
@@ -89,6 +90,8 @@ export type CodexRequestContext = {
89
90
  * swallowed by the transport and it must never receive request bodies/auth.
90
91
  */
91
92
  onModelRequestDiagnostic?: (event: CodexModelRequestEvent) => void;
93
+ /** Bounded synchronous checkpoints for pre-network request preparation. */
94
+ onRequestPreparationDiagnostic?: (phase: CodexRequestPreparationPhase) => void;
92
95
  /** Worker-owned durable audit sink; payloads never contain request bodies or auth. */
93
96
  onModelRequestEvent?: (event: CodexModelRequestEvent) => Promise<void> | void;
94
97
  /** Exact opaque artifacts on the normalized wire request, never their ciphertext. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/codex",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "ChatGPT/Codex subscription auth + transport: device-code login, token refresh, and the Responses-backend fetch. Pure HTTP + transforms; no database dependency.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/src/fetch.ts CHANGED
@@ -17,11 +17,23 @@ import { opaqueProviderArtifactFingerprints } from "./opaque-artifact";
17
17
  import {
18
18
  codexRequestStorage,
19
19
  type CodexModelRequestEvent,
20
+ type CodexRequestPreparationPhase,
20
21
  type CodexRequestContext,
21
22
  type CodexResponseTimeoutPolicy,
22
23
  type CodexTokenSnapshot,
23
24
  type CodexUsageHeaderSnapshot,
24
25
  } from "./request-context";
26
+
27
+ function emitRequestPreparationDiagnostic(
28
+ ctx: CodexRequestContext,
29
+ phase: CodexRequestPreparationPhase,
30
+ ): void {
31
+ try {
32
+ ctx.onRequestPreparationDiagnostic?.(phase);
33
+ } catch {
34
+ // Diagnostic observers are non-blocking and cannot affect transport.
35
+ }
36
+ }
25
37
  import {
26
38
  CODEX_RESPONSE_TIMEOUT_ERROR_TYPE,
27
39
  CodexResponseTimeoutError,
@@ -614,6 +626,7 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
614
626
  if (!ctx) {
615
627
  return base(input, init); // not a codex turn — passthrough, untouched
616
628
  }
629
+ emitRequestPreparationDiagnostic(ctx, "transport_entry");
617
630
 
618
631
  const rawUrl =
619
632
  typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
@@ -700,7 +713,10 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
700
713
  throw new Error("Model request could not be prepared");
701
714
  }
702
715
  if (!bodyAlreadyNormalized) {
703
- ctx.onRequestOpaqueArtifacts?.({ requestId, fingerprints: requestOpaqueArtifacts });
716
+ ctx.onRequestOpaqueArtifacts?.({
717
+ requestId,
718
+ fingerprints: requestOpaqueArtifacts,
719
+ });
704
720
  }
705
721
  headers.set(
706
722
  "Idempotency-Key",
@@ -726,6 +742,7 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
726
742
  policy,
727
743
  terminalOutcome: null,
728
744
  };
745
+ emitRequestPreparationDiagnostic(ctx, "wire_request_ready");
729
746
  await emitRequestEvent(audit, {
730
747
  phase: "started",
731
748
  responseObserved: false,
@@ -827,7 +844,9 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
827
844
  };
828
845
 
829
846
  try {
830
- let res = await attempt(await ctx.getToken(), 0);
847
+ const token = await ctx.getToken();
848
+ emitRequestPreparationDiagnostic(ctx, "credential_ready");
849
+ let res = await attempt(token, 0);
831
850
  if (res.status === 401) {
832
851
  res = await attempt(await ctx.refresh(), 1); // single refresh-on-401 retry (spec §1.9)
833
852
  }
@@ -67,6 +67,11 @@ export type CodexRequestOpaqueArtifacts = {
67
67
  fingerprints: readonly string[];
68
68
  };
69
69
 
70
+ export type CodexRequestPreparationPhase =
71
+ | "transport_entry"
72
+ | "credential_ready"
73
+ | "wire_request_ready";
74
+
70
75
  export type CodexRequestContext = {
71
76
  clientVersion: string;
72
77
  /**
@@ -103,6 +108,8 @@ export type CodexRequestContext = {
103
108
  * swallowed by the transport and it must never receive request bodies/auth.
104
109
  */
105
110
  onModelRequestDiagnostic?: (event: CodexModelRequestEvent) => void;
111
+ /** Bounded synchronous checkpoints for pre-network request preparation. */
112
+ onRequestPreparationDiagnostic?: (phase: CodexRequestPreparationPhase) => void;
106
113
  /** Worker-owned durable audit sink; payloads never contain request bodies or auth. */
107
114
  onModelRequestEvent?: (event: CodexModelRequestEvent) => Promise<void> | void;
108
115
  /** Exact opaque artifacts on the normalized wire request, never their ciphertext. */