@cydm/pie 1.0.40 → 1.0.42
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 +21 -2
- package/dist/builtin/extensions/ask-user/index.js +4 -4
- package/dist/builtin/extensions/changelog/index.js +1 -1
- package/dist/builtin/extensions/deploy/index.js +1 -1
- package/dist/builtin/extensions/document-attachments/index.js +1 -1
- package/dist/builtin/extensions/files/index.js +1 -1
- package/dist/builtin/extensions/init/index.js +1 -1
- package/dist/builtin/extensions/kimi-attachments/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +4 -4
- package/dist/builtin/extensions/subagent/index.js +5 -5
- package/dist/builtin/extensions/todo/index.js +4 -4
- package/dist/chunks/{chunk-SNSSIR3E.js → chunk-2GVFMYIV.js} +583 -91
- package/dist/chunks/{chunk-7IFMKPHH.js → chunk-JVLAKTAS.js} +1 -1
- package/dist/chunks/{chunk-TG2EQLX2.js → chunk-LZQXQOPJ.js} +5 -1
- package/dist/chunks/{chunk-HPTWCKJE.js → chunk-NGQ3PUOC.js} +315 -157
- package/dist/chunks/{chunk-F6VAOGFL.js → chunk-VYAW6RAX.js} +2 -2
- package/dist/chunks/{src-N6MKSRB3.js → src-TQNFXZGK.js} +3 -3
- package/dist/chunks/{test-stream-6F6VZ44U.js → test-stream-IPBFEEWH.js} +2 -2
- package/dist/cli.js +1758 -612
- package/dist/code-intel-worker.cjs +5 -1
- package/models.schema.json +412 -93
- package/package.json +3 -3
|
@@ -12,7 +12,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
12
12
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
13
|
});
|
|
14
14
|
var __commonJS = (cb, mod) => function __require2() {
|
|
15
|
-
|
|
15
|
+
try {
|
|
16
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
|
+
} catch (e) {
|
|
18
|
+
throw mod = 0, e;
|
|
19
|
+
}
|
|
16
20
|
};
|
|
17
21
|
var __export = (target, all) => {
|
|
18
22
|
for (var name in all)
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
__export,
|
|
5
5
|
__require,
|
|
6
6
|
__toESM
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LZQXQOPJ.js";
|
|
8
8
|
|
|
9
9
|
// ../../node_modules/partial-json/dist/options.js
|
|
10
10
|
var require_options = __commonJS({
|
|
@@ -3338,9 +3338,9 @@ var NodeFileSystem = class {
|
|
|
3338
3338
|
if (length === 0) return new Uint8Array();
|
|
3339
3339
|
const handle = await getNodeFs().promises.open(path, "r");
|
|
3340
3340
|
try {
|
|
3341
|
-
const
|
|
3342
|
-
const { bytesRead } = await handle.read(
|
|
3343
|
-
return
|
|
3341
|
+
const view = new Uint8Array(length);
|
|
3342
|
+
const { bytesRead } = await handle.read(view, 0, length, 0);
|
|
3343
|
+
return view.subarray(0, bytesRead);
|
|
3344
3344
|
} finally {
|
|
3345
3345
|
await handle.close();
|
|
3346
3346
|
}
|
|
@@ -3805,7 +3805,10 @@ var PuerTSFileSystem = class {
|
|
|
3805
3805
|
while (offset < length) {
|
|
3806
3806
|
const requested = Math.min(length - offset, 65536);
|
|
3807
3807
|
if (offset > 0 && typeof bridge.ReadRangeHex !== "function") {
|
|
3808
|
-
|
|
3808
|
+
console.warn(
|
|
3809
|
+
`[pie] readFilePrefix truncated at 64 KiB: the Unity file bridge is missing ReadRangeHex. Update the Pie package so PieFileBridge matches the runtime bundle. (requested ${length} bytes of '${path}')`
|
|
3810
|
+
);
|
|
3811
|
+
break;
|
|
3809
3812
|
}
|
|
3810
3813
|
const hex = String((offset === 0 ? bridge.ReadPrefixHex(normalizedPath, requested) : bridge.ReadRangeHex(normalizedPath, offset, requested)) ?? "");
|
|
3811
3814
|
if (hex.length % 2 !== 0) throw new Error("The Unity file bridge returned an invalid hex prefix.");
|
|
@@ -4162,6 +4165,7 @@ function isAbortErrorMessage(message) {
|
|
|
4162
4165
|
var nodeHttps = null;
|
|
4163
4166
|
var nodeHttp = null;
|
|
4164
4167
|
var nodeUrl = null;
|
|
4168
|
+
var nodeStringDecoder = null;
|
|
4165
4169
|
function getNodeHttps() {
|
|
4166
4170
|
if (!nodeHttps) {
|
|
4167
4171
|
nodeHttps = require3("https");
|
|
@@ -4180,6 +4184,12 @@ function getNodeUrl() {
|
|
|
4180
4184
|
}
|
|
4181
4185
|
return nodeUrl;
|
|
4182
4186
|
}
|
|
4187
|
+
function getNodeStringDecoder() {
|
|
4188
|
+
if (!nodeStringDecoder) {
|
|
4189
|
+
nodeStringDecoder = require3("string_decoder");
|
|
4190
|
+
}
|
|
4191
|
+
return nodeStringDecoder;
|
|
4192
|
+
}
|
|
4183
4193
|
var globalHttpsAgent = null;
|
|
4184
4194
|
var globalHttpAgent = null;
|
|
4185
4195
|
var agentStats = {
|
|
@@ -4322,8 +4332,9 @@ var NodeHttpClient = class {
|
|
|
4322
4332
|
const sseStartTime = Date.now();
|
|
4323
4333
|
let totalBytes = 0;
|
|
4324
4334
|
let lineCount = 0;
|
|
4325
|
-
|
|
4326
|
-
|
|
4335
|
+
const { StringDecoder } = getNodeStringDecoder();
|
|
4336
|
+
const decoder = new StringDecoder("utf8");
|
|
4337
|
+
let textBuffer = "";
|
|
4327
4338
|
const lineQueue = [];
|
|
4328
4339
|
let queueHead = 0;
|
|
4329
4340
|
let done = false;
|
|
@@ -4343,23 +4354,21 @@ var NodeHttpClient = class {
|
|
|
4343
4354
|
logHttp("ERROR", `Request [${requestId}] SSE stream error`, { error: e.message });
|
|
4344
4355
|
};
|
|
4345
4356
|
const flushBuffer = (final = false) => {
|
|
4346
|
-
if (
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4357
|
+
if (final) {
|
|
4358
|
+
textBuffer += decoder.end();
|
|
4359
|
+
}
|
|
4360
|
+
if (textBuffer.length === 0) return;
|
|
4361
|
+
const lines = textBuffer.split("\n");
|
|
4350
4362
|
const lastLine = lines.pop();
|
|
4351
4363
|
if (final) {
|
|
4352
4364
|
if (lastLine !== void 0 && lastLine.length > 0) {
|
|
4353
4365
|
lines.push(lastLine);
|
|
4354
4366
|
}
|
|
4355
|
-
|
|
4356
|
-
bufferLength = 0;
|
|
4367
|
+
textBuffer = "";
|
|
4357
4368
|
} else if (lastLine !== void 0) {
|
|
4358
|
-
|
|
4359
|
-
bufferLength = lastLine.length;
|
|
4369
|
+
textBuffer = lastLine;
|
|
4360
4370
|
} else {
|
|
4361
|
-
|
|
4362
|
-
bufferLength = 0;
|
|
4371
|
+
textBuffer = "";
|
|
4363
4372
|
}
|
|
4364
4373
|
for (const line of lines) {
|
|
4365
4374
|
lineQueue.push(line);
|
|
@@ -4379,17 +4388,15 @@ var NodeHttpClient = class {
|
|
|
4379
4388
|
}
|
|
4380
4389
|
res.on("data", (chunk) => {
|
|
4381
4390
|
totalBytes += chunk.length;
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
if (
|
|
4391
|
+
const decoded = decoder.write(chunk);
|
|
4392
|
+
textBuffer += decoded;
|
|
4393
|
+
if (textBuffer.length > 16384 || decoded.includes("\n")) {
|
|
4385
4394
|
flushBuffer();
|
|
4386
4395
|
}
|
|
4387
4396
|
wake({ done: false, value: void 0 });
|
|
4388
4397
|
});
|
|
4389
4398
|
res.on("end", () => {
|
|
4390
|
-
|
|
4391
|
-
flushBuffer(true);
|
|
4392
|
-
}
|
|
4399
|
+
flushBuffer(true);
|
|
4393
4400
|
if (!res.complete) {
|
|
4394
4401
|
failStream(new Error("SSE stream ended before response completed"));
|
|
4395
4402
|
return;
|
|
@@ -5212,6 +5219,8 @@ function detectCompat(_model) {
|
|
|
5212
5219
|
requiresAssistantAfterToolResult: false,
|
|
5213
5220
|
requiresThinkingAsText: true,
|
|
5214
5221
|
supportsStrictMode: true,
|
|
5222
|
+
streamRequiresDone: true,
|
|
5223
|
+
streamRequiresFinishReason: true,
|
|
5215
5224
|
cacheCapability: NO_CACHE_CAPABILITY
|
|
5216
5225
|
};
|
|
5217
5226
|
}
|
|
@@ -5229,6 +5238,8 @@ function getCompat(model) {
|
|
|
5229
5238
|
requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
|
|
5230
5239
|
requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
|
|
5231
5240
|
supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,
|
|
5241
|
+
streamRequiresDone: model.compat.streamRequiresDone ?? detected.streamRequiresDone,
|
|
5242
|
+
streamRequiresFinishReason: model.compat.streamRequiresFinishReason ?? detected.streamRequiresFinishReason,
|
|
5232
5243
|
cacheCapability: model.compat.cacheCapability ?? detected.cacheCapability
|
|
5233
5244
|
};
|
|
5234
5245
|
}
|
|
@@ -5539,7 +5550,7 @@ function hasAssistantContent(message) {
|
|
|
5539
5550
|
return block.text.trim().length > 0;
|
|
5540
5551
|
}
|
|
5541
5552
|
if (block.type === "thinking") {
|
|
5542
|
-
return
|
|
5553
|
+
return false;
|
|
5543
5554
|
}
|
|
5544
5555
|
if (block.type === "toolCall") {
|
|
5545
5556
|
return block.name.trim().length > 0;
|
|
@@ -5548,6 +5559,9 @@ function hasAssistantContent(message) {
|
|
|
5548
5559
|
});
|
|
5549
5560
|
}
|
|
5550
5561
|
function assertAssistantHasContent(message) {
|
|
5562
|
+
if (message.stopReason === "length") {
|
|
5563
|
+
return;
|
|
5564
|
+
}
|
|
5551
5565
|
if (!hasAssistantContent(message)) {
|
|
5552
5566
|
throw new EmptyAssistantContentError();
|
|
5553
5567
|
}
|
|
@@ -5571,6 +5585,14 @@ function logEmptyAssistantContentError(error, model, options) {
|
|
|
5571
5585
|
|
|
5572
5586
|
// ../../packages/ai/src/providers/openai-compat.ts
|
|
5573
5587
|
var DEFAULT_OPENAI_COMPAT_STREAM_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
5588
|
+
var OPENAI_COMPAT_PROTOCOL_ERROR_CODE = "provider_response_protocol_error";
|
|
5589
|
+
var OpenAICompatProtocolError = class extends Error {
|
|
5590
|
+
code = OPENAI_COMPAT_PROTOCOL_ERROR_CODE;
|
|
5591
|
+
constructor(message) {
|
|
5592
|
+
super(`${OPENAI_COMPAT_PROTOCOL_ERROR_CODE}: ${message}`);
|
|
5593
|
+
this.name = "OpenAICompatProtocolError";
|
|
5594
|
+
}
|
|
5595
|
+
};
|
|
5574
5596
|
function getOpenAICompatStreamTimeoutMs() {
|
|
5575
5597
|
const value = Number(process.env.PIE_OPENAI_COMPAT_STREAM_TIMEOUT_MS || "");
|
|
5576
5598
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_OPENAI_COMPAT_STREAM_TIMEOUT_MS;
|
|
@@ -5623,6 +5645,44 @@ function formatOpenAIStreamError(error) {
|
|
|
5623
5645
|
}
|
|
5624
5646
|
return metadata.length > 0 ? `${message} (${metadata.join(", ")})` : message;
|
|
5625
5647
|
}
|
|
5648
|
+
function isRecord(value) {
|
|
5649
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5650
|
+
}
|
|
5651
|
+
function createProtocolError(message) {
|
|
5652
|
+
return new OpenAICompatProtocolError(message);
|
|
5653
|
+
}
|
|
5654
|
+
function parseSSEDataLine(line) {
|
|
5655
|
+
const trimmed = line.trim();
|
|
5656
|
+
if (!trimmed || trimmed.startsWith(":")) return null;
|
|
5657
|
+
if (!trimmed.startsWith("data:")) return null;
|
|
5658
|
+
const data = trimmed.slice(5);
|
|
5659
|
+
return data.startsWith(" ") ? data.slice(1) : data;
|
|
5660
|
+
}
|
|
5661
|
+
function parseFinalToolArguments(partialArgs, toolName) {
|
|
5662
|
+
const text = partialArgs.trim();
|
|
5663
|
+
if (!text) return {};
|
|
5664
|
+
let parsed;
|
|
5665
|
+
try {
|
|
5666
|
+
parsed = JSON.parse(text);
|
|
5667
|
+
} catch (error) {
|
|
5668
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5669
|
+
throw createProtocolError(`OpenAI-compatible stream returned incomplete or invalid JSON arguments for tool "${toolName || "unknown"}": ${message}`);
|
|
5670
|
+
}
|
|
5671
|
+
if (!isRecord(parsed)) {
|
|
5672
|
+
throw createProtocolError(`OpenAI-compatible stream returned non-object JSON arguments for tool "${toolName || "unknown"}".`);
|
|
5673
|
+
}
|
|
5674
|
+
return parsed;
|
|
5675
|
+
}
|
|
5676
|
+
function tryParseFinalToolArguments(partialArgs) {
|
|
5677
|
+
const text = partialArgs.trim();
|
|
5678
|
+
if (!text) return null;
|
|
5679
|
+
try {
|
|
5680
|
+
const parsed = JSON.parse(text);
|
|
5681
|
+
return isRecord(parsed) ? parsed : null;
|
|
5682
|
+
} catch {
|
|
5683
|
+
return null;
|
|
5684
|
+
}
|
|
5685
|
+
}
|
|
5626
5686
|
var streamOpenAICompletions = (model, context, options) => {
|
|
5627
5687
|
const stream = new AssistantMessageEventStream();
|
|
5628
5688
|
(async () => {
|
|
@@ -5673,8 +5733,94 @@ var streamOpenAICompletions = (model, context, options) => {
|
|
|
5673
5733
|
let currentBlock = null;
|
|
5674
5734
|
const blocks = output.content;
|
|
5675
5735
|
const blockIndex = () => blocks.length - 1;
|
|
5676
|
-
const
|
|
5736
|
+
const toolCallEntries = [];
|
|
5737
|
+
const toolCallsByIndex = /* @__PURE__ */ new Map();
|
|
5738
|
+
const toolCallsById = /* @__PURE__ */ new Map();
|
|
5677
5739
|
let usageSnapshot = {};
|
|
5740
|
+
let sawDone = false;
|
|
5741
|
+
let sawFinishReason = false;
|
|
5742
|
+
let rawFinishReason = null;
|
|
5743
|
+
const createToolCallEntry = (toolCall, index) => {
|
|
5744
|
+
const block = {
|
|
5745
|
+
type: "toolCall",
|
|
5746
|
+
id: toolCall.id || "",
|
|
5747
|
+
name: toolCall.function?.name || "",
|
|
5748
|
+
arguments: {}
|
|
5749
|
+
};
|
|
5750
|
+
output.content.push(block);
|
|
5751
|
+
const entry = { block, partialArgs: "", contentIndex: blockIndex(), index };
|
|
5752
|
+
toolCallEntries.push(entry);
|
|
5753
|
+
stream.push({
|
|
5754
|
+
type: "toolcall_start",
|
|
5755
|
+
contentIndex: entry.contentIndex,
|
|
5756
|
+
partial: output
|
|
5757
|
+
});
|
|
5758
|
+
return entry;
|
|
5759
|
+
};
|
|
5760
|
+
const bindToolCallIndex = (index, entry) => {
|
|
5761
|
+
const existing = toolCallsByIndex.get(index);
|
|
5762
|
+
if (existing && existing !== entry) {
|
|
5763
|
+
throw createProtocolError(`OpenAI-compatible stream reused tool call index ${index} for multiple calls.`);
|
|
5764
|
+
}
|
|
5765
|
+
if (entry.index !== void 0 && entry.index !== index) {
|
|
5766
|
+
throw createProtocolError(`OpenAI-compatible stream moved tool call "${entry.block.id || entry.block.name || "unknown"}" from index ${entry.index} to ${index}.`);
|
|
5767
|
+
}
|
|
5768
|
+
entry.index = index;
|
|
5769
|
+
toolCallsByIndex.set(index, entry);
|
|
5770
|
+
};
|
|
5771
|
+
const rememberToolCallId = (id, entry) => {
|
|
5772
|
+
const existing = toolCallsById.get(id);
|
|
5773
|
+
if (existing && existing !== entry) {
|
|
5774
|
+
throw createProtocolError(`OpenAI-compatible stream reused tool call id "${id}" for multiple calls.`);
|
|
5775
|
+
}
|
|
5776
|
+
if (entry.block.id && entry.block.id !== id) {
|
|
5777
|
+
throw createProtocolError(`OpenAI-compatible stream changed tool call id from "${entry.block.id}" to "${id}".`);
|
|
5778
|
+
}
|
|
5779
|
+
entry.block.id = id;
|
|
5780
|
+
toolCallsById.set(id, entry);
|
|
5781
|
+
};
|
|
5782
|
+
const resolveToolCallEntry = (toolCall, toolCallCount) => {
|
|
5783
|
+
const id = typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : "";
|
|
5784
|
+
if (Number.isInteger(toolCall.index) && toolCall.index >= 0) {
|
|
5785
|
+
let entry = toolCallsByIndex.get(toolCall.index);
|
|
5786
|
+
if (entry && id && entry.block.id && entry.block.id !== id) {
|
|
5787
|
+
throw createProtocolError(`OpenAI-compatible stream changed tool call id at index ${toolCall.index} from "${entry.block.id}" to "${id}".`);
|
|
5788
|
+
}
|
|
5789
|
+
if (!entry && id) {
|
|
5790
|
+
entry = toolCallsById.get(id);
|
|
5791
|
+
if (entry) bindToolCallIndex(toolCall.index, entry);
|
|
5792
|
+
}
|
|
5793
|
+
if (!entry) {
|
|
5794
|
+
entry = createToolCallEntry(toolCall, toolCall.index);
|
|
5795
|
+
bindToolCallIndex(toolCall.index, entry);
|
|
5796
|
+
}
|
|
5797
|
+
if (id) rememberToolCallId(id, entry);
|
|
5798
|
+
return entry;
|
|
5799
|
+
}
|
|
5800
|
+
if (id) {
|
|
5801
|
+
let entry = toolCallsById.get(id);
|
|
5802
|
+
if (!entry) {
|
|
5803
|
+
const unpaired = toolCallEntries.filter((candidate) => !candidate.block.id);
|
|
5804
|
+
if (unpaired.length === 1) {
|
|
5805
|
+
rememberToolCallId(id, unpaired[0]);
|
|
5806
|
+
return unpaired[0];
|
|
5807
|
+
}
|
|
5808
|
+
if (unpaired.length > 1) {
|
|
5809
|
+
throw createProtocolError(`OpenAI-compatible stream returned tool call id "${id}" without an index while multiple unnamed calls are in flight; the call cannot be disambiguated.`);
|
|
5810
|
+
}
|
|
5811
|
+
entry = createToolCallEntry(toolCall);
|
|
5812
|
+
rememberToolCallId(id, entry);
|
|
5813
|
+
}
|
|
5814
|
+
return entry;
|
|
5815
|
+
}
|
|
5816
|
+
if (toolCallEntries.length === 1) {
|
|
5817
|
+
return toolCallEntries[0];
|
|
5818
|
+
}
|
|
5819
|
+
if (toolCallEntries.length === 0 && toolCallCount === 1) {
|
|
5820
|
+
return createToolCallEntry(toolCall);
|
|
5821
|
+
}
|
|
5822
|
+
throw createProtocolError("OpenAI-compatible stream returned tool call deltas without index or id and the call could not be disambiguated.");
|
|
5823
|
+
};
|
|
5678
5824
|
const finishCurrentBlock = (block) => {
|
|
5679
5825
|
if (block) {
|
|
5680
5826
|
if (block.type === "text") {
|
|
@@ -5699,155 +5845,166 @@ var streamOpenAICompletions = (model, context, options) => {
|
|
|
5699
5845
|
}
|
|
5700
5846
|
for await (const line of response.readSSELines(options?.signal)) {
|
|
5701
5847
|
{
|
|
5702
|
-
const
|
|
5703
|
-
if (
|
|
5704
|
-
if (
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5848
|
+
const data = parseSSEDataLine(line);
|
|
5849
|
+
if (data === null) continue;
|
|
5850
|
+
if (data === "[DONE]") {
|
|
5851
|
+
sawDone = true;
|
|
5852
|
+
break;
|
|
5853
|
+
}
|
|
5854
|
+
let chunk;
|
|
5855
|
+
try {
|
|
5856
|
+
chunk = JSON.parse(data);
|
|
5857
|
+
} catch (error) {
|
|
5858
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5859
|
+
throw createProtocolError(`OpenAI-compatible stream returned malformed SSE JSON: ${message}`);
|
|
5860
|
+
}
|
|
5861
|
+
if (chunk?.error) {
|
|
5862
|
+
throw new Error(formatOpenAIStreamError(chunk.error));
|
|
5863
|
+
}
|
|
5864
|
+
if (chunk.usage) {
|
|
5865
|
+
usageSnapshot = mergeOpenAIUsage(usageSnapshot, chunk.usage);
|
|
5866
|
+
const normalizedUsage = normalizeOpenAIUsage(usageSnapshot);
|
|
5867
|
+
output.usage = {
|
|
5868
|
+
input: normalizedUsage.input,
|
|
5869
|
+
output: normalizedUsage.output,
|
|
5870
|
+
cacheRead: normalizedUsage.cacheRead,
|
|
5871
|
+
cacheWrite: 0,
|
|
5872
|
+
totalTokens: normalizedUsage.totalTokens,
|
|
5873
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
5874
|
+
};
|
|
5875
|
+
output.usage.cost = calculateCost(model, output.usage);
|
|
5876
|
+
if (process.env.PIE_DEBUG_CACHE) {
|
|
5877
|
+
const normalizedPromptTokens = normalizedUsage.input + normalizedUsage.cacheRead;
|
|
5878
|
+
console.error("[CACHE DEBUG] Response usage:", JSON.stringify({
|
|
5879
|
+
input_tokens: normalizedUsage.input,
|
|
5880
|
+
output_tokens: normalizedUsage.output,
|
|
5881
|
+
cached_tokens: normalizedUsage.cacheRead,
|
|
5882
|
+
cache_hit_rate: normalizedPromptTokens > 0 ? `${(normalizedUsage.cacheRead / normalizedPromptTokens * 100).toFixed(1)}%` : "N/A"
|
|
5883
|
+
}, null, 2));
|
|
5715
5884
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5885
|
+
}
|
|
5886
|
+
const choice = chunk.choices?.[0];
|
|
5887
|
+
if (!choice) continue;
|
|
5888
|
+
if (choice.finish_reason) {
|
|
5889
|
+
sawFinishReason = true;
|
|
5890
|
+
rawFinishReason = String(choice.finish_reason);
|
|
5891
|
+
output.stopReason = mapOpenAIStopReason(choice.finish_reason);
|
|
5892
|
+
}
|
|
5893
|
+
if (choice.delta) {
|
|
5894
|
+
if (choice.delta.content !== null && choice.delta.content !== void 0 && choice.delta.content.length > 0) {
|
|
5895
|
+
if (!currentBlock || currentBlock.type !== "text") {
|
|
5896
|
+
finishCurrentBlock(currentBlock);
|
|
5897
|
+
currentBlock = { type: "text", text: "" };
|
|
5898
|
+
output.content.push(currentBlock);
|
|
5899
|
+
stream.push({
|
|
5900
|
+
type: "text_start",
|
|
5901
|
+
contentIndex: blockIndex(),
|
|
5902
|
+
partial: output
|
|
5903
|
+
});
|
|
5904
|
+
}
|
|
5905
|
+
if (currentBlock.type === "text") {
|
|
5906
|
+
currentBlock.text += choice.delta.content;
|
|
5907
|
+
stream.push({
|
|
5908
|
+
type: "text_delta",
|
|
5909
|
+
contentIndex: blockIndex(),
|
|
5910
|
+
delta: choice.delta.content,
|
|
5911
|
+
partial: output
|
|
5912
|
+
});
|
|
5736
5913
|
}
|
|
5737
5914
|
}
|
|
5738
|
-
const
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5915
|
+
const reasoningFields = [
|
|
5916
|
+
"reasoning_content",
|
|
5917
|
+
"reasoning",
|
|
5918
|
+
"reasoning_text"
|
|
5919
|
+
];
|
|
5920
|
+
let foundReasoningField = null;
|
|
5921
|
+
for (const field of reasoningFields) {
|
|
5922
|
+
if (choice.delta[field] !== null && choice.delta[field] !== void 0 && choice.delta[field].length > 0) {
|
|
5923
|
+
foundReasoningField = field;
|
|
5924
|
+
break;
|
|
5925
|
+
}
|
|
5742
5926
|
}
|
|
5743
|
-
if (
|
|
5744
|
-
if (
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
stream.push({
|
|
5758
|
-
type: "text_delta",
|
|
5759
|
-
contentIndex: blockIndex(),
|
|
5760
|
-
delta: choice.delta.content,
|
|
5761
|
-
partial: output
|
|
5762
|
-
});
|
|
5763
|
-
}
|
|
5927
|
+
if (foundReasoningField) {
|
|
5928
|
+
if (!currentBlock || currentBlock.type !== "thinking") {
|
|
5929
|
+
finishCurrentBlock(currentBlock);
|
|
5930
|
+
currentBlock = {
|
|
5931
|
+
type: "thinking",
|
|
5932
|
+
thinking: "",
|
|
5933
|
+
thinkingSignature: foundReasoningField
|
|
5934
|
+
};
|
|
5935
|
+
output.content.push(currentBlock);
|
|
5936
|
+
stream.push({
|
|
5937
|
+
type: "thinking_start",
|
|
5938
|
+
contentIndex: blockIndex(),
|
|
5939
|
+
partial: output
|
|
5940
|
+
});
|
|
5764
5941
|
}
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
break;
|
|
5775
|
-
}
|
|
5942
|
+
if (currentBlock.type === "thinking") {
|
|
5943
|
+
const delta = choice.delta[foundReasoningField];
|
|
5944
|
+
currentBlock.thinking += delta;
|
|
5945
|
+
stream.push({
|
|
5946
|
+
type: "thinking_delta",
|
|
5947
|
+
contentIndex: blockIndex(),
|
|
5948
|
+
delta,
|
|
5949
|
+
partial: output
|
|
5950
|
+
});
|
|
5776
5951
|
}
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5952
|
+
}
|
|
5953
|
+
if (choice.delta.tool_calls) {
|
|
5954
|
+
const deltaToolCalls = choice.delta.tool_calls;
|
|
5955
|
+
for (const toolCall of deltaToolCalls) {
|
|
5956
|
+
finishCurrentBlock(currentBlock);
|
|
5957
|
+
currentBlock = null;
|
|
5958
|
+
const entry = resolveToolCallEntry(toolCall, deltaToolCalls.length);
|
|
5959
|
+
if (entry) {
|
|
5960
|
+
if (toolCall.id) rememberToolCallId(toolCall.id, entry);
|
|
5961
|
+
if (toolCall.function?.name) {
|
|
5962
|
+
if (entry.block.name && entry.block.name !== toolCall.function.name) {
|
|
5963
|
+
throw createProtocolError(`OpenAI-compatible stream changed tool call name from "${entry.block.name}" to "${toolCall.function.name}".`);
|
|
5964
|
+
}
|
|
5965
|
+
entry.block.name = toolCall.function.name;
|
|
5966
|
+
}
|
|
5967
|
+
let delta = "";
|
|
5968
|
+
if (toolCall.function?.arguments) {
|
|
5969
|
+
delta = toolCall.function.arguments;
|
|
5970
|
+
entry.partialArgs += delta;
|
|
5971
|
+
entry.block.arguments = parseStreamingJson(entry.partialArgs);
|
|
5972
|
+
}
|
|
5795
5973
|
stream.push({
|
|
5796
|
-
type: "
|
|
5797
|
-
contentIndex:
|
|
5974
|
+
type: "toolcall_delta",
|
|
5975
|
+
contentIndex: entry.contentIndex,
|
|
5798
5976
|
delta,
|
|
5799
5977
|
partial: output
|
|
5800
5978
|
});
|
|
5801
5979
|
}
|
|
5802
5980
|
}
|
|
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
5981
|
}
|
|
5845
5982
|
}
|
|
5846
5983
|
}
|
|
5847
5984
|
}
|
|
5848
5985
|
finishCurrentBlock(currentBlock);
|
|
5849
|
-
|
|
5850
|
-
|
|
5986
|
+
if (compat.streamRequiresDone && !sawDone) {
|
|
5987
|
+
throw createProtocolError(`OpenAI-compatible stream ended without data: [DONE]${rawFinishReason ? ` (last finish_reason=${rawFinishReason})` : ""}. Set compat.streamRequiresDone=false for gateways that legitimately omit the terminator.`);
|
|
5988
|
+
}
|
|
5989
|
+
if (compat.streamRequiresFinishReason && !sawFinishReason) {
|
|
5990
|
+
throw createProtocolError("OpenAI-compatible stream ended without finish_reason. Set compat.streamRequiresFinishReason=false for endpoints that omit it.");
|
|
5991
|
+
}
|
|
5992
|
+
if (output.stopReason === "toolUse" && toolCallEntries.length === 0) {
|
|
5993
|
+
throw createProtocolError(`OpenAI-compatible stream ended with finish_reason=${rawFinishReason} but did not include any tool calls.`);
|
|
5994
|
+
}
|
|
5995
|
+
if (output.stopReason === "length" && toolCallEntries.length > 0) {
|
|
5996
|
+
const hasTruncatedArgs = toolCallEntries.some(
|
|
5997
|
+
({ partialArgs }) => tryParseFinalToolArguments(partialArgs) === null
|
|
5998
|
+
);
|
|
5999
|
+
if (hasTruncatedArgs) {
|
|
6000
|
+
throw new Error("OpenAI-compatible stream ended with finish_reason=length before tool call arguments were complete. Increase maxTokens or reduce prompt size.");
|
|
6001
|
+
}
|
|
6002
|
+
}
|
|
6003
|
+
for (const { block, partialArgs, contentIndex } of toolCallEntries) {
|
|
6004
|
+
if (!block.name.trim()) {
|
|
6005
|
+
throw createProtocolError("OpenAI-compatible stream returned a tool call without a function name.");
|
|
6006
|
+
}
|
|
6007
|
+
block.arguments = parseFinalToolArguments(partialArgs, block.name);
|
|
5851
6008
|
stream.push({ type: "toolcall_end", contentIndex, toolCall: block, partial: output });
|
|
5852
6009
|
}
|
|
5853
6010
|
if (output.stopReason !== "error" && output.stopReason !== "aborted" && output.content.some((block) => block.type === "toolCall")) {
|
|
@@ -9772,6 +9929,7 @@ export {
|
|
|
9772
9929
|
EventStream,
|
|
9773
9930
|
getModelCacheCapability,
|
|
9774
9931
|
EMPTY_ASSISTANT_CONTENT_ERROR,
|
|
9932
|
+
OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
|
|
9775
9933
|
streamSimple,
|
|
9776
9934
|
completeSimple,
|
|
9777
9935
|
MODEL_CLASS_FALLBACK_ORDER,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
createSharedWebSearchTool,
|
|
9
9
|
interpretShellExit,
|
|
10
10
|
requestInteraction
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2GVFMYIV.js";
|
|
12
12
|
import {
|
|
13
13
|
Type
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NGQ3PUOC.js";
|
|
15
15
|
|
|
16
16
|
// src/config.ts
|
|
17
17
|
import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
|