@cydm/pie 2.7.6 → 2.7.8
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/plan-mode/index.js +6 -4
- package/dist/builtin/extensions/subagent/index.js +11 -5
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/builtin/skills/chrome-devtools-axi/SKILL.md +2 -2
- package/dist/builtin/skills/computer-use-axi/SKILL.md +1 -1
- package/dist/builtin/skills/tui-use/SKILL.md +1 -1
- package/dist/chunks/{chunk-ZF5FHTES.js → chunk-2FEDB5GR.js} +22 -0
- package/dist/chunks/{chunk-GAUIKMBA.js → chunk-E6F4BTNN.js} +325 -56
- package/dist/chunks/{chunk-YWWLRZSG.js → chunk-P22SYVGO.js} +291 -44
- package/dist/chunks/{chunk-5YWEUFLM.js → chunk-W5B3OXHQ.js} +1 -1
- package/dist/chunks/{src-6WK5KYWQ.js → src-C2CBPEUY.js} +2 -2
- package/dist/chunks/{test-stream-7EH7BGY6.js → test-stream-LDVUVSUP.js} +10 -1
- package/dist/cli.js +494 -325
- package/package.json +6 -5
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
logTransportLifecycle,
|
|
24
24
|
migrateConfigFromAgentDir,
|
|
25
25
|
truncateHeadTail
|
|
26
|
-
} from "./chunks/chunk-
|
|
26
|
+
} from "./chunks/chunk-E6F4BTNN.js";
|
|
27
27
|
import {
|
|
28
28
|
resolveCliProjectRoot
|
|
29
29
|
} from "./chunks/chunk-WLFOBECN.js";
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
createEmptyExecutionState,
|
|
48
48
|
createExecutionStateStore,
|
|
49
49
|
createFileObservationState,
|
|
50
|
+
createHostEnvelopeProjectorRegistry,
|
|
50
51
|
createPolicyEnforcedTools,
|
|
51
52
|
createReadFileUnderstandingHandler,
|
|
52
53
|
createSearchContextTool,
|
|
@@ -71,11 +72,13 @@ import {
|
|
|
71
72
|
interactionAttentionResolution,
|
|
72
73
|
isCompactSummaryMessage,
|
|
73
74
|
isExtensionEnabled,
|
|
75
|
+
isHostContextBlock,
|
|
74
76
|
isToolAllowedInPlanMode,
|
|
75
77
|
maybeAdvanceTodoExecutionState,
|
|
76
78
|
modalityForReadFileUnderstandingKind,
|
|
77
79
|
pauseExecutionState,
|
|
78
80
|
prepareSessionCompaction,
|
|
81
|
+
projectHostEnvelopes,
|
|
79
82
|
registerInteractionHandler,
|
|
80
83
|
requestInteraction,
|
|
81
84
|
resolveExtensionIdentity,
|
|
@@ -85,8 +88,8 @@ import {
|
|
|
85
88
|
shouldPreserveExecutionStateForUserText,
|
|
86
89
|
supersedeExecutionState,
|
|
87
90
|
verifyPreparedCompactionCommit
|
|
88
|
-
} from "./chunks/chunk-
|
|
89
|
-
import "./chunks/chunk-
|
|
91
|
+
} from "./chunks/chunk-P22SYVGO.js";
|
|
92
|
+
import "./chunks/chunk-W5B3OXHQ.js";
|
|
90
93
|
import {
|
|
91
94
|
Deref,
|
|
92
95
|
EMPTY_ASSISTANT_CONTENT_ERROR,
|
|
@@ -111,7 +114,7 @@ import {
|
|
|
111
114
|
sortToolModelCandidatesByCapability,
|
|
112
115
|
streamSimple,
|
|
113
116
|
type_exports
|
|
114
|
-
} from "./chunks/chunk-
|
|
117
|
+
} from "./chunks/chunk-2FEDB5GR.js";
|
|
115
118
|
import {
|
|
116
119
|
IsArray,
|
|
117
120
|
IsBigInt,
|
|
@@ -53655,7 +53658,12 @@ var ModelRegistry = class {
|
|
|
53655
53658
|
import * as fs4 from "fs";
|
|
53656
53659
|
import * as path4 from "path";
|
|
53657
53660
|
function getDisabledToolNames(settingsManager) {
|
|
53658
|
-
|
|
53661
|
+
const disabled = new Set(typeof settingsManager?.getDisabledTools === "function" ? settingsManager.getDisabledTools() : []);
|
|
53662
|
+
if (disabled.has("bash") || disabled.has("shell")) {
|
|
53663
|
+
disabled.add("bash");
|
|
53664
|
+
disabled.add("shell");
|
|
53665
|
+
}
|
|
53666
|
+
return disabled;
|
|
53659
53667
|
}
|
|
53660
53668
|
function filterEnabledTools(tools, settingsManager) {
|
|
53661
53669
|
const disabled = getDisabledToolNames(settingsManager);
|
|
@@ -53983,11 +53991,12 @@ var SettingsManager = class {
|
|
|
53983
53991
|
}
|
|
53984
53992
|
/** Whether a runtime tool is enabled; absent means "enabled". */
|
|
53985
53993
|
isToolEnabled(name) {
|
|
53986
|
-
return !this
|
|
53994
|
+
return !getDisabledToolNames(this).has(name);
|
|
53987
53995
|
}
|
|
53988
53996
|
/** Enable/disable a runtime tool by name (persisted in settings.json). */
|
|
53989
53997
|
setToolEnabled(name, enabled) {
|
|
53990
|
-
const
|
|
53998
|
+
const isShell = name === "shell" || name === "bash";
|
|
53999
|
+
const disabled = this.getDisabledTools().filter((tool) => isShell ? tool !== "shell" && tool !== "bash" : tool !== name);
|
|
53991
54000
|
if (!enabled) disabled.push(name);
|
|
53992
54001
|
disabled.sort();
|
|
53993
54002
|
const nextTools = { ...this.settings.tools ?? {} };
|
|
@@ -54427,8 +54436,8 @@ var MODE_RULES = {
|
|
|
54427
54436
|
"File tools read and write inside the current workspace.",
|
|
54428
54437
|
"~/.pie is allowlisted for Pie configuration and session support.",
|
|
54429
54438
|
"Shell commands run from the workspace and return structured output, timeout, and truncation details.",
|
|
54430
|
-
"web_research is read-only, uses provider-native web/search/fetch capabilities, and does not grant
|
|
54431
|
-
"Desktop control runs through the computer-use-axi skill CLI via
|
|
54439
|
+
"web_research is read-only, uses provider-native web/search/fetch capabilities, and does not grant shell/curl web scraping permission.",
|
|
54440
|
+
"Desktop control runs through the computer-use-axi skill CLI via the shell tool: observation commands only read the screen, while act synthesizes real desktop input and goes through normal shell permission prompts.",
|
|
54432
54441
|
"Protected paths from extensions can block reads/writes even when tools are present."
|
|
54433
54442
|
],
|
|
54434
54443
|
plan: [
|
|
@@ -54454,7 +54463,9 @@ var MODE_TITLES = {
|
|
|
54454
54463
|
function buildPermissionsData() {
|
|
54455
54464
|
return {
|
|
54456
54465
|
modes: Object.fromEntries(Object.entries(MODE_RULES).map(([key, rules]) => [key, [...rules]])),
|
|
54457
|
-
|
|
54466
|
+
// The legacy bash policy key supports old history/settings; it is not a
|
|
54467
|
+
// second executable tool and must not be advertised as one here.
|
|
54468
|
+
tools: Object.entries(BUILTIN_TOOL_CAPABILITY_METADATA).filter(([name]) => name !== "bash").map(([name, meta]) => ({
|
|
54458
54469
|
name,
|
|
54459
54470
|
...meta.riskClass ? { riskClass: meta.riskClass } : {},
|
|
54460
54471
|
...meta.permissionScope ? { permissionScope: meta.permissionScope } : {},
|
|
@@ -54478,7 +54489,7 @@ ${toolLines}
|
|
|
54478
54489
|
|
|
54479
54490
|
Disable or narrow capabilities:
|
|
54480
54491
|
- Start from a trusted cwd.
|
|
54481
|
-
- Use selected tools or extension policy to omit write_file, edit_file,
|
|
54492
|
+
- Use selected tools or extension policy to omit write_file, edit_file, the shell tool, or host-specific tools.
|
|
54482
54493
|
- Keep API keys in environment variables or ~/.pie/models.json, not in prompts.`;
|
|
54483
54494
|
}
|
|
54484
54495
|
|
|
@@ -56581,6 +56592,10 @@ function createExtensionContext(extension, cwd, uiContext, abortFn, isIdleFn, ha
|
|
|
56581
56592
|
if (!actions?.registerProvider) throw new Error("registerProvider is not available in this host mode");
|
|
56582
56593
|
return actions.registerProvider(name, config);
|
|
56583
56594
|
},
|
|
56595
|
+
registerHostEnvelopeProjector(projector) {
|
|
56596
|
+
if (!actions?.registerHostEnvelopeProjector) throw new Error("registerHostEnvelopeProjector is not available in this host mode");
|
|
56597
|
+
return actions.registerHostEnvelopeProjector(projector);
|
|
56598
|
+
},
|
|
56584
56599
|
async loginProvider(name) {
|
|
56585
56600
|
if (!actions?.loginProvider) throw new Error("loginProvider is not available in this host mode");
|
|
56586
56601
|
return actions.loginProvider(name);
|
|
@@ -64338,6 +64353,10 @@ var ExtensionRunner = class {
|
|
|
64338
64353
|
if (!runner.actions.registerProvider) throw new Error("registerProvider is not available in this host mode");
|
|
64339
64354
|
return runner.trackUnregisterHandle(runner.actions.registerProvider(name, config));
|
|
64340
64355
|
},
|
|
64356
|
+
registerHostEnvelopeProjector: (projector) => {
|
|
64357
|
+
if (!runner.actions.registerHostEnvelopeProjector) throw new Error("registerHostEnvelopeProjector is not available in this host mode");
|
|
64358
|
+
return runner.trackUnregisterHandle(runner.actions.registerHostEnvelopeProjector(projector));
|
|
64359
|
+
},
|
|
64341
64360
|
loginProvider: async (name) => {
|
|
64342
64361
|
if (!runner.actions.loginProvider) throw new Error("loginProvider is not available in this host mode");
|
|
64343
64362
|
return runner.actions.loginProvider(name);
|
|
@@ -72295,7 +72314,7 @@ ${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
|
|
|
72295
72314
|
${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
|
|
72296
72315
|
}
|
|
72297
72316
|
}
|
|
72298
|
-
} else if (this.toolName === "bash") {
|
|
72317
|
+
} else if (this.toolName === "bash" || this.toolName === "shell") {
|
|
72299
72318
|
const command = str(this.args?.command);
|
|
72300
72319
|
const timeout = this.args?.timeout;
|
|
72301
72320
|
const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
|
|
@@ -76118,14 +76137,15 @@ function handleHotkeysCommand(host) {
|
|
|
76118
76137
|
"",
|
|
76119
76138
|
theme.fg("muted", "Editor shortcuts:"),
|
|
76120
76139
|
" Enter Submit message",
|
|
76121
|
-
" Shift+Enter New line",
|
|
76140
|
+
" Shift+Enter New line (if ineffective, use Ctrl+J)",
|
|
76141
|
+
" Ctrl+J New line (fallback)",
|
|
76122
76142
|
` ${theme.fg("dim", kb.getKeys("steer").join(" / "))} ${theme.fg("muted", "Queue steering message for the active turn")}`,
|
|
76123
76143
|
` ${theme.fg("dim", kb.getKeys("dequeue").join(" / "))} ${theme.fg("muted", "Restore queued messages")}`,
|
|
76124
76144
|
" / Show slash commands",
|
|
76125
76145
|
" Esc Cancel autocomplete",
|
|
76126
76146
|
"",
|
|
76127
76147
|
theme.fg("muted", "Direct mode:"),
|
|
76128
|
-
" !!command Execute
|
|
76148
|
+
" !!command Execute a shell command (bypasses AI)",
|
|
76129
76149
|
"",
|
|
76130
76150
|
theme.bold(theme.fg("accent", "Slash Commands")),
|
|
76131
76151
|
"",
|
|
@@ -76659,6 +76679,369 @@ function renderCompactionDiffPanel(target, stats) {
|
|
|
76659
76679
|
target.safeRequestRender();
|
|
76660
76680
|
}
|
|
76661
76681
|
|
|
76682
|
+
// src/runtime/runtime-mode-context.ts
|
|
76683
|
+
var RUNTIME_MODE_ENVELOPE_KIND = "pie.runtimeMode";
|
|
76684
|
+
var RUNTIME_MODE_ENVELOPE_VERSION = 1;
|
|
76685
|
+
function runtimeModeEnvelopeRegistry() {
|
|
76686
|
+
return sharedRuntimeModeRegistry ??= createHostEnvelopeProjectorRegistry([{
|
|
76687
|
+
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
76688
|
+
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
76689
|
+
project: (data) => buildRuntimeModeContext(runtimeModeStateFromEnvelope(data))
|
|
76690
|
+
}]);
|
|
76691
|
+
}
|
|
76692
|
+
var sharedRuntimeModeRegistry;
|
|
76693
|
+
function runtimeModeStateFromEnvelope(data) {
|
|
76694
|
+
return {
|
|
76695
|
+
planMode: data.planMode === "planning" ? "planning" : "off",
|
|
76696
|
+
yoloMode: data.yoloMode === true,
|
|
76697
|
+
filesystemScope: data.filesystemScope === "all" ? "all" : "workspace",
|
|
76698
|
+
pendingTransition: typeof data.pendingTransition === "string" ? data.pendingTransition : void 0,
|
|
76699
|
+
activeToolNames: Array.isArray(data.activeToolNames) ? data.activeToolNames.filter((name) => typeof name === "string") : [],
|
|
76700
|
+
planDisabledToolNames: Array.isArray(data.planDisabledToolNames) ? data.planDisabledToolNames.filter((name) => typeof name === "string") : [],
|
|
76701
|
+
currentDate: typeof data.currentDate === "string" ? data.currentDate : void 0,
|
|
76702
|
+
timeZone: typeof data.timeZone === "string" ? data.timeZone : void 0
|
|
76703
|
+
};
|
|
76704
|
+
}
|
|
76705
|
+
function runtimeModeEnvelopeData(state) {
|
|
76706
|
+
return {
|
|
76707
|
+
planMode: state.planMode,
|
|
76708
|
+
yoloMode: state.yoloMode,
|
|
76709
|
+
filesystemScope: state.filesystemScope,
|
|
76710
|
+
...state.pendingTransition ? { pendingTransition: state.pendingTransition } : {},
|
|
76711
|
+
activeToolNames: [...state.activeToolNames],
|
|
76712
|
+
planDisabledToolNames: [...state.planDisabledToolNames],
|
|
76713
|
+
...state.currentDate ? { currentDate: state.currentDate } : {},
|
|
76714
|
+
...state.timeZone ? { timeZone: state.timeZone } : {}
|
|
76715
|
+
};
|
|
76716
|
+
}
|
|
76717
|
+
function runtimeModeEnvelopeBlock(state) {
|
|
76718
|
+
return {
|
|
76719
|
+
type: "hostContext",
|
|
76720
|
+
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
76721
|
+
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
76722
|
+
data: runtimeModeEnvelopeData(state)
|
|
76723
|
+
};
|
|
76724
|
+
}
|
|
76725
|
+
function isAgentMessage(value) {
|
|
76726
|
+
return !!value && typeof value === "object" && "role" in value;
|
|
76727
|
+
}
|
|
76728
|
+
function prependRuntimeModeBlockToPrompt(input, block) {
|
|
76729
|
+
if (!block) return input;
|
|
76730
|
+
if (typeof input === "string") {
|
|
76731
|
+
return [{ ...block }, { type: "text", text: input }];
|
|
76732
|
+
}
|
|
76733
|
+
if (Array.isArray(input)) {
|
|
76734
|
+
if (input.length > 0 && isAgentMessage(input[0])) {
|
|
76735
|
+
return prependBlockToMessages(input, block);
|
|
76736
|
+
}
|
|
76737
|
+
return [block, ...input];
|
|
76738
|
+
}
|
|
76739
|
+
if (isAgentMessage(input)) {
|
|
76740
|
+
return prependBlockToMessages([input], block)[0];
|
|
76741
|
+
}
|
|
76742
|
+
return [block, ...input];
|
|
76743
|
+
}
|
|
76744
|
+
function prependBlockToMessages(messages, block) {
|
|
76745
|
+
const next = [...messages];
|
|
76746
|
+
let target = -1;
|
|
76747
|
+
for (let index = next.length - 1; index >= 0; index--) {
|
|
76748
|
+
if (next[index]?.role === "user") {
|
|
76749
|
+
target = index;
|
|
76750
|
+
break;
|
|
76751
|
+
}
|
|
76752
|
+
}
|
|
76753
|
+
if (target < 0) {
|
|
76754
|
+
next.push({ role: "user", content: [block], timestamp: Date.now() });
|
|
76755
|
+
return next;
|
|
76756
|
+
}
|
|
76757
|
+
const message = next[target];
|
|
76758
|
+
if (Array.isArray(message.content)) {
|
|
76759
|
+
next[target] = { ...message, content: [block, ...message.content] };
|
|
76760
|
+
} else if (typeof message.content === "string") {
|
|
76761
|
+
next[target] = { ...message, content: [block, { type: "text", text: message.content }] };
|
|
76762
|
+
} else {
|
|
76763
|
+
next.splice(target, 0, { role: "user", content: [block], timestamp: Date.now() });
|
|
76764
|
+
}
|
|
76765
|
+
return next;
|
|
76766
|
+
}
|
|
76767
|
+
var RUNTIME_MODE_CONTEXT_MARKER = "<runtime-mode-context>";
|
|
76768
|
+
var RUNTIME_MODE_CONTEXT_END_MARKER = "</runtime-mode-context>";
|
|
76769
|
+
function buildRuntimeModeContext(state) {
|
|
76770
|
+
const lines = [
|
|
76771
|
+
RUNTIME_MODE_CONTEXT_MARKER,
|
|
76772
|
+
"Current runtime mode:"
|
|
76773
|
+
];
|
|
76774
|
+
if (state.planMode === "planning") {
|
|
76775
|
+
lines.push(
|
|
76776
|
+
"- Plan mode: active (workspace read-only; plan_scratch permits session-local temporary drafts; submit the finished plan by calling plan_submit with the ordered steps for user approval)."
|
|
76777
|
+
);
|
|
76778
|
+
if (state.planDisabledToolNames.length > 0) {
|
|
76779
|
+
lines.push(
|
|
76780
|
+
`- Disabled this turn by plan mode (calls are denied): ${state.planDisabledToolNames.join(", ")}. Do not call them while planning.`
|
|
76781
|
+
);
|
|
76782
|
+
}
|
|
76783
|
+
} else {
|
|
76784
|
+
lines.push("- Plan mode: off.");
|
|
76785
|
+
}
|
|
76786
|
+
lines.push(
|
|
76787
|
+
`- YOLO mode: ${state.yoloMode ? "on (filesystem sandbox directory restrictions are disabled)" : "off (workspace/protected-path restrictions apply)"}.`,
|
|
76788
|
+
`- Filesystem scope: ${state.filesystemScope === "all" ? "all local paths may be passed directly to file tools when permitted" : "workspace paths and configured safe roots only"}.`
|
|
76789
|
+
);
|
|
76790
|
+
if (state.pendingTransition) {
|
|
76791
|
+
const transitionText = {
|
|
76792
|
+
entered_yolo: "YOLO mode was just enabled for this turn.",
|
|
76793
|
+
exited_yolo: "YOLO mode was just disabled; do not assume previous absolute-path access still applies.",
|
|
76794
|
+
entered_plan: "Plan mode was just enabled; analyze and plan without changing the workspace. Use plan_scratch for temporary drafts, then submit the finished plan by calling plan_submit with the ordered steps for user approval.",
|
|
76795
|
+
exited_plan: "Plan mode was just disabled; execution tools may be used when the task requires them."
|
|
76796
|
+
};
|
|
76797
|
+
lines.push(`- Transition: ${transitionText[state.pendingTransition]}`);
|
|
76798
|
+
}
|
|
76799
|
+
if (state.currentDate) {
|
|
76800
|
+
lines.push(`- Current date: ${state.currentDate}${state.timeZone ? ` (${state.timeZone})` : ""}.`);
|
|
76801
|
+
}
|
|
76802
|
+
if (state.activeToolNames.length > 0) {
|
|
76803
|
+
lines.push(`- Active tools: ${state.activeToolNames.join(", ")}.`);
|
|
76804
|
+
}
|
|
76805
|
+
lines.push(RUNTIME_MODE_CONTEXT_END_MARKER);
|
|
76806
|
+
return lines.join("\n");
|
|
76807
|
+
}
|
|
76808
|
+
function runtimeModeBlockKey(state) {
|
|
76809
|
+
return JSON.stringify({
|
|
76810
|
+
planMode: state.planMode,
|
|
76811
|
+
yoloMode: state.yoloMode,
|
|
76812
|
+
filesystemScope: state.filesystemScope,
|
|
76813
|
+
currentDate: state.currentDate ?? null,
|
|
76814
|
+
activeToolNames: state.activeToolNames,
|
|
76815
|
+
planDisabledToolNames: state.planDisabledToolNames
|
|
76816
|
+
});
|
|
76817
|
+
}
|
|
76818
|
+
function shouldInjectRuntimeModeBlock(lastKey, state) {
|
|
76819
|
+
if (lastKey === null) return true;
|
|
76820
|
+
return runtimeModeBlockKey(state) !== lastKey;
|
|
76821
|
+
}
|
|
76822
|
+
function runtimeModeTraceData(state) {
|
|
76823
|
+
return {
|
|
76824
|
+
yoloMode: state.yoloMode,
|
|
76825
|
+
planMode: state.planMode,
|
|
76826
|
+
filesystemScope: state.filesystemScope,
|
|
76827
|
+
pendingTransition: state.pendingTransition,
|
|
76828
|
+
currentDate: state.currentDate,
|
|
76829
|
+
timeZone: state.timeZone,
|
|
76830
|
+
activeToolCount: state.activeToolNames.length,
|
|
76831
|
+
planDisabledToolCount: state.planDisabledToolNames.length
|
|
76832
|
+
};
|
|
76833
|
+
}
|
|
76834
|
+
function currentDateInZone(timeZone) {
|
|
76835
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
76836
|
+
year: "numeric",
|
|
76837
|
+
month: "2-digit",
|
|
76838
|
+
day: "2-digit",
|
|
76839
|
+
timeZone
|
|
76840
|
+
}).formatToParts(/* @__PURE__ */ new Date());
|
|
76841
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "00";
|
|
76842
|
+
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
76843
|
+
}
|
|
76844
|
+
var RUNTIME_MODE_BLOCK_START_MARKER = "<runtime-mode-context>";
|
|
76845
|
+
function leadingRuntimeBlock(text) {
|
|
76846
|
+
const withoutLeadingWhitespace = text.replace(/^[\t ]+/, "");
|
|
76847
|
+
if (!withoutLeadingWhitespace.startsWith(RUNTIME_MODE_BLOCK_START_MARKER)) return null;
|
|
76848
|
+
const markerStart = text.length - withoutLeadingWhitespace.length;
|
|
76849
|
+
const endIndex = text.indexOf(RUNTIME_MODE_CONTEXT_END_MARKER, markerStart);
|
|
76850
|
+
if (endIndex < 0) return null;
|
|
76851
|
+
const block = text.slice(markerStart, endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length);
|
|
76852
|
+
const rest = text.slice(endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length).replace(/^[\t ]*(?:\r?\n){0,2}/, "");
|
|
76853
|
+
return { block, rest };
|
|
76854
|
+
}
|
|
76855
|
+
function stripLeadingRuntimeBlock(text) {
|
|
76856
|
+
const leading = leadingRuntimeBlock(text);
|
|
76857
|
+
return leading ? { rest: leading.rest } : null;
|
|
76858
|
+
}
|
|
76859
|
+
function lastUserMessageCarriesEnvelopeBlock(messages, block) {
|
|
76860
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
76861
|
+
const message = messages[index];
|
|
76862
|
+
if (message?.role !== "user") continue;
|
|
76863
|
+
const content = message.content;
|
|
76864
|
+
if (!Array.isArray(content) || content.length === 0) return false;
|
|
76865
|
+
const first = content[0];
|
|
76866
|
+
return first?.type === "hostContext" && first.kind === block.kind && first.version === block.version && JSON.stringify(first.data) === JSON.stringify(block.data);
|
|
76867
|
+
}
|
|
76868
|
+
return false;
|
|
76869
|
+
}
|
|
76870
|
+
function refreshRuntimeModeBlockOnLastUserMessage(messages, block) {
|
|
76871
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
76872
|
+
const message = messages[i];
|
|
76873
|
+
if (message?.role !== "user") continue;
|
|
76874
|
+
const content = message.content;
|
|
76875
|
+
if (typeof content === "string") {
|
|
76876
|
+
const stripped = stripLeadingRuntimeBlock(content);
|
|
76877
|
+
const rest = stripped ? stripped.rest : content;
|
|
76878
|
+
if (!rest) {
|
|
76879
|
+
const copy2 = [...messages];
|
|
76880
|
+
copy2[i] = { ...message, content: [block] };
|
|
76881
|
+
return copy2;
|
|
76882
|
+
}
|
|
76883
|
+
const copy = [...messages];
|
|
76884
|
+
copy[i] = { ...message, content: [block, { type: "text", text: rest }] };
|
|
76885
|
+
return copy;
|
|
76886
|
+
}
|
|
76887
|
+
if (Array.isArray(content)) {
|
|
76888
|
+
const first = content[0];
|
|
76889
|
+
if (first?.type === "hostContext") {
|
|
76890
|
+
if (first === block) return messages;
|
|
76891
|
+
const copy2 = [...messages];
|
|
76892
|
+
const contentCopy = [...content];
|
|
76893
|
+
contentCopy[0] = block;
|
|
76894
|
+
copy2[i] = { ...message, content: contentCopy };
|
|
76895
|
+
return copy2;
|
|
76896
|
+
}
|
|
76897
|
+
let userBlocks = content;
|
|
76898
|
+
const firstText = content[0];
|
|
76899
|
+
if (firstText?.type === "text" && typeof firstText.text === "string") {
|
|
76900
|
+
const stripped = stripLeadingRuntimeBlock(firstText.text);
|
|
76901
|
+
if (stripped) {
|
|
76902
|
+
userBlocks = stripped.rest ? [{ type: "text", text: stripped.rest }, ...content.slice(1)] : content.slice(1);
|
|
76903
|
+
}
|
|
76904
|
+
}
|
|
76905
|
+
const copy = [...messages];
|
|
76906
|
+
copy[i] = { ...message, content: [block, ...userBlocks] };
|
|
76907
|
+
return copy;
|
|
76908
|
+
}
|
|
76909
|
+
return messages;
|
|
76910
|
+
}
|
|
76911
|
+
return messages;
|
|
76912
|
+
}
|
|
76913
|
+
var RuntimeModeBlockInjector = class {
|
|
76914
|
+
constructor(options) {
|
|
76915
|
+
this.options = options;
|
|
76916
|
+
}
|
|
76917
|
+
options;
|
|
76918
|
+
lastKey = null;
|
|
76919
|
+
/** Exact frozen envelope block, including its consumed one-shot transition. */
|
|
76920
|
+
lastFrozenBlock = null;
|
|
76921
|
+
/**
|
|
76922
|
+
* Request-view overlay. While active, the CURRENT block is re-derived on
|
|
76923
|
+
* every request from the live message snapshot and applied to the latest
|
|
76924
|
+
* user message. It is not cached into history and it ends only when a real
|
|
76925
|
+
* user message freezes the current block (see `nextBlock` + the transform),
|
|
76926
|
+
* so consecutive tool rounds after a compaction retry keep the fresh state
|
|
76927
|
+
* instead of losing it after one request.
|
|
76928
|
+
*/
|
|
76929
|
+
overlayActive = false;
|
|
76930
|
+
reset() {
|
|
76931
|
+
this.lastKey = null;
|
|
76932
|
+
this.lastFrozenBlock = null;
|
|
76933
|
+
this.overlayActive = true;
|
|
76934
|
+
}
|
|
76935
|
+
/**
|
|
76936
|
+
* Arm the request-view overlay without resetting the frozen-block key. Used
|
|
76937
|
+
* when the runtime shape changed while a turn is still running (compaction
|
|
76938
|
+
* checkpoint committed, plan approval, YOLO toggle inside a tool turn): the
|
|
76939
|
+
* next and subsequent model requests must see the current state even though
|
|
76940
|
+
* no new user message has been accepted yet.
|
|
76941
|
+
*/
|
|
76942
|
+
armRefresh() {
|
|
76943
|
+
this.overlayActive = true;
|
|
76944
|
+
}
|
|
76945
|
+
/**
|
|
76946
|
+
* Envelope block to prepend to the next user message, or null when
|
|
76947
|
+
* unchanged. Does NOT end the overlay: the block is only proof once the
|
|
76948
|
+
* message carrying it reaches the request transform.
|
|
76949
|
+
*/
|
|
76950
|
+
nextBlock() {
|
|
76951
|
+
return this.freshBlock();
|
|
76952
|
+
}
|
|
76953
|
+
/**
|
|
76954
|
+
* Current envelope block for a request that reuses existing history
|
|
76955
|
+
* (overflow retry after compaction, manual-compact continue, or the tool
|
|
76956
|
+
* rounds that follow a mid-turn mode change). Returns the same block for
|
|
76957
|
+
* every request until the latest user message itself carries that block;
|
|
76958
|
+
* then the overlay is retired and null is returned. Derivation is per
|
|
76959
|
+
* request from the given snapshot; no message array is cached.
|
|
76960
|
+
*/
|
|
76961
|
+
consumeRetryRefreshBlock(messages) {
|
|
76962
|
+
if (!this.overlayActive) return null;
|
|
76963
|
+
const state = this.options.getState();
|
|
76964
|
+
const block = runtimeModeEnvelopeBlock(state);
|
|
76965
|
+
const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
|
|
76966
|
+
if (messages && (lastUserMessageCarriesEnvelopeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesEnvelopeBlock(messages, frozenCurrent))) {
|
|
76967
|
+
this.overlayActive = false;
|
|
76968
|
+
return null;
|
|
76969
|
+
}
|
|
76970
|
+
return block;
|
|
76971
|
+
}
|
|
76972
|
+
freshBlock() {
|
|
76973
|
+
const state = this.options.getState();
|
|
76974
|
+
if (!shouldInjectRuntimeModeBlock(this.lastKey, state)) return null;
|
|
76975
|
+
this.lastKey = runtimeModeBlockKey(state);
|
|
76976
|
+
if (state.pendingTransition) this.options.consumeTransition();
|
|
76977
|
+
this.options.noteTrace(state);
|
|
76978
|
+
this.lastFrozenBlock = runtimeModeEnvelopeBlock(state);
|
|
76979
|
+
return this.lastFrozenBlock;
|
|
76980
|
+
}
|
|
76981
|
+
};
|
|
76982
|
+
|
|
76983
|
+
// src/runtime/host-envelope-registry.ts
|
|
76984
|
+
var sharedCliEnvelopeRegistry;
|
|
76985
|
+
function cliHostEnvelopeRegistry() {
|
|
76986
|
+
if (sharedCliEnvelopeRegistry) return sharedCliEnvelopeRegistry;
|
|
76987
|
+
sharedCliEnvelopeRegistry = createHostEnvelopeProjectorRegistry();
|
|
76988
|
+
for (const { kind, version } of runtimeModeEnvelopeRegistry().listPins()) {
|
|
76989
|
+
sharedCliEnvelopeRegistry.register({
|
|
76990
|
+
kind,
|
|
76991
|
+
version,
|
|
76992
|
+
project: (data) => runtimeModeEnvelopeRegistry().resolve(kind, version).project(data)
|
|
76993
|
+
});
|
|
76994
|
+
}
|
|
76995
|
+
return sharedCliEnvelopeRegistry;
|
|
76996
|
+
}
|
|
76997
|
+
function registerExternalHostEnvelopeProjector(projector) {
|
|
76998
|
+
cliHostEnvelopeRegistry().register(projector);
|
|
76999
|
+
return () => {
|
|
77000
|
+
};
|
|
77001
|
+
}
|
|
77002
|
+
function cliHostEnvelopeKinds() {
|
|
77003
|
+
return cliHostEnvelopeRegistry().listPins().map(({ kind, version }) => `${kind}@${version}`).sort();
|
|
77004
|
+
}
|
|
77005
|
+
function projectCliHostEnvelopes(messages) {
|
|
77006
|
+
return projectHostEnvelopes(messages, cliHostEnvelopeRegistry());
|
|
77007
|
+
}
|
|
77008
|
+
function isIntakeHostContextError(value) {
|
|
77009
|
+
return value.code !== void 0;
|
|
77010
|
+
}
|
|
77011
|
+
function intakeHostContextBlock(value) {
|
|
77012
|
+
if (!isHostContextBlock(value)) {
|
|
77013
|
+
return {
|
|
77014
|
+
ok: false,
|
|
77015
|
+
code: "host_context_invalid_shape",
|
|
77016
|
+
message: "hostContext must be { type: 'hostContext', kind: string, version: integer >= 1, data: object }"
|
|
77017
|
+
};
|
|
77018
|
+
}
|
|
77019
|
+
const block = value;
|
|
77020
|
+
const projector = cliHostEnvelopeRegistry().resolve(block.kind, block.version);
|
|
77021
|
+
if (!projector) {
|
|
77022
|
+
return {
|
|
77023
|
+
ok: false,
|
|
77024
|
+
code: "host_context_unknown_projector",
|
|
77025
|
+
message: `no projector for ${block.kind}@${block.version}; this build supports: ${cliHostEnvelopeKinds().join(", ")}`
|
|
77026
|
+
};
|
|
77027
|
+
}
|
|
77028
|
+
try {
|
|
77029
|
+
const text = projector.project(block.data);
|
|
77030
|
+
if (typeof text !== "string" || text.trim().length === 0) throw new Error("projector returned empty text");
|
|
77031
|
+
} catch (error) {
|
|
77032
|
+
return {
|
|
77033
|
+
ok: false,
|
|
77034
|
+
code: "host_context_unknown_projector",
|
|
77035
|
+
message: `projector for ${block.kind}@${block.version} rejected the data: ${error instanceof Error ? error.message : String(error)}`
|
|
77036
|
+
};
|
|
77037
|
+
}
|
|
77038
|
+
return { ok: true, block };
|
|
77039
|
+
}
|
|
77040
|
+
function intakeHostContextFailure(value) {
|
|
77041
|
+
const result = intakeHostContextBlock(value);
|
|
77042
|
+
return isIntakeHostContextError(result) ? { code: result.code, message: result.message } : void 0;
|
|
77043
|
+
}
|
|
77044
|
+
|
|
76662
77045
|
// src/commands/interactive-compact-command.ts
|
|
76663
77046
|
async function handleCompactCommand(host) {
|
|
76664
77047
|
if (host.submitLock || host.isProcessing || host.isCompacting) {
|
|
@@ -76712,7 +77095,7 @@ async function handleCompactCommand(host) {
|
|
|
76712
77095
|
if (beforeCompact?.summary) {
|
|
76713
77096
|
summary = beforeCompact.summary;
|
|
76714
77097
|
} else {
|
|
76715
|
-
summary = await createCompactionSummary(preparation.messages, compactOptions);
|
|
77098
|
+
summary = await createCompactionSummary(projectCliHostEnvelopes(preparation.messages), compactOptions);
|
|
76716
77099
|
}
|
|
76717
77100
|
const verified = verifyPreparedCompactionCommit({
|
|
76718
77101
|
preparation,
|
|
@@ -78884,9 +79267,7 @@ function queueMessage(host, text, mode, options = {}) {
|
|
|
78884
79267
|
const clearEditor = options.clearEditor ?? true;
|
|
78885
79268
|
host.sessionTrace.notePendingUserText(text);
|
|
78886
79269
|
const runtimeBlock = host.runtimeModeBlockForNextMessage?.();
|
|
78887
|
-
const content = runtimeBlock ?
|
|
78888
|
-
|
|
78889
|
-
${text}` : text;
|
|
79270
|
+
const content = runtimeBlock ? [runtimeBlock, { type: "text", text }] : [{ type: "text", text }];
|
|
78890
79271
|
void host.agentSessionController.prompt(
|
|
78891
79272
|
{ role: "user", content, timestamp: Date.now() },
|
|
78892
79273
|
{
|
|
@@ -79274,7 +79655,11 @@ When the user asks about Pie itself, its extensions, skills, TUI, model configur
|
|
|
79274
79655
|
function buildCliSystemPrompt(options) {
|
|
79275
79656
|
const tools = options.tools.map((tool) => ({
|
|
79276
79657
|
name: tool.name,
|
|
79277
|
-
description: ""
|
|
79658
|
+
description: "",
|
|
79659
|
+
// Metadata travels with the projection: the <tools> section resolves
|
|
79660
|
+
// policy from tool-carried metadata first, so a renamed tool cannot
|
|
79661
|
+
// silently disappear from the prompt.
|
|
79662
|
+
capabilityMetadata: tool.capabilityMetadata
|
|
79278
79663
|
}));
|
|
79279
79664
|
return [
|
|
79280
79665
|
options.customPrompt?.trim() || "You are Pie, a helpful AI coding assistant.",
|
|
@@ -79373,7 +79758,7 @@ async function createCliAutoCompactionResult(params) {
|
|
|
79373
79758
|
systemPrompt: params.systemPrompt,
|
|
79374
79759
|
signal: params.context.signal
|
|
79375
79760
|
};
|
|
79376
|
-
const summary = await createCompactionSummary(params.context.messages, compactOptions);
|
|
79761
|
+
const summary = await createCompactionSummary(projectCliHostEnvelopes(params.context.messages), compactOptions);
|
|
79377
79762
|
if (params.context.signal?.aborted) {
|
|
79378
79763
|
return { aborted: true };
|
|
79379
79764
|
}
|
|
@@ -79580,10 +79965,7 @@ function estimateMessageTokens(msg) {
|
|
|
79580
79965
|
return estimateTokens(msg);
|
|
79581
79966
|
}
|
|
79582
79967
|
function buildSystemPrompt(host) {
|
|
79583
|
-
const tools = (host.agent?.state?.tools ?? host.options.tools ?? []).filter((tool) => typeof tool.name === "string")
|
|
79584
|
-
name: tool.name,
|
|
79585
|
-
description: tool.description
|
|
79586
|
-
}));
|
|
79968
|
+
const tools = (host.agent?.state?.tools ?? host.options.tools ?? []).filter((tool) => typeof tool.name === "string");
|
|
79587
79969
|
return buildCliSystemPrompt({
|
|
79588
79970
|
cwd: host.options.cwd,
|
|
79589
79971
|
tools,
|
|
@@ -79593,7 +79975,7 @@ function buildSystemPrompt(host) {
|
|
|
79593
79975
|
}
|
|
79594
79976
|
function getAllToolNames(host) {
|
|
79595
79977
|
if (!host.agent?.state?.tools) {
|
|
79596
|
-
return [...CLI_FILESYSTEM_TOOL_NAMES, "
|
|
79978
|
+
return [...CLI_FILESYSTEM_TOOL_NAMES, "shell"];
|
|
79597
79979
|
}
|
|
79598
79980
|
return host.agent.state.tools.map((tool) => tool.name);
|
|
79599
79981
|
}
|
|
@@ -80594,277 +80976,6 @@ function createInteractiveAgentSessionController(host) {
|
|
|
80594
80976
|
});
|
|
80595
80977
|
}
|
|
80596
80978
|
|
|
80597
|
-
// src/runtime/runtime-mode-context.ts
|
|
80598
|
-
function isAgentMessage(value) {
|
|
80599
|
-
return !!value && typeof value === "object" && "role" in value;
|
|
80600
|
-
}
|
|
80601
|
-
function prependRuntimeModeBlockToPrompt(input, block) {
|
|
80602
|
-
if (!block) return input;
|
|
80603
|
-
if (typeof input === "string") {
|
|
80604
|
-
return input.trim() ? `${block}
|
|
80605
|
-
|
|
80606
|
-
${input}` : block;
|
|
80607
|
-
}
|
|
80608
|
-
if (Array.isArray(input)) {
|
|
80609
|
-
if (input.length > 0 && isAgentMessage(input[0])) {
|
|
80610
|
-
return prependBlockToMessages(input, block);
|
|
80611
|
-
}
|
|
80612
|
-
return [{ type: "text", text: block }, ...input];
|
|
80613
|
-
}
|
|
80614
|
-
if (isAgentMessage(input)) {
|
|
80615
|
-
return prependBlockToMessages([input], block)[0];
|
|
80616
|
-
}
|
|
80617
|
-
return [{ type: "text", text: block }, ...input];
|
|
80618
|
-
}
|
|
80619
|
-
function prependBlockToMessages(messages, block) {
|
|
80620
|
-
const next = [...messages];
|
|
80621
|
-
let target = -1;
|
|
80622
|
-
for (let index = next.length - 1; index >= 0; index--) {
|
|
80623
|
-
if (next[index]?.role === "user") {
|
|
80624
|
-
target = index;
|
|
80625
|
-
break;
|
|
80626
|
-
}
|
|
80627
|
-
}
|
|
80628
|
-
if (target < 0) {
|
|
80629
|
-
next.push({ role: "user", content: block, timestamp: Date.now() });
|
|
80630
|
-
return next;
|
|
80631
|
-
}
|
|
80632
|
-
const message = next[target];
|
|
80633
|
-
if (typeof message.content === "string") {
|
|
80634
|
-
next[target] = { ...message, content: `${block}
|
|
80635
|
-
|
|
80636
|
-
${message.content}` };
|
|
80637
|
-
} else if (Array.isArray(message.content)) {
|
|
80638
|
-
next[target] = { ...message, content: [{ type: "text", text: block }, ...message.content] };
|
|
80639
|
-
} else {
|
|
80640
|
-
next.splice(target, 0, { role: "user", content: block, timestamp: Date.now() });
|
|
80641
|
-
}
|
|
80642
|
-
return next;
|
|
80643
|
-
}
|
|
80644
|
-
var RUNTIME_MODE_CONTEXT_MARKER = "<runtime-mode-context>";
|
|
80645
|
-
var RUNTIME_MODE_CONTEXT_END_MARKER = "</runtime-mode-context>";
|
|
80646
|
-
function buildRuntimeModeContext(state) {
|
|
80647
|
-
const lines = [
|
|
80648
|
-
RUNTIME_MODE_CONTEXT_MARKER,
|
|
80649
|
-
"Current runtime mode:"
|
|
80650
|
-
];
|
|
80651
|
-
if (state.planMode === "planning") {
|
|
80652
|
-
lines.push(
|
|
80653
|
-
"- Plan mode: active (workspace read-only; plan_scratch permits session-local temporary drafts; submit the finished plan by calling plan_submit with the ordered steps for user approval)."
|
|
80654
|
-
);
|
|
80655
|
-
if (state.planDisabledToolNames.length > 0) {
|
|
80656
|
-
lines.push(
|
|
80657
|
-
`- Disabled this turn by plan mode (calls are denied): ${state.planDisabledToolNames.join(", ")}. Do not call them while planning.`
|
|
80658
|
-
);
|
|
80659
|
-
}
|
|
80660
|
-
} else {
|
|
80661
|
-
lines.push("- Plan mode: off.");
|
|
80662
|
-
}
|
|
80663
|
-
lines.push(
|
|
80664
|
-
`- YOLO mode: ${state.yoloMode ? "on (filesystem sandbox directory restrictions are disabled)" : "off (workspace/protected-path restrictions apply)"}.`,
|
|
80665
|
-
`- Filesystem scope: ${state.filesystemScope === "all" ? "all local paths may be passed directly to file tools when permitted" : "workspace paths and configured safe roots only"}.`
|
|
80666
|
-
);
|
|
80667
|
-
if (state.pendingTransition) {
|
|
80668
|
-
const transitionText = {
|
|
80669
|
-
entered_yolo: "YOLO mode was just enabled for this turn.",
|
|
80670
|
-
exited_yolo: "YOLO mode was just disabled; do not assume previous absolute-path access still applies.",
|
|
80671
|
-
entered_plan: "Plan mode was just enabled; analyze and plan without changing the workspace. Use plan_scratch for temporary drafts, then submit the finished plan by calling plan_submit with the ordered steps for user approval.",
|
|
80672
|
-
exited_plan: "Plan mode was just disabled; execution tools may be used when the task requires them."
|
|
80673
|
-
};
|
|
80674
|
-
lines.push(`- Transition: ${transitionText[state.pendingTransition]}`);
|
|
80675
|
-
}
|
|
80676
|
-
if (state.currentDate) {
|
|
80677
|
-
lines.push(`- Current date: ${state.currentDate}${state.timeZone ? ` (${state.timeZone})` : ""}.`);
|
|
80678
|
-
}
|
|
80679
|
-
if (state.activeToolNames.length > 0) {
|
|
80680
|
-
lines.push(`- Active tools: ${state.activeToolNames.join(", ")}.`);
|
|
80681
|
-
}
|
|
80682
|
-
lines.push(RUNTIME_MODE_CONTEXT_END_MARKER);
|
|
80683
|
-
return lines.join("\n");
|
|
80684
|
-
}
|
|
80685
|
-
function runtimeModeBlockKey(state) {
|
|
80686
|
-
return JSON.stringify({
|
|
80687
|
-
planMode: state.planMode,
|
|
80688
|
-
yoloMode: state.yoloMode,
|
|
80689
|
-
filesystemScope: state.filesystemScope,
|
|
80690
|
-
currentDate: state.currentDate ?? null,
|
|
80691
|
-
activeToolNames: state.activeToolNames,
|
|
80692
|
-
planDisabledToolNames: state.planDisabledToolNames
|
|
80693
|
-
});
|
|
80694
|
-
}
|
|
80695
|
-
function shouldInjectRuntimeModeBlock(lastKey, state) {
|
|
80696
|
-
if (lastKey === null) return true;
|
|
80697
|
-
return runtimeModeBlockKey(state) !== lastKey;
|
|
80698
|
-
}
|
|
80699
|
-
function runtimeModeTraceData(state) {
|
|
80700
|
-
return {
|
|
80701
|
-
yoloMode: state.yoloMode,
|
|
80702
|
-
planMode: state.planMode,
|
|
80703
|
-
filesystemScope: state.filesystemScope,
|
|
80704
|
-
pendingTransition: state.pendingTransition,
|
|
80705
|
-
currentDate: state.currentDate,
|
|
80706
|
-
timeZone: state.timeZone,
|
|
80707
|
-
activeToolCount: state.activeToolNames.length,
|
|
80708
|
-
planDisabledToolCount: state.planDisabledToolNames.length
|
|
80709
|
-
};
|
|
80710
|
-
}
|
|
80711
|
-
function currentDateInZone(timeZone) {
|
|
80712
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
80713
|
-
year: "numeric",
|
|
80714
|
-
month: "2-digit",
|
|
80715
|
-
day: "2-digit",
|
|
80716
|
-
timeZone
|
|
80717
|
-
}).formatToParts(/* @__PURE__ */ new Date());
|
|
80718
|
-
const part = (type) => parts.find((p) => p.type === type)?.value ?? "00";
|
|
80719
|
-
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
80720
|
-
}
|
|
80721
|
-
var RUNTIME_MODE_BLOCK_START_MARKER = "<runtime-mode-context>";
|
|
80722
|
-
function leadingRuntimeBlock(text) {
|
|
80723
|
-
const withoutLeadingWhitespace = text.replace(/^[\t ]+/, "");
|
|
80724
|
-
if (!withoutLeadingWhitespace.startsWith(RUNTIME_MODE_BLOCK_START_MARKER)) return null;
|
|
80725
|
-
const markerStart = text.length - withoutLeadingWhitespace.length;
|
|
80726
|
-
const endIndex = text.indexOf(RUNTIME_MODE_CONTEXT_END_MARKER, markerStart);
|
|
80727
|
-
if (endIndex < 0) return null;
|
|
80728
|
-
const block = text.slice(markerStart, endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length);
|
|
80729
|
-
const rest = text.slice(endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length).replace(/^[\t ]*(?:\r?\n){0,2}/, "");
|
|
80730
|
-
return { block, rest };
|
|
80731
|
-
}
|
|
80732
|
-
function stripLeadingRuntimeBlock(text) {
|
|
80733
|
-
const leading = leadingRuntimeBlock(text);
|
|
80734
|
-
return leading ? { rest: leading.rest } : null;
|
|
80735
|
-
}
|
|
80736
|
-
function leadingRuntimeBlockOfMessage(message) {
|
|
80737
|
-
if (message.role !== "user") return null;
|
|
80738
|
-
const content = message.content;
|
|
80739
|
-
if (typeof content === "string") return leadingRuntimeBlock(content)?.block ?? null;
|
|
80740
|
-
if (!Array.isArray(content)) return null;
|
|
80741
|
-
const first = content[0];
|
|
80742
|
-
if (first?.type !== "text" || typeof first.text !== "string") return null;
|
|
80743
|
-
return leadingRuntimeBlock(first.text)?.block ?? null;
|
|
80744
|
-
}
|
|
80745
|
-
function lastUserMessageCarriesRuntimeBlock(messages, block) {
|
|
80746
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
80747
|
-
const message = messages[index];
|
|
80748
|
-
if (message?.role !== "user") continue;
|
|
80749
|
-
return leadingRuntimeBlockOfMessage(message) === block;
|
|
80750
|
-
}
|
|
80751
|
-
return false;
|
|
80752
|
-
}
|
|
80753
|
-
function applyRuntimeBlockToText(text, block) {
|
|
80754
|
-
const split = stripLeadingRuntimeBlock(text);
|
|
80755
|
-
const rest = split ? split.rest : text;
|
|
80756
|
-
const next = rest.length > 0 ? `${block}
|
|
80757
|
-
|
|
80758
|
-
${rest}` : block;
|
|
80759
|
-
return next === text ? text : next;
|
|
80760
|
-
}
|
|
80761
|
-
function applyRuntimeBlockToContentArray(content, block) {
|
|
80762
|
-
const first = content[0];
|
|
80763
|
-
if (first && typeof first === "object" && first.type === "text" && typeof first.text === "string") {
|
|
80764
|
-
const text = first.text;
|
|
80765
|
-
if (stripLeadingRuntimeBlock(text)) {
|
|
80766
|
-
const nextText = applyRuntimeBlockToText(text, block);
|
|
80767
|
-
if (nextText === text) return content;
|
|
80768
|
-
const copy = [...content];
|
|
80769
|
-
copy[0] = { ...first, text: nextText };
|
|
80770
|
-
return copy;
|
|
80771
|
-
}
|
|
80772
|
-
}
|
|
80773
|
-
return [{ type: "text", text: block }, ...content];
|
|
80774
|
-
}
|
|
80775
|
-
function refreshRuntimeModeBlockOnLastUserMessage(messages, block) {
|
|
80776
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
80777
|
-
const message = messages[i];
|
|
80778
|
-
if (message?.role !== "user") continue;
|
|
80779
|
-
const content = message.content;
|
|
80780
|
-
if (typeof content === "string") {
|
|
80781
|
-
const next = applyRuntimeBlockToText(content, block);
|
|
80782
|
-
if (next === content) return messages;
|
|
80783
|
-
const copy = [...messages];
|
|
80784
|
-
copy[i] = { ...message, content: next };
|
|
80785
|
-
return copy;
|
|
80786
|
-
}
|
|
80787
|
-
if (Array.isArray(content)) {
|
|
80788
|
-
const next = applyRuntimeBlockToContentArray(content, block);
|
|
80789
|
-
if (next === content) return messages;
|
|
80790
|
-
const copy = [...messages];
|
|
80791
|
-
copy[i] = { ...message, content: next };
|
|
80792
|
-
return copy;
|
|
80793
|
-
}
|
|
80794
|
-
return messages;
|
|
80795
|
-
}
|
|
80796
|
-
return messages;
|
|
80797
|
-
}
|
|
80798
|
-
var RuntimeModeBlockInjector = class {
|
|
80799
|
-
constructor(options) {
|
|
80800
|
-
this.options = options;
|
|
80801
|
-
}
|
|
80802
|
-
options;
|
|
80803
|
-
lastKey = null;
|
|
80804
|
-
/** Exact frozen block, including its consumed one-shot transition. */
|
|
80805
|
-
lastFrozenBlock = null;
|
|
80806
|
-
/**
|
|
80807
|
-
* Request-view overlay. While active, the CURRENT block is re-derived on
|
|
80808
|
-
* every request from the live message snapshot and applied to the latest
|
|
80809
|
-
* user message. It is not cached into history and it ends only when a real
|
|
80810
|
-
* user message freezes the current block (see `nextBlock` + the transform),
|
|
80811
|
-
* so consecutive tool rounds after a compaction retry keep the fresh state
|
|
80812
|
-
* instead of losing it after one request.
|
|
80813
|
-
*/
|
|
80814
|
-
overlayActive = false;
|
|
80815
|
-
reset() {
|
|
80816
|
-
this.lastKey = null;
|
|
80817
|
-
this.lastFrozenBlock = null;
|
|
80818
|
-
this.overlayActive = true;
|
|
80819
|
-
}
|
|
80820
|
-
/**
|
|
80821
|
-
* Arm the request-view overlay without resetting the frozen-block key. Used
|
|
80822
|
-
* when the runtime shape changed while a turn is still running (compaction
|
|
80823
|
-
* checkpoint committed, plan approval, YOLO toggle inside a tool turn): the
|
|
80824
|
-
* next and subsequent model requests must see the current state even though
|
|
80825
|
-
* no new user message has been accepted yet.
|
|
80826
|
-
*/
|
|
80827
|
-
armRefresh() {
|
|
80828
|
-
this.overlayActive = true;
|
|
80829
|
-
}
|
|
80830
|
-
/**
|
|
80831
|
-
* Block to prepend to the next user message, or null when unchanged. Does
|
|
80832
|
-
* NOT end the overlay: the block is only proof once the message carrying it
|
|
80833
|
-
* reaches the request transform.
|
|
80834
|
-
*/
|
|
80835
|
-
nextBlock() {
|
|
80836
|
-
return this.freshBlock();
|
|
80837
|
-
}
|
|
80838
|
-
/**
|
|
80839
|
-
* Current block for a request that reuses existing history (overflow retry
|
|
80840
|
-
* after compaction, manual-compact continue, or the tool rounds that follow
|
|
80841
|
-
* a mid-turn mode change). Returns the same block for every request until
|
|
80842
|
-
* the latest user message itself carries that block; then the overlay is
|
|
80843
|
-
* retired and null is returned. Derivation is per request from the given
|
|
80844
|
-
* snapshot; no message array is cached.
|
|
80845
|
-
*/
|
|
80846
|
-
consumeRetryRefreshBlock(messages) {
|
|
80847
|
-
if (!this.overlayActive) return null;
|
|
80848
|
-
const state = this.options.getState();
|
|
80849
|
-
const block = buildRuntimeModeContext(state);
|
|
80850
|
-
const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
|
|
80851
|
-
if (messages && (lastUserMessageCarriesRuntimeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesRuntimeBlock(messages, frozenCurrent))) {
|
|
80852
|
-
this.overlayActive = false;
|
|
80853
|
-
return null;
|
|
80854
|
-
}
|
|
80855
|
-
return block;
|
|
80856
|
-
}
|
|
80857
|
-
freshBlock() {
|
|
80858
|
-
const state = this.options.getState();
|
|
80859
|
-
if (!shouldInjectRuntimeModeBlock(this.lastKey, state)) return null;
|
|
80860
|
-
this.lastKey = runtimeModeBlockKey(state);
|
|
80861
|
-
if (state.pendingTransition) this.options.consumeTransition();
|
|
80862
|
-
this.options.noteTrace(state);
|
|
80863
|
-
this.lastFrozenBlock = buildRuntimeModeContext(state);
|
|
80864
|
-
return this.lastFrozenBlock;
|
|
80865
|
-
}
|
|
80866
|
-
};
|
|
80867
|
-
|
|
80868
80979
|
// src/runtime/cache-retention.ts
|
|
80869
80980
|
function createCacheRetentionStreamFn(configured, getConfiguredRetention) {
|
|
80870
80981
|
const base = configured ?? ((model, context, options) => streamSimple(model, context, options));
|
|
@@ -81727,6 +81838,7 @@ async function loadInteractiveExtensions(host) {
|
|
|
81727
81838
|
host.noteRuntimeModeChanged("extension_register_provider");
|
|
81728
81839
|
return unregister;
|
|
81729
81840
|
},
|
|
81841
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
81730
81842
|
loginProvider: async (name) => {
|
|
81731
81843
|
const loggedIn = await loginExtensionProvider({
|
|
81732
81844
|
provider: name,
|
|
@@ -81860,7 +81972,7 @@ var InteractiveMode = class {
|
|
|
81860
81972
|
pendingYoloModeTransition = null;
|
|
81861
81973
|
executionReminder = null;
|
|
81862
81974
|
pendingRuntimeGuardAdvisory = null;
|
|
81863
|
-
/** Freezes runtime mode blocks into user messages (cache-stable history). */
|
|
81975
|
+
/** Freezes runtime mode envelope blocks into user messages (cache-stable history). */
|
|
81864
81976
|
runtimeModeBlocks = new RuntimeModeBlockInjector({
|
|
81865
81977
|
getState: () => this.getRuntimeModeState(),
|
|
81866
81978
|
consumeTransition: () => this.consumeRuntimeModeTransition(),
|
|
@@ -82037,7 +82149,7 @@ var InteractiveMode = class {
|
|
|
82037
82149
|
});
|
|
82038
82150
|
rebuildSkillAwareTools(sourceTools) {
|
|
82039
82151
|
const preservedTools = sourceTools.filter(
|
|
82040
|
-
(tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name) && tool.name !== "bash"
|
|
82152
|
+
(tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name) && tool.name !== "bash" && tool.name !== "shell"
|
|
82041
82153
|
);
|
|
82042
82154
|
const bashTool = createBashTool(this.options.cwd, { isYoloMode: () => this.yoloMode, getEnv: () => computerUseOwnerEnv(this.sessionManager.getActiveSessionId() || COMPUTER_USE_STANDALONE_OWNER, String(process.pid)) });
|
|
82043
82155
|
const fileSystemToolOptions = (allowlistedDirs) => ({
|
|
@@ -82092,16 +82204,13 @@ var InteractiveMode = class {
|
|
|
82092
82204
|
resetRuntimeModeBlocks() {
|
|
82093
82205
|
this.runtimeModeBlocks.reset();
|
|
82094
82206
|
}
|
|
82095
|
-
/** Runtime mode block for the next user message; frozen into it (append-only history, cache-stable prefixes). */
|
|
82207
|
+
/** Runtime mode envelope block for the next user message; frozen into it (append-only history, cache-stable prefixes). */
|
|
82096
82208
|
runtimeModeBlockForNextMessage() {
|
|
82097
82209
|
return this.runtimeModeBlocks.nextBlock();
|
|
82098
82210
|
}
|
|
82099
82211
|
getPendingRuntimeModeTransition() {
|
|
82100
|
-
|
|
82101
|
-
|
|
82102
|
-
if (this.pendingPlanModeTransition === "enter") return "entered_plan";
|
|
82103
|
-
if (this.pendingPlanModeTransition === "exit") return "exited_plan";
|
|
82104
|
-
return void 0;
|
|
82212
|
+
const yolo = this.pendingYoloModeTransition === "enter" ? "entered_yolo" : this.pendingYoloModeTransition === "exit" ? "exited_yolo" : void 0;
|
|
82213
|
+
return yolo ?? (this.pendingPlanModeTransition === "enter" ? "entered_plan" : this.pendingPlanModeTransition === "exit" ? "exited_plan" : void 0);
|
|
82105
82214
|
}
|
|
82106
82215
|
consumeRuntimeModeTransition() {
|
|
82107
82216
|
this.pendingYoloModeTransition = null;
|
|
@@ -82190,7 +82299,7 @@ var InteractiveMode = class {
|
|
|
82190
82299
|
async init() {
|
|
82191
82300
|
const activeSession = this.sessionManager.getActiveSession();
|
|
82192
82301
|
this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
|
|
82193
|
-
const { Agent } = await import("./chunks/src-
|
|
82302
|
+
const { Agent } = await import("./chunks/src-C2CBPEUY.js");
|
|
82194
82303
|
this.agent = new Agent({
|
|
82195
82304
|
initialState: {
|
|
82196
82305
|
systemPrompt: this.buildSystemPrompt(),
|
|
@@ -82201,14 +82310,21 @@ var InteractiveMode = class {
|
|
|
82201
82310
|
apiKey: this.options.apiKey,
|
|
82202
82311
|
sessionId: activeSession?.id,
|
|
82203
82312
|
streamFn: createTransportDiagnosticsStreamFn(createCacheRetentionStreamFn(this.options.streamFn, () => this.options.settingsManager.getPromptCacheRetention()), createTraceTransportSink((type, meta) => this.sessionTrace.noteRuntimeEvent(type, meta))),
|
|
82204
|
-
transformContext: async (messages) =>
|
|
82205
|
-
|
|
82206
|
-
|
|
82207
|
-
|
|
82208
|
-
|
|
82209
|
-
|
|
82210
|
-
|
|
82211
|
-
|
|
82313
|
+
transformContext: async (messages) => {
|
|
82314
|
+
const structured = applyRuntimeRequestTransform(messages, {
|
|
82315
|
+
takeAdvisory: () => {
|
|
82316
|
+
const advisory = this.pendingRuntimeGuardAdvisory;
|
|
82317
|
+
this.pendingRuntimeGuardAdvisory = null;
|
|
82318
|
+
return advisory;
|
|
82319
|
+
},
|
|
82320
|
+
takeRetryBlock: (snapshot) => this.runtimeModeBlocks.consumeRetryRefreshBlock(snapshot)
|
|
82321
|
+
});
|
|
82322
|
+
return projectHostEnvelopes(
|
|
82323
|
+
structured,
|
|
82324
|
+
cliHostEnvelopeRegistry(),
|
|
82325
|
+
(outcome) => this.sessionTrace.noteRuntimeEvent(outcome.degraded ? "host_envelope_degraded" : "host_envelope_projected", outcome.audit)
|
|
82326
|
+
);
|
|
82327
|
+
}
|
|
82212
82328
|
});
|
|
82213
82329
|
this.agentSessionController = createInteractiveAgentSessionController(this.controllerSetupHost);
|
|
82214
82330
|
this.updateTerminalTitle();
|
|
@@ -82995,6 +83111,7 @@ async function loadPrintModeExtensions(params) {
|
|
|
82995
83111
|
setSessionName: (name) => params.sessionManager.setSessionName(name),
|
|
82996
83112
|
getSessionName: () => params.sessionManager.getSessionName(),
|
|
82997
83113
|
registerProvider: (name, config) => params.modelRegistry.registerProvider(name, config),
|
|
83114
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
82998
83115
|
loginProvider: (name) => loginExtensionProvider({
|
|
82999
83116
|
provider: name,
|
|
83000
83117
|
modelRegistry: params.modelRegistry,
|
|
@@ -83049,7 +83166,7 @@ async function runPrintMode(params) {
|
|
|
83049
83166
|
`);
|
|
83050
83167
|
console.log("Assistant: ");
|
|
83051
83168
|
}
|
|
83052
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
83169
|
+
const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
|
|
83053
83170
|
let agent;
|
|
83054
83171
|
const printModeExtensions = await loadPrintModeExtensions({
|
|
83055
83172
|
cwd: runtime.cwd,
|
|
@@ -83082,7 +83199,7 @@ async function runPrintMode(params) {
|
|
|
83082
83199
|
cwd: runtime.cwd,
|
|
83083
83200
|
skillsSection: runtime.skillsSection,
|
|
83084
83201
|
knowledgeSection: runtime.knowledgeSection,
|
|
83085
|
-
tools: printModeTools
|
|
83202
|
+
tools: printModeTools
|
|
83086
83203
|
});
|
|
83087
83204
|
const printThinkingLevel = resolveInitialThinkingLevel({ session: runtime.sessionManager.getActiveSession(), settingsManager: runtime.settingsManager });
|
|
83088
83205
|
agent = new AgentClass({
|
|
@@ -83093,6 +83210,12 @@ async function runPrintMode(params) {
|
|
|
83093
83210
|
thinkingLevel: printThinkingLevel
|
|
83094
83211
|
},
|
|
83095
83212
|
apiKey: runtime.apiKey,
|
|
83213
|
+
// Print mode restores interactive sessions verbatim (AgentSessionController
|
|
83214
|
+
// loads stored history on construction). Those sessions carry persisted
|
|
83215
|
+
// hostContext facts; project them to model-visible text or the provider
|
|
83216
|
+
// converters reject the request (`Unprojected hostContext block`). The
|
|
83217
|
+
// persisted history is never rewritten — projection builds the wire view.
|
|
83218
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
83096
83219
|
// Body-free transport timeline for the main (print-mode) agent.
|
|
83097
83220
|
streamFn: createTransportDiagnosticsStreamFn(params.streamFn ?? streamSimple, logTransportLifecycle)
|
|
83098
83221
|
});
|
|
@@ -83336,14 +83459,17 @@ function parseInput(line) {
|
|
|
83336
83459
|
};
|
|
83337
83460
|
}
|
|
83338
83461
|
if (parsed.type === "sidechat.request" && typeof parsed.requestId === "string" && typeof parsed.prompt === "string") {
|
|
83462
|
+
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
83339
83463
|
return {
|
|
83340
83464
|
type: "sidechat.request",
|
|
83341
83465
|
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
83342
83466
|
requestId: parsed.requestId,
|
|
83343
|
-
prompt: parsed.prompt
|
|
83467
|
+
prompt: parsed.prompt,
|
|
83468
|
+
hostContext: parsed.hostContext
|
|
83344
83469
|
};
|
|
83345
83470
|
}
|
|
83346
83471
|
if ((parsed.type === "turn.request" || parsed.type === "turn.input") && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
|
|
83472
|
+
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
83347
83473
|
const streamingBehavior = parsed.streamingBehavior;
|
|
83348
83474
|
if (streamingBehavior !== void 0 && streamingBehavior !== "steer" && streamingBehavior !== "followUp") {
|
|
83349
83475
|
return null;
|
|
@@ -83353,6 +83479,7 @@ function parseInput(line) {
|
|
|
83353
83479
|
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
83354
83480
|
turnId: parsed.turnId,
|
|
83355
83481
|
prompt: parsed.prompt,
|
|
83482
|
+
hostContext: parsed.hostContext,
|
|
83356
83483
|
streamingBehavior,
|
|
83357
83484
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
|
|
83358
83485
|
metadata: isRecord3(parsed.metadata) ? parsed.metadata : void 0
|
|
@@ -83461,6 +83588,7 @@ async function loadJsonModeExtensions(params) {
|
|
|
83461
83588
|
getRuntimeTools: () => params.getAgent()?.state.tools ?? [],
|
|
83462
83589
|
resolveModelClass: (modelClass) => params.runtime.modelRegistry.resolveModelClass(modelClass),
|
|
83463
83590
|
resolveModelRef: (modelRef) => params.runtime.modelRegistry.resolveModelRef(modelRef),
|
|
83591
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
83464
83592
|
getMessages: () => params.getAgent()?.state.messages ?? [],
|
|
83465
83593
|
getSessionMetadata: () => ({ ...params.runtime.sessionManager.getActiveSession()?.metadata ?? {} }),
|
|
83466
83594
|
setSessionMetadata: (key, value) => {
|
|
@@ -83535,7 +83663,14 @@ async function runJsonEventsMode(params) {
|
|
|
83535
83663
|
const prewarmTimeoutMs = Number(process.env.PIE_JSON_EVENTS_PREWARM_TIMEOUT_MS || 1e4);
|
|
83536
83664
|
const sidechatTimeoutMs = Number(process.env.PIE_JSON_EVENTS_SIDECHAT_TIMEOUT_MS || 3e5);
|
|
83537
83665
|
await prewarmRuntime();
|
|
83538
|
-
writeEvent({
|
|
83666
|
+
writeEvent({
|
|
83667
|
+
type: "agent.ready",
|
|
83668
|
+
sessionId,
|
|
83669
|
+
// Capability broadcast: the envelope kinds THIS build can project at
|
|
83670
|
+
// intake (embedded external kinds included), so embedders can probe
|
|
83671
|
+
// before their first turn instead of learning mismatches from failures.
|
|
83672
|
+
capabilities: { hostContextKinds: cliHostEnvelopeKinds() }
|
|
83673
|
+
});
|
|
83539
83674
|
function trackSidechatPromise(promise) {
|
|
83540
83675
|
activeSidechatPromise = promise;
|
|
83541
83676
|
void promise.finally(() => {
|
|
@@ -83637,7 +83772,7 @@ async function runJsonEventsMode(params) {
|
|
|
83637
83772
|
timestamp: startedAt,
|
|
83638
83773
|
message: {
|
|
83639
83774
|
role: "user",
|
|
83640
|
-
content: message.prompt,
|
|
83775
|
+
content: message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : message.prompt,
|
|
83641
83776
|
timestamp: startedAt
|
|
83642
83777
|
}
|
|
83643
83778
|
};
|
|
@@ -83850,6 +83985,11 @@ async function runJsonEventsMode(params) {
|
|
|
83850
83985
|
});
|
|
83851
83986
|
}
|
|
83852
83987
|
async function handleSidechat(message) {
|
|
83988
|
+
const hostContextFailure = validateIntakeHostContext(message);
|
|
83989
|
+
if (hostContextFailure) {
|
|
83990
|
+
writeSidechatFailure(message, hostContextFailure.message, hostContextFailure.code);
|
|
83991
|
+
return;
|
|
83992
|
+
}
|
|
83853
83993
|
if (isSessionMismatch(message)) {
|
|
83854
83994
|
writeSidechatFailure(message, sessionMismatchError(message.sessionId), "session_mismatch");
|
|
83855
83995
|
return;
|
|
@@ -83905,7 +84045,7 @@ async function runJsonEventsMode(params) {
|
|
|
83905
84045
|
return;
|
|
83906
84046
|
}
|
|
83907
84047
|
const parent = agent;
|
|
83908
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
84048
|
+
const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
|
|
83909
84049
|
const sideAgent = new AgentClass({
|
|
83910
84050
|
initialState: {
|
|
83911
84051
|
systemPrompt: parent.state.systemPrompt,
|
|
@@ -83915,6 +84055,9 @@ async function runJsonEventsMode(params) {
|
|
|
83915
84055
|
messages: structuredClone(parent.state.messages)
|
|
83916
84056
|
},
|
|
83917
84057
|
apiKey: runtime.apiKey,
|
|
84058
|
+
// The sidechat snapshot clones the parent's stored history, including
|
|
84059
|
+
// persisted hostContext facts; project them like the main agent does.
|
|
84060
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
83918
84061
|
// Same body-free transport timeline as the main agent: a sidechat is
|
|
83919
84062
|
// an independent Responses request and previously had no record at all
|
|
83920
84063
|
// when it stalled. `streamSimple` matches the host default when the
|
|
@@ -83928,7 +84071,7 @@ async function runJsonEventsMode(params) {
|
|
|
83928
84071
|
}, sidechatTimeoutMs);
|
|
83929
84072
|
timer.unref?.();
|
|
83930
84073
|
try {
|
|
83931
|
-
await sideAgent.prompt(message
|
|
84074
|
+
await sideAgent.prompt(sidechatPromptBlocks(message));
|
|
83932
84075
|
} finally {
|
|
83933
84076
|
clearTimeout(timer);
|
|
83934
84077
|
}
|
|
@@ -84259,7 +84402,7 @@ async function runJsonEventsMode(params) {
|
|
|
84259
84402
|
if (runtime.initialModel.unconfigured || controller) {
|
|
84260
84403
|
return;
|
|
84261
84404
|
}
|
|
84262
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
84405
|
+
const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
|
|
84263
84406
|
if (runtimeClosing) return;
|
|
84264
84407
|
const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
|
|
84265
84408
|
if (runtimeClosing) {
|
|
@@ -84286,7 +84429,7 @@ async function runJsonEventsMode(params) {
|
|
|
84286
84429
|
skillsSection: runtime.skillsSection,
|
|
84287
84430
|
knowledgeSection: runtime.knowledgeSection,
|
|
84288
84431
|
appendSystemPrompt: params.developerInstructions,
|
|
84289
|
-
tools
|
|
84432
|
+
tools
|
|
84290
84433
|
});
|
|
84291
84434
|
agent = new AgentClass({
|
|
84292
84435
|
initialState: {
|
|
@@ -84296,6 +84439,10 @@ async function runJsonEventsMode(params) {
|
|
|
84296
84439
|
thinkingLevel
|
|
84297
84440
|
},
|
|
84298
84441
|
apiKey: runtime.apiKey,
|
|
84442
|
+
// Restored interactive sessions carry persisted hostContext facts; project
|
|
84443
|
+
// them to model-visible text at the request boundary or the provider
|
|
84444
|
+
// converters reject the request (`Unprojected hostContext block`).
|
|
84445
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
84299
84446
|
// Body-free transport timeline for the main (JSON-events) agent.
|
|
84300
84447
|
streamFn: createJsonEventsTransportStreamFn(params.streamFn)
|
|
84301
84448
|
});
|
|
@@ -84429,7 +84576,27 @@ async function runJsonEventsMode(params) {
|
|
|
84429
84576
|
syncSessionModelMetadata(runtime.sessionManager, runtime.model, thinkingLevel);
|
|
84430
84577
|
}
|
|
84431
84578
|
}
|
|
84579
|
+
function promptInputFor(message) {
|
|
84580
|
+
return message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : message.prompt;
|
|
84581
|
+
}
|
|
84582
|
+
function sidechatPromptBlocks(message) {
|
|
84583
|
+
return message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : [{ type: "text", text: message.prompt }];
|
|
84584
|
+
}
|
|
84585
|
+
function validateIntakeHostContext(message) {
|
|
84586
|
+
return message.hostContext ? intakeHostContextFailure(message.hostContext) : void 0;
|
|
84587
|
+
}
|
|
84432
84588
|
async function runTurn(message) {
|
|
84589
|
+
const hostContextFailure = validateIntakeHostContext(message);
|
|
84590
|
+
if (hostContextFailure) {
|
|
84591
|
+
writeEvent({
|
|
84592
|
+
type: "turn.failed",
|
|
84593
|
+
sessionId,
|
|
84594
|
+
turnId: message.turnId,
|
|
84595
|
+
error: hostContextFailure.message,
|
|
84596
|
+
...hostContextFailure.code === "host_context_unknown_projector" ? { hostContextKinds: cliHostEnvelopeKinds() } : {}
|
|
84597
|
+
});
|
|
84598
|
+
return;
|
|
84599
|
+
}
|
|
84433
84600
|
if (isSessionMismatch(message)) {
|
|
84434
84601
|
writeEvent({
|
|
84435
84602
|
type: "turn.failed",
|
|
@@ -84527,7 +84694,7 @@ async function runJsonEventsMode(params) {
|
|
|
84527
84694
|
try {
|
|
84528
84695
|
trace?.notePendingUserText(message.prompt);
|
|
84529
84696
|
trace?.noteDispatchStart({ mode: "json-events" });
|
|
84530
|
-
await controller.prompt(message
|
|
84697
|
+
await controller.prompt(promptInputFor(message), { source: "json-events" });
|
|
84531
84698
|
trace?.noteDispatchSettled({ mode: "json-events" });
|
|
84532
84699
|
trace?.noteWaitForIdleStart({ mode: "json-events" });
|
|
84533
84700
|
await controller.waitForSettled();
|
|
@@ -84592,7 +84759,7 @@ async function runJsonEventsMode(params) {
|
|
|
84592
84759
|
mode: message.streamingBehavior,
|
|
84593
84760
|
turnId: message.turnId
|
|
84594
84761
|
});
|
|
84595
|
-
await activeController.prompt(message
|
|
84762
|
+
await activeController.prompt(promptInputFor(message), {
|
|
84596
84763
|
source: "json-events",
|
|
84597
84764
|
streamingBehavior: message.streamingBehavior,
|
|
84598
84765
|
displayText: message.prompt,
|
|
@@ -84797,6 +84964,8 @@ Commands:
|
|
|
84797
84964
|
|
|
84798
84965
|
Interactive Mode Key Bindings:
|
|
84799
84966
|
Enter Submit message
|
|
84967
|
+
Shift+Enter New line; if ineffective, use Ctrl+J
|
|
84968
|
+
Ctrl+J New line (fallback)
|
|
84800
84969
|
\\ + Enter New line (fallback)
|
|
84801
84970
|
Alt+Enter Queue steering message for the active turn
|
|
84802
84971
|
Ctrl+C Exit
|
|
@@ -84866,7 +85035,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
|
|
|
84866
85035
|
}
|
|
84867
85036
|
async function createCliTestStreamFnFromEnv() {
|
|
84868
85037
|
if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
|
|
84869
|
-
return (await import("./chunks/test-stream-
|
|
85038
|
+
return (await import("./chunks/test-stream-LDVUVSUP.js")).createTestStreamFnFromSequenceEnv();
|
|
84870
85039
|
}
|
|
84871
85040
|
function resolveJsonEventsDetailFlag() {
|
|
84872
85041
|
for (let index = 0; index < process.argv.length; index += 1) {
|