@janole/ai-sdk-provider-codex-asp 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -111,6 +111,7 @@ const codex = createCodexAppServer({
111
111
  clientInfo?: { name, version, title? }, // defaults to package.json
112
112
  transport?: { type: 'stdio' | 'websocket', stdio?, websocket? },
113
113
  persistent?: { poolSize?, idleTimeoutMs?, scope?, key? },
114
+ compaction?: { onResume?, strict? }, // optional thread/compact/start before resumed turns
114
115
  debug?: { logPackets?, logger? }, // packet-level JSON-RPC debug logging
115
116
  defaultThreadSettings?: { cwd?, approvalMode?, sandboxMode? },
116
117
  approvals?: { onCommandApproval?, onFileChangeApproval? },
@@ -154,6 +155,9 @@ npx tsx examples/stream-text.ts
154
155
  - Increase `interruptTimeoutMs` if `turn/interrupt` acks are slow under heavy load.
155
156
  - Empty generated text:
156
157
  - Verify Codex emits `item/agentMessage/delta` and `turn/completed` notifications.
158
+ - Compaction fails on resumed threads:
159
+ - Leave `compaction.strict` unset/false to continue the turn when `thread/compact/start` fails.
160
+ - Set `compaction.strict: true` if you want compaction failures to fail fast.
157
161
 
158
162
  ## Development
159
163
 
package/dist/index.cjs CHANGED
@@ -776,16 +776,26 @@ function withTimeout(promise, timeoutMs) {
776
776
  var DynamicToolsDispatcher = class {
777
777
  handlers = /* @__PURE__ */ new Map();
778
778
  timeoutMs;
779
+ onDebugEvent;
779
780
  constructor(settings = {}) {
780
781
  this.timeoutMs = settings.timeoutMs ?? 3e4;
782
+ this.onDebugEvent = settings.onDebugEvent;
781
783
  if (settings.tools) {
782
784
  for (const [name, def] of Object.entries(settings.tools)) {
783
785
  this.register(name, def.execute);
786
+ this.onDebugEvent?.({
787
+ event: "dynamic-tool-registered",
788
+ data: { name, source: "tools" }
789
+ });
784
790
  }
785
791
  }
786
792
  if (settings.handlers) {
787
793
  for (const [name, handler] of Object.entries(settings.handlers)) {
788
794
  this.register(name, handler);
795
+ this.onDebugEvent?.({
796
+ event: "dynamic-tool-registered",
797
+ data: { name, source: "handlers" }
798
+ });
789
799
  }
790
800
  }
791
801
  }
@@ -798,10 +808,27 @@ var DynamicToolsDispatcher = class {
798
808
  async dispatch(params) {
799
809
  const toolName = params.tool ?? params.toolName;
800
810
  if (!toolName) {
811
+ this.onDebugEvent?.({
812
+ event: "dynamic-tool-missing-name",
813
+ data: {
814
+ callId: params.callId,
815
+ threadId: params.threadId,
816
+ turnId: params.turnId
817
+ }
818
+ });
801
819
  return toTextResult("Dynamic tool call is missing the tool name.", false);
802
820
  }
803
821
  const handler = this.handlers.get(toolName);
804
822
  if (!handler) {
823
+ this.onDebugEvent?.({
824
+ event: "dynamic-tool-missing-handler",
825
+ data: {
826
+ toolName,
827
+ callId: params.callId,
828
+ threadId: params.threadId,
829
+ turnId: params.turnId
830
+ }
831
+ });
805
832
  return toTextResult(`No dynamic tool handler registered for "${toolName}".`, false);
806
833
  }
807
834
  const context = stripUndefined({
@@ -811,10 +838,41 @@ var DynamicToolsDispatcher = class {
811
838
  callId: params.callId
812
839
  });
813
840
  const args = params.arguments ?? params.input;
841
+ const startedAt = Date.now();
842
+ this.onDebugEvent?.({
843
+ event: "dynamic-tool-dispatch-start",
844
+ data: {
845
+ toolName,
846
+ callId: params.callId,
847
+ threadId: params.threadId,
848
+ turnId: params.turnId,
849
+ hasArguments: args !== void 0
850
+ }
851
+ });
814
852
  try {
815
- return await withTimeout(handler(args, context), this.timeoutMs);
853
+ const result = await withTimeout(handler(args, context), this.timeoutMs);
854
+ this.onDebugEvent?.({
855
+ event: "dynamic-tool-dispatch-success",
856
+ data: {
857
+ toolName,
858
+ callId: params.callId,
859
+ durationMs: Date.now() - startedAt,
860
+ success: result.success,
861
+ contentItemsCount: result.contentItems.length
862
+ }
863
+ });
864
+ return result;
816
865
  } catch (error) {
817
866
  const message = error instanceof Error ? error.message : "Dynamic tool execution failed.";
867
+ this.onDebugEvent?.({
868
+ event: "dynamic-tool-dispatch-error",
869
+ data: {
870
+ toolName,
871
+ callId: params.callId,
872
+ durationMs: Date.now() - startedAt,
873
+ message
874
+ }
875
+ });
818
876
  return toTextResult(message, false);
819
877
  }
820
878
  }
@@ -823,7 +881,7 @@ var DynamicToolsDispatcher = class {
823
881
  // package.json
824
882
  var package_default = {
825
883
  name: "@janole/ai-sdk-provider-codex-asp",
826
- version: "0.1.5"};
884
+ version: "0.1.6"};
827
885
 
828
886
  // src/package-info.ts
829
887
  var PACKAGE_NAME = package_default.name;
@@ -1198,7 +1256,7 @@ function extractResumeThreadId(prompt) {
1198
1256
  }
1199
1257
  return void 0;
1200
1258
  }
1201
- function extractToolResults(prompt) {
1259
+ function extractToolResults(prompt, callId) {
1202
1260
  for (let i = prompt.length - 1; i >= 0; i--) {
1203
1261
  const message = prompt[i];
1204
1262
  if (message?.role === "tool") {
@@ -1206,6 +1264,9 @@ function extractToolResults(prompt) {
1206
1264
  let success = true;
1207
1265
  for (const part of message.content) {
1208
1266
  if (part.type === "tool-result") {
1267
+ if (callId && part.toolCallId !== callId) {
1268
+ continue;
1269
+ }
1209
1270
  if (part.output.type === "text") {
1210
1271
  contentItems.push({ type: "inputText", text: part.output.value });
1211
1272
  } else if (part.output.type === "json") {
@@ -1222,6 +1283,9 @@ function extractToolResults(prompt) {
1222
1283
  if (contentItems.length > 0) {
1223
1284
  return { success, contentItems };
1224
1285
  }
1286
+ if (callId) {
1287
+ return void 0;
1288
+ }
1225
1289
  }
1226
1290
  }
1227
1291
  return void 0;
@@ -1370,6 +1434,9 @@ var CodexLanguageModel = class {
1370
1434
  console.debug("[codex packet]", packet.message);
1371
1435
  }
1372
1436
  }) : void 0;
1437
+ const toolLogger = this.config.providerSettings.debug?.logToolCalls === true ? this.config.providerSettings.debug.toolLogger ?? ((event) => {
1438
+ console.debug("[codex tool]", event.event, event.data);
1439
+ }) : void 0;
1373
1440
  const debugLog = packetLogger ? (direction, label, data) => {
1374
1441
  packetLogger({ direction, message: { debug: label, data } });
1375
1442
  } : void 0;
@@ -1439,7 +1506,24 @@ var CodexLanguageModel = class {
1439
1506
  const persistentTransport = transport instanceof PersistentTransport ? transport : null;
1440
1507
  const pendingToolCall = persistentTransport?.getPendingToolCall() ?? null;
1441
1508
  if (pendingToolCall && persistentTransport) {
1442
- const toolResult = extractToolResults(options.prompt);
1509
+ toolLogger?.({
1510
+ event: "cross-call-resume",
1511
+ data: {
1512
+ threadId: pendingToolCall.threadId,
1513
+ callId: pendingToolCall.callId,
1514
+ toolName: pendingToolCall.toolName
1515
+ }
1516
+ });
1517
+ const toolResult = extractToolResults(options.prompt, pendingToolCall.callId);
1518
+ toolLogger?.({
1519
+ event: "cross-call-result-extracted",
1520
+ data: {
1521
+ callId: pendingToolCall.callId,
1522
+ found: !!toolResult,
1523
+ success: toolResult?.success,
1524
+ contentItemsCount: toolResult?.contentItems.length ?? 0
1525
+ }
1526
+ });
1443
1527
  mapper.setThreadId(pendingToolCall.threadId);
1444
1528
  client.onAnyNotification((method, params) => {
1445
1529
  const parts = mapper.map({ method, params });
@@ -1462,9 +1546,23 @@ var CodexLanguageModel = class {
1462
1546
  onFileChangeApproval: this.config.providerSettings.approvals?.onFileChangeApproval
1463
1547
  }));
1464
1548
  approvalsDispatcher2.attach(client);
1465
- await persistentTransport.respondToToolCall(
1466
- toolResult ?? { success: true, contentItems: [] }
1467
- );
1549
+ const result = toolResult ?? {
1550
+ success: false,
1551
+ contentItems: [{
1552
+ type: "inputText",
1553
+ text: `Missing tool result for pending callId "${pendingToolCall.callId}".`
1554
+ }]
1555
+ };
1556
+ await persistentTransport.respondToToolCall(result);
1557
+ toolLogger?.({
1558
+ event: "cross-call-result-sent",
1559
+ data: {
1560
+ callId: pendingToolCall.callId,
1561
+ found: !!toolResult,
1562
+ success: result.success,
1563
+ contentItemsCount: result.contentItems.length ?? 0
1564
+ }
1565
+ });
1468
1566
  return;
1469
1567
  }
1470
1568
  const dynamicToolsEnabled = this.config.providerSettings.experimentalApi === true;
@@ -1472,7 +1570,8 @@ var CodexLanguageModel = class {
1472
1570
  const dispatcher = new DynamicToolsDispatcher(stripUndefined({
1473
1571
  tools: this.config.providerSettings.tools,
1474
1572
  handlers: this.config.providerSettings.toolHandlers,
1475
- timeoutMs: this.config.providerSettings.toolTimeoutMs
1573
+ timeoutMs: this.config.providerSettings.toolTimeoutMs,
1574
+ onDebugEvent: toolLogger
1476
1575
  }));
1477
1576
  dispatcher.attach(client);
1478
1577
  }
@@ -1499,6 +1598,14 @@ var CodexLanguageModel = class {
1499
1598
  const sdkDynamicTools = options.tools ? sdkToolsToCodexDynamicTools(options.tools) : [];
1500
1599
  const allDynamicTools = [...providerDynamicTools, ...sdkDynamicTools];
1501
1600
  const dynamicTools = allDynamicTools.length > 0 ? allDynamicTools : void 0;
1601
+ toolLogger?.({
1602
+ event: "dynamic-tools-advertised",
1603
+ data: {
1604
+ providerTools: providerDynamicTools.map((t) => t.name),
1605
+ sdkTools: sdkDynamicTools.map((t) => t.name),
1606
+ total: allDynamicTools.length
1607
+ }
1608
+ });
1502
1609
  const hasSdkTools = sdkDynamicTools.length > 0;
1503
1610
  const needsExperimentalApi = this.config.providerSettings.experimentalApi === true || dynamicTools !== void 0;
1504
1611
  const initializeParams = stripUndefined({
@@ -1527,6 +1634,28 @@ var CodexLanguageModel = class {
1527
1634
  resumeParams
1528
1635
  );
1529
1636
  threadId = resumeResult.thread.id;
1637
+ if (this.config.providerSettings.compaction?.onResume) {
1638
+ const compactParams = { threadId };
1639
+ debugLog?.("outbound", "thread/compact/start", compactParams);
1640
+ const strictCompaction = this.config.providerSettings.compaction.strict === true;
1641
+ if (strictCompaction) {
1642
+ await client.request(
1643
+ "thread/compact/start",
1644
+ compactParams
1645
+ );
1646
+ } else {
1647
+ try {
1648
+ await client.request(
1649
+ "thread/compact/start",
1650
+ compactParams
1651
+ );
1652
+ } catch (error) {
1653
+ debugLog?.("inbound", "thread/compact/start:error", {
1654
+ message: error instanceof Error ? error.message : String(error)
1655
+ });
1656
+ }
1657
+ }
1658
+ }
1530
1659
  } else {
1531
1660
  const threadStartParams = stripUndefined({
1532
1661
  model: this.config.providerSettings.defaultModel ?? this.modelId,
@@ -1697,6 +1826,7 @@ function createCodexAppServer(settings = {}) {
1697
1826
  websocket: settings.transport.websocket ? { ...settings.transport.websocket } : void 0
1698
1827
  }) : void 0,
1699
1828
  defaultThreadSettings: settings.defaultThreadSettings ? { ...settings.defaultThreadSettings } : void 0,
1829
+ compaction: settings.compaction ? { ...settings.compaction } : void 0,
1700
1830
  transportFactory: effectiveTransportFactory,
1701
1831
  tools: settings.tools ? { ...settings.tools } : void 0,
1702
1832
  toolHandlers: settings.toolHandlers ? { ...settings.toolHandlers } : void 0,