@janole/ai-sdk-provider-codex-asp 0.2.1 → 0.2.2

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/index.cjs CHANGED
@@ -886,7 +886,7 @@ var DynamicToolsDispatcher = class {
886
886
  // package.json
887
887
  var package_default = {
888
888
  name: "@janole/ai-sdk-provider-codex-asp",
889
- version: "0.2.1"};
889
+ version: "0.2.2"};
890
890
 
891
891
  // src/package-info.ts
892
892
  var PACKAGE_NAME = package_default.name;
@@ -932,15 +932,28 @@ function toFinishReason(status) {
932
932
  }
933
933
  }
934
934
  var CodexEventMapper = class {
935
+ options;
935
936
  streamStarted = false;
936
937
  openTextParts = /* @__PURE__ */ new Set();
938
+ textDeltaReceived = /* @__PURE__ */ new Set();
937
939
  openReasoningParts = /* @__PURE__ */ new Set();
938
940
  openToolCalls = /* @__PURE__ */ new Map();
941
+ planSequenceByTurnId = /* @__PURE__ */ new Map();
939
942
  threadId;
940
943
  latestUsage;
944
+ constructor(options) {
945
+ this.options = {
946
+ emitPlanUpdates: options?.emitPlanUpdates ?? true
947
+ };
948
+ }
941
949
  setThreadId(threadId) {
942
950
  this.threadId = threadId;
943
951
  }
952
+ nextPlanSequence(turnId) {
953
+ const next = (this.planSequenceByTurnId.get(turnId) ?? 0) + 1;
954
+ this.planSequenceByTurnId.set(turnId, next);
955
+ return next;
956
+ }
944
957
  map(event) {
945
958
  const parts = [];
946
959
  const withMeta = (part) => withProviderMetadata(part, this.threadId);
@@ -1020,6 +1033,7 @@ var CodexEventMapper = class {
1020
1033
  parts.push(withMeta({ type: "text-start", id: delta.itemId }));
1021
1034
  }
1022
1035
  parts.push(withMeta({ type: "text-delta", id: delta.itemId, delta: delta.delta }));
1036
+ this.textDeltaReceived.add(delta.itemId);
1023
1037
  break;
1024
1038
  }
1025
1039
  case "item/completed": {
@@ -1028,9 +1042,19 @@ var CodexEventMapper = class {
1028
1042
  if (!item?.id) {
1029
1043
  break;
1030
1044
  }
1031
- if (item.type === "agentMessage" && this.openTextParts.has(item.id)) {
1032
- parts.push(withMeta({ type: "text-end", id: item.id }));
1033
- this.openTextParts.delete(item.id);
1045
+ if (item.type === "agentMessage") {
1046
+ if (!this.textDeltaReceived.has(item.id) && item.text) {
1047
+ pushStreamStart();
1048
+ if (!this.openTextParts.has(item.id)) {
1049
+ this.openTextParts.add(item.id);
1050
+ parts.push(withMeta({ type: "text-start", id: item.id }));
1051
+ }
1052
+ parts.push(withMeta({ type: "text-delta", id: item.id, delta: item.text }));
1053
+ }
1054
+ if (this.openTextParts.has(item.id)) {
1055
+ parts.push(withMeta({ type: "text-end", id: item.id }));
1056
+ this.openTextParts.delete(item.id);
1057
+ }
1034
1058
  } else if (item.type === "commandExecution" && this.openToolCalls.has(item.id)) {
1035
1059
  const tracked = this.openToolCalls.get(item.id);
1036
1060
  const output = item.aggregatedOutput ?? tracked.output;
@@ -1059,6 +1083,64 @@ var CodexEventMapper = class {
1059
1083
  }
1060
1084
  break;
1061
1085
  }
1086
+ case "item/reasoning/summaryPartAdded": {
1087
+ const params = event.params ?? {};
1088
+ if (params.itemId) {
1089
+ pushReasoningDelta(params.itemId, "\n\n");
1090
+ }
1091
+ break;
1092
+ }
1093
+ // codex/event/agent_reasoning mirrors canonical reasoning summary
1094
+ // stream events in current logs. Ignore wrapper to avoid duplicate
1095
+ // reasoning text in consumers.
1096
+ case "codex/event/agent_reasoning":
1097
+ break;
1098
+ // codex/event/agent_reasoning_section_break is the wrapper form of
1099
+ // item/reasoning/summaryPartAdded (identical 1:1). Handled by the
1100
+ // canonical event above — skip the wrapper to avoid double "\n\n".
1101
+ case "codex/event/agent_reasoning_section_break":
1102
+ break;
1103
+ case "turn/plan/updated": {
1104
+ if (!this.options.emitPlanUpdates) {
1105
+ break;
1106
+ }
1107
+ const params = event.params ?? {};
1108
+ const turnId = params.turnId;
1109
+ const plan = params.plan;
1110
+ if (turnId && plan) {
1111
+ pushStreamStart();
1112
+ const planSequence = this.nextPlanSequence(turnId);
1113
+ const toolCallId = `plan:${turnId}:${planSequence}`;
1114
+ const toolName = "codex_plan_update";
1115
+ parts.push(withMeta({
1116
+ type: "tool-call",
1117
+ toolCallId,
1118
+ toolName,
1119
+ input: JSON.stringify({}),
1120
+ providerExecuted: true,
1121
+ dynamic: true
1122
+ }));
1123
+ parts.push(withMeta({
1124
+ type: "tool-result",
1125
+ toolCallId,
1126
+ toolName,
1127
+ result: { plan, explanation: params.explanation ?? void 0 }
1128
+ }));
1129
+ }
1130
+ break;
1131
+ }
1132
+ // codex/event/plan_update is the wrapper form of turn/plan/updated (1:1).
1133
+ case "codex/event/plan_update":
1134
+ break;
1135
+ // NOTE: turn/diff/updated and codex/event/turn_diff are intentionally
1136
+ // NOT mapped. They carry full unified diffs (often 50-100 KB) which,
1137
+ // when emitted as reasoning deltas, crash or freeze the frontend
1138
+ // markdown renderer. If these need to surface in the UI, they should
1139
+ // use a dedicated part type with lazy/collapsed rendering — not
1140
+ // reasoning text.
1141
+ case "turn/diff/updated":
1142
+ case "codex/event/turn_diff":
1143
+ break;
1062
1144
  case "item/commandExecution/outputDelta": {
1063
1145
  const delta = event.params ?? {};
1064
1146
  if (delta.itemId && delta.delta && this.openToolCalls.has(delta.itemId)) {
@@ -1074,6 +1156,43 @@ var CodexEventMapper = class {
1074
1156
  }
1075
1157
  break;
1076
1158
  }
1159
+ case "codex/event/mcp_tool_call_begin": {
1160
+ const params = event.params ?? {};
1161
+ const callId = params.msg?.call_id;
1162
+ const inv = params.msg?.invocation;
1163
+ if (callId && inv) {
1164
+ pushStreamStart();
1165
+ const toolName = `mcp:${inv.server}/${inv.tool}`;
1166
+ this.openToolCalls.set(callId, { toolName, output: "" });
1167
+ parts.push(withMeta({
1168
+ type: "tool-call",
1169
+ toolCallId: callId,
1170
+ toolName,
1171
+ input: JSON.stringify(inv.arguments ?? {}),
1172
+ providerExecuted: true,
1173
+ dynamic: true
1174
+ }));
1175
+ }
1176
+ break;
1177
+ }
1178
+ case "codex/event/mcp_tool_call_end": {
1179
+ const params = event.params ?? {};
1180
+ const callId = params.msg?.call_id;
1181
+ if (callId && this.openToolCalls.has(callId)) {
1182
+ const tracked = this.openToolCalls.get(callId);
1183
+ const result = params.msg?.result;
1184
+ const textParts = result?.Ok?.content?.filter((c) => c.type === "text").map((c) => c.text) ?? [];
1185
+ const output = textParts.join("\n") || (result?.Err ? JSON.stringify(result.Err) : "");
1186
+ parts.push(withMeta({
1187
+ type: "tool-result",
1188
+ toolCallId: callId,
1189
+ toolName: tracked.toolName,
1190
+ result: { output }
1191
+ }));
1192
+ this.openToolCalls.delete(callId);
1193
+ }
1194
+ break;
1195
+ }
1077
1196
  case "item/mcpToolCall/progress": {
1078
1197
  const params = event.params ?? {};
1079
1198
  if (params.itemId && params.message) {
@@ -1143,6 +1262,9 @@ var CodexEventMapper = class {
1143
1262
  }
1144
1263
  this.openToolCalls.clear();
1145
1264
  const completed = event.params ?? {};
1265
+ if (completed.turn?.id) {
1266
+ this.planSequenceByTurnId.delete(completed.turn.id);
1267
+ }
1146
1268
  const usage = this.latestUsage ?? EMPTY_USAGE;
1147
1269
  parts.push(withMeta({ type: "finish", finishReason: toFinishReason(completed.turn?.status), usage }));
1148
1270
  break;
@@ -1448,7 +1570,9 @@ var CodexLanguageModel = class {
1448
1570
  const client = new AppServerClient(transport, stripUndefined({
1449
1571
  onPacket: packetLogger
1450
1572
  }));
1451
- const mapper = new CodexEventMapper();
1573
+ const mapper = new CodexEventMapper(stripUndefined({
1574
+ emitPlanUpdates: this.config.providerSettings.emitPlanUpdates
1575
+ }));
1452
1576
  let activeThreadId;
1453
1577
  let activeTurnId;
1454
1578
  const interruptTimeoutMs = this.config.providerSettings.interruptTimeoutMs ?? 1e4;