@opengeni/codex 0.2.23 → 0.2.24-canary.35585322809001

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/fetch.d.ts CHANGED
@@ -21,6 +21,8 @@ export type CodexEncryptedArtifactRejection = {
21
21
  status: 400;
22
22
  kind: "encrypted_content_rejected";
23
23
  };
24
+ /** Exact Codex `error.code` for an opaque artifact the backend can no longer use. */
25
+ export declare const CODEX_ENCRYPTED_CONTENT_REJECTION_CODE = "invalid_encrypted_content";
24
26
  /**
25
27
  * Classify only the provider's definitive request rejection for an opaque
26
28
  * reasoning artifact that it can no longer decrypt/parse. A Codex transport
package/dist/index.d.ts CHANGED
@@ -15,3 +15,4 @@ export * from "./opaque-artifact.js";
15
15
  export * from "./images.js";
16
16
  export * from "./realtime.js";
17
17
  export * from "./realtime-v3.js";
18
+ export * from "./reasoning-configuration.js";
package/dist/index.js CHANGED
@@ -814,6 +814,28 @@ function isPreHeadersTimeoutError(error) {
814
814
  // src/fetch.ts
815
815
  import { randomUUID } from "crypto";
816
816
 
817
+ // src/meaningful-output.ts
818
+ function hasMeaningfulCodexOutput(output) {
819
+ if (!Array.isArray(output)) return false;
820
+ return output.some((value) => {
821
+ if (!value || typeof value !== "object") return false;
822
+ const item = value;
823
+ if (item.status !== void 0 && item.status !== "completed") return false;
824
+ if (item.type === "message" && item.role === "assistant" && Array.isArray(item.content)) {
825
+ return item.content.some((part) => {
826
+ if (!part || typeof part !== "object") return false;
827
+ const content = part;
828
+ return content.type === "output_text" && typeof content.text === "string" && content.text.trim().length > 0;
829
+ });
830
+ }
831
+ if (item.type === "function_call" || item.type === "custom_tool_call") {
832
+ const payload = item.type === "function_call" ? item.arguments : item.input;
833
+ return typeof item.name === "string" && item.name.trim().length > 0 && typeof item.call_id === "string" && item.call_id.length > 0 && typeof payload === "string" && payload.trim().length > 0;
834
+ }
835
+ return item.type === "image_generation_call" && typeof item.result === "string" && item.result.length > 0;
836
+ });
837
+ }
838
+
817
839
  // src/opaque-artifact.ts
818
840
  import { createHash } from "crypto";
819
841
  function opaqueProviderArtifactFingerprint(item) {
@@ -865,6 +887,7 @@ function isCodexTransportError(error) {
865
887
  }
866
888
  return false;
867
889
  }
890
+ var CODEX_ENCRYPTED_CONTENT_REJECTION_CODE = "invalid_encrypted_content";
868
891
  function classifyCodexEncryptedArtifactRejection(error) {
869
892
  if (!isCodexTransportError(error)) return null;
870
893
  let current = error;
@@ -872,6 +895,10 @@ function classifyCodexEncryptedArtifactRejection(error) {
872
895
  const value = current;
873
896
  const body = value.error && typeof value.error === "object" ? value.error : null;
874
897
  const status = Number(value.status ?? body?.status);
898
+ const exactCode = typeof body?.code === "string" ? body.code : typeof value.code === "string" ? value.code : "";
899
+ if (status === 400 && exactCode === CODEX_ENCRYPTED_CONTENT_REJECTION_CODE) {
900
+ return { status: 400, kind: "encrypted_content_rejected" };
901
+ }
875
902
  const message = [
876
903
  typeof value.message === "string" ? value.message : "",
877
904
  typeof body?.message === "string" ? body.message : "",
@@ -986,6 +1013,9 @@ function markSemanticTerminal(state, phase) {
986
1013
  state.phase = phase;
987
1014
  }
988
1015
  }
1016
+ function semanticCompletionEvidence(state) {
1017
+ return state?.phase === "completed" ? { meaningfulOutput: state.meaningfulOutput === true } : {};
1018
+ }
989
1019
  function terminalOutcomeForPhase(phase) {
990
1020
  if (phase === "completed" || phase === "failed" || phase === "timed_out") {
991
1021
  return phase;
@@ -1063,6 +1093,7 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1063
1093
  if (semanticTerminal) markSemanticTerminal(semanticTerminal, "failed");
1064
1094
  await emitRequestEvent(audit, {
1065
1095
  phase: semanticTerminal?.phase ?? (res.ok ? "completed" : "failed"),
1096
+ ...semanticCompletionEvidence(semanticTerminal),
1066
1097
  responseObserved: true,
1067
1098
  status: res.status,
1068
1099
  ...requestId ? { providerRequestId: requestId } : {}
@@ -1093,6 +1124,7 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1093
1124
  void reader.cancel(error).catch(() => void 0);
1094
1125
  void emitRequestEvent(audit, {
1095
1126
  phase,
1127
+ ...semanticCompletionEvidence(semanticTerminal),
1096
1128
  responseObserved: true,
1097
1129
  ...phase === "timed_out" ? { timeoutClass: klass } : {},
1098
1130
  status: res.status,
@@ -1120,6 +1152,7 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1120
1152
  void reader.cancel(reason).catch(() => void 0);
1121
1153
  void emitRequestEvent(audit, {
1122
1154
  phase: semanticTerminal?.phase ?? "failed",
1155
+ ...semanticCompletionEvidence(semanticTerminal),
1123
1156
  responseObserved: true,
1124
1157
  status: res.status,
1125
1158
  ...requestId ? { providerRequestId: requestId } : {}
@@ -1144,14 +1177,10 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1144
1177
  if (chunk.done) {
1145
1178
  terminal = true;
1146
1179
  clearTimers();
1147
- if (semanticTerminal && semanticTerminal.phase === null) {
1148
- if (!semanticTerminal.deferTransportTerminal) {
1149
- markSemanticTerminal(semanticTerminal, "failed");
1150
- }
1151
- }
1152
- if (!semanticTerminal?.deferTransportTerminal || semanticTerminal.phase !== null) {
1180
+ if (!semanticTerminal || semanticTerminal.phase !== null) {
1153
1181
  await emitRequestEvent(audit, {
1154
1182
  phase: semanticTerminal?.phase ?? (res.ok ? "completed" : "failed"),
1183
+ ...semanticCompletionEvidence(semanticTerminal),
1155
1184
  responseObserved: true,
1156
1185
  status: res.status,
1157
1186
  ...requestId ? { providerRequestId: requestId } : {}
@@ -1185,6 +1214,7 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1185
1214
  }
1186
1215
  await emitRequestEvent(audit, {
1187
1216
  phase: semanticPhase ?? "failed",
1217
+ ...semanticCompletionEvidence(semanticTerminal),
1188
1218
  responseObserved: true,
1189
1219
  status: res.status,
1190
1220
  ...requestId ? { providerRequestId: requestId } : {}
@@ -1205,6 +1235,7 @@ async function observedResponse(res, audit, externalSignal, semanticTerminal) {
1205
1235
  }
1206
1236
  await emitRequestEvent(audit, {
1207
1237
  phase: semanticTerminal?.phase ?? "failed",
1238
+ ...semanticCompletionEvidence(semanticTerminal),
1208
1239
  responseObserved: true,
1209
1240
  status: res.status,
1210
1241
  ...requestId ? { providerRequestId: requestId } : {}
@@ -1348,8 +1379,7 @@ function codexSubscriptionFetch(base = globalThis.fetch) {
1348
1379
  responseObserved: false
1349
1380
  });
1350
1381
  const semanticTerminal = {
1351
- phase: null,
1352
- deferTransportTerminal: !callerWantsStream
1382
+ phase: null
1353
1383
  };
1354
1384
  try {
1355
1385
  await ctx.beforeProviderDispatch?.();
@@ -1410,9 +1440,23 @@ function codexSubscriptionFetch(base = globalThis.fetch) {
1410
1440
  return buffered;
1411
1441
  }
1412
1442
  if (callerWantsStream) {
1413
- res = validateCodexStream(res, (phase) => {
1414
- markSemanticTerminal(semanticTerminal, phase);
1415
- });
1443
+ res = validateCodexStream(
1444
+ res,
1445
+ (phase, meaningfulOutput) => {
1446
+ markSemanticTerminal(semanticTerminal, phase);
1447
+ semanticTerminal.meaningfulOutput = meaningfulOutput === true;
1448
+ },
1449
+ async () => {
1450
+ const upstreamRequestId = providerRequestId(res.headers);
1451
+ await emitRequestEvent(audit, {
1452
+ phase: semanticTerminal.phase ?? "failed",
1453
+ ...semanticCompletionEvidence(semanticTerminal),
1454
+ responseObserved: true,
1455
+ status: res.status,
1456
+ ...upstreamRequestId ? { providerRequestId: upstreamRequestId } : {}
1457
+ });
1458
+ }
1459
+ );
1416
1460
  } else {
1417
1461
  res = await sseToJsonResponse(res, audit, semanticTerminal);
1418
1462
  }
@@ -1596,6 +1640,7 @@ async function sseToJsonResponse(res, audit, semanticTerminal) {
1596
1640
  markSemanticTerminal(semanticTerminal, "completed");
1597
1641
  await emitRequestEvent(audit, {
1598
1642
  phase: "completed",
1643
+ meaningfulOutput: hasMeaningfulCodexOutput(final?.output),
1599
1644
  responseObserved: true,
1600
1645
  status: res.status,
1601
1646
  ...upstreamRequestId ? { providerRequestId: upstreamRequestId } : {}
@@ -1752,7 +1797,7 @@ function codexSseFailureError(source, rawError, fallbackCode, publicMessage, met
1752
1797
  codexSseFailureProjection(source, rawError, fallbackCode, publicMessage, metadata)
1753
1798
  );
1754
1799
  }
1755
- function validateCodexStream(res, onSemanticTerminal) {
1800
+ function validateCodexStream(res, onSemanticTerminal, onParsedEof) {
1756
1801
  if (!res.body) {
1757
1802
  onSemanticTerminal?.("failed");
1758
1803
  const error = codexSseFailureError(
@@ -1778,13 +1823,18 @@ function validateCodexStream(res, onSemanticTerminal) {
1778
1823
  const encoder = new TextEncoder();
1779
1824
  let buffer = "";
1780
1825
  let successfulTerminalSeen = false;
1826
+ let meaningfulOutput = false;
1827
+ const observeOutput = (output) => {
1828
+ meaningfulOutput ||= hasMeaningfulCodexOutput(output);
1829
+ };
1830
+ const observeTerminal = (phase) => onSemanticTerminal?.(phase, phase === "completed" && meaningfulOutput);
1781
1831
  const emitCompleteBlocks = (controller, final) => {
1782
1832
  let boundary = findSseBlockBoundary(buffer, final);
1783
1833
  while (boundary) {
1784
1834
  const block = buffer.slice(0, boundary.start);
1785
1835
  const separator = buffer.slice(boundary.start, boundary.end);
1786
1836
  buffer = buffer.slice(boundary.end);
1787
- successfulTerminalSeen ||= inspectCodexSseBlock(block, res, onSemanticTerminal);
1837
+ successfulTerminalSeen ||= inspectCodexSseBlock(block, res, observeTerminal, observeOutput);
1788
1838
  controller.enqueue(encoder.encode(`${block}${separator}`));
1789
1839
  boundary = findSseBlockBoundary(buffer, final);
1790
1840
  }
@@ -1794,21 +1844,31 @@ function validateCodexStream(res, onSemanticTerminal) {
1794
1844
  buffer += decoder.decode(chunk, { stream: true });
1795
1845
  emitCompleteBlocks(controller, false);
1796
1846
  },
1797
- flush(controller) {
1798
- buffer += decoder.decode();
1799
- emitCompleteBlocks(controller, true);
1800
- if (buffer.length > 0) {
1801
- successfulTerminalSeen ||= inspectCodexSseBlock(buffer, res, onSemanticTerminal);
1802
- controller.enqueue(encoder.encode(buffer));
1803
- buffer = "";
1804
- }
1805
- if (!successfulTerminalSeen) {
1806
- throw codexSseFailureError(
1807
- res,
1808
- null,
1809
- "invalid_sse_terminal",
1810
- "The Codex response stream ended without a terminal response"
1811
- );
1847
+ async flush(controller) {
1848
+ try {
1849
+ buffer += decoder.decode();
1850
+ emitCompleteBlocks(controller, true);
1851
+ if (buffer.length > 0) {
1852
+ successfulTerminalSeen ||= inspectCodexSseBlock(
1853
+ buffer,
1854
+ res,
1855
+ observeTerminal,
1856
+ observeOutput
1857
+ );
1858
+ controller.enqueue(encoder.encode(buffer));
1859
+ buffer = "";
1860
+ }
1861
+ if (!successfulTerminalSeen) {
1862
+ observeTerminal("failed");
1863
+ throw codexSseFailureError(
1864
+ res,
1865
+ null,
1866
+ "invalid_sse_terminal",
1867
+ "The Codex response stream ended without a terminal response"
1868
+ );
1869
+ }
1870
+ } finally {
1871
+ await onParsedEof?.();
1812
1872
  }
1813
1873
  }
1814
1874
  });
@@ -1848,13 +1908,13 @@ var CODEX_TERMINAL_TYPE_HINTS = [
1848
1908
  '"response.error"',
1849
1909
  '"error"'
1850
1910
  ];
1851
- function inspectCodexSseBlock(block, source, onSemanticTerminal) {
1911
+ function inspectCodexSseBlock(block, source, onSemanticTerminal, onOutput) {
1852
1912
  const lines = block.split(/\r\n|\r|\n/);
1853
1913
  const dataStr = lines.filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trim()).join("\n");
1854
1914
  if (!dataStr || dataStr === "[DONE]") {
1855
1915
  return false;
1856
1916
  }
1857
- if (!CODEX_TERMINAL_TYPE_HINTS.some((terminalType) => dataStr.includes(terminalType))) {
1917
+ if (!dataStr.includes('"response.output_item.done"') && !CODEX_TERMINAL_TYPE_HINTS.some((terminalType) => dataStr.includes(terminalType))) {
1858
1918
  return false;
1859
1919
  }
1860
1920
  let ev;
@@ -1864,6 +1924,7 @@ function inspectCodexSseBlock(block, source, onSemanticTerminal) {
1864
1924
  return false;
1865
1925
  }
1866
1926
  const terminal = classifyCodexSseTerminal(ev);
1927
+ if (ev.type === "response.output_item.done") onOutput?.([ev.item]);
1867
1928
  if (terminal?.phase === "failed") {
1868
1929
  onSemanticTerminal?.("failed");
1869
1930
  throw codexSseFailureError(
@@ -1879,6 +1940,7 @@ function inspectCodexSseBlock(block, source, onSemanticTerminal) {
1879
1940
  );
1880
1941
  }
1881
1942
  if (terminal?.phase === "completed") {
1943
+ onOutput?.(ev.response?.output);
1882
1944
  onSemanticTerminal?.("completed");
1883
1945
  return true;
1884
1946
  }
@@ -2996,6 +3058,58 @@ async function readBoundedSdp(response) {
2996
3058
  );
2997
3059
  }
2998
3060
  }
3061
+
3062
+ // src/reasoning-configuration.ts
3063
+ var REASONING_CONFIGURATION_FIELD = "opengeniReasoningConfiguration";
3064
+ var efforts = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]);
3065
+ function supportsReasoningConfiguration(model, effort) {
3066
+ return model === "gpt-6-astra" && efforts.has(effort);
3067
+ }
3068
+ function readReasoningConfiguration(item) {
3069
+ const state = item[REASONING_CONFIGURATION_FIELD];
3070
+ if (!state || state.version !== 1 || !efforts.has(state.baselineEffort) || !efforts.has(state.effort) || typeof state.turnId !== "string")
3071
+ return null;
3072
+ const data = item.providerData;
3073
+ if (item.type !== "unknown" || data?.type !== "configuration_update" || data.reasoning?.effort !== state.effort)
3074
+ return null;
3075
+ return state;
3076
+ }
3077
+ function reasoningConfigurationItem(state) {
3078
+ return {
3079
+ type: "unknown",
3080
+ providerData: { type: "configuration_update", reasoning: { effort: state.effort } },
3081
+ [REASONING_CONFIGURATION_FIELD]: state
3082
+ };
3083
+ }
3084
+ function latestReasoningConfiguration(items) {
3085
+ for (let i = items.length - 1; i >= 0; i--) {
3086
+ const state = readReasoningConfiguration(items[i]);
3087
+ if (state) return state;
3088
+ }
3089
+ return null;
3090
+ }
3091
+ function isReasoningConfigurationUpdate(item) {
3092
+ return item.type === "configuration_update" || item.type === "unknown" && item.providerData?.type === "configuration_update";
3093
+ }
3094
+ function projectReasoningConfigurations(items, enabled) {
3095
+ const projected = [];
3096
+ for (const item of items) {
3097
+ if (!isReasoningConfigurationUpdate(item)) {
3098
+ projected.push(item);
3099
+ continue;
3100
+ }
3101
+ if (!enabled) continue;
3102
+ if (projected.length && isReasoningConfigurationUpdate(projected[projected.length - 1]))
3103
+ projected.pop();
3104
+ projected.push(
3105
+ item.type === "unknown" ? { type: "unknown", providerData: item.providerData } : {
3106
+ type: "unknown",
3107
+ providerData: { type: "configuration_update", reasoning: item.reasoning }
3108
+ }
3109
+ );
3110
+ }
3111
+ return projected;
3112
+ }
2999
3113
  export {
3000
3114
  CODEX_APPS_MCP_SERVER_ID,
3001
3115
  CODEX_APPS_MCP_SERVER_NAME,
@@ -3009,6 +3123,7 @@ export {
3009
3123
  CODEX_DEVICE_REDIRECT_URI,
3010
3124
  CODEX_DEVICE_VERIFICATION_URL,
3011
3125
  CODEX_EFFECTIVE_CONTEXT_WINDOW_PERCENT,
3126
+ CODEX_ENCRYPTED_CONTENT_REJECTION_CODE,
3012
3127
  CODEX_FALLBACK_MODEL_SLUGS,
3013
3128
  CODEX_FIVE_HOUR_WINDOW_SECONDS,
3014
3129
  CODEX_ID_TOKEN_AUTH_CLAIM,
@@ -3070,6 +3185,7 @@ export {
3070
3185
  DEFAULT_MODEL_TOOL_OUTPUT_TRUNCATION_TOKENS,
3071
3186
  MODEL_TOOL_OUTPUT_OPAQUE_PAYLOAD_MAX_BYTES,
3072
3187
  MODEL_TOOL_OUTPUT_OVERSIZED_IMAGE_CARD_DATA_URL,
3188
+ REASONING_CONFIGURATION_FIELD,
3073
3189
  ToolNameMapper,
3074
3190
  accessTokenExpiry,
3075
3191
  approximateTokenCount,
@@ -3101,6 +3217,8 @@ export {
3101
3217
  isCodexBilledModel,
3102
3218
  isCodexTransportError,
3103
3219
  isPreHeadersTimeoutError,
3220
+ isReasoningConfigurationUpdate,
3221
+ latestReasoningConfiguration,
3104
3222
  modelToolOutputSerializationBudgetTokens,
3105
3223
  normalizeCodexRequestBody,
3106
3224
  normalizeCodexUsage,
@@ -3115,6 +3233,9 @@ export {
3115
3233
  parseCodexUsageHeaders,
3116
3234
  parseIdToken,
3117
3235
  pollDeviceCode,
3236
+ projectReasoningConfigurations,
3237
+ readReasoningConfiguration,
3238
+ reasoningConfigurationItem,
3118
3239
  refreshCodexToken,
3119
3240
  remapToolCallRequestBody,
3120
3241
  resolveCodexResponseTimeoutPolicy,
@@ -3122,6 +3243,7 @@ export {
3122
3243
  sanitizeMcpSseBody,
3123
3244
  selectCodexCredentialId,
3124
3245
  startDeviceCode,
3246
+ supportsReasoningConfiguration,
3125
3247
  truncateMiddleWithTokenBudget,
3126
3248
  withCodexRequestOverrides
3127
3249
  };