@cydm/pie 2.5.2 → 2.6.1
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/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/computer-use/index.js +10 -3
- package/dist/builtin/extensions/mcp-adapter/index.js +38 -16
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +8 -5
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-bridge.js +194 -40
- package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-runtime.js +1 -1
- package/dist/builtin/skills/chrome-devtools-axi/{cli-EJ5MQZNA.js → cli-GB37NZHQ.js} +2 -2
- package/dist/builtin/skills/tui-use/SKILL.md +44 -0
- package/dist/builtin/skills/tui-use/tui-use-cli.cjs +15 -7
- package/dist/chunks/{chunk-M4OJARWJ.js → chunk-3F5ZP2CV.js} +1 -1
- package/dist/chunks/{chunk-LO2V5DZZ.js → chunk-IKLQHWY2.js} +400 -73
- package/dist/chunks/{chunk-UD7KYQ6J.js → chunk-O2DKMLNX.js} +146 -11
- package/dist/chunks/{chunk-RTTGO2A6.js → chunk-Y4CYXJR7.js} +27 -2
- package/dist/chunks/src-VCWCE7YV.js +20 -0
- package/dist/chunks/{test-stream-LFR6GSKQ.js → test-stream-GOSEWMJ3.js} +1 -1
- package/dist/cli.js +26 -21
- package/package.json +2 -2
- package/dist/chunks/src-33WRCQWX.js +0 -14
|
@@ -2191,15 +2191,120 @@ var FileSystemGateway = class {
|
|
|
2191
2191
|
return true;
|
|
2192
2192
|
}
|
|
2193
2193
|
}
|
|
2194
|
-
return
|
|
2194
|
+
return this.allowedViaCaseAlias(path, normalized);
|
|
2195
2195
|
}
|
|
2196
2196
|
/**
|
|
2197
|
-
* Normalize path for comparison
|
|
2197
|
+
* Normalize path for comparison.
|
|
2198
|
+
*
|
|
2199
|
+
* Both sides of every comparison get the identical structural
|
|
2200
|
+
* transformation (backslashes to slashes, repeated separators collapsed,
|
|
2201
|
+
* trailing separators trimmed) so boundary checks stay segment-exact.
|
|
2202
|
+
* Case is folded only where the compared path is Windows-shaped: a drive
|
|
2203
|
+
* letter, a backslash UNC root (`\\server\share`), or any path on a win32
|
|
2204
|
+
* host. POSIX paths keep their case — on a case-sensitive volume a
|
|
2205
|
+
* different-case spelling is a different directory, and a leading "//" on
|
|
2206
|
+
* a POSIX host is an ordinary POSIX path, not a UNC share, so it must never
|
|
2207
|
+
* earn case-insensitive treatment there (that would let `//Tmp/...`-style
|
|
2208
|
+
* spellings borrow the identity of case-distinct siblings).
|
|
2198
2209
|
*/
|
|
2199
2210
|
normalizePath(path) {
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
|
|
2211
|
+
const slashed = path.replace(/\\/g, "/");
|
|
2212
|
+
const collapsed = slashed.replace(/\/+/g, "/");
|
|
2213
|
+
const trimmed = collapsed === "/" ? collapsed : collapsed.replace(/\/+$/, "");
|
|
2214
|
+
return this.usesCaseInsensitiveComparison(path, trimmed) ? trimmed.toLowerCase() : trimmed;
|
|
2215
|
+
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Windows compares all path names case-insensitively; UNC roots are
|
|
2218
|
+
* recognized by their backslash form. Forward-slash "//" prefixes on a
|
|
2219
|
+
* POSIX host stay case-sensitive POSIX paths.
|
|
2220
|
+
*/
|
|
2221
|
+
usesCaseInsensitiveComparison(rawPath, normalizedPath) {
|
|
2222
|
+
if (rawPath.startsWith("\\\\")) return true;
|
|
2223
|
+
if (/^[a-zA-Z]:/.test(normalizedPath)) return true;
|
|
2224
|
+
return typeof process !== "undefined" && process.platform === "win32";
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Slow path for POSIX hosts: preserve legitimate case aliases (the default
|
|
2228
|
+
* macOS volume resolves `/Users/alice` and `/Users/Alice` to the same
|
|
2229
|
+
* directory) without blanket darwin case-folding and without probing the
|
|
2230
|
+
* filesystem with writes. A candidate is allowed only when the canonical
|
|
2231
|
+
* identity of its nearest existing ancestor — rebuilt segment by segment
|
|
2232
|
+
* with read-only stat/readdir probes — lands inside the canonical identity
|
|
2233
|
+
* of an allowed root. On a case-sensitive volume a case-variant spelling of
|
|
2234
|
+
* a different directory never resolves through this walk (the exact
|
|
2235
|
+
* spelling wins whenever it exists), so it stays denied. Windows-shaped
|
|
2236
|
+
* candidates skip this path: their comparison is already case-folded.
|
|
2237
|
+
*/
|
|
2238
|
+
allowedViaCaseAlias(rawPath, normalizedPath) {
|
|
2239
|
+
if (!normalizedPath.startsWith("/")) return false;
|
|
2240
|
+
if (this.usesCaseInsensitiveComparison(rawPath, normalizedPath)) return false;
|
|
2241
|
+
if (typeof process !== "undefined" && process.platform === "win32") return false;
|
|
2242
|
+
if (detectPlatform() === "puerts") return false;
|
|
2243
|
+
let fs;
|
|
2244
|
+
try {
|
|
2245
|
+
fs = nodeRequire("fs");
|
|
2246
|
+
} catch {
|
|
2247
|
+
return false;
|
|
2248
|
+
}
|
|
2249
|
+
let resolved;
|
|
2250
|
+
try {
|
|
2251
|
+
resolved = this.resolveCaseAlias(fs, normalizedPath);
|
|
2252
|
+
} catch {
|
|
2253
|
+
return false;
|
|
2254
|
+
}
|
|
2255
|
+
for (const root of this.allowedRoots) {
|
|
2256
|
+
const normalizedRoot = this.normalizePath(root);
|
|
2257
|
+
if (!normalizedRoot.startsWith("/")) continue;
|
|
2258
|
+
try {
|
|
2259
|
+
const resolvedRoot = this.resolveCaseAlias(fs, normalizedRoot);
|
|
2260
|
+
if (resolved === resolvedRoot || resolved.startsWith(this.withTrailingSep(resolvedRoot))) {
|
|
2261
|
+
return true;
|
|
2262
|
+
}
|
|
2263
|
+
} catch {
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
return false;
|
|
2267
|
+
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Rebuild a POSIX path with its true on-disk case. The canonical prefix
|
|
2270
|
+
* grows only through segments the filesystem itself accepts in the
|
|
2271
|
+
* requested spelling (a read-only stat probe): on a case-insensitive
|
|
2272
|
+
* volume a different-case spelling still resolves and is rewritten to the
|
|
2273
|
+
* directory's actual entry name; on a case-sensitive volume it does not
|
|
2274
|
+
* resolve, the walk stops, and the remaining segments stay verbatim — so
|
|
2275
|
+
* they can never borrow a sibling directory's identity.
|
|
2276
|
+
*/
|
|
2277
|
+
resolveCaseAlias(fs, normalizedPath) {
|
|
2278
|
+
const segments = normalizedPath.slice(1).split("/").filter((segment) => segment.length > 0 && segment !== ".");
|
|
2279
|
+
let canonical = "";
|
|
2280
|
+
let index = 0;
|
|
2281
|
+
while (index < segments.length) {
|
|
2282
|
+
const segment = segments[index];
|
|
2283
|
+
const probe = `${canonical}/${segment}`;
|
|
2284
|
+
if (!fs.statSync(probe, { throwIfNoEntry: false })) break;
|
|
2285
|
+
canonical = `${canonical}/${this.trueCaseName(fs, canonical, segment)}`;
|
|
2286
|
+
index += 1;
|
|
2287
|
+
}
|
|
2288
|
+
const tail = segments.slice(index).join("/");
|
|
2289
|
+
return tail ? `${canonical}/${tail}` : canonical;
|
|
2290
|
+
}
|
|
2291
|
+
/**
|
|
2292
|
+
* Actual directory-entry name for a segment the filesystem already
|
|
2293
|
+
* resolved. Exact spelling wins; a different-case entry can only be the
|
|
2294
|
+
* same file (case-insensitive volume), otherwise statSync above would have
|
|
2295
|
+
* failed. Read-only; never falls back to writing a probe.
|
|
2296
|
+
*/
|
|
2297
|
+
trueCaseName(fs, directory, name) {
|
|
2298
|
+
try {
|
|
2299
|
+
const entries = fs.readdirSync(directory === "" ? "/" : directory);
|
|
2300
|
+
if (entries.includes(name)) return name;
|
|
2301
|
+
const lowered = name.toLowerCase();
|
|
2302
|
+
for (const entry of entries) {
|
|
2303
|
+
if (entry.toLowerCase() === lowered) return entry;
|
|
2304
|
+
}
|
|
2305
|
+
} catch {
|
|
2306
|
+
}
|
|
2307
|
+
return name;
|
|
2203
2308
|
}
|
|
2204
2309
|
/**
|
|
2205
2310
|
* Normalize root path for prefix comparison
|
|
@@ -2914,7 +3019,7 @@ function convertMessages(model, context, compat) {
|
|
|
2914
3019
|
if (typeof msg.content === "string") {
|
|
2915
3020
|
params.push({ role: "user", content: msg.content });
|
|
2916
3021
|
} else {
|
|
2917
|
-
const content = msg.content.flatMap((item) =>
|
|
3022
|
+
const content = msg.content.flatMap((item) => convertCheckedContent(item, model));
|
|
2918
3023
|
const filteredContent = content.filter((c) => {
|
|
2919
3024
|
if (c.type === "text") return true;
|
|
2920
3025
|
if (c.type === "image_url") return model.input.includes("image");
|
|
@@ -2971,11 +3076,17 @@ function convertMessages(model, context, compat) {
|
|
|
2971
3076
|
};
|
|
2972
3077
|
if (compat.requiresToolResultName && toolMsg.toolName) toolResultMsg.name = toolMsg.toolName;
|
|
2973
3078
|
params.push(toolResultMsg);
|
|
2974
|
-
|
|
2975
|
-
const images = toolMsg.content.filter((c) => c.type
|
|
3079
|
+
{
|
|
3080
|
+
const images = toolMsg.content.filter((c) => c.type !== "text");
|
|
2976
3081
|
if (images.length > 0) {
|
|
2977
3082
|
attachments.push({ type: "text", text: `Images from tool ${toolMsg.toolName ?? "unknown"} (call ${toolMsg.toolCallId}):` });
|
|
2978
|
-
for (const image of images)
|
|
3083
|
+
for (const image of images) {
|
|
3084
|
+
const kind = image.type;
|
|
3085
|
+
const capability = kind === "audio" || kind === "video" ? model.fileCapabilities?.[kind] : void 0;
|
|
3086
|
+
if ((kind === "audio" || kind === "video") && !(capability && typeof capability === "object" && capability.supported !== false && capability.nativeInline === true)) {
|
|
3087
|
+
attachments.push({ type: "text", text: `[${kind} attachment omitted: endpoint nativeInline transport is not enabled. Re-read with a compatible model.]` });
|
|
3088
|
+
} else attachments.push(...convertCheckedContent(image, model));
|
|
3089
|
+
}
|
|
2979
3090
|
}
|
|
2980
3091
|
}
|
|
2981
3092
|
}
|
|
@@ -2985,6 +3096,30 @@ function convertMessages(model, context, compat) {
|
|
|
2985
3096
|
}
|
|
2986
3097
|
return params;
|
|
2987
3098
|
}
|
|
3099
|
+
function convertCheckedContent(item, model) {
|
|
3100
|
+
const modality = item.type === "fileRef" ? item.modality : item.type;
|
|
3101
|
+
if (modality === "image" || modality === "video" || modality === "audio") {
|
|
3102
|
+
if (!model.input.includes(modality)) return [{ type: "text", text: `[${modality} attachment omitted: current model does not support this modality. Re-read with a compatible model.]` }];
|
|
3103
|
+
if (item.type === "audio") {
|
|
3104
|
+
const audio = item;
|
|
3105
|
+
if (audioFormatFor(audio.mimeType) === void 0) {
|
|
3106
|
+
return [{ type: "text", text: `[audio attachment omitted: unsupported format ${audio.mimeType}. Convert to WAV or MP3 first.]` }];
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
return convertUserContentItem(item);
|
|
3111
|
+
}
|
|
3112
|
+
function audioFormatFor(mimeType) {
|
|
3113
|
+
const mime = mimeType.toLowerCase().split(";")[0].trim();
|
|
3114
|
+
if (["audio/wav", "audio/x-wav", "audio/wave", "audio/vnd.wave"].includes(mime)) return "wav";
|
|
3115
|
+
if (["audio/mpeg", "audio/mp3"].includes(mime)) return "mp3";
|
|
3116
|
+
return void 0;
|
|
3117
|
+
}
|
|
3118
|
+
function audioFormat(mimeType) {
|
|
3119
|
+
const format = audioFormatFor(mimeType);
|
|
3120
|
+
if (format === void 0) throw new Error(`Unsupported audio attachment format: ${mimeType}. Convert to WAV or MP3 first.`);
|
|
3121
|
+
return format;
|
|
3122
|
+
}
|
|
2988
3123
|
function convertUserContentItem(item) {
|
|
2989
3124
|
if (item.type === "text") return [{ type: "text", text: item.text }];
|
|
2990
3125
|
if (item.type === "image") return [{ type: "image_url", image_url: { url: `data:${item.mimeType};base64,${item.data}` } }];
|
|
@@ -2994,7 +3129,7 @@ function convertUserContentItem(item) {
|
|
|
2994
3129
|
}
|
|
2995
3130
|
if (item.type === "audio") {
|
|
2996
3131
|
const audio = item;
|
|
2997
|
-
return [{ type: "input_audio", input_audio: { data: audio.data, format: audio.mimeType
|
|
3132
|
+
return [{ type: "input_audio", input_audio: { data: audio.data, format: audioFormat(audio.mimeType) } }];
|
|
2998
3133
|
}
|
|
2999
3134
|
if (item.type === "fileRef") {
|
|
3000
3135
|
const ref = item;
|
|
@@ -3641,7 +3776,7 @@ function mapStopReason(reason) {
|
|
|
3641
3776
|
}
|
|
3642
3777
|
}
|
|
3643
3778
|
function convertContentBlocks(content) {
|
|
3644
|
-
const supportedBlocks = content.
|
|
3779
|
+
const supportedBlocks = content.map((block) => block.type === "text" || block.type === "image" ? block : { type: "text", text: `[${block.type} attachment omitted: unsupported by this provider. Re-read with a compatible model.]` });
|
|
3645
3780
|
const hasImages = supportedBlocks.some((c) => c.type === "image");
|
|
3646
3781
|
if (!hasImages) {
|
|
3647
3782
|
const text = supportedBlocks.filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
EventStream,
|
|
4
4
|
streamSimple,
|
|
5
5
|
validateToolArguments
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-O2DKMLNX.js";
|
|
7
7
|
|
|
8
8
|
// ../../packages/agent-core/src/agent-loop.ts
|
|
9
9
|
function createLoopErrorMessage(error, config, signal) {
|
|
@@ -409,6 +409,19 @@ function skipToolCall(toolCall, stream) {
|
|
|
409
409
|
return toolResultMessage;
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
+
// ../../packages/agent-core/src/tool-caller-identity.ts
|
|
413
|
+
var kToolCallerIdentity = /* @__PURE__ */ Symbol("pie.toolCallerIdentity");
|
|
414
|
+
function createToolCallerIdentity() {
|
|
415
|
+
return { kind: "pie.toolCallerIdentity" };
|
|
416
|
+
}
|
|
417
|
+
function bindToolCallerIdentity(signal, identity) {
|
|
418
|
+
signal[kToolCallerIdentity] = identity;
|
|
419
|
+
}
|
|
420
|
+
function getToolCallerIdentity(signal) {
|
|
421
|
+
if (!signal) return void 0;
|
|
422
|
+
return signal[kToolCallerIdentity];
|
|
423
|
+
}
|
|
424
|
+
|
|
412
425
|
// ../../packages/agent-core/src/agent.ts
|
|
413
426
|
function defaultConvertToLlm(messages) {
|
|
414
427
|
return messages.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "toolResult");
|
|
@@ -443,11 +456,16 @@ var Agent = class {
|
|
|
443
456
|
_thinkingBudgets;
|
|
444
457
|
_maxRetryDelayMs;
|
|
445
458
|
hooks;
|
|
459
|
+
/** Stable identity for this agent instance, bound onto every run signal
|
|
460
|
+
* handed to tools (signals themselves are per-run; see tool-caller-identity.ts). */
|
|
461
|
+
toolCallerIdentity = createToolCallerIdentity();
|
|
446
462
|
statusSnapshot = {
|
|
447
463
|
phase: "idle",
|
|
448
464
|
turnState: "completed",
|
|
449
465
|
hasPendingToolContinuation: false
|
|
450
466
|
};
|
|
467
|
+
/** Assistant message already reported as turn_failed during this run. */
|
|
468
|
+
reportedFailureMessage;
|
|
451
469
|
constructor(opts = {}) {
|
|
452
470
|
this._state = {
|
|
453
471
|
systemPrompt: "",
|
|
@@ -729,6 +747,7 @@ var Agent = class {
|
|
|
729
747
|
const model = this._state.model;
|
|
730
748
|
if (!model) throw new Error("No model configured");
|
|
731
749
|
this.abortController = new AbortController();
|
|
750
|
+
bindToolCallerIdentity(this.abortController.signal, this.toolCallerIdentity);
|
|
732
751
|
this._state.isStreaming = true;
|
|
733
752
|
this._state.streamMessage = null;
|
|
734
753
|
this._state.error = void 0;
|
|
@@ -954,6 +973,7 @@ var Agent = class {
|
|
|
954
973
|
const stopReason = event.message.role === "assistant" ? event.message.stopReason : void 0;
|
|
955
974
|
const hasToolCalls = event.message.role === "assistant" && Array.isArray(event.message.content) && event.message.content.some((block) => block.type === "toolCall");
|
|
956
975
|
if (stopReason === "error" || stopReason === "aborted") {
|
|
976
|
+
this.reportedFailureMessage = event.message;
|
|
957
977
|
this.updateStatusSnapshot({
|
|
958
978
|
phase: "failed",
|
|
959
979
|
turnState: "failed",
|
|
@@ -997,7 +1017,9 @@ var Agent = class {
|
|
|
997
1017
|
}
|
|
998
1018
|
case "agent_end": {
|
|
999
1019
|
const lastMessage = event.messages[event.messages.length - 1];
|
|
1000
|
-
|
|
1020
|
+
const alreadyReported = lastMessage !== void 0 && lastMessage === this.reportedFailureMessage;
|
|
1021
|
+
this.reportedFailureMessage = void 0;
|
|
1022
|
+
if (!alreadyReported && lastMessage?.role === "assistant" && (lastMessage.stopReason === "error" || lastMessage.stopReason === "aborted")) {
|
|
1001
1023
|
this.updateStatusSnapshot({
|
|
1002
1024
|
phase: "failed",
|
|
1003
1025
|
turnState: "failed",
|
|
@@ -1025,5 +1047,8 @@ var Agent = class {
|
|
|
1025
1047
|
export {
|
|
1026
1048
|
agentLoop,
|
|
1027
1049
|
agentLoopContinue,
|
|
1050
|
+
createToolCallerIdentity,
|
|
1051
|
+
bindToolCallerIdentity,
|
|
1052
|
+
getToolCallerIdentity,
|
|
1028
1053
|
Agent
|
|
1029
1054
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
Agent,
|
|
4
|
+
agentLoop,
|
|
5
|
+
agentLoopContinue,
|
|
6
|
+
bindToolCallerIdentity,
|
|
7
|
+
createToolCallerIdentity,
|
|
8
|
+
getToolCallerIdentity
|
|
9
|
+
} from "./chunk-Y4CYXJR7.js";
|
|
10
|
+
import "./chunk-O2DKMLNX.js";
|
|
11
|
+
import "./chunk-XXGYUYXI.js";
|
|
12
|
+
import "./chunk-LZQXQOPJ.js";
|
|
13
|
+
export {
|
|
14
|
+
Agent,
|
|
15
|
+
agentLoop,
|
|
16
|
+
agentLoopContinue,
|
|
17
|
+
bindToolCallerIdentity,
|
|
18
|
+
createToolCallerIdentity,
|
|
19
|
+
getToolCallerIdentity
|
|
20
|
+
};
|
|
@@ -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-
|
|
4
|
+
} from "./chunk-O2DKMLNX.js";
|
|
5
5
|
import "./chunk-XXGYUYXI.js";
|
|
6
6
|
import "./chunk-LZQXQOPJ.js";
|
|
7
7
|
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
createCliWebResearchHealthStore,
|
|
8
8
|
formatSize,
|
|
9
9
|
truncateHeadTail
|
|
10
|
-
} from "./chunks/chunk-
|
|
10
|
+
} from "./chunks/chunk-3F5ZP2CV.js";
|
|
11
11
|
import {
|
|
12
12
|
AGENTS_CONTEXT_FILE_NAME,
|
|
13
13
|
AgentSessionController,
|
|
@@ -60,8 +60,8 @@ import {
|
|
|
60
60
|
setExtensionEnabledInSettings,
|
|
61
61
|
shouldPreserveExecutionStateForUserText,
|
|
62
62
|
supersedeExecutionState
|
|
63
|
-
} from "./chunks/chunk-
|
|
64
|
-
import "./chunks/chunk-
|
|
63
|
+
} from "./chunks/chunk-IKLQHWY2.js";
|
|
64
|
+
import "./chunks/chunk-Y4CYXJR7.js";
|
|
65
65
|
import {
|
|
66
66
|
Deref,
|
|
67
67
|
EMPTY_ASSISTANT_CONTENT_ERROR,
|
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
setLogger,
|
|
86
86
|
sortToolModelCandidatesByCapability,
|
|
87
87
|
type_exports
|
|
88
|
-
} from "./chunks/chunk-
|
|
88
|
+
} from "./chunks/chunk-O2DKMLNX.js";
|
|
89
89
|
import {
|
|
90
90
|
VERSION,
|
|
91
91
|
getAgentDir,
|
|
@@ -52476,8 +52476,9 @@ function validateFileCapabilities(value, label) {
|
|
|
52476
52476
|
if (!["image", "video", "audio", "document"].includes(kind)) throw new Error(`${label}.${kind} is unsupported`);
|
|
52477
52477
|
if (typeof capability === "boolean") continue;
|
|
52478
52478
|
if (!isPlainRecord(capability)) throw new Error(`${label}.${kind} is invalid`);
|
|
52479
|
-
assertOnlyKeys(capability, ["supported", "formats", "maxFileSizeMb", "maxDurationSeconds"], `${label}.${kind}`);
|
|
52479
|
+
assertOnlyKeys(capability, ["supported", "formats", "maxFileSizeMb", "maxDurationSeconds", "nativeInline"], `${label}.${kind}`);
|
|
52480
52480
|
assertOptionalBoolean(capability.supported, `${label}.${kind}.supported`);
|
|
52481
|
+
assertOptionalBoolean(capability.nativeInline, `${label}.${kind}.nativeInline`);
|
|
52481
52482
|
if (capability.formats !== void 0 && (!Array.isArray(capability.formats) || capability.formats.some((item) => typeof item !== "string" || !item))) {
|
|
52482
52483
|
throw new Error(`${label}.${kind}.formats is invalid`);
|
|
52483
52484
|
}
|
|
@@ -53689,6 +53690,13 @@ var SettingsManager = class {
|
|
|
53689
53690
|
this.settings.calmMode = enabled;
|
|
53690
53691
|
this.writeSettings();
|
|
53691
53692
|
}
|
|
53693
|
+
getToolOutputExpanded() {
|
|
53694
|
+
return this.settings.toolOutputExpanded === true;
|
|
53695
|
+
}
|
|
53696
|
+
setToolOutputExpanded(expanded) {
|
|
53697
|
+
this.settings.toolOutputExpanded = expanded;
|
|
53698
|
+
this.writeSettings();
|
|
53699
|
+
}
|
|
53692
53700
|
// ==========================================================================
|
|
53693
53701
|
// Extension enablement (user ~/.pie/settings.json + project ./.pie/settings.json)
|
|
53694
53702
|
// ==========================================================================
|
|
@@ -70165,7 +70173,7 @@ function deriveSessionTitle(options) {
|
|
|
70165
70173
|
}
|
|
70166
70174
|
if (activeSession.metadata.nameSource === "manual") {
|
|
70167
70175
|
const manual = normalizeSessionTitle(activeSession.metadata.name);
|
|
70168
|
-
|
|
70176
|
+
return manual || activeSession.metadata.name.trim() || `S:${activeSession.id.slice(-6)}`;
|
|
70169
70177
|
}
|
|
70170
70178
|
if (persistedNameIsAuthoritative(activeSession.metadata)) {
|
|
70171
70179
|
const persisted = normalizeSessionTitle(activeSession.metadata.name);
|
|
@@ -72843,12 +72851,6 @@ async function loadSession(host, sessionId) {
|
|
|
72843
72851
|
host.agentSessionController?.drainQueuedInputsForEditor();
|
|
72844
72852
|
host.updatePendingMessagesDisplay();
|
|
72845
72853
|
renderChatHistory(host, messages);
|
|
72846
|
-
if (messages.length > 50) {
|
|
72847
|
-
host.chatContainer.addChild(new Spacer(1));
|
|
72848
|
-
host.chatContainer.addChild(
|
|
72849
|
-
new Text(theme.fg("dim", `... (${messages.length - 50} earlier messages hidden)`), 1, 0)
|
|
72850
|
-
);
|
|
72851
|
-
}
|
|
72852
72854
|
host.chatContainer.addChild(new Spacer(1));
|
|
72853
72855
|
host.chatContainer.addChild(
|
|
72854
72856
|
new Text(theme.fg("accent", `\u2713 Loaded session: ${sessionId.slice(0, 8)}...`), 1, 0)
|
|
@@ -73072,7 +73074,7 @@ async function navigateToEntry(host, entryId) {
|
|
|
73072
73074
|
}
|
|
73073
73075
|
}
|
|
73074
73076
|
function renderChatHistory(host, messages) {
|
|
73075
|
-
const messagesToShow = messages
|
|
73077
|
+
const messagesToShow = messages;
|
|
73076
73078
|
const toolResultMap = /* @__PURE__ */ new Map();
|
|
73077
73079
|
for (const msg of messages) {
|
|
73078
73080
|
if (msg.role === "toolResult") {
|
|
@@ -77641,9 +77643,10 @@ function stripStaleUsageBeforeCompaction(messages, latestCompactionTimestamp) {
|
|
|
77641
77643
|
|
|
77642
77644
|
// src/runtime/retry-policy.ts
|
|
77643
77645
|
var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|client network socket disconnected before secure TLS connection was established|certificate (?:has )?expired|unable to verify (?:the first certificate|certificate)|self[- ]signed cert|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
|
|
77644
|
-
var PROVIDER_TRANSIENT_ERROR_PATTERN = /overloaded|rate.?limit|too many requests|\b429\b|\b500\b|\b502\b|\b503\b|\b504\b|service.?unavailable|server error|internal error|retry delay/i;
|
|
77646
|
+
var PROVIDER_TRANSIENT_ERROR_PATTERN = /overloaded|rate.?limit|too many requests|\b429\b|\b500\b|\b502\b|\b503\b|\b504\b|service.?unavailable|server error|internal error|retry delay|quota (?:has been |is )?exhausted/i;
|
|
77645
77647
|
var USER_ABORT_PATTERN = /request was aborted|local abort signal|user abort|user_interrupt|interrupted by user|esc pressed|ctrl\+c/i;
|
|
77646
77648
|
var AUTH_CONFIG_PATTERN = /missing api key|invalid api key|api key.*invalid|unauthorized|\b401\b|\b403\b|forbidden|authentication failed|no configured model|no models? are configured/i;
|
|
77649
|
+
var QUOTA_EXHAUSTED_PATTERN = /insufficient[_ ]quota|exceeded[_ ]current[_ ]quota|exceeded your current quota|billing[_ ]hard[_ ]limit|insufficient[_ ]balance|credit balance is too low|\barrearage\b|余额不足|\b(?:account|monthly|billing) quota (?:has been |is )?exhausted/i;
|
|
77647
77650
|
var INVALID_FILE_REFERENCE_PATTERN = /not the owner of this file|owner of this file|invalid_authentication_error/i;
|
|
77648
77651
|
var INVALID_REQUEST_PATTERN = /bad request|\b400\b|invalid request|invalid schema|schema validation|invalid parameter|unsupported parameter|malformed/i;
|
|
77649
77652
|
var CLI_RETRY_MAX_RETRIES = 3;
|
|
@@ -77683,7 +77686,7 @@ function classifyCliFailure(context) {
|
|
|
77683
77686
|
if (INVALID_FILE_REFERENCE_PATTERN.test(errorMessage4)) {
|
|
77684
77687
|
return createClassification("invalid_file_reference", errorMessage4);
|
|
77685
77688
|
}
|
|
77686
|
-
if (AUTH_CONFIG_PATTERN.test(errorMessage4)) {
|
|
77689
|
+
if (AUTH_CONFIG_PATTERN.test(errorMessage4) || QUOTA_EXHAUSTED_PATTERN.test(errorMessage4)) {
|
|
77687
77690
|
return createClassification("auth_config", errorMessage4);
|
|
77688
77691
|
}
|
|
77689
77692
|
if (TRANSIENT_NETWORK_ERROR_PATTERN.test(errorMessage4)) {
|
|
@@ -79837,6 +79840,7 @@ var InteractiveMode = class {
|
|
|
79837
79840
|
this.skillsSection = formatSkillsForPrompt(options.skills);
|
|
79838
79841
|
this.knowledgeSection = buildCliProjectContextSection(options.cwd);
|
|
79839
79842
|
this.calmMode = options.settingsManager.getCalmModeEnabled();
|
|
79843
|
+
this.toolOutputExpanded = options.settingsManager.getToolOutputExpanded();
|
|
79840
79844
|
}
|
|
79841
79845
|
options;
|
|
79842
79846
|
get runtimeEventHost() {
|
|
@@ -80034,7 +80038,7 @@ var InteractiveMode = class {
|
|
|
80034
80038
|
async init() {
|
|
80035
80039
|
const activeSession = this.sessionManager.getActiveSession();
|
|
80036
80040
|
this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
|
|
80037
|
-
const { Agent } = await import("./chunks/src-
|
|
80041
|
+
const { Agent } = await import("./chunks/src-VCWCE7YV.js");
|
|
80038
80042
|
this.agent = new Agent({
|
|
80039
80043
|
initialState: {
|
|
80040
80044
|
systemPrompt: this.buildSystemPrompt(),
|
|
@@ -80389,7 +80393,8 @@ var InteractiveMode = class {
|
|
|
80389
80393
|
return interactiveCommands.some((cmd) => commandPath.startsWith(cmd));
|
|
80390
80394
|
}
|
|
80391
80395
|
toggleToolsExpansion() {
|
|
80392
|
-
|
|
80396
|
+
toggleToolsExpansion(this.uiHelperHost);
|
|
80397
|
+
this.options.settingsManager.setToolOutputExpanded(this.toolOutputExpanded);
|
|
80393
80398
|
}
|
|
80394
80399
|
showSelector(create) {
|
|
80395
80400
|
return showSelector(this.uiHelperHost, create);
|
|
@@ -80868,7 +80873,7 @@ async function runPrintMode(params) {
|
|
|
80868
80873
|
`);
|
|
80869
80874
|
console.log("Assistant: ");
|
|
80870
80875
|
}
|
|
80871
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
80876
|
+
const { Agent: AgentClass } = await import("./chunks/src-VCWCE7YV.js");
|
|
80872
80877
|
let agent;
|
|
80873
80878
|
const printModeExtensions = await loadPrintModeExtensions({
|
|
80874
80879
|
cwd: runtime.cwd,
|
|
@@ -81729,7 +81734,7 @@ async function runJsonEventsMode(params) {
|
|
|
81729
81734
|
return;
|
|
81730
81735
|
}
|
|
81731
81736
|
const parent = agent;
|
|
81732
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
81737
|
+
const { Agent: AgentClass } = await import("./chunks/src-VCWCE7YV.js");
|
|
81733
81738
|
const sideAgent = new AgentClass({
|
|
81734
81739
|
initialState: {
|
|
81735
81740
|
systemPrompt: parent.state.systemPrompt,
|
|
@@ -82073,7 +82078,7 @@ async function runJsonEventsMode(params) {
|
|
|
82073
82078
|
if (runtime.initialModel.unconfigured || controller) {
|
|
82074
82079
|
return;
|
|
82075
82080
|
}
|
|
82076
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
82081
|
+
const { Agent: AgentClass } = await import("./chunks/src-VCWCE7YV.js");
|
|
82077
82082
|
const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
|
|
82078
82083
|
extensionRunner = jsonModeExtensions.runner;
|
|
82079
82084
|
const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
|
|
@@ -82662,7 +82667,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
|
|
|
82662
82667
|
}
|
|
82663
82668
|
async function createCliTestStreamFnFromEnv() {
|
|
82664
82669
|
if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
|
|
82665
|
-
return (await import("./chunks/test-stream-
|
|
82670
|
+
return (await import("./chunks/test-stream-GOSEWMJ3.js")).createTestStreamFnFromSequenceEnv();
|
|
82666
82671
|
}
|
|
82667
82672
|
function resolveJsonEventsDetailFlag() {
|
|
82668
82673
|
for (let index = 0; index < process.argv.length; index += 1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cydm/pie",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "Pie AI Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"validate:models": "tsx scripts/validate-models-config.ts",
|
|
18
18
|
"test": "npm run test:offline",
|
|
19
19
|
"pretest:offline": "npm run build --workspace @pie/agent-framework && npm run build --workspace @pie/shared-headless-capabilities && npm run build && npm run test:skill-regressions",
|
|
20
|
-
"test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/skill-creator-runner.test.ts test/tui-use-contract.test.ts test/tui-use-runtime.test.ts test/browser-runtime.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
|
|
20
|
+
"test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/skill-creator-runner.test.ts test/tui-use-contract.test.ts test/tui-use-runtime.test.ts test/browser-runtime.test.ts test/axi-stop-semantics.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
|
|
21
21
|
"posttest:offline": "node --test --import tsx test/remote-model-catalog.test.ts",
|
|
22
22
|
"test:offline": "node --test --test-concurrency=4 --import tsx test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts",
|
|
23
23
|
"test:all": "npm run test:offline && npm run test:terminal:vitest",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
Agent,
|
|
4
|
-
agentLoop,
|
|
5
|
-
agentLoopContinue
|
|
6
|
-
} from "./chunk-RTTGO2A6.js";
|
|
7
|
-
import "./chunk-UD7KYQ6J.js";
|
|
8
|
-
import "./chunk-XXGYUYXI.js";
|
|
9
|
-
import "./chunk-LZQXQOPJ.js";
|
|
10
|
-
export {
|
|
11
|
-
Agent,
|
|
12
|
-
agentLoop,
|
|
13
|
-
agentLoopContinue
|
|
14
|
-
};
|