@bman654/clodex 2.11.2 → 2.11.4

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/cli.js CHANGED
@@ -382,7 +382,7 @@ import { join } from "path";
382
382
  // package.json
383
383
  var package_default = {
384
384
  name: "@bman654/clodex",
385
- version: "2.11.2",
385
+ version: "2.11.4",
386
386
  publishConfig: {
387
387
  access: "public"
388
388
  },
@@ -8663,6 +8663,7 @@ function normalizeToolCallJson(value) {
8663
8663
  }
8664
8664
  }
8665
8665
  if (record.type === "reasoning") {
8666
+ delete out.id;
8666
8667
  if (Array.isArray(record.content) && record.content.length === 0) delete out.content;
8667
8668
  if (typeof record.encrypted_content === "string" && record.encrypted_content) delete out.summary;
8668
8669
  }
@@ -11672,6 +11673,71 @@ var CLAUDE_CODE_COMPACT_PROMPT_MARKERS = Object.freeze({
11672
11673
  end: "REMINDER: Do NOT call any tools. Respond with plain text only"
11673
11674
  });
11674
11675
 
11676
+ // src/openai-thinking.ts
11677
+ var SIGNATURE_PREFIX = "clodex:openai-thinking:";
11678
+ var SIGNATURE_V1 = `${SIGNATURE_PREFIX}v1:`;
11679
+ function openAiReasoningItemId(part) {
11680
+ const id = part.providerMetadata?.openai?.itemId;
11681
+ return typeof id === "string" && id.length > 0 ? id : void 0;
11682
+ }
11683
+ var OpenAiThinkingBlock = class {
11684
+ parts = /* @__PURE__ */ new Map();
11685
+ hasText = false;
11686
+ start(part) {
11687
+ const itemId = openAiReasoningItemId(part);
11688
+ if (!itemId || !part.id) throw new Error("OpenAI reasoning part has no identity");
11689
+ if (!this.parts.has(part.id)) this.parts.set(part.id, { itemId, text: "" });
11690
+ this.end(part);
11691
+ }
11692
+ append(part) {
11693
+ const entry = this.parts.get(part.id ?? "");
11694
+ if (!entry) throw new Error("OpenAI reasoning delta has no matching start");
11695
+ const text5 = part.text ?? "";
11696
+ if (!text5) return "";
11697
+ const separator = entry.text.length === 0 && this.hasText ? "\n\n" : "";
11698
+ entry.text += text5;
11699
+ this.hasText = true;
11700
+ return separator + text5;
11701
+ }
11702
+ end(part) {
11703
+ const entry = this.parts.get(part.id ?? "");
11704
+ const encrypted = part.providerMetadata?.openai?.reasoningEncryptedContent;
11705
+ if (entry && typeof encrypted === "string" && encrypted) entry.encryptedContent = encrypted;
11706
+ }
11707
+ signature() {
11708
+ return SIGNATURE_V1 + JSON.stringify({ parts: [...this.parts.values()] });
11709
+ }
11710
+ };
11711
+ function isRecord(value) {
11712
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11713
+ }
11714
+ function restoreOpenAiThinking(text5, signature, npm) {
11715
+ if (!signature?.startsWith(SIGNATURE_PREFIX)) return void 0;
11716
+ if (!signature.startsWith(SIGNATURE_V1)) return [];
11717
+ try {
11718
+ const envelope = JSON.parse(signature.slice(SIGNATURE_V1.length));
11719
+ if (!isRecord(envelope) || !Array.isArray(envelope.parts) || envelope.parts.length === 0) return [];
11720
+ const parts = [];
11721
+ for (const part of envelope.parts) {
11722
+ if (!isRecord(part) || typeof part.itemId !== "string" || !part.itemId || typeof part.text !== "string" || part.encryptedContent !== void 0 && typeof part.encryptedContent !== "string") return [];
11723
+ parts.push(part);
11724
+ }
11725
+ if (npm !== "@ai-sdk/openai") return text5 ? [{ type: "reasoning", text: text5 }] : [];
11726
+ return parts.map((part) => ({
11727
+ type: "reasoning",
11728
+ text: part.text,
11729
+ providerOptions: {
11730
+ openai: {
11731
+ itemId: part.itemId,
11732
+ ...part.encryptedContent ? { reasoningEncryptedContent: part.encryptedContent } : {}
11733
+ }
11734
+ }
11735
+ }));
11736
+ } catch {
11737
+ return [];
11738
+ }
11739
+ }
11740
+
11675
11741
  // src/sdk-adapter.ts
11676
11742
  function sdkTranslationErrorSignature(error) {
11677
11743
  const message = error instanceof Error ? error.message : typeof error === "string" ? error : void 0;
@@ -11876,8 +11942,12 @@ function translateMessages(messages, npm, openAiPromptCacheBreakpoints = false)
11876
11942
  if (b.type === "text") {
11877
11943
  parts.push({ type: "text", text: b.text ?? "" });
11878
11944
  } else if (b.type === "thinking") {
11879
- const part = thinkingToSdkPart(b, npm);
11880
- if (part) parts.push(part);
11945
+ const restored = restoreOpenAiThinking(b.thinking ?? "", b.signature, npm);
11946
+ if (restored) parts.push(...restored);
11947
+ else {
11948
+ const part = thinkingToSdkPart(b, npm);
11949
+ if (part) parts.push(part);
11950
+ }
11881
11951
  } else if (b.type === "tool_use" && b.id) {
11882
11952
  const { rawId, thoughtSignature } = splitToolUseId(b.id);
11883
11953
  const part = {
@@ -12119,6 +12189,7 @@ async function writeAnthropicStream(stream, modelId, write, log12, observer, too
12119
12189
  let started = false;
12120
12190
  let openType = null;
12121
12191
  let pendingThinkingSig;
12192
+ let openAiThinking;
12122
12193
  const idToBlock = /* @__PURE__ */ new Map();
12123
12194
  const toolJsonBuffer = /* @__PURE__ */ new Map();
12124
12195
  const flushedTools = /* @__PURE__ */ new Set();
@@ -12158,9 +12229,10 @@ async function writeAnthropicStream(stream, modelId, write, log12, observer, too
12158
12229
  emit("content_block_delta", {
12159
12230
  type: "content_block_delta",
12160
12231
  index: blockIndex,
12161
- delta: { type: "signature_delta", signature: pendingThinkingSig ?? "" }
12232
+ delta: { type: "signature_delta", signature: openAiThinking?.signature() ?? pendingThinkingSig ?? "" }
12162
12233
  });
12163
12234
  pendingThinkingSig = void 0;
12235
+ openAiThinking = void 0;
12164
12236
  }
12165
12237
  if (openType === "tool" && openToolId !== null && !flushedTools.has(openToolId)) {
12166
12238
  const buffered = toolJsonBuffer.get(openToolId);
@@ -12200,19 +12272,30 @@ async function writeAnthropicStream(stream, modelId, write, log12, observer, too
12200
12272
  case "abort":
12201
12273
  throw streamAbortError(observer?.abortSignal);
12202
12274
  case "reasoning-start":
12203
- openBlock("thinking", { type: "thinking", thinking: "", signature: "" });
12275
+ if (openAiReasoningItemId(part) && part.id) {
12276
+ if (!openAiThinking) {
12277
+ openBlock("thinking", { type: "thinking", thinking: "", signature: "" });
12278
+ openAiThinking = new OpenAiThinkingBlock();
12279
+ }
12280
+ openAiThinking.start(part);
12281
+ } else {
12282
+ openBlock("thinking", { type: "thinking", thinking: "", signature: "" });
12283
+ }
12204
12284
  break;
12205
12285
  case "reasoning-delta":
12206
12286
  if (openType !== "thinking") openBlock("thinking", { type: "thinking", thinking: "", signature: "" });
12207
12287
  emit("content_block_delta", {
12208
12288
  type: "content_block_delta",
12209
12289
  index: blockIndex,
12210
- delta: { type: "thinking_delta", thinking: part.text ?? "" }
12290
+ delta: { type: "thinking_delta", thinking: openAiThinking ? openAiThinking.append(part) : part.text ?? "" }
12211
12291
  });
12212
12292
  break;
12213
12293
  case "reasoning-end": {
12214
- const sig = grabRoundTripSignature(part);
12215
- if (sig) pendingThinkingSig = sig;
12294
+ if (openAiThinking) openAiThinking.end(part);
12295
+ else {
12296
+ const sig = grabRoundTripSignature(part);
12297
+ if (sig) pendingThinkingSig = sig;
12298
+ }
12216
12299
  break;
12217
12300
  }
12218
12301
  case "text-start":
@@ -18389,6 +18472,7 @@ import * as p9 from "@clack/prompts";
18389
18472
  import * as http2 from "http";
18390
18473
  import * as https from "https";
18391
18474
  import * as net from "net";
18475
+ import { PassThrough } from "stream";
18392
18476
  import { randomUUID as randomUUID6 } from "crypto";
18393
18477
  import { URL as URL2 } from "url";
18394
18478
  import { createBrotliDecompress, createGunzip, createInflate } from "zlib";
@@ -19076,6 +19160,97 @@ function forwardToAdapter(req, res, rawBody, adapter, adapterRequest = http2.req
19076
19160
  upstream.end(rawBody);
19077
19161
  });
19078
19162
  }
19163
+ function forwardAnthropicUpgrade(req, clientSocket, head, origin, rejectUnauthorized, agent, sockets) {
19164
+ if (clientSocket._httpMessage) {
19165
+ clientSocket.destroy();
19166
+ return;
19167
+ }
19168
+ const clientData = new PassThrough();
19169
+ clientSocket.pipe(clientData);
19170
+ let responseStarted = false;
19171
+ let upgradedSocket;
19172
+ const upstream = https.request({
19173
+ protocol: "https:",
19174
+ hostname: origin.hostname,
19175
+ port: origin.port || 443,
19176
+ method: req.method,
19177
+ path: req.url,
19178
+ headers: requestHeadersWithoutProxyHeaders(req),
19179
+ servername: net.isIP(origin.hostname) ? void 0 : origin.hostname,
19180
+ rejectUnauthorized,
19181
+ agent
19182
+ });
19183
+ const fail = () => {
19184
+ if (clientSocket.destroyed) return;
19185
+ if (responseStarted) {
19186
+ clientSocket.destroy();
19187
+ return;
19188
+ }
19189
+ responseStarted = true;
19190
+ clientSocket.end(
19191
+ "HTTP/1.1 502 Bad Gateway\r\nConnection: close\r\nContent-Length: 0\r\n\r\n",
19192
+ () => clientSocket.destroy()
19193
+ );
19194
+ };
19195
+ clientSocket.once("error", () => clientSocket.destroy());
19196
+ clientSocket.once("end", () => {
19197
+ if (!responseStarted) clientSocket.destroy();
19198
+ });
19199
+ clientSocket.once("close", () => {
19200
+ clientData.destroy();
19201
+ upstream.destroy();
19202
+ upgradedSocket?.destroy();
19203
+ });
19204
+ upstream.once("socket", (socket) => {
19205
+ if (clientSocket.destroyed) socket.destroy();
19206
+ });
19207
+ upstream.once("error", fail);
19208
+ upstream.once("close", () => {
19209
+ if (!responseStarted) fail();
19210
+ });
19211
+ upstream.once("response", (upstreamRes) => {
19212
+ if (clientSocket.destroyed) {
19213
+ upstreamRes.destroy();
19214
+ return;
19215
+ }
19216
+ responseStarted = true;
19217
+ const response = new http2.ServerResponse(req);
19218
+ response.shouldKeepAlive = false;
19219
+ response.assignSocket(clientSocket);
19220
+ clientSocket.on("drain", () => response.emit("drain"));
19221
+ response.once("error", () => clientSocket.destroy());
19222
+ response.once("finish", () => clientSocket.end(() => clientSocket.destroy()));
19223
+ copyResponse(upstreamRes, response);
19224
+ });
19225
+ upstream.once("upgrade", (upstreamRes, socket, upstreamHead) => {
19226
+ if (clientSocket.destroyed) {
19227
+ socket.destroy();
19228
+ return;
19229
+ }
19230
+ responseStarted = true;
19231
+ upgradedSocket = socket;
19232
+ sockets.add(socket);
19233
+ socket.once("error", () => clientSocket.destroy());
19234
+ socket.once("close", () => {
19235
+ sockets.delete(socket);
19236
+ clientSocket.destroy();
19237
+ });
19238
+ const headers = [
19239
+ `HTTP/${upstreamRes.httpVersion} ${upstreamRes.statusCode} ${upstreamRes.statusMessage}`
19240
+ ];
19241
+ for (let i = 0; i < upstreamRes.rawHeaders.length; i += 2) {
19242
+ headers.push(`${upstreamRes.rawHeaders[i]}: ${upstreamRes.rawHeaders[i + 1]}`);
19243
+ }
19244
+ clientSocket.write(Buffer.from(`${headers.join("\r\n")}\r
19245
+ \r
19246
+ `, "latin1"));
19247
+ if (upstreamHead.length > 0) clientSocket.write(upstreamHead);
19248
+ if (head.length > 0) socket.write(head);
19249
+ clientData.pipe(socket);
19250
+ socket.pipe(clientSocket);
19251
+ });
19252
+ upstream.end();
19253
+ }
19079
19254
  function forwardPlainHttp(req, res) {
19080
19255
  let target;
19081
19256
  try {
@@ -19292,6 +19467,17 @@ async function startHttpProxy(options) {
19292
19467
  );
19293
19468
  });
19294
19469
  const sockets = /* @__PURE__ */ new Set();
19470
+ mitmServer.on("upgrade", (req, socket, head) => {
19471
+ forwardAnthropicUpgrade(
19472
+ req,
19473
+ socket,
19474
+ head,
19475
+ anthropicOrigin,
19476
+ options.anthropicRejectUnauthorized ?? true,
19477
+ anthropicAgent,
19478
+ sockets
19479
+ );
19480
+ });
19295
19481
  const proxyServer = http2.createServer(forwardPlainHttp);
19296
19482
  proxyServer.on("connection", (socket) => {
19297
19483
  sockets.add(socket);