@cydm/pie 1.0.39 → 1.0.41

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.
@@ -1,9 +1,9 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createAskUserCapability
4
- } from "../../../chunks/chunk-SNSSIR3E.js";
5
- import "../../../chunks/chunk-7IFMKPHH.js";
6
- import "../../../chunks/chunk-HPTWCKJE.js";
4
+ } from "../../../chunks/chunk-OBCFKF6H.js";
5
+ import "../../../chunks/chunk-E3ELBCCX.js";
6
+ import "../../../chunks/chunk-YCPKJCUB.js";
7
7
  import "../../../chunks/chunk-TG2EQLX2.js";
8
8
 
9
9
  // builtin/extensions/ask-user/index.ts
@@ -7,11 +7,11 @@ import {
7
7
  isPlanModeSafeCommand,
8
8
  markCompletedPlanSteps,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-SNSSIR3E.js";
11
- import "../../../chunks/chunk-7IFMKPHH.js";
10
+ } from "../../../chunks/chunk-OBCFKF6H.js";
11
+ import "../../../chunks/chunk-E3ELBCCX.js";
12
12
  import {
13
13
  Type
14
- } from "../../../chunks/chunk-HPTWCKJE.js";
14
+ } from "../../../chunks/chunk-YCPKJCUB.js";
15
15
  import "../../../chunks/chunk-TG2EQLX2.js";
16
16
 
17
17
  // builtin/extensions/plan-mode/index.ts
@@ -1,13 +1,13 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createCliHostCapabilities
4
- } from "../../../chunks/chunk-F6VAOGFL.js";
4
+ } from "../../../chunks/chunk-4WGEYDPO.js";
5
5
  import {
6
6
  createSharedFileSystemTools,
7
7
  createSubagentCapability
8
- } from "../../../chunks/chunk-SNSSIR3E.js";
9
- import "../../../chunks/chunk-7IFMKPHH.js";
10
- import "../../../chunks/chunk-HPTWCKJE.js";
8
+ } from "../../../chunks/chunk-OBCFKF6H.js";
9
+ import "../../../chunks/chunk-E3ELBCCX.js";
10
+ import "../../../chunks/chunk-YCPKJCUB.js";
11
11
  import "../../../chunks/chunk-TG2EQLX2.js";
12
12
 
13
13
  // builtin/extensions/subagent/index.ts
@@ -7,9 +7,9 @@ import {
7
7
  executeManageTodoList,
8
8
  executionStateToTodos,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-SNSSIR3E.js";
11
- import "../../../chunks/chunk-7IFMKPHH.js";
12
- import "../../../chunks/chunk-HPTWCKJE.js";
10
+ } from "../../../chunks/chunk-OBCFKF6H.js";
11
+ import "../../../chunks/chunk-E3ELBCCX.js";
12
+ import "../../../chunks/chunk-YCPKJCUB.js";
13
13
  import "../../../chunks/chunk-TG2EQLX2.js";
14
14
 
15
15
  // builtin/extensions/todo/index.ts
@@ -8,10 +8,10 @@ import {
8
8
  createSharedWebSearchTool,
9
9
  interpretShellExit,
10
10
  requestInteraction
11
- } from "./chunk-SNSSIR3E.js";
11
+ } from "./chunk-OBCFKF6H.js";
12
12
  import {
13
13
  Type
14
- } from "./chunk-HPTWCKJE.js";
14
+ } from "./chunk-YCPKJCUB.js";
15
15
 
16
16
  // src/config.ts
17
17
  import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  EventStream,
4
4
  streamSimple,
5
5
  validateToolArguments
6
- } from "./chunk-HPTWCKJE.js";
6
+ } from "./chunk-YCPKJCUB.js";
7
7
 
8
8
  // ../../packages/agent-core/src/agent-loop.ts
9
9
  function createLoopErrorMessage(error, config, signal) {
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  Agent
4
- } from "./chunk-7IFMKPHH.js";
4
+ } from "./chunk-E3ELBCCX.js";
5
5
  import {
6
6
  FileSystemGateway,
7
7
  Type,
@@ -11,7 +11,7 @@ import {
11
11
  getPlatformConfig,
12
12
  hashText,
13
13
  streamSimple
14
- } from "./chunk-HPTWCKJE.js";
14
+ } from "./chunk-YCPKJCUB.js";
15
15
  import {
16
16
  __commonJS,
17
17
  __toESM
@@ -4162,6 +4162,7 @@ function isAbortErrorMessage(message) {
4162
4162
  var nodeHttps = null;
4163
4163
  var nodeHttp = null;
4164
4164
  var nodeUrl = null;
4165
+ var nodeStringDecoder = null;
4165
4166
  function getNodeHttps() {
4166
4167
  if (!nodeHttps) {
4167
4168
  nodeHttps = require3("https");
@@ -4180,6 +4181,12 @@ function getNodeUrl() {
4180
4181
  }
4181
4182
  return nodeUrl;
4182
4183
  }
4184
+ function getNodeStringDecoder() {
4185
+ if (!nodeStringDecoder) {
4186
+ nodeStringDecoder = require3("string_decoder");
4187
+ }
4188
+ return nodeStringDecoder;
4189
+ }
4183
4190
  var globalHttpsAgent = null;
4184
4191
  var globalHttpAgent = null;
4185
4192
  var agentStats = {
@@ -4322,8 +4329,9 @@ var NodeHttpClient = class {
4322
4329
  const sseStartTime = Date.now();
4323
4330
  let totalBytes = 0;
4324
4331
  let lineCount = 0;
4325
- let bufferChunks = [];
4326
- let bufferLength = 0;
4332
+ const { StringDecoder } = getNodeStringDecoder();
4333
+ const decoder = new StringDecoder("utf8");
4334
+ let textBuffer = "";
4327
4335
  const lineQueue = [];
4328
4336
  let queueHead = 0;
4329
4337
  let done = false;
@@ -4343,23 +4351,21 @@ var NodeHttpClient = class {
4343
4351
  logHttp("ERROR", `Request [${requestId}] SSE stream error`, { error: e.message });
4344
4352
  };
4345
4353
  const flushBuffer = (final = false) => {
4346
- if (bufferLength === 0) return;
4347
- const buffer = Buffer.concat(bufferChunks, bufferLength);
4348
- const bufferStr = buffer.toString("utf-8");
4349
- const lines = bufferStr.split("\n");
4354
+ if (final) {
4355
+ textBuffer += decoder.end();
4356
+ }
4357
+ if (textBuffer.length === 0) return;
4358
+ const lines = textBuffer.split("\n");
4350
4359
  const lastLine = lines.pop();
4351
4360
  if (final) {
4352
4361
  if (lastLine !== void 0 && lastLine.length > 0) {
4353
4362
  lines.push(lastLine);
4354
4363
  }
4355
- bufferChunks = [];
4356
- bufferLength = 0;
4364
+ textBuffer = "";
4357
4365
  } else if (lastLine !== void 0) {
4358
- bufferChunks = [Buffer.from(lastLine)];
4359
- bufferLength = lastLine.length;
4366
+ textBuffer = lastLine;
4360
4367
  } else {
4361
- bufferChunks = [];
4362
- bufferLength = 0;
4368
+ textBuffer = "";
4363
4369
  }
4364
4370
  for (const line of lines) {
4365
4371
  lineQueue.push(line);
@@ -4379,17 +4385,15 @@ var NodeHttpClient = class {
4379
4385
  }
4380
4386
  res.on("data", (chunk) => {
4381
4387
  totalBytes += chunk.length;
4382
- bufferChunks.push(chunk);
4383
- bufferLength += chunk.length;
4384
- if (bufferLength > 16384 || chunk.includes(10)) {
4388
+ const decoded = decoder.write(chunk);
4389
+ textBuffer += decoded;
4390
+ if (textBuffer.length > 16384 || decoded.includes("\n")) {
4385
4391
  flushBuffer();
4386
4392
  }
4387
4393
  wake({ done: false, value: void 0 });
4388
4394
  });
4389
4395
  res.on("end", () => {
4390
- if (bufferLength > 0) {
4391
- flushBuffer(true);
4392
- }
4396
+ flushBuffer(true);
4393
4397
  if (!res.complete) {
4394
4398
  failStream(new Error("SSE stream ended before response completed"));
4395
4399
  return;
@@ -5539,7 +5543,7 @@ function hasAssistantContent(message) {
5539
5543
  return block.text.trim().length > 0;
5540
5544
  }
5541
5545
  if (block.type === "thinking") {
5542
- return block.thinking.trim().length > 0;
5546
+ return false;
5543
5547
  }
5544
5548
  if (block.type === "toolCall") {
5545
5549
  return block.name.trim().length > 0;
@@ -5548,6 +5552,9 @@ function hasAssistantContent(message) {
5548
5552
  });
5549
5553
  }
5550
5554
  function assertAssistantHasContent(message) {
5555
+ if (message.stopReason === "length") {
5556
+ return;
5557
+ }
5551
5558
  if (!hasAssistantContent(message)) {
5552
5559
  throw new EmptyAssistantContentError();
5553
5560
  }
@@ -5571,6 +5578,14 @@ function logEmptyAssistantContentError(error, model, options) {
5571
5578
 
5572
5579
  // ../../packages/ai/src/providers/openai-compat.ts
5573
5580
  var DEFAULT_OPENAI_COMPAT_STREAM_TIMEOUT_MS = 10 * 60 * 1e3;
5581
+ var OPENAI_COMPAT_PROTOCOL_ERROR_CODE = "provider_response_protocol_error";
5582
+ var OpenAICompatProtocolError = class extends Error {
5583
+ code = OPENAI_COMPAT_PROTOCOL_ERROR_CODE;
5584
+ constructor(message) {
5585
+ super(`${OPENAI_COMPAT_PROTOCOL_ERROR_CODE}: ${message}`);
5586
+ this.name = "OpenAICompatProtocolError";
5587
+ }
5588
+ };
5574
5589
  function getOpenAICompatStreamTimeoutMs() {
5575
5590
  const value = Number(process.env.PIE_OPENAI_COMPAT_STREAM_TIMEOUT_MS || "");
5576
5591
  return Number.isFinite(value) && value > 0 ? value : DEFAULT_OPENAI_COMPAT_STREAM_TIMEOUT_MS;
@@ -5623,6 +5638,34 @@ function formatOpenAIStreamError(error) {
5623
5638
  }
5624
5639
  return metadata.length > 0 ? `${message} (${metadata.join(", ")})` : message;
5625
5640
  }
5641
+ function isRecord(value) {
5642
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5643
+ }
5644
+ function createProtocolError(message) {
5645
+ return new OpenAICompatProtocolError(message);
5646
+ }
5647
+ function parseSSEDataLine(line) {
5648
+ const trimmed = line.trim();
5649
+ if (!trimmed || trimmed.startsWith(":")) return null;
5650
+ if (!trimmed.startsWith("data:")) return null;
5651
+ const data = trimmed.slice(5);
5652
+ return data.startsWith(" ") ? data.slice(1) : data;
5653
+ }
5654
+ function parseFinalToolArguments(partialArgs, toolName) {
5655
+ const text = partialArgs.trim();
5656
+ if (!text) return {};
5657
+ let parsed;
5658
+ try {
5659
+ parsed = JSON.parse(text);
5660
+ } catch (error) {
5661
+ const message = error instanceof Error ? error.message : String(error);
5662
+ throw createProtocolError(`OpenAI-compatible stream returned incomplete or invalid JSON arguments for tool "${toolName || "unknown"}": ${message}`);
5663
+ }
5664
+ if (!isRecord(parsed)) {
5665
+ throw createProtocolError(`OpenAI-compatible stream returned non-object JSON arguments for tool "${toolName || "unknown"}".`);
5666
+ }
5667
+ return parsed;
5668
+ }
5626
5669
  var streamOpenAICompletions = (model, context, options) => {
5627
5670
  const stream = new AssistantMessageEventStream();
5628
5671
  (async () => {
@@ -5673,8 +5716,86 @@ var streamOpenAICompletions = (model, context, options) => {
5673
5716
  let currentBlock = null;
5674
5717
  const blocks = output.content;
5675
5718
  const blockIndex = () => blocks.length - 1;
5676
- const toolCalls = /* @__PURE__ */ new Map();
5719
+ const toolCallEntries = [];
5720
+ const toolCallsByIndex = /* @__PURE__ */ new Map();
5721
+ const toolCallsById = /* @__PURE__ */ new Map();
5677
5722
  let usageSnapshot = {};
5723
+ let sawDone = false;
5724
+ let sawFinishReason = false;
5725
+ let rawFinishReason = null;
5726
+ const createToolCallEntry = (toolCall, index) => {
5727
+ const block = {
5728
+ type: "toolCall",
5729
+ id: toolCall.id || "",
5730
+ name: toolCall.function?.name || "",
5731
+ arguments: {}
5732
+ };
5733
+ output.content.push(block);
5734
+ const entry = { block, partialArgs: "", contentIndex: blockIndex(), index };
5735
+ toolCallEntries.push(entry);
5736
+ stream.push({
5737
+ type: "toolcall_start",
5738
+ contentIndex: entry.contentIndex,
5739
+ partial: output
5740
+ });
5741
+ return entry;
5742
+ };
5743
+ const bindToolCallIndex = (index, entry) => {
5744
+ const existing = toolCallsByIndex.get(index);
5745
+ if (existing && existing !== entry) {
5746
+ throw createProtocolError(`OpenAI-compatible stream reused tool call index ${index} for multiple calls.`);
5747
+ }
5748
+ if (entry.index !== void 0 && entry.index !== index) {
5749
+ throw createProtocolError(`OpenAI-compatible stream moved tool call "${entry.block.id || entry.block.name || "unknown"}" from index ${entry.index} to ${index}.`);
5750
+ }
5751
+ entry.index = index;
5752
+ toolCallsByIndex.set(index, entry);
5753
+ };
5754
+ const rememberToolCallId = (id, entry) => {
5755
+ const existing = toolCallsById.get(id);
5756
+ if (existing && existing !== entry) {
5757
+ throw createProtocolError(`OpenAI-compatible stream reused tool call id "${id}" for multiple calls.`);
5758
+ }
5759
+ if (entry.block.id && entry.block.id !== id) {
5760
+ throw createProtocolError(`OpenAI-compatible stream changed tool call id from "${entry.block.id}" to "${id}".`);
5761
+ }
5762
+ entry.block.id = id;
5763
+ toolCallsById.set(id, entry);
5764
+ };
5765
+ const resolveToolCallEntry = (toolCall, toolCallCount) => {
5766
+ const id = typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : "";
5767
+ if (Number.isInteger(toolCall.index) && toolCall.index >= 0) {
5768
+ let entry = toolCallsByIndex.get(toolCall.index);
5769
+ if (entry && id && entry.block.id && entry.block.id !== id) {
5770
+ throw createProtocolError(`OpenAI-compatible stream changed tool call id at index ${toolCall.index} from "${entry.block.id}" to "${id}".`);
5771
+ }
5772
+ if (!entry && id) {
5773
+ entry = toolCallsById.get(id);
5774
+ if (entry) bindToolCallIndex(toolCall.index, entry);
5775
+ }
5776
+ if (!entry) {
5777
+ entry = createToolCallEntry(toolCall, toolCall.index);
5778
+ bindToolCallIndex(toolCall.index, entry);
5779
+ }
5780
+ if (id) rememberToolCallId(id, entry);
5781
+ return entry;
5782
+ }
5783
+ if (id) {
5784
+ let entry = toolCallsById.get(id);
5785
+ if (!entry) {
5786
+ entry = createToolCallEntry(toolCall);
5787
+ rememberToolCallId(id, entry);
5788
+ }
5789
+ return entry;
5790
+ }
5791
+ if (toolCallEntries.length === 1) {
5792
+ return toolCallEntries[0];
5793
+ }
5794
+ if (toolCallEntries.length === 0 && toolCallCount === 1) {
5795
+ return createToolCallEntry(toolCall);
5796
+ }
5797
+ throw createProtocolError("OpenAI-compatible stream returned tool call deltas without index or id and the call could not be disambiguated.");
5798
+ };
5678
5799
  const finishCurrentBlock = (block) => {
5679
5800
  if (block) {
5680
5801
  if (block.type === "text") {
@@ -5699,155 +5820,161 @@ var streamOpenAICompletions = (model, context, options) => {
5699
5820
  }
5700
5821
  for await (const line of response.readSSELines(options?.signal)) {
5701
5822
  {
5702
- const trimmed = line.trim();
5703
- if (!trimmed || trimmed.startsWith(":")) continue;
5704
- if (trimmed.startsWith("data: ")) {
5705
- const data = trimmed.slice(6);
5706
- if (data === "[DONE]") break;
5707
- let chunk;
5708
- try {
5709
- chunk = JSON.parse(data);
5710
- } catch {
5711
- continue;
5712
- }
5713
- if (chunk?.error) {
5714
- throw new Error(formatOpenAIStreamError(chunk.error));
5823
+ const data = parseSSEDataLine(line);
5824
+ if (data === null) continue;
5825
+ if (data === "[DONE]") {
5826
+ sawDone = true;
5827
+ break;
5828
+ }
5829
+ let chunk;
5830
+ try {
5831
+ chunk = JSON.parse(data);
5832
+ } catch (error) {
5833
+ const message = error instanceof Error ? error.message : String(error);
5834
+ throw createProtocolError(`OpenAI-compatible stream returned malformed SSE JSON: ${message}`);
5835
+ }
5836
+ if (chunk?.error) {
5837
+ throw new Error(formatOpenAIStreamError(chunk.error));
5838
+ }
5839
+ if (chunk.usage) {
5840
+ usageSnapshot = mergeOpenAIUsage(usageSnapshot, chunk.usage);
5841
+ const normalizedUsage = normalizeOpenAIUsage(usageSnapshot);
5842
+ output.usage = {
5843
+ input: normalizedUsage.input,
5844
+ output: normalizedUsage.output,
5845
+ cacheRead: normalizedUsage.cacheRead,
5846
+ cacheWrite: 0,
5847
+ totalTokens: normalizedUsage.totalTokens,
5848
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
5849
+ };
5850
+ output.usage.cost = calculateCost(model, output.usage);
5851
+ if (process.env.PIE_DEBUG_CACHE) {
5852
+ const normalizedPromptTokens = normalizedUsage.input + normalizedUsage.cacheRead;
5853
+ console.error("[CACHE DEBUG] Response usage:", JSON.stringify({
5854
+ input_tokens: normalizedUsage.input,
5855
+ output_tokens: normalizedUsage.output,
5856
+ cached_tokens: normalizedUsage.cacheRead,
5857
+ cache_hit_rate: normalizedPromptTokens > 0 ? `${(normalizedUsage.cacheRead / normalizedPromptTokens * 100).toFixed(1)}%` : "N/A"
5858
+ }, null, 2));
5715
5859
  }
5716
- if (chunk.usage) {
5717
- usageSnapshot = mergeOpenAIUsage(usageSnapshot, chunk.usage);
5718
- const normalizedUsage = normalizeOpenAIUsage(usageSnapshot);
5719
- output.usage = {
5720
- input: normalizedUsage.input,
5721
- output: normalizedUsage.output,
5722
- cacheRead: normalizedUsage.cacheRead,
5723
- cacheWrite: 0,
5724
- totalTokens: normalizedUsage.totalTokens,
5725
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
5726
- };
5727
- output.usage.cost = calculateCost(model, output.usage);
5728
- if (process.env.PIE_DEBUG_CACHE) {
5729
- const normalizedPromptTokens = normalizedUsage.input + normalizedUsage.cacheRead;
5730
- console.error("[CACHE DEBUG] Response usage:", JSON.stringify({
5731
- input_tokens: normalizedUsage.input,
5732
- output_tokens: normalizedUsage.output,
5733
- cached_tokens: normalizedUsage.cacheRead,
5734
- cache_hit_rate: normalizedPromptTokens > 0 ? `${(normalizedUsage.cacheRead / normalizedPromptTokens * 100).toFixed(1)}%` : "N/A"
5735
- }, null, 2));
5860
+ }
5861
+ const choice = chunk.choices?.[0];
5862
+ if (!choice) continue;
5863
+ if (choice.finish_reason) {
5864
+ sawFinishReason = true;
5865
+ rawFinishReason = String(choice.finish_reason);
5866
+ output.stopReason = mapOpenAIStopReason(choice.finish_reason);
5867
+ }
5868
+ if (choice.delta) {
5869
+ if (choice.delta.content !== null && choice.delta.content !== void 0 && choice.delta.content.length > 0) {
5870
+ if (!currentBlock || currentBlock.type !== "text") {
5871
+ finishCurrentBlock(currentBlock);
5872
+ currentBlock = { type: "text", text: "" };
5873
+ output.content.push(currentBlock);
5874
+ stream.push({
5875
+ type: "text_start",
5876
+ contentIndex: blockIndex(),
5877
+ partial: output
5878
+ });
5879
+ }
5880
+ if (currentBlock.type === "text") {
5881
+ currentBlock.text += choice.delta.content;
5882
+ stream.push({
5883
+ type: "text_delta",
5884
+ contentIndex: blockIndex(),
5885
+ delta: choice.delta.content,
5886
+ partial: output
5887
+ });
5736
5888
  }
5737
5889
  }
5738
- const choice = chunk.choices?.[0];
5739
- if (!choice) continue;
5740
- if (choice.finish_reason) {
5741
- output.stopReason = mapOpenAIStopReason(choice.finish_reason);
5890
+ const reasoningFields = [
5891
+ "reasoning_content",
5892
+ "reasoning",
5893
+ "reasoning_text"
5894
+ ];
5895
+ let foundReasoningField = null;
5896
+ for (const field of reasoningFields) {
5897
+ if (choice.delta[field] !== null && choice.delta[field] !== void 0 && choice.delta[field].length > 0) {
5898
+ foundReasoningField = field;
5899
+ break;
5900
+ }
5742
5901
  }
5743
- if (choice.delta) {
5744
- if (choice.delta.content !== null && choice.delta.content !== void 0 && choice.delta.content.length > 0) {
5745
- if (!currentBlock || currentBlock.type !== "text") {
5746
- finishCurrentBlock(currentBlock);
5747
- currentBlock = { type: "text", text: "" };
5748
- output.content.push(currentBlock);
5749
- stream.push({
5750
- type: "text_start",
5751
- contentIndex: blockIndex(),
5752
- partial: output
5753
- });
5754
- }
5755
- if (currentBlock.type === "text") {
5756
- currentBlock.text += choice.delta.content;
5757
- stream.push({
5758
- type: "text_delta",
5759
- contentIndex: blockIndex(),
5760
- delta: choice.delta.content,
5761
- partial: output
5762
- });
5763
- }
5902
+ if (foundReasoningField) {
5903
+ if (!currentBlock || currentBlock.type !== "thinking") {
5904
+ finishCurrentBlock(currentBlock);
5905
+ currentBlock = {
5906
+ type: "thinking",
5907
+ thinking: "",
5908
+ thinkingSignature: foundReasoningField
5909
+ };
5910
+ output.content.push(currentBlock);
5911
+ stream.push({
5912
+ type: "thinking_start",
5913
+ contentIndex: blockIndex(),
5914
+ partial: output
5915
+ });
5764
5916
  }
5765
- const reasoningFields = [
5766
- "reasoning_content",
5767
- "reasoning",
5768
- "reasoning_text"
5769
- ];
5770
- let foundReasoningField = null;
5771
- for (const field of reasoningFields) {
5772
- if (choice.delta[field] !== null && choice.delta[field] !== void 0 && choice.delta[field].length > 0) {
5773
- foundReasoningField = field;
5774
- break;
5775
- }
5917
+ if (currentBlock.type === "thinking") {
5918
+ const delta = choice.delta[foundReasoningField];
5919
+ currentBlock.thinking += delta;
5920
+ stream.push({
5921
+ type: "thinking_delta",
5922
+ contentIndex: blockIndex(),
5923
+ delta,
5924
+ partial: output
5925
+ });
5776
5926
  }
5777
- if (foundReasoningField) {
5778
- if (!currentBlock || currentBlock.type !== "thinking") {
5779
- finishCurrentBlock(currentBlock);
5780
- currentBlock = {
5781
- type: "thinking",
5782
- thinking: "",
5783
- thinkingSignature: foundReasoningField
5784
- };
5785
- output.content.push(currentBlock);
5786
- stream.push({
5787
- type: "thinking_start",
5788
- contentIndex: blockIndex(),
5789
- partial: output
5790
- });
5791
- }
5792
- if (currentBlock.type === "thinking") {
5793
- const delta = choice.delta[foundReasoningField];
5794
- currentBlock.thinking += delta;
5927
+ }
5928
+ if (choice.delta.tool_calls) {
5929
+ const deltaToolCalls = choice.delta.tool_calls;
5930
+ for (const toolCall of deltaToolCalls) {
5931
+ finishCurrentBlock(currentBlock);
5932
+ currentBlock = null;
5933
+ const entry = resolveToolCallEntry(toolCall, deltaToolCalls.length);
5934
+ if (entry) {
5935
+ if (toolCall.id) rememberToolCallId(toolCall.id, entry);
5936
+ if (toolCall.function?.name) {
5937
+ if (entry.block.name && entry.block.name !== toolCall.function.name) {
5938
+ throw createProtocolError(`OpenAI-compatible stream changed tool call name from "${entry.block.name}" to "${toolCall.function.name}".`);
5939
+ }
5940
+ entry.block.name = toolCall.function.name;
5941
+ }
5942
+ let delta = "";
5943
+ if (toolCall.function?.arguments) {
5944
+ delta = toolCall.function.arguments;
5945
+ entry.partialArgs += delta;
5946
+ entry.block.arguments = parseStreamingJson(entry.partialArgs);
5947
+ }
5795
5948
  stream.push({
5796
- type: "thinking_delta",
5797
- contentIndex: blockIndex(),
5949
+ type: "toolcall_delta",
5950
+ contentIndex: entry.contentIndex,
5798
5951
  delta,
5799
5952
  partial: output
5800
5953
  });
5801
5954
  }
5802
5955
  }
5803
- if (choice.delta.tool_calls) {
5804
- for (const [toolCallPosition, toolCall] of choice.delta.tool_calls.entries()) {
5805
- const toolCallIndex = Number.isInteger(toolCall.index) && toolCall.index >= 0 ? toolCall.index : toolCallPosition;
5806
- finishCurrentBlock(currentBlock);
5807
- currentBlock = null;
5808
- let entry = toolCalls.get(toolCallIndex);
5809
- if (!entry) {
5810
- const block = {
5811
- type: "toolCall",
5812
- id: toolCall.id || "",
5813
- name: toolCall.function?.name || "",
5814
- arguments: {}
5815
- };
5816
- output.content.push(block);
5817
- entry = { block, partialArgs: "", contentIndex: blockIndex() };
5818
- toolCalls.set(toolCallIndex, entry);
5819
- stream.push({
5820
- type: "toolcall_start",
5821
- contentIndex: entry.contentIndex,
5822
- partial: output
5823
- });
5824
- }
5825
- if (entry) {
5826
- if (toolCall.id) entry.block.id = toolCall.id;
5827
- if (toolCall.function?.name)
5828
- entry.block.name = toolCall.function.name;
5829
- let delta = "";
5830
- if (toolCall.function?.arguments) {
5831
- delta = toolCall.function.arguments;
5832
- entry.partialArgs += delta;
5833
- entry.block.arguments = parseStreamingJson(entry.partialArgs);
5834
- }
5835
- stream.push({
5836
- type: "toolcall_delta",
5837
- contentIndex: entry.contentIndex,
5838
- delta,
5839
- partial: output
5840
- });
5841
- }
5842
- }
5843
- }
5844
5956
  }
5845
5957
  }
5846
5958
  }
5847
5959
  }
5848
5960
  finishCurrentBlock(currentBlock);
5849
- for (const { block, partialArgs, contentIndex } of toolCalls.values()) {
5850
- block.arguments = parseStreamingJson(partialArgs);
5961
+ if (!sawDone) {
5962
+ throw createProtocolError(`OpenAI-compatible stream ended without data: [DONE]${rawFinishReason ? ` (last finish_reason=${rawFinishReason})` : ""}.`);
5963
+ }
5964
+ if (!sawFinishReason) {
5965
+ throw createProtocolError("OpenAI-compatible stream ended without finish_reason.");
5966
+ }
5967
+ if (output.stopReason === "toolUse" && toolCallEntries.length === 0) {
5968
+ throw createProtocolError(`OpenAI-compatible stream ended with finish_reason=${rawFinishReason} but did not include any tool calls.`);
5969
+ }
5970
+ if (output.stopReason === "length" && toolCallEntries.length > 0) {
5971
+ throw new Error("OpenAI-compatible stream ended with finish_reason=length before tool calls could be safely executed.");
5972
+ }
5973
+ for (const { block, partialArgs, contentIndex } of toolCallEntries) {
5974
+ if (!block.name.trim()) {
5975
+ throw createProtocolError("OpenAI-compatible stream returned a tool call without a function name.");
5976
+ }
5977
+ block.arguments = parseFinalToolArguments(partialArgs, block.name);
5851
5978
  stream.push({ type: "toolcall_end", contentIndex, toolCall: block, partial: output });
5852
5979
  }
5853
5980
  if (output.stopReason !== "error" && output.stopReason !== "aborted" && output.content.some((block) => block.type === "toolCall")) {
@@ -9772,6 +9899,7 @@ export {
9772
9899
  EventStream,
9773
9900
  getModelCacheCapability,
9774
9901
  EMPTY_ASSISTANT_CONTENT_ERROR,
9902
+ OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
9775
9903
  streamSimple,
9776
9904
  completeSimple,
9777
9905
  MODEL_CLASS_FALLBACK_ORDER,
@@ -3,8 +3,8 @@ import {
3
3
  Agent,
4
4
  agentLoop,
5
5
  agentLoopContinue
6
- } from "./chunk-7IFMKPHH.js";
7
- import "./chunk-HPTWCKJE.js";
6
+ } from "./chunk-E3ELBCCX.js";
7
+ import "./chunk-YCPKJCUB.js";
8
8
  import "./chunk-TG2EQLX2.js";
9
9
  export {
10
10
  Agent,
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  EventStream
4
- } from "./chunk-HPTWCKJE.js";
4
+ } from "./chunk-YCPKJCUB.js";
5
5
  import "./chunk-TG2EQLX2.js";
6
6
 
7
7
  // src/app/test-stream.ts
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  getThemesDir,
20
20
  migrateConfigFromAgentDir,
21
21
  truncateHeadTail
22
- } from "./chunks/chunk-F6VAOGFL.js";
22
+ } from "./chunks/chunk-4WGEYDPO.js";
23
23
  import {
24
24
  AGENTS_CONTEXT_FILE_NAME,
25
25
  AgentSessionController,
@@ -69,8 +69,8 @@ import {
69
69
  setExtensionEnabledInSettings,
70
70
  shouldPreserveExecutionStateForUserText,
71
71
  supersedeExecutionState
72
- } from "./chunks/chunk-SNSSIR3E.js";
73
- import "./chunks/chunk-7IFMKPHH.js";
72
+ } from "./chunks/chunk-OBCFKF6H.js";
73
+ import "./chunks/chunk-E3ELBCCX.js";
74
74
  import {
75
75
  Deref,
76
76
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -87,6 +87,7 @@ import {
87
87
  Kind,
88
88
  MODEL_CLASS_FALLBACK_ORDER,
89
89
  Never,
90
+ OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
90
91
  Ref,
91
92
  TransformDecode,
92
93
  TransformDecodeCheckError,
@@ -105,7 +106,7 @@ import {
105
106
  setLogger,
106
107
  sortToolModelCandidatesByCapability,
107
108
  type_exports
108
- } from "./chunks/chunk-HPTWCKJE.js";
109
+ } from "./chunks/chunk-YCPKJCUB.js";
109
110
  import {
110
111
  resolveCliProjectRoot
111
112
  } from "./chunks/chunk-NTYHFBUA.js";
@@ -67414,6 +67415,12 @@ function classifyCliFailure(context) {
67414
67415
  terminal: false
67415
67416
  });
67416
67417
  }
67418
+ if (errorMessage3.includes(OPENAI_COMPAT_PROTOCOL_ERROR_CODE)) {
67419
+ return createClassification("provider_transient", errorMessage3, {
67420
+ retryable: true,
67421
+ terminal: false
67422
+ });
67423
+ }
67417
67424
  if (PROVIDER_TRANSIENT_ERROR_PATTERN.test(errorMessage3)) {
67418
67425
  return createClassification("provider_transient", errorMessage3, {
67419
67426
  retryable: true,
@@ -69382,7 +69389,7 @@ var InteractiveMode = class {
69382
69389
  if (savedLevel) {
69383
69390
  this.thinkingLevel = savedLevel;
69384
69391
  }
69385
- const { Agent } = await import("./chunks/src-N6MKSRB3.js");
69392
+ const { Agent } = await import("./chunks/src-NHRMBQAJ.js");
69386
69393
  const activeSession = this.sessionManager.getActiveSession();
69387
69394
  this.agent = new Agent({
69388
69395
  initialState: {
@@ -70103,7 +70110,7 @@ async function runPrintMode(params) {
70103
70110
  `);
70104
70111
  console.log("Assistant: ");
70105
70112
  }
70106
- const { Agent: AgentClass } = await import("./chunks/src-N6MKSRB3.js");
70113
+ const { Agent: AgentClass } = await import("./chunks/src-NHRMBQAJ.js");
70107
70114
  let agent;
70108
70115
  const printModeExtensions = await loadPrintModeExtensions({
70109
70116
  cwd: runtime.cwd,
@@ -71053,7 +71060,7 @@ async function runJsonEventsMode(params) {
71053
71060
  if (runtime.initialModel.unconfigured || controller) {
71054
71061
  return;
71055
71062
  }
71056
- const { Agent: AgentClass } = await import("./chunks/src-N6MKSRB3.js");
71063
+ const { Agent: AgentClass } = await import("./chunks/src-NHRMBQAJ.js");
71057
71064
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
71058
71065
  const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
71059
71066
  recordCliCompositionStep(runtime.compositionTrace, {
@@ -71685,7 +71692,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
71685
71692
  }
71686
71693
  async function createCliTestStreamFnFromEnv() {
71687
71694
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
71688
- return (await import("./chunks/test-stream-6F6VZ44U.js")).createTestStreamFnFromSequenceEnv();
71695
+ return (await import("./chunks/test-stream-I6S23PTW.js")).createTestStreamFnFromSequenceEnv();
71689
71696
  }
71690
71697
  async function startChat(initialPrompt, testCommand) {
71691
71698
  const rawOutput = process.argv.includes("--raw-output");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {