@cydm/pie 1.0.24 → 1.0.26
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 +23 -5
- package/dist/builtin/extensions/ask-user/index.js +3 -4
- package/dist/builtin/extensions/ask-user/package.json +16 -0
- package/dist/builtin/extensions/changelog/index.js +65 -65
- package/dist/builtin/extensions/changelog/package.json +11 -0
- package/dist/builtin/extensions/deploy/package.json +11 -0
- package/dist/builtin/extensions/document-attachments/package.json +11 -0
- package/dist/builtin/extensions/files/package.json +14 -0
- package/dist/builtin/extensions/init/index.js +33 -33
- package/dist/builtin/extensions/init/package.json +11 -0
- package/dist/builtin/extensions/kimi-attachments/index.js +1 -1
- package/dist/builtin/extensions/kimi-attachments/package.json +11 -0
- package/dist/builtin/extensions/plan-mode/index.js +5 -34
- package/dist/builtin/extensions/plan-mode/package.json +11 -0
- package/dist/builtin/extensions/subagent/index.js +4 -5
- package/dist/builtin/extensions/subagent/package.json +14 -0
- package/dist/builtin/extensions/todo/index.js +3 -4
- package/dist/builtin/extensions/todo/package.json +11 -0
- package/dist/chunks/{chunk-X44YTB6R.js → chunk-4B42ZU4B.js} +1 -1
- package/dist/chunks/{chunk-HAAYC2N5.js → chunk-64XJIKVK.js} +334 -99
- package/dist/chunks/{chunk-QYYRJ7JW.js → chunk-GARJAWH6.js} +375 -252
- package/dist/chunks/{chunk-XWNIIJ3X.js → chunk-L63BJMTT.js} +7537 -6629
- package/dist/chunks/{src-PENSDHBM.js → src-27UD2ZBZ.js} +2 -2
- package/dist/chunks/{test-stream-PRUYMLXQ.js → test-stream-ZNGAUUVH.js} +6 -2
- package/dist/cli.js +2229 -1686
- package/dist/{chunks/typescript-GSKWJIO4.js → code-intel-worker.cjs} +2507 -2031
- package/models.schema.json +38 -13
- package/package.json +10 -6
- package/dist/chunks/chunk-J4P2LP7K.js +0 -3846
- package/dist/chunks/chunk-QMIIW75M.js +0 -95
- package/dist/session-preview-worker.js +0 -159
|
@@ -1560,12 +1560,12 @@ function Iterator(items, options) {
|
|
|
1560
1560
|
function RequiredArray(properties) {
|
|
1561
1561
|
return globalThis.Object.keys(properties).filter((key) => !IsOptional(properties[key]));
|
|
1562
1562
|
}
|
|
1563
|
-
function
|
|
1563
|
+
function _Object(properties, options) {
|
|
1564
1564
|
const required = RequiredArray(properties);
|
|
1565
1565
|
const schema = required.length > 0 ? { [Kind]: "Object", type: "object", required, properties } : { [Kind]: "Object", type: "object", properties };
|
|
1566
1566
|
return CreateType(schema, options);
|
|
1567
1567
|
}
|
|
1568
|
-
var Object2 =
|
|
1568
|
+
var Object2 = _Object;
|
|
1569
1569
|
|
|
1570
1570
|
// ../../node_modules/@sinclair/typebox/build/esm/type/promise/promise.mjs
|
|
1571
1571
|
function Promise2(item, options) {
|
|
@@ -3270,7 +3270,8 @@ function convertStats(stats) {
|
|
|
3270
3270
|
isDirectory: stats.isDirectory(),
|
|
3271
3271
|
isFile: stats.isFile(),
|
|
3272
3272
|
size: stats.size,
|
|
3273
|
-
mtime: stats.mtime
|
|
3273
|
+
mtime: stats.mtime,
|
|
3274
|
+
isSymbolicLink: stats.isSymbolicLink()
|
|
3274
3275
|
};
|
|
3275
3276
|
}
|
|
3276
3277
|
function byteLength(text) {
|
|
@@ -3284,6 +3285,40 @@ function normalizeRangeOptions(options) {
|
|
|
3284
3285
|
maxOutputBytes: Math.max(0, Math.floor(options?.maxOutputBytes ?? Number.POSITIVE_INFINITY))
|
|
3285
3286
|
};
|
|
3286
3287
|
}
|
|
3288
|
+
var StreamingBinaryDetector = class {
|
|
3289
|
+
decoder = new TextDecoder("utf-8", { fatal: true });
|
|
3290
|
+
byteCount = 0;
|
|
3291
|
+
suspiciousControlCount = 0;
|
|
3292
|
+
invalidUtf8 = false;
|
|
3293
|
+
hasNul = false;
|
|
3294
|
+
update(bytes) {
|
|
3295
|
+
if (bytes.byteLength === 0) return;
|
|
3296
|
+
this.byteCount += bytes.byteLength;
|
|
3297
|
+
for (const byte of bytes) {
|
|
3298
|
+
if (byte === 0) this.hasNul = true;
|
|
3299
|
+
if (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13 || byte === 127) {
|
|
3300
|
+
this.suspiciousControlCount++;
|
|
3301
|
+
}
|
|
3302
|
+
}
|
|
3303
|
+
if (!this.invalidUtf8) {
|
|
3304
|
+
try {
|
|
3305
|
+
this.decoder.decode(bytes, { stream: true });
|
|
3306
|
+
} catch {
|
|
3307
|
+
this.invalidUtf8 = true;
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
finish() {
|
|
3312
|
+
if (!this.invalidUtf8) {
|
|
3313
|
+
try {
|
|
3314
|
+
this.decoder.decode();
|
|
3315
|
+
} catch {
|
|
3316
|
+
this.invalidUtf8 = true;
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
return this.invalidUtf8 || this.hasNul || this.byteCount > 0 && this.suspiciousControlCount / this.byteCount > 0.02;
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3287
3322
|
var NodeFileSystem = class {
|
|
3288
3323
|
platform = "node";
|
|
3289
3324
|
sep;
|
|
@@ -3298,6 +3333,18 @@ var NodeFileSystem = class {
|
|
|
3298
3333
|
readFileSync(path, encoding = "utf-8") {
|
|
3299
3334
|
return getNodeFs().readFileSync(path, encoding);
|
|
3300
3335
|
}
|
|
3336
|
+
async readFilePrefix(path, maxBytes) {
|
|
3337
|
+
const length = Math.max(0, Math.floor(maxBytes));
|
|
3338
|
+
if (length === 0) return new Uint8Array();
|
|
3339
|
+
const handle = await getNodeFs().promises.open(path, "r");
|
|
3340
|
+
try {
|
|
3341
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
3342
|
+
const { bytesRead } = await handle.read(buffer, 0, length, 0);
|
|
3343
|
+
return new Uint8Array(buffer.subarray(0, bytesRead));
|
|
3344
|
+
} finally {
|
|
3345
|
+
await handle.close();
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3301
3348
|
async readTextRange(path, options, signal) {
|
|
3302
3349
|
const fs = getNodeFs();
|
|
3303
3350
|
const range = normalizeRangeOptions(options);
|
|
@@ -3320,6 +3367,10 @@ var NodeFileSystem = class {
|
|
|
3320
3367
|
let truncated = false;
|
|
3321
3368
|
let truncatedBy = null;
|
|
3322
3369
|
let firstLineExceedsLimit = false;
|
|
3370
|
+
const fileBinaryDetector = new StreamingBinaryDetector();
|
|
3371
|
+
const selectedBinaryDetector = new StreamingBinaryDetector();
|
|
3372
|
+
const textDecoder = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
3373
|
+
let rawLineIndex = 0;
|
|
3323
3374
|
const selectedEndLine = Number.isFinite(range.limitLines) ? range.offsetLine + range.limitLines : Number.POSITIVE_INFINITY;
|
|
3324
3375
|
const startLine = () => {
|
|
3325
3376
|
if (lineStarted) return;
|
|
@@ -3395,23 +3446,41 @@ var NodeFileSystem = class {
|
|
|
3395
3446
|
lineStarted = false;
|
|
3396
3447
|
lineIndex++;
|
|
3397
3448
|
};
|
|
3398
|
-
const
|
|
3449
|
+
const scanRawBytes = (bytes) => {
|
|
3450
|
+
fileBinaryDetector.update(bytes);
|
|
3451
|
+
let segmentStart = 0;
|
|
3452
|
+
for (let index = 0; index < bytes.byteLength; index++) {
|
|
3453
|
+
if (bytes[index] !== 10) continue;
|
|
3454
|
+
if (rawLineIndex >= range.offsetLine && rawLineIndex < selectedEndLine) {
|
|
3455
|
+
selectedBinaryDetector.update(bytes.subarray(segmentStart, index + 1));
|
|
3456
|
+
}
|
|
3457
|
+
rawLineIndex++;
|
|
3458
|
+
segmentStart = index + 1;
|
|
3459
|
+
}
|
|
3460
|
+
if (segmentStart < bytes.byteLength && rawLineIndex >= range.offsetLine && rawLineIndex < selectedEndLine) {
|
|
3461
|
+
selectedBinaryDetector.update(bytes.subarray(segmentStart));
|
|
3462
|
+
}
|
|
3463
|
+
};
|
|
3464
|
+
const scanText = (text) => {
|
|
3465
|
+
if (!text) return;
|
|
3466
|
+
fullHasher.update(text);
|
|
3467
|
+
for (const char of text) {
|
|
3468
|
+
if (char === "\n") finishLine();
|
|
3469
|
+
else scanLineChar(char);
|
|
3470
|
+
}
|
|
3471
|
+
};
|
|
3472
|
+
const stream = fs.createReadStream(path);
|
|
3399
3473
|
try {
|
|
3400
3474
|
for await (const chunk of stream) {
|
|
3401
3475
|
if (signal?.aborted) {
|
|
3402
3476
|
stream.destroy();
|
|
3403
3477
|
throw new Error("Operation aborted");
|
|
3404
3478
|
}
|
|
3405
|
-
const
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
if (char === "\n") {
|
|
3409
|
-
finishLine();
|
|
3410
|
-
} else {
|
|
3411
|
-
scanLineChar(char);
|
|
3412
|
-
}
|
|
3413
|
-
}
|
|
3479
|
+
const bytes = chunk;
|
|
3480
|
+
scanRawBytes(bytes);
|
|
3481
|
+
scanText(textDecoder.decode(bytes, { stream: true }));
|
|
3414
3482
|
}
|
|
3483
|
+
scanText(textDecoder.decode());
|
|
3415
3484
|
finishLine();
|
|
3416
3485
|
} finally {
|
|
3417
3486
|
stream.destroy();
|
|
@@ -3430,6 +3499,8 @@ var NodeFileSystem = class {
|
|
|
3430
3499
|
truncated,
|
|
3431
3500
|
truncatedBy,
|
|
3432
3501
|
firstLineExceedsLimit,
|
|
3502
|
+
selectedBytesLookBinary: selectedBinaryDetector.finish(),
|
|
3503
|
+
fileBytesLookBinary: fileBinaryDetector.finish(),
|
|
3433
3504
|
mtimeMs: stat.mtime.getTime(),
|
|
3434
3505
|
size: stat.size
|
|
3435
3506
|
};
|
|
@@ -3450,6 +3521,28 @@ var NodeFileSystem = class {
|
|
|
3450
3521
|
async readdir(path) {
|
|
3451
3522
|
return getNodeFs().promises.readdir(path);
|
|
3452
3523
|
}
|
|
3524
|
+
async readDirectoryBounded(path, limit, signal) {
|
|
3525
|
+
if (!Number.isSafeInteger(limit) || limit < 0) throw new Error("directory entry limit must be a non-negative safe integer");
|
|
3526
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
3527
|
+
const entries = [];
|
|
3528
|
+
const directory = await getNodeFs().promises.opendir(path);
|
|
3529
|
+
let limitReached = false;
|
|
3530
|
+
try {
|
|
3531
|
+
while (entries.length <= limit) {
|
|
3532
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
3533
|
+
const entry = await directory.read();
|
|
3534
|
+
if (!entry) break;
|
|
3535
|
+
if (entries.length === limit) {
|
|
3536
|
+
limitReached = true;
|
|
3537
|
+
break;
|
|
3538
|
+
}
|
|
3539
|
+
entries.push(entry.name);
|
|
3540
|
+
}
|
|
3541
|
+
} finally {
|
|
3542
|
+
await directory.close().catch(() => void 0);
|
|
3543
|
+
}
|
|
3544
|
+
return { entries, limitReached };
|
|
3545
|
+
}
|
|
3453
3546
|
readdirSync(path) {
|
|
3454
3547
|
return getNodeFs().readdirSync(path);
|
|
3455
3548
|
}
|
|
@@ -3477,6 +3570,15 @@ var NodeFileSystem = class {
|
|
|
3477
3570
|
entry.name = getNodePath().basename(path);
|
|
3478
3571
|
return entry;
|
|
3479
3572
|
}
|
|
3573
|
+
lstatSync(path) {
|
|
3574
|
+
const stats = getNodeFs().lstatSync(path);
|
|
3575
|
+
const entry = convertStats(stats);
|
|
3576
|
+
entry.name = getNodePath().basename(path);
|
|
3577
|
+
return entry;
|
|
3578
|
+
}
|
|
3579
|
+
realpathSync(path) {
|
|
3580
|
+
return getNodeFs().realpathSync(path);
|
|
3581
|
+
}
|
|
3480
3582
|
async access(path, mode) {
|
|
3481
3583
|
await getNodeFs().promises.access(path, mode);
|
|
3482
3584
|
}
|
|
@@ -3537,6 +3639,35 @@ async function taskToPromise(task) {
|
|
|
3537
3639
|
}
|
|
3538
3640
|
return task;
|
|
3539
3641
|
}
|
|
3642
|
+
function getFileCompletionStore() {
|
|
3643
|
+
const globalValue = globalThis;
|
|
3644
|
+
if (!globalValue.__pieFileCompletionStore) {
|
|
3645
|
+
globalValue.__pieFileCompletionStore = { completions: /* @__PURE__ */ new Map(), waiters: /* @__PURE__ */ new Map() };
|
|
3646
|
+
}
|
|
3647
|
+
if (!globalValue._pieFileComplete) {
|
|
3648
|
+
globalValue._pieFileComplete = (requestId, resultJson, error) => {
|
|
3649
|
+
const store = getFileCompletionStore();
|
|
3650
|
+
const completion = { resultJson, error };
|
|
3651
|
+
const waiter = store.waiters.get(requestId);
|
|
3652
|
+
if (waiter) {
|
|
3653
|
+
store.waiters.delete(requestId);
|
|
3654
|
+
waiter(completion);
|
|
3655
|
+
} else {
|
|
3656
|
+
store.completions.set(requestId, completion);
|
|
3657
|
+
}
|
|
3658
|
+
};
|
|
3659
|
+
}
|
|
3660
|
+
return globalValue.__pieFileCompletionStore;
|
|
3661
|
+
}
|
|
3662
|
+
function waitForFileCompletion(requestId) {
|
|
3663
|
+
const store = getFileCompletionStore();
|
|
3664
|
+
const existing = store.completions.get(requestId);
|
|
3665
|
+
if (existing) {
|
|
3666
|
+
store.completions.delete(requestId);
|
|
3667
|
+
return Promise.resolve(existing);
|
|
3668
|
+
}
|
|
3669
|
+
return new Promise((resolve) => store.waiters.set(requestId, resolve));
|
|
3670
|
+
}
|
|
3540
3671
|
function toJsStringArray(value) {
|
|
3541
3672
|
if (Array.isArray(value)) {
|
|
3542
3673
|
return value.map((entry) => String(entry ?? ""));
|
|
@@ -3566,6 +3697,11 @@ function normalizeOptionalNumber(value, fallback) {
|
|
|
3566
3697
|
}
|
|
3567
3698
|
return Math.max(0, Math.floor(value));
|
|
3568
3699
|
}
|
|
3700
|
+
function normalizeInt32(value, fallback) {
|
|
3701
|
+
const normalized = normalizeOptionalNumber(value, fallback);
|
|
3702
|
+
if (!Number.isSafeInteger(normalized) || normalized > 2147483647) throw new Error("Unity range-read arguments exceed Int32 bounds");
|
|
3703
|
+
return normalized;
|
|
3704
|
+
}
|
|
3569
3705
|
function convertTextRangeResult(result) {
|
|
3570
3706
|
return {
|
|
3571
3707
|
content: String(result?.Content ?? ""),
|
|
@@ -3581,66 +3717,12 @@ function convertTextRangeResult(result) {
|
|
|
3581
3717
|
truncated: !!result?.Truncated,
|
|
3582
3718
|
truncatedBy: result?.TruncatedBy ? String(result.TruncatedBy) : null,
|
|
3583
3719
|
firstLineExceedsLimit: !!result?.FirstLineExceedsLimit,
|
|
3720
|
+
...typeof result?.SelectedBytesLookBinary === "boolean" ? { selectedBytesLookBinary: result.SelectedBytesLookBinary } : {},
|
|
3721
|
+
...typeof result?.FileBytesLookBinary === "boolean" ? { fileBytesLookBinary: result.FileBytesLookBinary } : {},
|
|
3584
3722
|
mtimeMs: (Number(result?.LastWriteTicksUtc || 0) - 621355968e9) / 1e4,
|
|
3585
3723
|
size: Number(result?.Size ?? 0)
|
|
3586
3724
|
};
|
|
3587
3725
|
}
|
|
3588
|
-
function byteLength2(text) {
|
|
3589
|
-
if (typeof Buffer !== "undefined") {
|
|
3590
|
-
return Buffer.byteLength(text, "utf-8");
|
|
3591
|
-
}
|
|
3592
|
-
return unescape(encodeURIComponent(text)).length;
|
|
3593
|
-
}
|
|
3594
|
-
function buildTextRangeFallback(content, stat, offsetLine, limitLines, maxOutputLines, maxOutputBytes) {
|
|
3595
|
-
const lines = content.split("\n");
|
|
3596
|
-
const endLine = Number.isFinite(limitLines) ? Math.min(lines.length, offsetLine + limitLines) : lines.length;
|
|
3597
|
-
const selectedLinesArray = offsetLine >= lines.length ? [] : lines.slice(offsetLine, endLine);
|
|
3598
|
-
const selectedContent = selectedLinesArray.join("\n");
|
|
3599
|
-
const outputLines = [];
|
|
3600
|
-
let outputBytes = 0;
|
|
3601
|
-
let truncated = false;
|
|
3602
|
-
let truncatedBy = null;
|
|
3603
|
-
let firstLineExceedsLimit = false;
|
|
3604
|
-
for (const line of selectedLinesArray) {
|
|
3605
|
-
const lineBytes = byteLength2(line);
|
|
3606
|
-
if (outputLines.length === 0 && lineBytes > maxOutputBytes) {
|
|
3607
|
-
firstLineExceedsLimit = true;
|
|
3608
|
-
truncated = true;
|
|
3609
|
-
truncatedBy = "bytes";
|
|
3610
|
-
break;
|
|
3611
|
-
}
|
|
3612
|
-
if (outputLines.length >= maxOutputLines) {
|
|
3613
|
-
truncated = true;
|
|
3614
|
-
truncatedBy = "lines";
|
|
3615
|
-
break;
|
|
3616
|
-
}
|
|
3617
|
-
const candidateBytes = lineBytes + (outputLines.length > 0 ? 1 : 0);
|
|
3618
|
-
if (outputBytes + candidateBytes > maxOutputBytes) {
|
|
3619
|
-
truncated = true;
|
|
3620
|
-
truncatedBy = "bytes";
|
|
3621
|
-
break;
|
|
3622
|
-
}
|
|
3623
|
-
outputLines.push(line);
|
|
3624
|
-
outputBytes += candidateBytes;
|
|
3625
|
-
}
|
|
3626
|
-
return {
|
|
3627
|
-
content: outputLines.join("\n"),
|
|
3628
|
-
contentHash: hashText(content),
|
|
3629
|
-
selectedContentHash: hashText(selectedContent),
|
|
3630
|
-
totalLines: lines.length,
|
|
3631
|
-
totalBytes: stat.size,
|
|
3632
|
-
selectedLines: selectedLinesArray.length,
|
|
3633
|
-
selectedBytes: byteLength2(selectedContent),
|
|
3634
|
-
firstLineBytes: selectedLinesArray.length > 0 ? byteLength2(selectedLinesArray[0]) : 0,
|
|
3635
|
-
outputLines: outputLines.length,
|
|
3636
|
-
outputBytes,
|
|
3637
|
-
truncated,
|
|
3638
|
-
truncatedBy,
|
|
3639
|
-
firstLineExceedsLimit,
|
|
3640
|
-
mtimeMs: stat.mtime.getTime(),
|
|
3641
|
-
size: stat.size
|
|
3642
|
-
};
|
|
3643
|
-
}
|
|
3644
3726
|
function convertDateTime(dateTime) {
|
|
3645
3727
|
if (!dateTime) return /* @__PURE__ */ new Date(0);
|
|
3646
3728
|
const ticks = dateTime.get_Ticks?.() || 0;
|
|
@@ -3667,6 +3749,9 @@ function convertFileSystemInfo(info) {
|
|
|
3667
3749
|
mtime: info.LastWriteTimeUtc ? convertDateTime(info.LastWriteTimeUtc) : /* @__PURE__ */ new Date(0)
|
|
3668
3750
|
};
|
|
3669
3751
|
}
|
|
3752
|
+
function fileNameFromPath(IO, path) {
|
|
3753
|
+
return String(IO.Path.GetFileName(path) || IO.Path.GetPathRoot(path) || path);
|
|
3754
|
+
}
|
|
3670
3755
|
var PuerTSFileSystem = class {
|
|
3671
3756
|
platform = "puerts";
|
|
3672
3757
|
sep = "/";
|
|
@@ -3706,32 +3791,62 @@ var PuerTSFileSystem = class {
|
|
|
3706
3791
|
}
|
|
3707
3792
|
return IO.File.ReadAllText(normalizedPath);
|
|
3708
3793
|
}
|
|
3794
|
+
async readFilePrefix(path, maxBytes) {
|
|
3795
|
+
const IO = getSystemIO();
|
|
3796
|
+
const normalizedPath = this.normalizePath(path);
|
|
3797
|
+
if (!IO.File.Exists(normalizedPath)) {
|
|
3798
|
+
throw new Error(`ENOENT: no such file or directory, open '${path}'`);
|
|
3799
|
+
}
|
|
3800
|
+
const length = Math.max(0, Math.floor(maxBytes));
|
|
3801
|
+
if (length === 0) return new Uint8Array();
|
|
3802
|
+
const stream = IO.File.OpenRead(normalizedPath);
|
|
3803
|
+
try {
|
|
3804
|
+
const count = Math.min(length, Number(stream.Length));
|
|
3805
|
+
const buffer = CS.System.Array.CreateInstance(CS.System.Byte, count);
|
|
3806
|
+
const bytesRead = Number(stream.Read(buffer, 0, count));
|
|
3807
|
+
const result = new Uint8Array(bytesRead);
|
|
3808
|
+
for (let index = 0; index < bytesRead; index += 1) {
|
|
3809
|
+
result[index] = Number(buffer.GetValue(index));
|
|
3810
|
+
}
|
|
3811
|
+
return result;
|
|
3812
|
+
} finally {
|
|
3813
|
+
stream.Dispose();
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3709
3816
|
async readTextRange(path, options, signal) {
|
|
3710
3817
|
if (signal?.aborted) {
|
|
3711
3818
|
throw new Error("Operation aborted");
|
|
3712
3819
|
}
|
|
3713
3820
|
const bridge = getPieFileBridge();
|
|
3714
3821
|
const normalizedPath = this.normalizePath(path);
|
|
3715
|
-
if (typeof bridge.
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
const limitLines = options?.limitLines === void 0 ? Number.POSITIVE_INFINITY : normalizeOptionalNumber(options.limitLines, 0);
|
|
3720
|
-
const maxOutputLines = normalizeOptionalNumber(options?.maxOutputLines, Number.POSITIVE_INFINITY);
|
|
3721
|
-
const maxOutputBytes = normalizeOptionalNumber(options?.maxOutputBytes, Number.POSITIVE_INFINITY);
|
|
3722
|
-
return buildTextRangeFallback(content, stat, offsetLine, limitLines, maxOutputLines, maxOutputBytes);
|
|
3723
|
-
}
|
|
3724
|
-
const payload = await taskToPromise(bridge.ReadTextRangeAsync(
|
|
3822
|
+
if (typeof bridge.StartReadTextRange !== "function" || typeof bridge.CancelRequest !== "function" || typeof bridge.ReleaseRequest !== "function") {
|
|
3823
|
+
throw new Error("The Unity host does not provide the cancellable bounded range-read bridge required by read_file.");
|
|
3824
|
+
}
|
|
3825
|
+
const requestId = Number(bridge.StartReadTextRange(
|
|
3725
3826
|
normalizedPath,
|
|
3726
|
-
|
|
3727
|
-
options?.limitLines === void 0 ? -1 :
|
|
3728
|
-
|
|
3729
|
-
|
|
3827
|
+
normalizeInt32(options?.offsetLine, 0),
|
|
3828
|
+
options?.limitLines === void 0 ? -1 : normalizeInt32(options.limitLines, 0),
|
|
3829
|
+
normalizeInt32(options?.maxOutputLines, -1),
|
|
3830
|
+
normalizeInt32(options?.maxOutputBytes, -1)
|
|
3730
3831
|
));
|
|
3731
|
-
if (
|
|
3732
|
-
throw new Error("
|
|
3832
|
+
if (!Number.isSafeInteger(requestId) || requestId <= 0) {
|
|
3833
|
+
throw new Error("The Unity range-read bridge returned an invalid request id.");
|
|
3834
|
+
}
|
|
3835
|
+
const onAbort = () => bridge.CancelRequest(requestId);
|
|
3836
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
3837
|
+
try {
|
|
3838
|
+
if (signal?.aborted) bridge.CancelRequest(requestId);
|
|
3839
|
+
const completion = await waitForFileCompletion(requestId);
|
|
3840
|
+
if (completion.error) throw new Error(completion.error);
|
|
3841
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
3842
|
+
return convertTextRangeResult(JSON.parse(String(completion.resultJson ?? "{}")));
|
|
3843
|
+
} finally {
|
|
3844
|
+
const store = getFileCompletionStore();
|
|
3845
|
+
store.completions.delete(requestId);
|
|
3846
|
+
store.waiters.delete(requestId);
|
|
3847
|
+
signal?.removeEventListener("abort", onAbort);
|
|
3848
|
+
bridge.ReleaseRequest(requestId);
|
|
3733
3849
|
}
|
|
3734
|
-
return convertTextRangeResult(JSON.parse(String(payload ?? "{}")));
|
|
3735
3850
|
}
|
|
3736
3851
|
async writeFile(path, data, encoding = "utf-8") {
|
|
3737
3852
|
const bridge = getPieFileBridge();
|
|
@@ -3789,6 +3904,32 @@ var PuerTSFileSystem = class {
|
|
|
3789
3904
|
const entries = await taskToPromise(bridge.ReadDirectoryAsync(normalizedPath));
|
|
3790
3905
|
return toJsStringArray(entries);
|
|
3791
3906
|
}
|
|
3907
|
+
async readDirectoryBounded(path, limit, signal) {
|
|
3908
|
+
if (!Number.isSafeInteger(limit) || limit < 0 || limit > 2147483647) throw new Error("directory entry limit must be between 0 and 2147483647");
|
|
3909
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
3910
|
+
const IO = getSystemIO();
|
|
3911
|
+
const bridge = getPieFileBridge();
|
|
3912
|
+
const normalizedPath = this.normalizePath(path);
|
|
3913
|
+
if (!IO.Directory.Exists(normalizedPath)) throw new Error(`ENOENT: no such file or directory, scandir '${path}'`);
|
|
3914
|
+
if (typeof bridge.StartReadDirectoryBounded !== "function") throw new Error("The Unity host does not provide bounded cancellable directory enumeration.");
|
|
3915
|
+
const requestId = Number(bridge.StartReadDirectoryBounded(normalizedPath, limit));
|
|
3916
|
+
const onAbort = () => bridge.CancelRequest(requestId);
|
|
3917
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
3918
|
+
try {
|
|
3919
|
+
if (signal?.aborted) bridge.CancelRequest(requestId);
|
|
3920
|
+
const completion = await waitForFileCompletion(requestId);
|
|
3921
|
+
if (completion.error) throw new Error(completion.error);
|
|
3922
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
3923
|
+
const result = JSON.parse(String(completion.resultJson ?? "{}"));
|
|
3924
|
+
return { entries: toJsStringArray(result?.Entries), limitReached: !!result?.LimitReached };
|
|
3925
|
+
} finally {
|
|
3926
|
+
const store = getFileCompletionStore();
|
|
3927
|
+
store.completions.delete(requestId);
|
|
3928
|
+
store.waiters.delete(requestId);
|
|
3929
|
+
signal?.removeEventListener("abort", onAbort);
|
|
3930
|
+
bridge.ReleaseRequest(requestId);
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3792
3933
|
readdirSync(path) {
|
|
3793
3934
|
const IO = getSystemIO();
|
|
3794
3935
|
const normalizedPath = this.normalizePath(path);
|
|
@@ -3840,6 +3981,49 @@ var PuerTSFileSystem = class {
|
|
|
3840
3981
|
}
|
|
3841
3982
|
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
|
|
3842
3983
|
}
|
|
3984
|
+
lstatSync(path) {
|
|
3985
|
+
const IO = getSystemIO();
|
|
3986
|
+
const normalizedPath = this.normalizePath(path);
|
|
3987
|
+
let attributes;
|
|
3988
|
+
try {
|
|
3989
|
+
attributes = Number(IO.File.GetAttributes(normalizedPath));
|
|
3990
|
+
} catch {
|
|
3991
|
+
throw new Error(`ENOENT: no such file or directory, lstat '${path}'`);
|
|
3992
|
+
}
|
|
3993
|
+
const isSymbolicLink = (attributes & Number(IO.FileAttributes.ReparsePoint)) !== 0;
|
|
3994
|
+
if (!isSymbolicLink) {
|
|
3995
|
+
return this.statSync(path);
|
|
3996
|
+
}
|
|
3997
|
+
return {
|
|
3998
|
+
name: fileNameFromPath(IO, normalizedPath),
|
|
3999
|
+
isDirectory: false,
|
|
4000
|
+
isFile: false,
|
|
4001
|
+
isSymbolicLink: true,
|
|
4002
|
+
size: 0,
|
|
4003
|
+
mtime: /* @__PURE__ */ new Date(0)
|
|
4004
|
+
};
|
|
4005
|
+
}
|
|
4006
|
+
realpathSync(path) {
|
|
4007
|
+
const IO = getSystemIO();
|
|
4008
|
+
const fullPath = this.normalizePath(String(IO.Path.GetFullPath(this.normalizePath(path))));
|
|
4009
|
+
const root = this.normalizePath(String(IO.Path.GetPathRoot(fullPath) || ""));
|
|
4010
|
+
const relative = fullPath.slice(root.length);
|
|
4011
|
+
const parts = relative.split("/").filter(Boolean);
|
|
4012
|
+
let cursor = root;
|
|
4013
|
+
for (const part of parts) {
|
|
4014
|
+
cursor = cursor ? this.normalizePath(String(IO.Path.Combine(cursor, part))) : part;
|
|
4015
|
+
let attributes;
|
|
4016
|
+
try {
|
|
4017
|
+
attributes = Number(IO.File.GetAttributes(cursor));
|
|
4018
|
+
} catch {
|
|
4019
|
+
throw new Error(`ENOENT: no such file or directory, realpath '${path}'`);
|
|
4020
|
+
}
|
|
4021
|
+
if ((attributes & Number(IO.FileAttributes.ReparsePoint)) !== 0) {
|
|
4022
|
+
throw new Error(`Symbolic links are not supported by the Unity filesystem sandbox: ${cursor}`);
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
return fullPath;
|
|
4026
|
+
}
|
|
3843
4027
|
async access(path, mode) {
|
|
3844
4028
|
const IO = getSystemIO();
|
|
3845
4029
|
const normalizedPath = this.normalizePath(path);
|
|
@@ -5369,6 +5553,54 @@ function logEmptyAssistantContentError(error, model, options) {
|
|
|
5369
5553
|
}
|
|
5370
5554
|
|
|
5371
5555
|
// ../../packages/ai/src/providers/openai-compat.ts
|
|
5556
|
+
function normalizeTokenCount(value) {
|
|
5557
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
5558
|
+
return void 0;
|
|
5559
|
+
}
|
|
5560
|
+
return Math.floor(value);
|
|
5561
|
+
}
|
|
5562
|
+
function mergeOpenAIUsage(previous, usage) {
|
|
5563
|
+
return {
|
|
5564
|
+
promptTokens: normalizeTokenCount(usage?.prompt_tokens) ?? previous.promptTokens,
|
|
5565
|
+
completionTokens: normalizeTokenCount(usage?.completion_tokens) ?? previous.completionTokens,
|
|
5566
|
+
cachedTokens: normalizeTokenCount(usage?.prompt_tokens_details?.cached_tokens) ?? previous.cachedTokens,
|
|
5567
|
+
reasoningTokens: normalizeTokenCount(usage?.completion_tokens_details?.reasoning_tokens) ?? previous.reasoningTokens,
|
|
5568
|
+
totalTokens: normalizeTokenCount(usage?.total_tokens) ?? previous.totalTokens
|
|
5569
|
+
};
|
|
5570
|
+
}
|
|
5571
|
+
function normalizeOpenAIUsage(usage) {
|
|
5572
|
+
const reportedPromptTokens = usage.promptTokens;
|
|
5573
|
+
const reportedCachedTokens = usage.cachedTokens;
|
|
5574
|
+
const reportedCompletionTokens = usage.completionTokens;
|
|
5575
|
+
const reportedReasoningTokens = usage.reasoningTokens;
|
|
5576
|
+
const reportedTotalTokens = usage.totalTokens;
|
|
5577
|
+
const cachedTokens = reportedCachedTokens ?? 0;
|
|
5578
|
+
const promptTokens = reportedPromptTokens ?? (reportedTotalTokens !== void 0 && reportedCompletionTokens !== void 0 ? Math.max(cachedTokens, reportedTotalTokens - reportedCompletionTokens) : cachedTokens);
|
|
5579
|
+
const cacheRead = Math.min(cachedTokens, promptTokens);
|
|
5580
|
+
const input = promptTokens - cacheRead;
|
|
5581
|
+
const output = reportedCompletionTokens ?? (reportedTotalTokens !== void 0 ? Math.max(reportedReasoningTokens ?? 0, reportedTotalTokens - promptTokens) : reportedReasoningTokens ?? 0);
|
|
5582
|
+
const partitionTotal = promptTokens + output;
|
|
5583
|
+
return {
|
|
5584
|
+
input,
|
|
5585
|
+
output,
|
|
5586
|
+
cacheRead,
|
|
5587
|
+
totalTokens: Math.max(reportedTotalTokens ?? 0, partitionTotal)
|
|
5588
|
+
};
|
|
5589
|
+
}
|
|
5590
|
+
function formatOpenAIStreamError(error) {
|
|
5591
|
+
if (!error || typeof error !== "object") {
|
|
5592
|
+
return typeof error === "string" ? error : "OpenAI-compatible stream returned an error";
|
|
5593
|
+
}
|
|
5594
|
+
const message = typeof error.message === "string" && error.message.length > 0 ? error.message : "OpenAI-compatible stream returned an error";
|
|
5595
|
+
const metadata = [];
|
|
5596
|
+
if (typeof error.type === "string" && error.type.length > 0) {
|
|
5597
|
+
metadata.push(`type=${error.type}`);
|
|
5598
|
+
}
|
|
5599
|
+
if (typeof error.code === "string" && error.code.length > 0) {
|
|
5600
|
+
metadata.push(`code=${error.code}`);
|
|
5601
|
+
}
|
|
5602
|
+
return metadata.length > 0 ? `${message} (${metadata.join(", ")})` : message;
|
|
5603
|
+
}
|
|
5372
5604
|
var streamOpenAICompletions = (model, context, options) => {
|
|
5373
5605
|
const stream = new AssistantMessageEventStream();
|
|
5374
5606
|
(async () => {
|
|
@@ -5418,6 +5650,7 @@ var streamOpenAICompletions = (model, context, options) => {
|
|
|
5418
5650
|
let currentBlock = null;
|
|
5419
5651
|
const blocks = output.content;
|
|
5420
5652
|
const blockIndex = () => blocks.length - 1;
|
|
5653
|
+
let usageSnapshot = {};
|
|
5421
5654
|
const finishCurrentBlock = (block) => {
|
|
5422
5655
|
if (block) {
|
|
5423
5656
|
if (block.type === "text") {
|
|
@@ -5462,26 +5695,28 @@ var streamOpenAICompletions = (model, context, options) => {
|
|
|
5462
5695
|
} catch {
|
|
5463
5696
|
continue;
|
|
5464
5697
|
}
|
|
5698
|
+
if (chunk?.error) {
|
|
5699
|
+
throw new Error(formatOpenAIStreamError(chunk.error));
|
|
5700
|
+
}
|
|
5465
5701
|
if (chunk.usage) {
|
|
5466
|
-
|
|
5467
|
-
const
|
|
5468
|
-
const input = (chunk.usage.prompt_tokens || 0) - cachedTokens;
|
|
5469
|
-
const outputTokens = (chunk.usage.completion_tokens || 0) + reasoningTokens;
|
|
5702
|
+
usageSnapshot = mergeOpenAIUsage(usageSnapshot, chunk.usage);
|
|
5703
|
+
const normalizedUsage = normalizeOpenAIUsage(usageSnapshot);
|
|
5470
5704
|
output.usage = {
|
|
5471
|
-
input,
|
|
5472
|
-
output:
|
|
5473
|
-
cacheRead:
|
|
5705
|
+
input: normalizedUsage.input,
|
|
5706
|
+
output: normalizedUsage.output,
|
|
5707
|
+
cacheRead: normalizedUsage.cacheRead,
|
|
5474
5708
|
cacheWrite: 0,
|
|
5475
|
-
totalTokens:
|
|
5709
|
+
totalTokens: normalizedUsage.totalTokens,
|
|
5476
5710
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
5477
5711
|
};
|
|
5478
|
-
calculateCost(model, output.usage);
|
|
5712
|
+
output.usage.cost = calculateCost(model, output.usage);
|
|
5479
5713
|
if (process.env.PIE_DEBUG_CACHE) {
|
|
5714
|
+
const normalizedPromptTokens = normalizedUsage.input + normalizedUsage.cacheRead;
|
|
5480
5715
|
console.error("[CACHE DEBUG] Response usage:", JSON.stringify({
|
|
5481
|
-
input_tokens: input,
|
|
5482
|
-
output_tokens:
|
|
5483
|
-
cached_tokens:
|
|
5484
|
-
cache_hit_rate:
|
|
5716
|
+
input_tokens: normalizedUsage.input,
|
|
5717
|
+
output_tokens: normalizedUsage.output,
|
|
5718
|
+
cached_tokens: normalizedUsage.cacheRead,
|
|
5719
|
+
cache_hit_rate: normalizedPromptTokens > 0 ? `${(normalizedUsage.cacheRead / normalizedPromptTokens * 100).toFixed(1)}%` : "N/A"
|
|
5485
5720
|
}, null, 2));
|
|
5486
5721
|
}
|
|
5487
5722
|
}
|