@letta-ai/letta-code 0.14.7 → 0.14.9
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/letta.js +1205 -649
- package/package.json +2 -2
- package/skills/converting-mcps-to-skills/SKILL.md +171 -0
- package/skills/converting-mcps-to-skills/references/skill-templates.md +141 -0
- package/skills/converting-mcps-to-skills/scripts/mcp-http.ts +429 -0
- package/skills/converting-mcps-to-skills/scripts/mcp-stdio.ts +359 -0
- package/skills/converting-mcps-to-skills/scripts/package.json +13 -0
- package/vendor/ink/build/hooks/use-input.js +23 -11
package/letta.js
CHANGED
|
@@ -166,20 +166,39 @@ var init_error = __esm(() => {
|
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
// src/utils/debug.ts
|
|
169
|
+
import { appendFileSync } from "node:fs";
|
|
170
|
+
import { format } from "node:util";
|
|
169
171
|
function isDebugEnabled() {
|
|
170
172
|
const debug = process.env.LETTA_DEBUG;
|
|
171
173
|
return debug === "1" || debug === "true";
|
|
172
174
|
}
|
|
175
|
+
function getDebugFile() {
|
|
176
|
+
const path = process.env.LETTA_DEBUG_FILE;
|
|
177
|
+
return path && path.trim().length > 0 ? path : null;
|
|
178
|
+
}
|
|
179
|
+
function writeDebugLine(prefix, message, args) {
|
|
180
|
+
const debugFile = getDebugFile();
|
|
181
|
+
const line = `${format(`[${prefix}] ${message}`, ...args)}
|
|
182
|
+
`;
|
|
183
|
+
if (debugFile) {
|
|
184
|
+
try {
|
|
185
|
+
appendFileSync(debugFile, line, { encoding: "utf8" });
|
|
186
|
+
return;
|
|
187
|
+
} catch {}
|
|
188
|
+
}
|
|
189
|
+
console.log(line.trimEnd());
|
|
190
|
+
}
|
|
173
191
|
function debugLog(prefix, message, ...args) {
|
|
174
192
|
if (isDebugEnabled()) {
|
|
175
|
-
|
|
193
|
+
writeDebugLine(prefix, message, args);
|
|
176
194
|
}
|
|
177
195
|
}
|
|
178
196
|
function debugWarn(prefix, message, ...args) {
|
|
179
197
|
if (isDebugEnabled()) {
|
|
180
|
-
|
|
198
|
+
writeDebugLine(prefix, `WARN: ${message}`, args);
|
|
181
199
|
}
|
|
182
200
|
}
|
|
201
|
+
var init_debug = () => {};
|
|
183
202
|
|
|
184
203
|
// node_modules/@letta-ai/letta-client/internal/tslib.mjs
|
|
185
204
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
@@ -493,7 +512,7 @@ function maybe_map(val, fn) {
|
|
|
493
512
|
}
|
|
494
513
|
return fn(val);
|
|
495
514
|
}
|
|
496
|
-
var has = (obj, key) => (has = Object.hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty), has(obj, key)), hex_table, limit = 1024, encode = (str, _defaultEncoder, charset, _kind,
|
|
515
|
+
var has = (obj, key) => (has = Object.hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty), has(obj, key)), hex_table, limit = 1024, encode = (str, _defaultEncoder, charset, _kind, format2) => {
|
|
497
516
|
if (str.length === 0) {
|
|
498
517
|
return str;
|
|
499
518
|
}
|
|
@@ -514,7 +533,7 @@ var has = (obj, key) => (has = Object.hasOwn ?? Function.prototype.call.bind(Obj
|
|
|
514
533
|
const arr = [];
|
|
515
534
|
for (let i = 0;i < segment.length; ++i) {
|
|
516
535
|
let c = segment.charCodeAt(i);
|
|
517
|
-
if (c === 45 || c === 46 || c === 95 || c === 126 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 ||
|
|
536
|
+
if (c === 45 || c === 46 || c === 95 || c === 126 || c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || format2 === RFC1738 && (c === 40 || c === 41)) {
|
|
518
537
|
arr[arr.length] = segment.charAt(i);
|
|
519
538
|
continue;
|
|
520
539
|
}
|
|
@@ -554,7 +573,7 @@ var init_utils = __esm(() => {
|
|
|
554
573
|
function is_non_nullish_primitive(v) {
|
|
555
574
|
return typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "symbol" || typeof v === "bigint";
|
|
556
575
|
}
|
|
557
|
-
function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate,
|
|
576
|
+
function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format2, formatter, encodeValuesOnly, charset, sideChannel) {
|
|
558
577
|
let obj = object;
|
|
559
578
|
let tmp_sc = sideChannel;
|
|
560
579
|
let step = 0;
|
|
@@ -587,15 +606,15 @@ function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, al
|
|
|
587
606
|
}
|
|
588
607
|
if (obj === null) {
|
|
589
608
|
if (strictNullHandling) {
|
|
590
|
-
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, "key",
|
|
609
|
+
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, "key", format2) : prefix;
|
|
591
610
|
}
|
|
592
611
|
obj = "";
|
|
593
612
|
}
|
|
594
613
|
if (is_non_nullish_primitive(obj) || is_buffer(obj)) {
|
|
595
614
|
if (encoder) {
|
|
596
|
-
const key_value = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, "key",
|
|
615
|
+
const key_value = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, "key", format2);
|
|
597
616
|
return [
|
|
598
|
-
formatter?.(key_value) + "=" + formatter?.(encoder(obj, defaults.encoder, charset, "value",
|
|
617
|
+
formatter?.(key_value) + "=" + formatter?.(encoder(obj, defaults.encoder, charset, "value", format2))
|
|
599
618
|
];
|
|
600
619
|
}
|
|
601
620
|
return [formatter?.(prefix) + "=" + formatter?.(String(obj))];
|
|
@@ -632,7 +651,7 @@ function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, al
|
|
|
632
651
|
sideChannel.set(object, step);
|
|
633
652
|
const valueSideChannel = new WeakMap;
|
|
634
653
|
valueSideChannel.set(sentinel, sideChannel);
|
|
635
|
-
push_to_array(values, inner_stringify(value, key_prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, generateArrayPrefix === "comma" && encodeValuesOnly && isArray(obj) ? null : encoder, filter, sort, allowDots, serializeDate,
|
|
654
|
+
push_to_array(values, inner_stringify(value, key_prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, generateArrayPrefix === "comma" && encodeValuesOnly && isArray(obj) ? null : encoder, filter, sort, allowDots, serializeDate, format2, formatter, encodeValuesOnly, charset, valueSideChannel));
|
|
636
655
|
}
|
|
637
656
|
return values;
|
|
638
657
|
}
|
|
@@ -650,14 +669,14 @@ function normalize_stringify_options(opts = defaults) {
|
|
|
650
669
|
if (typeof opts.charset !== "undefined" && opts.charset !== "utf-8" && opts.charset !== "iso-8859-1") {
|
|
651
670
|
throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");
|
|
652
671
|
}
|
|
653
|
-
let
|
|
672
|
+
let format2 = default_format;
|
|
654
673
|
if (typeof opts.format !== "undefined") {
|
|
655
674
|
if (!has(formatters, opts.format)) {
|
|
656
675
|
throw new TypeError("Unknown format option provided.");
|
|
657
676
|
}
|
|
658
|
-
|
|
677
|
+
format2 = opts.format;
|
|
659
678
|
}
|
|
660
|
-
const formatter = formatters[
|
|
679
|
+
const formatter = formatters[format2];
|
|
661
680
|
let filter = defaults.filter;
|
|
662
681
|
if (typeof opts.filter === "function" || isArray(opts.filter)) {
|
|
663
682
|
filter = opts.filter;
|
|
@@ -688,7 +707,7 @@ function normalize_stringify_options(opts = defaults) {
|
|
|
688
707
|
encoder: typeof opts.encoder === "function" ? opts.encoder : defaults.encoder,
|
|
689
708
|
encodeValuesOnly: typeof opts.encodeValuesOnly === "boolean" ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
|
|
690
709
|
filter,
|
|
691
|
-
format,
|
|
710
|
+
format: format2,
|
|
692
711
|
formatter,
|
|
693
712
|
serializeDate: typeof opts.serializeDate === "function" ? opts.serializeDate : defaults.serializeDate,
|
|
694
713
|
skipNulls: typeof opts.skipNulls === "boolean" ? opts.skipNulls : defaults.skipNulls,
|
|
@@ -3108,7 +3127,7 @@ var package_default;
|
|
|
3108
3127
|
var init_package = __esm(() => {
|
|
3109
3128
|
package_default = {
|
|
3110
3129
|
name: "@letta-ai/letta-code",
|
|
3111
|
-
version: "0.14.
|
|
3130
|
+
version: "0.14.9",
|
|
3112
3131
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3113
3132
|
type: "module",
|
|
3114
3133
|
bin: {
|
|
@@ -3170,7 +3189,7 @@ var init_package = __esm(() => {
|
|
|
3170
3189
|
check: "bun run scripts/check.js",
|
|
3171
3190
|
dev: "bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
|
|
3172
3191
|
build: "node scripts/postinstall-patches.js && bun run build.js",
|
|
3173
|
-
|
|
3192
|
+
prepublishOnly: "bun run build",
|
|
3174
3193
|
postinstall: "node scripts/postinstall-patches.js"
|
|
3175
3194
|
},
|
|
3176
3195
|
"lint-staged": {
|
|
@@ -3570,7 +3589,7 @@ class SettingsManager {
|
|
|
3570
3589
|
}
|
|
3571
3590
|
this.settings = updatedSettings;
|
|
3572
3591
|
await this.persistSettings();
|
|
3573
|
-
|
|
3592
|
+
debugWarn("settings", "Successfully migrated tokens to secrets");
|
|
3574
3593
|
} catch (error) {
|
|
3575
3594
|
console.warn("Failed to migrate tokens to secrets:", error);
|
|
3576
3595
|
console.warn("Tokens will remain in settings file for persistence");
|
|
@@ -4287,6 +4306,7 @@ class SettingsManager {
|
|
|
4287
4306
|
}
|
|
4288
4307
|
var DEFAULT_SETTINGS, DEFAULT_PROJECT_SETTINGS, DEFAULT_LOCAL_PROJECT_SETTINGS, DEFAULT_LETTA_API_URL = "https://api.letta.com", settingsManager;
|
|
4289
4308
|
var init_settings_manager = __esm(async () => {
|
|
4309
|
+
init_debug();
|
|
4290
4310
|
init_fs();
|
|
4291
4311
|
await init_secrets();
|
|
4292
4312
|
DEFAULT_SETTINGS = {
|
|
@@ -7367,38 +7387,38 @@ var require_react_development = __commonJS((exports, module) => {
|
|
|
7367
7387
|
ReactSharedInternals.ReactDebugCurrentFrame = ReactDebugCurrentFrame;
|
|
7368
7388
|
ReactSharedInternals.ReactCurrentActQueue = ReactCurrentActQueue;
|
|
7369
7389
|
}
|
|
7370
|
-
function warn(
|
|
7390
|
+
function warn(format2) {
|
|
7371
7391
|
{
|
|
7372
7392
|
{
|
|
7373
7393
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1;_key < _len; _key++) {
|
|
7374
7394
|
args[_key - 1] = arguments[_key];
|
|
7375
7395
|
}
|
|
7376
|
-
printWarning("warn",
|
|
7396
|
+
printWarning("warn", format2, args);
|
|
7377
7397
|
}
|
|
7378
7398
|
}
|
|
7379
7399
|
}
|
|
7380
|
-
function error(
|
|
7400
|
+
function error(format2) {
|
|
7381
7401
|
{
|
|
7382
7402
|
{
|
|
7383
7403
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
7384
7404
|
args[_key2 - 1] = arguments[_key2];
|
|
7385
7405
|
}
|
|
7386
|
-
printWarning("error",
|
|
7406
|
+
printWarning("error", format2, args);
|
|
7387
7407
|
}
|
|
7388
7408
|
}
|
|
7389
7409
|
}
|
|
7390
|
-
function printWarning(level,
|
|
7410
|
+
function printWarning(level, format2, args) {
|
|
7391
7411
|
{
|
|
7392
7412
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
7393
7413
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
7394
7414
|
if (stack !== "") {
|
|
7395
|
-
|
|
7415
|
+
format2 += "%s";
|
|
7396
7416
|
args = args.concat([stack]);
|
|
7397
7417
|
}
|
|
7398
7418
|
var argsWithFormat = args.map(function(item) {
|
|
7399
7419
|
return String(item);
|
|
7400
7420
|
});
|
|
7401
|
-
argsWithFormat.unshift("Warning: " +
|
|
7421
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
7402
7422
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
7403
7423
|
}
|
|
7404
7424
|
}
|
|
@@ -11750,38 +11770,38 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
11750
11770
|
suppressWarning = newSuppressWarning;
|
|
11751
11771
|
}
|
|
11752
11772
|
}
|
|
11753
|
-
function warn(
|
|
11773
|
+
function warn(format2) {
|
|
11754
11774
|
{
|
|
11755
11775
|
if (!suppressWarning) {
|
|
11756
11776
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1;_key < _len; _key++) {
|
|
11757
11777
|
args[_key - 1] = arguments[_key];
|
|
11758
11778
|
}
|
|
11759
|
-
printWarning("warn",
|
|
11779
|
+
printWarning("warn", format2, args);
|
|
11760
11780
|
}
|
|
11761
11781
|
}
|
|
11762
11782
|
}
|
|
11763
|
-
function error(
|
|
11783
|
+
function error(format2) {
|
|
11764
11784
|
{
|
|
11765
11785
|
if (!suppressWarning) {
|
|
11766
11786
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
11767
11787
|
args[_key2 - 1] = arguments[_key2];
|
|
11768
11788
|
}
|
|
11769
|
-
printWarning("error",
|
|
11789
|
+
printWarning("error", format2, args);
|
|
11770
11790
|
}
|
|
11771
11791
|
}
|
|
11772
11792
|
}
|
|
11773
|
-
function printWarning(level,
|
|
11793
|
+
function printWarning(level, format2, args) {
|
|
11774
11794
|
{
|
|
11775
11795
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
11776
11796
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
11777
11797
|
if (stack !== "") {
|
|
11778
|
-
|
|
11798
|
+
format2 += "%s";
|
|
11779
11799
|
args = args.concat([stack]);
|
|
11780
11800
|
}
|
|
11781
11801
|
var argsWithFormat = args.map(function(item) {
|
|
11782
11802
|
return String(item);
|
|
11783
11803
|
});
|
|
11784
|
-
argsWithFormat.unshift("Warning: " +
|
|
11804
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
11785
11805
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
11786
11806
|
}
|
|
11787
11807
|
}
|
|
@@ -30620,11 +30640,22 @@ var import_react16, useInput = (inputHandler, options = {}) => {
|
|
|
30620
30640
|
}
|
|
30621
30641
|
let keypress = parse_keypress_default(data);
|
|
30622
30642
|
if (!keypress.name && typeof data === "string") {
|
|
30643
|
+
let keycode = null;
|
|
30644
|
+
let modifier = 0;
|
|
30645
|
+
let event = 1;
|
|
30623
30646
|
const csiUMatch = data.match(/^\x1b\[(\d+)(?:;(\d+))?(?::(\d+))?u$/);
|
|
30624
30647
|
if (csiUMatch) {
|
|
30625
|
-
|
|
30626
|
-
|
|
30627
|
-
|
|
30648
|
+
keycode = parseInt(csiUMatch[1], 10);
|
|
30649
|
+
modifier = parseInt(csiUMatch[2] || "1", 10) - 1;
|
|
30650
|
+
event = csiUMatch[3] ? parseInt(csiUMatch[3], 10) : 1;
|
|
30651
|
+
} else {
|
|
30652
|
+
const modifyOtherKeysMatch = data.match(/^\x1b\[27;(\d+);(\d+)~$/);
|
|
30653
|
+
if (modifyOtherKeysMatch) {
|
|
30654
|
+
modifier = parseInt(modifyOtherKeysMatch[1], 10) - 1;
|
|
30655
|
+
keycode = parseInt(modifyOtherKeysMatch[2], 10);
|
|
30656
|
+
}
|
|
30657
|
+
}
|
|
30658
|
+
if (keycode !== null) {
|
|
30628
30659
|
if (event === 3) {
|
|
30629
30660
|
return;
|
|
30630
30661
|
}
|
|
@@ -30660,7 +30691,7 @@ var import_react16, useInput = (inputHandler, options = {}) => {
|
|
|
30660
30691
|
rightArrow: keypress.name === "right",
|
|
30661
30692
|
pageDown: keypress.name === "pagedown",
|
|
30662
30693
|
pageUp: keypress.name === "pageup",
|
|
30663
|
-
return: keypress.name === "return",
|
|
30694
|
+
return: keypress.name === "return" || keypress.name === "enter",
|
|
30664
30695
|
escape: keypress.name === "escape",
|
|
30665
30696
|
ctrl: keypress.ctrl,
|
|
30666
30697
|
shift: keypress.shift,
|
|
@@ -31094,28 +31125,28 @@ var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
|
|
|
31094
31125
|
return null;
|
|
31095
31126
|
}
|
|
31096
31127
|
var ReactSharedInternals = React10.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
31097
|
-
function error(
|
|
31128
|
+
function error(format2) {
|
|
31098
31129
|
{
|
|
31099
31130
|
{
|
|
31100
31131
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
31101
31132
|
args[_key2 - 1] = arguments[_key2];
|
|
31102
31133
|
}
|
|
31103
|
-
printWarning("error",
|
|
31134
|
+
printWarning("error", format2, args);
|
|
31104
31135
|
}
|
|
31105
31136
|
}
|
|
31106
31137
|
}
|
|
31107
|
-
function printWarning(level,
|
|
31138
|
+
function printWarning(level, format2, args) {
|
|
31108
31139
|
{
|
|
31109
31140
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
31110
31141
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
31111
31142
|
if (stack !== "") {
|
|
31112
|
-
|
|
31143
|
+
format2 += "%s";
|
|
31113
31144
|
args = args.concat([stack]);
|
|
31114
31145
|
}
|
|
31115
31146
|
var argsWithFormat = args.map(function(item) {
|
|
31116
31147
|
return String(item);
|
|
31117
31148
|
});
|
|
31118
|
-
argsWithFormat.unshift("Warning: " +
|
|
31149
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
31119
31150
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
31120
31151
|
}
|
|
31121
31152
|
}
|
|
@@ -33252,10 +33283,11 @@ function getSnapshot() {
|
|
|
33252
33283
|
return tick;
|
|
33253
33284
|
}
|
|
33254
33285
|
function AnimatedLogo({
|
|
33255
|
-
color = colors.welcome.accent
|
|
33286
|
+
color = colors.welcome.accent,
|
|
33287
|
+
animate = true
|
|
33256
33288
|
}) {
|
|
33257
33289
|
const tick2 = import_react24.useSyncExternalStore(subscribe, getSnapshot);
|
|
33258
|
-
const frame = tick2 % logoFrames.length;
|
|
33290
|
+
const frame = animate ? tick2 % logoFrames.length : 0;
|
|
33259
33291
|
const logoLines = logoFrames[frame]?.split(`
|
|
33260
33292
|
`) ?? [];
|
|
33261
33293
|
return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(jsx_dev_runtime5.Fragment, {
|
|
@@ -33409,7 +33441,8 @@ function WelcomeScreen({
|
|
|
33409
33441
|
paddingLeft: 1,
|
|
33410
33442
|
paddingRight: 2,
|
|
33411
33443
|
children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AnimatedLogo, {
|
|
33412
|
-
color: colors.welcome.accent
|
|
33444
|
+
color: colors.welcome.accent,
|
|
33445
|
+
animate: loadingState !== "ready"
|
|
33413
33446
|
}, undefined, false, undefined, this)
|
|
33414
33447
|
}, undefined, false, undefined, this),
|
|
33415
33448
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
|
|
@@ -34598,13 +34631,19 @@ function windowsLaunchers(command) {
|
|
|
34598
34631
|
return [];
|
|
34599
34632
|
const launchers = [];
|
|
34600
34633
|
const seen = new Set;
|
|
34634
|
+
const powerShellCommand = trimmed.startsWith("&") || trimmed.startsWith('"') || trimmed.startsWith("'") ? trimmed.startsWith("&") ? trimmed : `& ${trimmed}` : trimmed;
|
|
34601
34635
|
pushUnique(launchers, seen, [
|
|
34602
34636
|
"powershell.exe",
|
|
34603
34637
|
"-NoProfile",
|
|
34604
34638
|
"-Command",
|
|
34605
|
-
|
|
34639
|
+
powerShellCommand
|
|
34640
|
+
]);
|
|
34641
|
+
pushUnique(launchers, seen, [
|
|
34642
|
+
"pwsh",
|
|
34643
|
+
"-NoProfile",
|
|
34644
|
+
"-Command",
|
|
34645
|
+
powerShellCommand
|
|
34606
34646
|
]);
|
|
34607
|
-
pushUnique(launchers, seen, ["pwsh", "-NoProfile", "-Command", trimmed]);
|
|
34608
34647
|
const envComSpecRaw = process.env.ComSpec || process.env.COMSPEC;
|
|
34609
34648
|
const envComSpec = envComSpecRaw?.trim();
|
|
34610
34649
|
if (envComSpec) {
|
|
@@ -34667,6 +34706,7 @@ var init_types = __esm(() => {
|
|
|
34667
34706
|
TOOL_EVENTS = new Set([
|
|
34668
34707
|
"PreToolUse",
|
|
34669
34708
|
"PostToolUse",
|
|
34709
|
+
"PostToolUseFailure",
|
|
34670
34710
|
"PermissionRequest"
|
|
34671
34711
|
]);
|
|
34672
34712
|
});
|
|
@@ -34737,8 +34777,10 @@ function executeWithLauncher(launcher, inputJson, workingDirectory, input, timeo
|
|
|
34737
34777
|
const safeResolve = (result) => {
|
|
34738
34778
|
if (!resolved) {
|
|
34739
34779
|
resolved = true;
|
|
34740
|
-
const
|
|
34741
|
-
|
|
34780
|
+
const exitCode = result.exitCode === 0 /* ALLOW */ ? 0 : result.exitCode === 2 /* BLOCK */ ? 2 : 1;
|
|
34781
|
+
const exitColor = result.exitCode === 0 /* ALLOW */ ? "\x1B[32m" : result.exitCode === 2 /* BLOCK */ ? "\x1B[31m" : "\x1B[33m";
|
|
34782
|
+
const exitLabel = result.timedOut ? `${exitColor}timeout\x1B[0m` : `${exitColor}exit ${exitCode}\x1B[0m`;
|
|
34783
|
+
console.log(`\x1B[90m[hook:${input.event_type}] ${command}\x1B[0m`);
|
|
34742
34784
|
console.log(`\x1B[90m ⎿ ${exitLabel} (${result.durationMs}ms)\x1B[0m`);
|
|
34743
34785
|
if (result.stdout) {
|
|
34744
34786
|
console.log(`\x1B[90m ⎿ (stdout)\x1B[0m`);
|
|
@@ -34908,7 +34950,8 @@ var init_executor = __esm(() => {
|
|
|
34908
34950
|
function loadGlobalHooks() {
|
|
34909
34951
|
try {
|
|
34910
34952
|
return settingsManager.getSettings().hooks || {};
|
|
34911
|
-
} catch {
|
|
34953
|
+
} catch (error) {
|
|
34954
|
+
debugLog("hooks", "loadGlobalHooks: Settings not initialized yet", error);
|
|
34912
34955
|
return {};
|
|
34913
34956
|
}
|
|
34914
34957
|
}
|
|
@@ -34920,7 +34963,8 @@ async function loadProjectHooks(workingDirectory = process.cwd()) {
|
|
|
34920
34963
|
await settingsManager.loadProjectSettings(workingDirectory);
|
|
34921
34964
|
}
|
|
34922
34965
|
return settingsManager.getProjectSettings(workingDirectory)?.hooks || {};
|
|
34923
|
-
} catch {
|
|
34966
|
+
} catch (error) {
|
|
34967
|
+
debugLog("hooks", "loadProjectHooks: Settings not available", error);
|
|
34924
34968
|
return {};
|
|
34925
34969
|
}
|
|
34926
34970
|
}
|
|
@@ -34932,7 +34976,8 @@ async function loadProjectLocalHooks(workingDirectory = process.cwd()) {
|
|
|
34932
34976
|
await settingsManager.loadLocalProjectSettings(workingDirectory);
|
|
34933
34977
|
}
|
|
34934
34978
|
return settingsManager.getLocalProjectSettings(workingDirectory)?.hooks || {};
|
|
34935
|
-
} catch {
|
|
34979
|
+
} catch (error) {
|
|
34980
|
+
debugLog("hooks", "loadProjectLocalHooks: Settings not available", error);
|
|
34936
34981
|
return {};
|
|
34937
34982
|
}
|
|
34938
34983
|
}
|
|
@@ -34983,7 +35028,8 @@ function matchesTool(pattern, toolName) {
|
|
|
34983
35028
|
try {
|
|
34984
35029
|
const regex2 = new RegExp(`^(?:${pattern})$`);
|
|
34985
35030
|
return regex2.test(toolName);
|
|
34986
|
-
} catch {
|
|
35031
|
+
} catch (error) {
|
|
35032
|
+
debugLog("hooks", `matchesTool: Invalid regex pattern "${pattern}", falling back to exact match`, error);
|
|
34987
35033
|
return pattern === toolName;
|
|
34988
35034
|
}
|
|
34989
35035
|
}
|
|
@@ -35026,15 +35072,20 @@ function areHooksDisabled(workingDirectory = process.cwd()) {
|
|
|
35026
35072
|
if (projectDisabled === true) {
|
|
35027
35073
|
return true;
|
|
35028
35074
|
}
|
|
35029
|
-
} catch {
|
|
35075
|
+
} catch (error) {
|
|
35076
|
+
debugLog("hooks", "areHooksDisabled: Project settings not loaded, skipping", error);
|
|
35077
|
+
}
|
|
35030
35078
|
try {
|
|
35031
35079
|
const localDisabled = settingsManager.getLocalProjectSettings(workingDirectory)?.hooks?.disabled;
|
|
35032
35080
|
if (localDisabled === true) {
|
|
35033
35081
|
return true;
|
|
35034
35082
|
}
|
|
35035
|
-
} catch {
|
|
35083
|
+
} catch (error) {
|
|
35084
|
+
debugLog("hooks", "areHooksDisabled: Local project settings not loaded, skipping", error);
|
|
35085
|
+
}
|
|
35036
35086
|
return false;
|
|
35037
|
-
} catch {
|
|
35087
|
+
} catch (error) {
|
|
35088
|
+
debugLog("hooks", "areHooksDisabled: Failed to check hooks disabled status", error);
|
|
35038
35089
|
return false;
|
|
35039
35090
|
}
|
|
35040
35091
|
}
|
|
@@ -35046,6 +35097,7 @@ async function getHooksForEvent(event, toolName, workingDirectory = process.cwd(
|
|
|
35046
35097
|
return getMatchingHooks(config, event, toolName);
|
|
35047
35098
|
}
|
|
35048
35099
|
var init_loader = __esm(async () => {
|
|
35100
|
+
init_debug();
|
|
35049
35101
|
init_types();
|
|
35050
35102
|
await init_settings_manager();
|
|
35051
35103
|
});
|
|
@@ -35084,6 +35136,31 @@ async function runPostToolUseHooks(toolName, toolInput, toolResult, toolCallId,
|
|
|
35084
35136
|
};
|
|
35085
35137
|
return executeHooksParallel(hooks, input, workingDirectory);
|
|
35086
35138
|
}
|
|
35139
|
+
async function runPostToolUseFailureHooks(toolName, toolInput, errorMessage, errorType, toolCallId, workingDirectory = process.cwd(), agentId, precedingReasoning, precedingAssistantMessage) {
|
|
35140
|
+
const hooks = await getHooksForEvent("PostToolUseFailure", toolName, workingDirectory);
|
|
35141
|
+
if (hooks.length === 0) {
|
|
35142
|
+
return { blocked: false, errored: false, feedback: [], results: [] };
|
|
35143
|
+
}
|
|
35144
|
+
const input = {
|
|
35145
|
+
event_type: "PostToolUseFailure",
|
|
35146
|
+
working_directory: workingDirectory,
|
|
35147
|
+
tool_name: toolName,
|
|
35148
|
+
tool_input: toolInput,
|
|
35149
|
+
tool_call_id: toolCallId,
|
|
35150
|
+
error_message: errorMessage,
|
|
35151
|
+
error_type: errorType,
|
|
35152
|
+
agent_id: agentId,
|
|
35153
|
+
preceding_reasoning: precedingReasoning,
|
|
35154
|
+
preceding_assistant_message: precedingAssistantMessage
|
|
35155
|
+
};
|
|
35156
|
+
const result = await executeHooksParallel(hooks, input, workingDirectory);
|
|
35157
|
+
return {
|
|
35158
|
+
blocked: false,
|
|
35159
|
+
errored: result.errored,
|
|
35160
|
+
feedback: result.feedback,
|
|
35161
|
+
results: result.results
|
|
35162
|
+
};
|
|
35163
|
+
}
|
|
35087
35164
|
async function runPermissionRequestHooks(toolName, toolInput, permissionType, scope, workingDirectory = process.cwd()) {
|
|
35088
35165
|
const hooks = await getHooksForEvent("PermissionRequest", toolName, workingDirectory);
|
|
35089
35166
|
if (hooks.length === 0) {
|
|
@@ -35194,7 +35271,19 @@ async function runSessionStartHooks(isNewSession, agentId, agentName, conversati
|
|
|
35194
35271
|
agent_name: agentName,
|
|
35195
35272
|
conversation_id: conversationId
|
|
35196
35273
|
};
|
|
35197
|
-
|
|
35274
|
+
const result = await executeHooks(hooks, input, workingDirectory);
|
|
35275
|
+
const feedback = [];
|
|
35276
|
+
for (const hookResult of result.results) {
|
|
35277
|
+
if (hookResult.stdout?.trim()) {
|
|
35278
|
+
feedback.push(hookResult.stdout.trim());
|
|
35279
|
+
}
|
|
35280
|
+
}
|
|
35281
|
+
return {
|
|
35282
|
+
blocked: false,
|
|
35283
|
+
errored: result.errored,
|
|
35284
|
+
feedback,
|
|
35285
|
+
results: result.results
|
|
35286
|
+
};
|
|
35198
35287
|
}
|
|
35199
35288
|
async function runSessionEndHooks(durationMs, messageCount, toolCallCount, agentId, conversationId, workingDirectory = process.cwd()) {
|
|
35200
35289
|
const hooks = await getHooksForEvent("SessionEnd", undefined, workingDirectory);
|
|
@@ -36939,8 +37028,8 @@ function getShellEnv() {
|
|
|
36939
37028
|
const env3 = { ...process.env };
|
|
36940
37029
|
const rgBinDir = getRipgrepBinDir();
|
|
36941
37030
|
if (rgBinDir) {
|
|
36942
|
-
const
|
|
36943
|
-
env3
|
|
37031
|
+
const pathKey = Object.keys(env3).find((k) => k.toUpperCase() === "PATH") || "PATH";
|
|
37032
|
+
env3[pathKey] = `${rgBinDir}${path3.delimiter}${env3[pathKey] || ""}`;
|
|
36944
37033
|
}
|
|
36945
37034
|
try {
|
|
36946
37035
|
env3.LETTA_AGENT_ID = getCurrentAgentId();
|
|
@@ -39701,11 +39790,11 @@ var require_picomatch = __commonJS((exports, module) => {
|
|
|
39701
39790
|
return { isMatch: false, output: "" };
|
|
39702
39791
|
}
|
|
39703
39792
|
const opts = options || {};
|
|
39704
|
-
const
|
|
39793
|
+
const format2 = opts.format || (posix ? utils.toPosixSlashes : null);
|
|
39705
39794
|
let match = input === glob2;
|
|
39706
|
-
let output = match &&
|
|
39795
|
+
let output = match && format2 ? format2(input) : input;
|
|
39707
39796
|
if (match === false) {
|
|
39708
|
-
output =
|
|
39797
|
+
output = format2 ? format2(input) : input;
|
|
39709
39798
|
match = output === glob2;
|
|
39710
39799
|
}
|
|
39711
39800
|
if (match === false || opts.capture === true) {
|
|
@@ -39979,14 +40068,14 @@ async function getImageDimensions(buffer) {
|
|
|
39979
40068
|
const output = execSync(`magick identify -format "%w %h %m" "${tempInput}"`, {
|
|
39980
40069
|
encoding: "utf-8"
|
|
39981
40070
|
});
|
|
39982
|
-
const [width, height,
|
|
39983
|
-
if (!width || !height || !
|
|
40071
|
+
const [width, height, format2] = output.trim().split(" ");
|
|
40072
|
+
if (!width || !height || !format2) {
|
|
39984
40073
|
throw new Error("Failed to get image dimensions");
|
|
39985
40074
|
}
|
|
39986
40075
|
return {
|
|
39987
40076
|
width: parseInt(width, 10),
|
|
39988
40077
|
height: parseInt(height, 10),
|
|
39989
|
-
format:
|
|
40078
|
+
format: format2.toLowerCase()
|
|
39990
40079
|
};
|
|
39991
40080
|
} finally {
|
|
39992
40081
|
unlinkSync2(tempInput);
|
|
@@ -40055,9 +40144,9 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40055
40144
|
}
|
|
40056
40145
|
}
|
|
40057
40146
|
async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
40058
|
-
const { width, height, format } = await getImageDimensions(buffer);
|
|
40147
|
+
const { width, height, format: format2 } = await getImageDimensions(buffer);
|
|
40059
40148
|
const needsResize = width > MAX_IMAGE_WIDTH || height > MAX_IMAGE_HEIGHT;
|
|
40060
|
-
const isPassthroughFormat =
|
|
40149
|
+
const isPassthroughFormat = format2 === "png" || format2 === "jpeg" || format2 === "jpg";
|
|
40061
40150
|
if (!needsResize && isPassthroughFormat) {
|
|
40062
40151
|
const compressed = await compressToFitByteLimit(buffer, width, height);
|
|
40063
40152
|
if (compressed) {
|
|
@@ -40078,7 +40167,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
40078
40167
|
const tempOutput2 = join12(tmpdir(), `resize-output-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
40079
40168
|
let outputBuffer2;
|
|
40080
40169
|
let outputMediaType;
|
|
40081
|
-
if (
|
|
40170
|
+
if (format2 === "jpeg" || format2 === "jpg") {
|
|
40082
40171
|
execSync(`magick "${tempInput}" -resize ${MAX_IMAGE_WIDTH}x${MAX_IMAGE_HEIGHT}> -quality 85 "${tempOutput2}.jpg"`, {
|
|
40083
40172
|
stdio: "ignore"
|
|
40084
40173
|
});
|
|
@@ -45680,10 +45769,10 @@ var require_output = __commonJS((exports, module) => {
|
|
|
45680
45769
|
}
|
|
45681
45770
|
return this;
|
|
45682
45771
|
}
|
|
45683
|
-
function toFormat(
|
|
45684
|
-
const actualFormat = formats.get((is.object(
|
|
45772
|
+
function toFormat(format2, options) {
|
|
45773
|
+
const actualFormat = formats.get((is.object(format2) && is.string(format2.id) ? format2.id : format2).toLowerCase());
|
|
45685
45774
|
if (!actualFormat) {
|
|
45686
|
-
throw is.invalidParameterError("format", `one of: ${[...formats.keys()].join(", ")}`,
|
|
45775
|
+
throw is.invalidParameterError("format", `one of: ${[...formats.keys()].join(", ")}`, format2);
|
|
45687
45776
|
}
|
|
45688
45777
|
return this[actualFormat](options);
|
|
45689
45778
|
}
|
|
@@ -46405,11 +46494,11 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46405
46494
|
var sharp = require_sharp();
|
|
46406
46495
|
var runtimePlatform = runtimePlatformArch();
|
|
46407
46496
|
var libvipsVersion = sharp.libvipsVersion();
|
|
46408
|
-
var
|
|
46409
|
-
|
|
46410
|
-
|
|
46411
|
-
|
|
46412
|
-
|
|
46497
|
+
var format2 = sharp.format();
|
|
46498
|
+
format2.heif.output.alias = ["avif", "heic"];
|
|
46499
|
+
format2.jpeg.output.alias = ["jpe", "jpg"];
|
|
46500
|
+
format2.tiff.output.alias = ["tif"];
|
|
46501
|
+
format2.jp2k.output.alias = ["j2c", "j2k", "jp2", "jpx"];
|
|
46413
46502
|
var interpolators = {
|
|
46414
46503
|
nearest: "nearest",
|
|
46415
46504
|
bilinear: "bilinear",
|
|
@@ -46437,9 +46526,9 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46437
46526
|
}
|
|
46438
46527
|
}
|
|
46439
46528
|
versions.sharp = require_package().version;
|
|
46440
|
-
if (versions.heif &&
|
|
46441
|
-
|
|
46442
|
-
|
|
46529
|
+
if (versions.heif && format2.heif) {
|
|
46530
|
+
format2.heif.input.fileSuffix = [".avif"];
|
|
46531
|
+
format2.heif.output.alias = ["avif"];
|
|
46443
46532
|
}
|
|
46444
46533
|
function cache4(options) {
|
|
46445
46534
|
if (is.bool(options)) {
|
|
@@ -46497,7 +46586,7 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46497
46586
|
Sharp.concurrency = concurrency;
|
|
46498
46587
|
Sharp.counters = counters;
|
|
46499
46588
|
Sharp.simd = simd;
|
|
46500
|
-
Sharp.format =
|
|
46589
|
+
Sharp.format = format2;
|
|
46501
46590
|
Sharp.interpolators = interpolators;
|
|
46502
46591
|
Sharp.versions = versions;
|
|
46503
46592
|
Sharp.queue = queue;
|
|
@@ -46576,9 +46665,9 @@ async function resizeImageIfNeeded2(buffer, inputMediaType) {
|
|
|
46576
46665
|
const metadata = await image2.metadata();
|
|
46577
46666
|
const width = metadata.width ?? 0;
|
|
46578
46667
|
const height = metadata.height ?? 0;
|
|
46579
|
-
const
|
|
46668
|
+
const format2 = metadata.format;
|
|
46580
46669
|
const needsResize = width > MAX_IMAGE_WIDTH2 || height > MAX_IMAGE_HEIGHT2;
|
|
46581
|
-
const isPassthroughFormat =
|
|
46670
|
+
const isPassthroughFormat = format2 === "png" || format2 === "jpeg";
|
|
46582
46671
|
if (!needsResize && isPassthroughFormat) {
|
|
46583
46672
|
const compressed2 = await compressToFitByteLimit2(buffer, width, height);
|
|
46584
46673
|
if (compressed2) {
|
|
@@ -46599,7 +46688,7 @@ async function resizeImageIfNeeded2(buffer, inputMediaType) {
|
|
|
46599
46688
|
});
|
|
46600
46689
|
let outputBuffer2;
|
|
46601
46690
|
let outputMediaType;
|
|
46602
|
-
if (
|
|
46691
|
+
if (format2 === "jpeg") {
|
|
46603
46692
|
outputBuffer2 = await resized.jpeg({ quality: 85 }).toBuffer();
|
|
46604
46693
|
outputMediaType = "image/jpeg";
|
|
46605
46694
|
} else {
|
|
@@ -54363,7 +54452,10 @@ async function getAvailableModelHandles(options) {
|
|
|
54363
54452
|
function prefetchAvailableModelHandles() {
|
|
54364
54453
|
getAvailableModelHandles().catch(() => {});
|
|
54365
54454
|
}
|
|
54366
|
-
function getModelContextWindow(handle) {
|
|
54455
|
+
async function getModelContextWindow(handle) {
|
|
54456
|
+
if (!cache4) {
|
|
54457
|
+
await getAvailableModelHandles();
|
|
54458
|
+
}
|
|
54367
54459
|
return cache4?.contextWindows.get(handle);
|
|
54368
54460
|
}
|
|
54369
54461
|
var CACHE_TTL_MS, cache4 = null, inflight = null;
|
|
@@ -57621,19 +57713,22 @@ var init_esm7 = __esm(() => {
|
|
|
57621
57713
|
|
|
57622
57714
|
// src/permissions/matcher.ts
|
|
57623
57715
|
import { resolve as resolve13 } from "node:path";
|
|
57716
|
+
function normalizePath(p) {
|
|
57717
|
+
return p.replace(/\\/g, "/");
|
|
57718
|
+
}
|
|
57624
57719
|
function matchesFilePattern(query, pattern, workingDirectory) {
|
|
57625
57720
|
const queryMatch = query.match(/^([^(]+)\((.+)\)$/);
|
|
57626
57721
|
if (!queryMatch || !queryMatch[1] || !queryMatch[2]) {
|
|
57627
57722
|
return false;
|
|
57628
57723
|
}
|
|
57629
57724
|
const queryTool = queryMatch[1];
|
|
57630
|
-
const filePath = queryMatch[2];
|
|
57725
|
+
const filePath = normalizePath(queryMatch[2]);
|
|
57631
57726
|
const patternMatch = pattern.match(/^([^(]+)\((.+)\)$/);
|
|
57632
57727
|
if (!patternMatch || !patternMatch[1] || !patternMatch[2]) {
|
|
57633
57728
|
return false;
|
|
57634
57729
|
}
|
|
57635
57730
|
const patternTool = patternMatch[1];
|
|
57636
|
-
let globPattern = patternMatch[2];
|
|
57731
|
+
let globPattern = normalizePath(patternMatch[2]);
|
|
57637
57732
|
if (queryTool !== patternTool) {
|
|
57638
57733
|
return false;
|
|
57639
57734
|
}
|
|
@@ -57647,11 +57742,12 @@ function matchesFilePattern(query, pattern, workingDirectory) {
|
|
|
57647
57742
|
if (globPattern.startsWith("//")) {
|
|
57648
57743
|
globPattern = globPattern.slice(1);
|
|
57649
57744
|
}
|
|
57650
|
-
const absoluteFilePath = resolve13(workingDirectory, filePath);
|
|
57745
|
+
const absoluteFilePath = normalizePath(resolve13(workingDirectory, filePath));
|
|
57651
57746
|
if (globPattern.startsWith("/")) {
|
|
57652
57747
|
return minimatch2(absoluteFilePath, globPattern);
|
|
57653
57748
|
}
|
|
57654
|
-
const
|
|
57749
|
+
const normalizedWorkingDir = normalizePath(workingDirectory);
|
|
57750
|
+
const relativeFilePath = filePath.startsWith("/") ? absoluteFilePath.replace(`${normalizedWorkingDir}/`, "") : filePath;
|
|
57655
57751
|
return minimatch2(relativeFilePath, globPattern) || minimatch2(absoluteFilePath, globPattern);
|
|
57656
57752
|
}
|
|
57657
57753
|
function extractActualCommand(command) {
|
|
@@ -58971,10 +59067,51 @@ async function executeTool(name, args, options) {
|
|
|
58971
59067
|
const responseSize = typeof flattenedResponse === "string" ? flattenedResponse.length : JSON.stringify(flattenedResponse).length;
|
|
58972
59068
|
telemetry2.trackToolUsage(internalName, toolStatus === "success", duration, responseSize, toolStatus === "error" ? "tool_error" : undefined, stderr ? stderr.join(`
|
|
58973
59069
|
`) : undefined);
|
|
58974
|
-
|
|
58975
|
-
|
|
58976
|
-
|
|
58977
|
-
|
|
59070
|
+
let postToolUseFeedback = [];
|
|
59071
|
+
try {
|
|
59072
|
+
const postHookResult = await runPostToolUseHooks(internalName, args, {
|
|
59073
|
+
status: toolStatus,
|
|
59074
|
+
output: getDisplayableToolReturn(flattenedResponse)
|
|
59075
|
+
}, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59076
|
+
postToolUseFeedback = postHookResult.feedback;
|
|
59077
|
+
} catch (error) {
|
|
59078
|
+
debugLog("hooks", "PostToolUse hook error (success path)", error);
|
|
59079
|
+
}
|
|
59080
|
+
let postToolUseFailureFeedback = [];
|
|
59081
|
+
if (toolStatus === "error") {
|
|
59082
|
+
const errorOutput = typeof flattenedResponse === "string" ? flattenedResponse : JSON.stringify(flattenedResponse);
|
|
59083
|
+
try {
|
|
59084
|
+
const failureHookResult = await runPostToolUseFailureHooks(internalName, args, errorOutput, "tool_error", options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59085
|
+
postToolUseFailureFeedback = failureHookResult.feedback;
|
|
59086
|
+
} catch (error) {
|
|
59087
|
+
debugLog("hooks", "PostToolUseFailure hook error (tool returned error)", error);
|
|
59088
|
+
}
|
|
59089
|
+
}
|
|
59090
|
+
const allFeedback = [...postToolUseFeedback, ...postToolUseFailureFeedback];
|
|
59091
|
+
if (allFeedback.length > 0) {
|
|
59092
|
+
const feedbackMessage = `
|
|
59093
|
+
|
|
59094
|
+
[Hook feedback]:
|
|
59095
|
+
${allFeedback.join(`
|
|
59096
|
+
`)}`;
|
|
59097
|
+
let finalToolReturn;
|
|
59098
|
+
if (typeof flattenedResponse === "string") {
|
|
59099
|
+
finalToolReturn = flattenedResponse + feedbackMessage;
|
|
59100
|
+
} else if (Array.isArray(flattenedResponse)) {
|
|
59101
|
+
finalToolReturn = [
|
|
59102
|
+
...flattenedResponse,
|
|
59103
|
+
{ type: "text", text: feedbackMessage }
|
|
59104
|
+
];
|
|
59105
|
+
} else {
|
|
59106
|
+
finalToolReturn = flattenedResponse;
|
|
59107
|
+
}
|
|
59108
|
+
return {
|
|
59109
|
+
toolReturn: finalToolReturn,
|
|
59110
|
+
status: toolStatus,
|
|
59111
|
+
...stdout && { stdout },
|
|
59112
|
+
...stderr && { stderr }
|
|
59113
|
+
};
|
|
59114
|
+
}
|
|
58978
59115
|
return {
|
|
58979
59116
|
toolReturn: flattenedResponse,
|
|
58980
59117
|
status: toolStatus,
|
|
@@ -58987,9 +59124,28 @@ async function executeTool(name, args, options) {
|
|
|
58987
59124
|
const errorType = isAbort ? "abort" : error instanceof Error ? error.name : "unknown";
|
|
58988
59125
|
const errorMessage = isAbort ? INTERRUPTED_BY_USER : error instanceof Error ? error.message : String(error);
|
|
58989
59126
|
telemetry2.trackToolUsage(internalName, false, duration, errorMessage.length, errorType, errorMessage);
|
|
58990
|
-
|
|
59127
|
+
let postToolUseFeedback = [];
|
|
59128
|
+
try {
|
|
59129
|
+
const postHookResult = await runPostToolUseHooks(internalName, args, { status: "error", output: errorMessage }, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59130
|
+
postToolUseFeedback = postHookResult.feedback;
|
|
59131
|
+
} catch (error2) {
|
|
59132
|
+
debugLog("hooks", "PostToolUse hook error (error path)", error2);
|
|
59133
|
+
}
|
|
59134
|
+
let postToolUseFailureFeedback = [];
|
|
59135
|
+
try {
|
|
59136
|
+
const failureHookResult = await runPostToolUseFailureHooks(internalName, args, errorMessage, errorType, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59137
|
+
postToolUseFailureFeedback = failureHookResult.feedback;
|
|
59138
|
+
} catch (error2) {
|
|
59139
|
+
debugLog("hooks", "PostToolUseFailure hook error (exception path)", error2);
|
|
59140
|
+
}
|
|
59141
|
+
const allFeedback = [...postToolUseFeedback, ...postToolUseFailureFeedback];
|
|
59142
|
+
const finalErrorMessage = allFeedback.length > 0 ? `${errorMessage}
|
|
59143
|
+
|
|
59144
|
+
[Hook feedback]:
|
|
59145
|
+
${allFeedback.join(`
|
|
59146
|
+
`)}` : errorMessage;
|
|
58991
59147
|
return {
|
|
58992
|
-
toolReturn:
|
|
59148
|
+
toolReturn: finalErrorMessage,
|
|
58993
59149
|
status: "error"
|
|
58994
59150
|
};
|
|
58995
59151
|
}
|
|
@@ -59025,6 +59181,7 @@ var init_manager3 = __esm(async () => {
|
|
|
59025
59181
|
init_model();
|
|
59026
59182
|
init_subagents();
|
|
59027
59183
|
init_constants();
|
|
59184
|
+
init_debug();
|
|
59028
59185
|
await __promiseAll([
|
|
59029
59186
|
init_approval_execution(),
|
|
59030
59187
|
init_hooks(),
|
|
@@ -61856,7 +62013,7 @@ function buildModelSettings(modelHandle, updateArgs) {
|
|
|
61856
62013
|
async function updateAgentLLMConfig(agentId, modelHandle, updateArgs) {
|
|
61857
62014
|
const client = await getClient2();
|
|
61858
62015
|
const modelSettings = buildModelSettings(modelHandle, updateArgs);
|
|
61859
|
-
const contextWindow = updateArgs?.context_window;
|
|
62016
|
+
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
61860
62017
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
61861
62018
|
await client.agents.update(agentId, {
|
|
61862
62019
|
model: modelHandle,
|
|
@@ -61938,6 +62095,7 @@ async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
|
61938
62095
|
var init_modify = __esm(async () => {
|
|
61939
62096
|
await __promiseAll([
|
|
61940
62097
|
init_openai_codex_provider(),
|
|
62098
|
+
init_available_models(),
|
|
61941
62099
|
init_client2()
|
|
61942
62100
|
]);
|
|
61943
62101
|
});
|
|
@@ -62109,7 +62267,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
62109
62267
|
blockProvenance.push({ label: blockId, source: "shared" });
|
|
62110
62268
|
}
|
|
62111
62269
|
const modelUpdateArgs = getModelUpdateArgs(modelHandle);
|
|
62112
|
-
const contextWindow = modelUpdateArgs?.context_window;
|
|
62270
|
+
const contextWindow = modelUpdateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
62113
62271
|
let systemPromptContent;
|
|
62114
62272
|
if (options.systemPromptCustom) {
|
|
62115
62273
|
systemPromptContent = options.systemPromptCustom;
|
|
@@ -62182,6 +62340,7 @@ var init_create = __esm(async () => {
|
|
|
62182
62340
|
init_promptAssets();
|
|
62183
62341
|
init_skills2();
|
|
62184
62342
|
await __promiseAll([
|
|
62343
|
+
init_available_models(),
|
|
62185
62344
|
init_client2(),
|
|
62186
62345
|
init_modify()
|
|
62187
62346
|
]);
|
|
@@ -62853,16 +63012,6 @@ function isGlobTool(name) {
|
|
|
62853
63012
|
}
|
|
62854
63013
|
|
|
62855
63014
|
// src/cli/helpers/accumulator.ts
|
|
62856
|
-
var exports_accumulator = {};
|
|
62857
|
-
__export(exports_accumulator, {
|
|
62858
|
-
toLines: () => toLines,
|
|
62859
|
-
setToolCallsRunning: () => setToolCallsRunning,
|
|
62860
|
-
onChunk: () => onChunk,
|
|
62861
|
-
markIncompleteToolsAsCancelled: () => markIncompleteToolsAsCancelled,
|
|
62862
|
-
markCurrentLineAsFinished: () => markCurrentLineAsFinished,
|
|
62863
|
-
createBuffers: () => createBuffers,
|
|
62864
|
-
appendStreamingOutput: () => appendStreamingOutput
|
|
62865
|
-
});
|
|
62866
63015
|
function appendStreamingOutput(state, chunk, startTime, isStderr = false) {
|
|
62867
63016
|
const current = state || {
|
|
62868
63017
|
tailLines: [],
|
|
@@ -62963,7 +63112,7 @@ function markCurrentLineAsFinished(b) {
|
|
|
62963
63112
|
if (!b.lastOtid) {
|
|
62964
63113
|
return;
|
|
62965
63114
|
}
|
|
62966
|
-
const prev = b.byId.get(b.lastOtid)
|
|
63115
|
+
const prev = b.byId.get(b.lastOtid);
|
|
62967
63116
|
if (prev && (prev.kind === "assistant" || prev.kind === "reasoning")) {
|
|
62968
63117
|
markAsFinished(b, b.lastOtid);
|
|
62969
63118
|
} else {}
|
|
@@ -63109,48 +63258,33 @@ function onChunk(b, chunk) {
|
|
|
63109
63258
|
}
|
|
63110
63259
|
case "tool_call_message":
|
|
63111
63260
|
case "approval_request_message": {
|
|
63112
|
-
|
|
63261
|
+
handleOtidTransition(b, chunk.otid ?? undefined);
|
|
63113
63262
|
const toolCall = chunk.tool_call || (Array.isArray(chunk.tool_calls) && chunk.tool_calls.length > 0 ? chunk.tool_calls[0] : null);
|
|
63114
|
-
|
|
63115
|
-
const name = toolCall?.name;
|
|
63116
|
-
const argsText = toolCall?.arguments;
|
|
63117
|
-
if (toolCallId && b.toolCallIdToLineId.has(toolCallId)) {
|
|
63118
|
-
const existingId = b.toolCallIdToLineId.get(toolCallId);
|
|
63119
|
-
if (existingId) {
|
|
63120
|
-
id = existingId;
|
|
63121
|
-
}
|
|
63122
|
-
handleOtidTransition(b, chunk.otid ?? undefined);
|
|
63123
|
-
} else {
|
|
63124
|
-
if (id && b.byId.has(id)) {
|
|
63125
|
-
const existing = b.byId.get(id);
|
|
63126
|
-
if (existing && existing.kind === "reasoning") {
|
|
63127
|
-
markAsFinished(b, id);
|
|
63128
|
-
id = `${id}-tool`;
|
|
63129
|
-
} else if (existing && existing.kind === "tool_call") {
|
|
63130
|
-
if (toolCallId) {
|
|
63131
|
-
id = `${id}-${toolCallId.slice(-8)}`;
|
|
63132
|
-
} else {
|
|
63133
|
-
id = `${id}-${Date.now().toString(36)}`;
|
|
63134
|
-
}
|
|
63135
|
-
}
|
|
63136
|
-
}
|
|
63137
|
-
handleOtidTransition(b, id ?? undefined);
|
|
63138
|
-
if (!id) {
|
|
63139
|
-
break;
|
|
63140
|
-
}
|
|
63141
|
-
if (toolCallId)
|
|
63142
|
-
b.toolCallIdToLineId.set(toolCallId, id);
|
|
63143
|
-
}
|
|
63144
|
-
if (!id)
|
|
63263
|
+
if (!toolCall || !toolCall.tool_call_id)
|
|
63145
63264
|
break;
|
|
63265
|
+
const toolCallId = toolCall.tool_call_id;
|
|
63266
|
+
const name = toolCall.name;
|
|
63267
|
+
const argsText = toolCall.arguments;
|
|
63268
|
+
const id = b.toolCallIdToLineId.get(toolCallId) ?? toolCallId;
|
|
63269
|
+
if (!b.toolCallIdToLineId.has(toolCallId)) {
|
|
63270
|
+
b.toolCallIdToLineId.set(toolCallId, id);
|
|
63271
|
+
}
|
|
63146
63272
|
const desiredPhase = "ready";
|
|
63147
|
-
|
|
63273
|
+
let line = ensure(b, id, () => ({
|
|
63148
63274
|
kind: "tool_call",
|
|
63149
63275
|
id,
|
|
63150
|
-
toolCallId
|
|
63276
|
+
toolCallId,
|
|
63151
63277
|
name: name ?? undefined,
|
|
63152
63278
|
phase: desiredPhase
|
|
63153
63279
|
}));
|
|
63280
|
+
if (name && !line.name || line.toolCallId !== toolCallId) {
|
|
63281
|
+
line = {
|
|
63282
|
+
...line,
|
|
63283
|
+
toolCallId,
|
|
63284
|
+
name: line.name ?? name ?? undefined
|
|
63285
|
+
};
|
|
63286
|
+
b.byId.set(id, line);
|
|
63287
|
+
}
|
|
63154
63288
|
if (chunk.message_type === "approval_request_message" && line.phase !== "finished") {
|
|
63155
63289
|
b.byId.set(id, { ...line, phase: "ready" });
|
|
63156
63290
|
}
|
|
@@ -63182,7 +63316,9 @@ function onChunk(b, chunk) {
|
|
|
63182
63316
|
parsedArgs = JSON.parse(toolInfo.toolArgs);
|
|
63183
63317
|
}
|
|
63184
63318
|
} catch {}
|
|
63185
|
-
runPreToolUseHooks(toolInfo.toolName, parsedArgs, toolCallId, undefined, b.agentId).catch(() => {
|
|
63319
|
+
runPreToolUseHooks(toolInfo.toolName, parsedArgs, toolCallId, undefined, b.agentId).catch((error) => {
|
|
63320
|
+
debugLog("hooks", "PreToolUse hook error (accumulator)", error);
|
|
63321
|
+
});
|
|
63186
63322
|
}
|
|
63187
63323
|
}
|
|
63188
63324
|
break;
|
|
@@ -63231,7 +63367,9 @@ function onChunk(b, chunk) {
|
|
|
63231
63367
|
runPostToolUseHooks(serverToolInfo.toolName, parsedArgs, {
|
|
63232
63368
|
status: status === "success" ? "success" : "error",
|
|
63233
63369
|
output: resultText
|
|
63234
|
-
}, toolCallId, undefined, b.agentId, precedingReasoning, precedingAssistantMessage).catch(() => {
|
|
63370
|
+
}, toolCallId, undefined, b.agentId, precedingReasoning, precedingAssistantMessage).catch((error) => {
|
|
63371
|
+
debugLog("hooks", "PostToolUse hook error (accumulator)", error);
|
|
63372
|
+
});
|
|
63235
63373
|
b.serverToolCalls.delete(toolCallId);
|
|
63236
63374
|
}
|
|
63237
63375
|
}
|
|
@@ -63337,6 +63475,7 @@ function setToolCallsRunning(b, toolCallIds) {
|
|
|
63337
63475
|
var MAX_TAIL_LINES = 5, MAX_BUFFER_SIZE = 1e5, CANCEL_REASON_TEXT;
|
|
63338
63476
|
var init_accumulator = __esm(async () => {
|
|
63339
63477
|
init_constants();
|
|
63478
|
+
init_debug();
|
|
63340
63479
|
init_backfill();
|
|
63341
63480
|
await init_hooks();
|
|
63342
63481
|
CANCEL_REASON_TEXT = {
|
|
@@ -63347,6 +63486,99 @@ var init_accumulator = __esm(async () => {
|
|
|
63347
63486
|
};
|
|
63348
63487
|
});
|
|
63349
63488
|
|
|
63489
|
+
// src/cli/helpers/safeJsonParse.ts
|
|
63490
|
+
function safeJsonParse(json) {
|
|
63491
|
+
try {
|
|
63492
|
+
const data = JSON.parse(json);
|
|
63493
|
+
return { success: true, data };
|
|
63494
|
+
} catch (error) {
|
|
63495
|
+
return {
|
|
63496
|
+
success: false,
|
|
63497
|
+
error: error instanceof Error ? error.message : String(error)
|
|
63498
|
+
};
|
|
63499
|
+
}
|
|
63500
|
+
}
|
|
63501
|
+
function safeJsonParseOr(json, defaultValue) {
|
|
63502
|
+
const result = safeJsonParse(json);
|
|
63503
|
+
return result.success ? result.data : defaultValue;
|
|
63504
|
+
}
|
|
63505
|
+
|
|
63506
|
+
// src/cli/helpers/approvalClassification.ts
|
|
63507
|
+
async function getMissingRequiredArgs(toolName, parsedArgs) {
|
|
63508
|
+
const schema = getToolSchema(toolName);
|
|
63509
|
+
const required = schema?.input_schema?.required || [];
|
|
63510
|
+
return required.filter((key) => !(key in parsedArgs) || parsedArgs[key] == null);
|
|
63511
|
+
}
|
|
63512
|
+
async function classifyApprovals(approvals, opts = {}) {
|
|
63513
|
+
const needsUserInput = [];
|
|
63514
|
+
const autoAllowed = [];
|
|
63515
|
+
const autoDenied = [];
|
|
63516
|
+
const denyReasonForAsk = opts.denyReasonForAsk ?? "Tool requires approval (headless mode)";
|
|
63517
|
+
const missingNameReason = opts.missingNameReason ?? "Tool call incomplete - missing name";
|
|
63518
|
+
for (const approval of approvals) {
|
|
63519
|
+
const toolName = approval.toolName;
|
|
63520
|
+
if (!toolName) {
|
|
63521
|
+
autoDenied.push({
|
|
63522
|
+
approval,
|
|
63523
|
+
permission: { decision: "deny", reason: missingNameReason },
|
|
63524
|
+
context: null,
|
|
63525
|
+
parsedArgs: {},
|
|
63526
|
+
denyReason: missingNameReason
|
|
63527
|
+
});
|
|
63528
|
+
continue;
|
|
63529
|
+
}
|
|
63530
|
+
const parsedArgs = safeJsonParseOr(approval.toolArgs || "{}", {});
|
|
63531
|
+
const permission = await checkToolPermission(toolName, parsedArgs);
|
|
63532
|
+
const context3 = opts.getContext ? await opts.getContext(toolName, parsedArgs) : null;
|
|
63533
|
+
let decision = permission.decision;
|
|
63534
|
+
if (opts.alwaysRequiresUserInput?.(toolName) && decision === "allow") {
|
|
63535
|
+
decision = "ask";
|
|
63536
|
+
}
|
|
63537
|
+
if (decision === "ask" && opts.treatAskAsDeny) {
|
|
63538
|
+
autoDenied.push({
|
|
63539
|
+
approval,
|
|
63540
|
+
permission,
|
|
63541
|
+
context: context3,
|
|
63542
|
+
parsedArgs,
|
|
63543
|
+
denyReason: denyReasonForAsk
|
|
63544
|
+
});
|
|
63545
|
+
continue;
|
|
63546
|
+
}
|
|
63547
|
+
if (decision === "allow" && opts.requireArgsForAutoApprove) {
|
|
63548
|
+
const missingRequiredArgs = await getMissingRequiredArgs(toolName, parsedArgs);
|
|
63549
|
+
if (missingRequiredArgs.length > 0) {
|
|
63550
|
+
const denyReason = opts.missingArgsReason ? opts.missingArgsReason(missingRequiredArgs) : `Missing required parameter${missingRequiredArgs.length > 1 ? "s" : ""}: ${missingRequiredArgs.join(", ")}`;
|
|
63551
|
+
autoDenied.push({
|
|
63552
|
+
approval,
|
|
63553
|
+
permission,
|
|
63554
|
+
context: context3,
|
|
63555
|
+
parsedArgs,
|
|
63556
|
+
missingRequiredArgs,
|
|
63557
|
+
denyReason
|
|
63558
|
+
});
|
|
63559
|
+
continue;
|
|
63560
|
+
}
|
|
63561
|
+
}
|
|
63562
|
+
const entry = {
|
|
63563
|
+
approval,
|
|
63564
|
+
permission,
|
|
63565
|
+
context: context3,
|
|
63566
|
+
parsedArgs
|
|
63567
|
+
};
|
|
63568
|
+
if (decision === "ask") {
|
|
63569
|
+
needsUserInput.push(entry);
|
|
63570
|
+
} else if (decision === "deny") {
|
|
63571
|
+
autoDenied.push(entry);
|
|
63572
|
+
} else {
|
|
63573
|
+
autoAllowed.push(entry);
|
|
63574
|
+
}
|
|
63575
|
+
}
|
|
63576
|
+
return { needsUserInput, autoAllowed, autoDenied };
|
|
63577
|
+
}
|
|
63578
|
+
var init_approvalClassification = __esm(async () => {
|
|
63579
|
+
await init_manager3();
|
|
63580
|
+
});
|
|
63581
|
+
|
|
63350
63582
|
// src/cli/helpers/errorContext.ts
|
|
63351
63583
|
function setErrorContext(context3) {
|
|
63352
63584
|
currentContext = { ...currentContext, ...context3 };
|
|
@@ -63543,23 +63775,6 @@ var init_errorFormatter = __esm(() => {
|
|
|
63543
63775
|
init_errorContext();
|
|
63544
63776
|
});
|
|
63545
63777
|
|
|
63546
|
-
// src/cli/helpers/safeJsonParse.ts
|
|
63547
|
-
function safeJsonParse(json) {
|
|
63548
|
-
try {
|
|
63549
|
-
const data = JSON.parse(json);
|
|
63550
|
-
return { success: true, data };
|
|
63551
|
-
} catch (error) {
|
|
63552
|
-
return {
|
|
63553
|
-
success: false,
|
|
63554
|
-
error: error instanceof Error ? error.message : String(error)
|
|
63555
|
-
};
|
|
63556
|
-
}
|
|
63557
|
-
}
|
|
63558
|
-
function safeJsonParseOr(json, defaultValue) {
|
|
63559
|
-
const result = safeJsonParse(json);
|
|
63560
|
-
return result.success ? result.data : defaultValue;
|
|
63561
|
-
}
|
|
63562
|
-
|
|
63563
63778
|
// src/cli/helpers/streamProcessor.ts
|
|
63564
63779
|
class StreamProcessor {
|
|
63565
63780
|
pendingApprovals = new Map;
|
|
@@ -63567,7 +63782,6 @@ class StreamProcessor {
|
|
|
63567
63782
|
lastRunId = null;
|
|
63568
63783
|
lastSeqId = null;
|
|
63569
63784
|
stopReason = null;
|
|
63570
|
-
lastApprovalId = null;
|
|
63571
63785
|
processChunk(chunk) {
|
|
63572
63786
|
let errorInfo;
|
|
63573
63787
|
let updatedApproval;
|
|
@@ -63607,21 +63821,13 @@ class StreamProcessor {
|
|
|
63607
63821
|
this.pendingApprovals.delete(chunk.tool_call_id);
|
|
63608
63822
|
}
|
|
63609
63823
|
}
|
|
63610
|
-
if (chunk.message_type === "approval_request_message") {
|
|
63611
|
-
this.lastApprovalId = chunk.id;
|
|
63612
|
-
}
|
|
63613
63824
|
if (chunk.message_type === "approval_request_message") {
|
|
63614
63825
|
const toolCalls = Array.isArray(chunk.tool_calls) ? chunk.tool_calls : chunk.tool_call ? [chunk.tool_call] : [];
|
|
63615
63826
|
for (const toolCall of toolCalls) {
|
|
63616
|
-
|
|
63617
|
-
if (!
|
|
63618
|
-
if (this.pendingApprovals.size === 1) {
|
|
63619
|
-
id = Array.from(this.pendingApprovals.keys())[0] ?? null;
|
|
63620
|
-
}
|
|
63621
|
-
}
|
|
63622
|
-
if (!id)
|
|
63827
|
+
const toolCallId = toolCall?.tool_call_id;
|
|
63828
|
+
if (!toolCallId)
|
|
63623
63829
|
continue;
|
|
63624
|
-
|
|
63830
|
+
const id = toolCallId;
|
|
63625
63831
|
const existing = this.pendingApprovals.get(id) || {
|
|
63626
63832
|
toolCallId: id,
|
|
63627
63833
|
toolName: "",
|
|
@@ -63652,7 +63858,7 @@ class StreamProcessor {
|
|
|
63652
63858
|
}
|
|
63653
63859
|
|
|
63654
63860
|
// src/cli/helpers/stream.ts
|
|
63655
|
-
async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage) {
|
|
63861
|
+
async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed) {
|
|
63656
63862
|
const startTime = performance.now();
|
|
63657
63863
|
const requestStartTime = stream2[STREAM_REQUEST_START_TIME];
|
|
63658
63864
|
let hasLoggedTTFT = false;
|
|
@@ -63702,17 +63908,44 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
63702
63908
|
const ttft = performance.now() - requestStartTime;
|
|
63703
63909
|
logTiming(`TTFT: ${formatDuration(ttft)} (from POST to first content)`);
|
|
63704
63910
|
}
|
|
63705
|
-
const { shouldOutput } = streamProcessor.processChunk(chunk);
|
|
63911
|
+
const { shouldOutput, errorInfo, updatedApproval } = streamProcessor.processChunk(chunk);
|
|
63706
63912
|
if (abortSignal?.aborted) {
|
|
63707
63913
|
stopReason = "cancelled";
|
|
63708
63914
|
markIncompleteToolsAsCancelled(buffers, true, "user_interrupt");
|
|
63709
63915
|
queueMicrotask(refresh);
|
|
63710
63916
|
break;
|
|
63711
63917
|
}
|
|
63712
|
-
|
|
63918
|
+
let shouldOutputChunk = shouldOutput;
|
|
63919
|
+
let shouldAccumulate = shouldOutput;
|
|
63920
|
+
if (onChunkProcessed) {
|
|
63921
|
+
const hookResult = await onChunkProcessed({
|
|
63922
|
+
chunk,
|
|
63923
|
+
shouldOutput: shouldOutputChunk,
|
|
63924
|
+
errorInfo,
|
|
63925
|
+
updatedApproval,
|
|
63926
|
+
streamProcessor
|
|
63927
|
+
});
|
|
63928
|
+
if (hookResult?.shouldOutput !== undefined) {
|
|
63929
|
+
shouldOutputChunk = hookResult.shouldOutput;
|
|
63930
|
+
}
|
|
63931
|
+
if (hookResult?.shouldAccumulate !== undefined) {
|
|
63932
|
+
shouldAccumulate = hookResult.shouldAccumulate;
|
|
63933
|
+
} else {
|
|
63934
|
+
shouldAccumulate = shouldOutputChunk;
|
|
63935
|
+
}
|
|
63936
|
+
if (hookResult?.stopReason) {
|
|
63937
|
+
stopReason = hookResult.stopReason;
|
|
63938
|
+
}
|
|
63939
|
+
} else {
|
|
63940
|
+
shouldAccumulate = shouldOutputChunk;
|
|
63941
|
+
}
|
|
63942
|
+
if (shouldAccumulate) {
|
|
63713
63943
|
onChunk(buffers, chunk);
|
|
63714
63944
|
queueMicrotask(refresh);
|
|
63715
63945
|
}
|
|
63946
|
+
if (stopReason) {
|
|
63947
|
+
break;
|
|
63948
|
+
}
|
|
63716
63949
|
}
|
|
63717
63950
|
} catch (e) {
|
|
63718
63951
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
@@ -63779,9 +64012,9 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
63779
64012
|
fallbackError
|
|
63780
64013
|
};
|
|
63781
64014
|
}
|
|
63782
|
-
async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onFirstMessage) {
|
|
64015
|
+
async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed) {
|
|
63783
64016
|
const overallStartTime = performance.now();
|
|
63784
|
-
let result = await drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage);
|
|
64017
|
+
let result = await drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed);
|
|
63785
64018
|
if (result.stopReason === "error" && result.lastRunId && result.lastSeqId !== null && abortSignal && !abortSignal.aborted) {
|
|
63786
64019
|
const originalFallbackError = result.fallbackError;
|
|
63787
64020
|
try {
|
|
@@ -63792,7 +64025,7 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
63792
64025
|
starting_after: result.lastSeqId,
|
|
63793
64026
|
batch_size: 1000
|
|
63794
64027
|
});
|
|
63795
|
-
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal);
|
|
64028
|
+
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal, undefined, onChunkProcessed);
|
|
63796
64029
|
result = resumeResult;
|
|
63797
64030
|
} catch (_e) {
|
|
63798
64031
|
result.fallbackError = originalFallbackError;
|
|
@@ -63803,6 +64036,7 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
63803
64036
|
}
|
|
63804
64037
|
var init_stream = __esm(async () => {
|
|
63805
64038
|
init_error();
|
|
64039
|
+
init_debug();
|
|
63806
64040
|
init_timing();
|
|
63807
64041
|
await __promiseAll([
|
|
63808
64042
|
init_client2(),
|
|
@@ -64227,6 +64461,7 @@ async function getResumeData2(client, agent, conversationId) {
|
|
|
64227
64461
|
var MESSAGE_HISTORY_LIMIT2 = 15;
|
|
64228
64462
|
var init_check_approval = __esm(() => {
|
|
64229
64463
|
init_error();
|
|
64464
|
+
init_debug();
|
|
64230
64465
|
});
|
|
64231
64466
|
|
|
64232
64467
|
// src/headless.ts
|
|
@@ -64313,6 +64548,13 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
|
|
|
64313
64548
|
}
|
|
64314
64549
|
const inputFormat = values["input-format"];
|
|
64315
64550
|
const isBidirectionalMode = inputFormat === "stream-json";
|
|
64551
|
+
process.stdout.on("error", (err) => {
|
|
64552
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : undefined;
|
|
64553
|
+
if (code === "EPIPE") {
|
|
64554
|
+
process.exit(0);
|
|
64555
|
+
}
|
|
64556
|
+
throw err;
|
|
64557
|
+
});
|
|
64316
64558
|
let prompt = positionals.slice(2).join(" ");
|
|
64317
64559
|
if (!prompt && !isBidirectionalMode) {
|
|
64318
64560
|
if (!process.stdin.isTTY) {
|
|
@@ -64617,10 +64859,7 @@ In headless mode, use:
|
|
|
64617
64859
|
const noSkillsFlag = values["no-skills"];
|
|
64618
64860
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
64619
64861
|
if (!noSkillsFlag && !isSubagent) {
|
|
64620
|
-
|
|
64621
|
-
if (createdBlocks.length > 0) {
|
|
64622
|
-
console.log("Created missing skills blocks for agent compatibility");
|
|
64623
|
-
}
|
|
64862
|
+
await ensureSkillsBlocks(agent.id);
|
|
64624
64863
|
}
|
|
64625
64864
|
if (memfsFlag) {
|
|
64626
64865
|
settingsManager.setMemfsEnabled(agent.id, true);
|
|
@@ -64628,6 +64867,8 @@ In headless mode, use:
|
|
|
64628
64867
|
settingsManager.setMemfsEnabled(agent.id, false);
|
|
64629
64868
|
} else if (isNewlyCreatedAgent && !isSubagent) {
|
|
64630
64869
|
settingsManager.setMemfsEnabled(agent.id, true);
|
|
64870
|
+
} else if (specifiedAgentId && !isSubagent) {
|
|
64871
|
+
settingsManager.setMemfsEnabled(agent.id, true);
|
|
64631
64872
|
}
|
|
64632
64873
|
if (settingsManager.isMemfsEnabled(agent.id)) {
|
|
64633
64874
|
try {
|
|
@@ -64638,9 +64879,6 @@ In headless mode, use:
|
|
|
64638
64879
|
process.exit(1);
|
|
64639
64880
|
}
|
|
64640
64881
|
await updateMemoryFilesystemBlock(agent.id);
|
|
64641
|
-
if (syncResult.updatedBlocks.length > 0 || syncResult.createdBlocks.length > 0 || syncResult.deletedBlocks.length > 0 || syncResult.updatedFiles.length > 0 || syncResult.createdFiles.length > 0 || syncResult.deletedFiles.length > 0) {
|
|
64642
|
-
console.log(formatMemorySyncSummary(syncResult));
|
|
64643
|
-
}
|
|
64644
64882
|
} catch (error) {
|
|
64645
64883
|
console.error(`Memory filesystem sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
64646
64884
|
process.exit(1);
|
|
@@ -64771,39 +65009,28 @@ In headless mode, use:
|
|
|
64771
65009
|
const pendingApprovals = resume.pendingApprovals || [];
|
|
64772
65010
|
if (pendingApprovals.length === 0)
|
|
64773
65011
|
break;
|
|
64774
|
-
const
|
|
64775
|
-
|
|
64776
|
-
|
|
64777
|
-
|
|
64778
|
-
|
|
64779
|
-
|
|
64780
|
-
|
|
64781
|
-
|
|
64782
|
-
type: "deny",
|
|
64783
|
-
approval: currentApproval,
|
|
64784
|
-
reason: denyReason
|
|
64785
|
-
});
|
|
64786
|
-
continue;
|
|
64787
|
-
}
|
|
64788
|
-
const { getToolSchema: getToolSchema2 } = await init_manager3().then(() => exports_manager2);
|
|
64789
|
-
const schema = getToolSchema2(toolName);
|
|
64790
|
-
const required = schema?.input_schema?.required || [];
|
|
64791
|
-
const missing = required.filter((key) => !(key in parsedArgs) || parsedArgs[key] == null);
|
|
64792
|
-
if (missing.length > 0) {
|
|
64793
|
-
decisions.push({
|
|
64794
|
-
type: "deny",
|
|
64795
|
-
approval: currentApproval,
|
|
64796
|
-
reason: `Missing required parameter${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`
|
|
64797
|
-
});
|
|
64798
|
-
continue;
|
|
64799
|
-
}
|
|
64800
|
-
decisions.push({
|
|
65012
|
+
const { autoAllowed, autoDenied } = await classifyApprovals(pendingApprovals, {
|
|
65013
|
+
treatAskAsDeny: true,
|
|
65014
|
+
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
65015
|
+
requireArgsForAutoApprove: true,
|
|
65016
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65017
|
+
});
|
|
65018
|
+
const decisions = [
|
|
65019
|
+
...autoAllowed.map((ac) => ({
|
|
64801
65020
|
type: "approve",
|
|
64802
|
-
approval:
|
|
64803
|
-
reason: permission.reason || "Allowed by permission rule",
|
|
64804
|
-
matchedRule: permission.matchedRule
|
|
64805
|
-
})
|
|
64806
|
-
|
|
65021
|
+
approval: ac.approval,
|
|
65022
|
+
reason: ac.permission.reason || "Allowed by permission rule",
|
|
65023
|
+
matchedRule: "matchedRule" in ac.permission && ac.permission.matchedRule ? ac.permission.matchedRule : "auto-approved"
|
|
65024
|
+
})),
|
|
65025
|
+
...autoDenied.map((ac) => {
|
|
65026
|
+
const fallback = "matchedRule" in ac.permission && ac.permission.matchedRule ? `Permission denied: ${ac.permission.matchedRule}` : ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : "Permission denied: Unknown reason";
|
|
65027
|
+
return {
|
|
65028
|
+
type: "deny",
|
|
65029
|
+
approval: ac.approval,
|
|
65030
|
+
reason: ac.denyReason ?? fallback
|
|
65031
|
+
};
|
|
65032
|
+
})
|
|
65033
|
+
];
|
|
64807
65034
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
64808
65035
|
if (outputFormat === "stream-json") {
|
|
64809
65036
|
for (const decision of decisions) {
|
|
@@ -64923,12 +65150,16 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
64923
65150
|
let approvals = [];
|
|
64924
65151
|
let apiDurationMs;
|
|
64925
65152
|
let lastRunId = null;
|
|
65153
|
+
let approvalPendingRecovery = false;
|
|
64926
65154
|
if (outputFormat === "stream-json") {
|
|
64927
|
-
const startTime = performance.now();
|
|
64928
65155
|
const autoApprovalEmitted = new Set;
|
|
64929
|
-
const
|
|
64930
|
-
|
|
64931
|
-
|
|
65156
|
+
const streamJsonHook = async ({
|
|
65157
|
+
chunk,
|
|
65158
|
+
shouldOutput,
|
|
65159
|
+
errorInfo,
|
|
65160
|
+
updatedApproval
|
|
65161
|
+
}) => {
|
|
65162
|
+
let shouldOutputChunk = shouldOutput;
|
|
64932
65163
|
if (errorInfo && shouldOutput) {
|
|
64933
65164
|
const errorEvent = {
|
|
64934
65165
|
type: "error",
|
|
@@ -64948,52 +65179,45 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
64948
65179
|
}
|
|
64949
65180
|
};
|
|
64950
65181
|
console.log(JSON.stringify(errorEvent));
|
|
64951
|
-
|
|
64952
|
-
accumulatorOnChunk(buffers, chunk);
|
|
64953
|
-
continue;
|
|
65182
|
+
shouldOutputChunk = false;
|
|
64954
65183
|
}
|
|
64955
65184
|
if (isApprovalPendingError(errorInfo?.detail) || isApprovalPendingError(errorInfo?.message)) {
|
|
64956
|
-
|
|
64957
|
-
|
|
64958
|
-
|
|
64959
|
-
|
|
64960
|
-
|
|
64961
|
-
|
|
65185
|
+
const recoveryRunId = errorInfo?.run_id;
|
|
65186
|
+
const recoveryMsg = {
|
|
65187
|
+
type: "recovery",
|
|
65188
|
+
recovery_type: "approval_pending",
|
|
65189
|
+
message: "Detected pending approval conflict; auto-denying stale approval and retrying",
|
|
65190
|
+
run_id: recoveryRunId ?? undefined,
|
|
65191
|
+
session_id: sessionId,
|
|
65192
|
+
uuid: `recovery-${recoveryRunId || crypto.randomUUID()}`
|
|
65193
|
+
};
|
|
65194
|
+
console.log(JSON.stringify(recoveryMsg));
|
|
65195
|
+
approvalPendingRecovery = true;
|
|
65196
|
+
return { stopReason: "error", shouldAccumulate: true };
|
|
65197
|
+
}
|
|
65198
|
+
if (updatedApproval && !autoApprovalEmitted.has(updatedApproval.toolCallId)) {
|
|
65199
|
+
const { autoAllowed } = await classifyApprovals([updatedApproval], {
|
|
65200
|
+
requireArgsForAutoApprove: true,
|
|
65201
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65202
|
+
});
|
|
65203
|
+
const [approval] = autoAllowed;
|
|
65204
|
+
if (approval) {
|
|
65205
|
+
const permission = approval.permission;
|
|
65206
|
+
shouldOutputChunk = false;
|
|
65207
|
+
const autoApprovalMsg = {
|
|
65208
|
+
type: "auto_approval",
|
|
65209
|
+
tool_call: {
|
|
65210
|
+
name: approval.approval.toolName,
|
|
65211
|
+
tool_call_id: approval.approval.toolCallId,
|
|
65212
|
+
arguments: approval.approval.toolArgs || "{}"
|
|
65213
|
+
},
|
|
65214
|
+
reason: permission.reason || "Allowed by permission rule",
|
|
65215
|
+
matched_rule: "matchedRule" in permission && permission.matchedRule ? permission.matchedRule : "auto-approved",
|
|
64962
65216
|
session_id: sessionId,
|
|
64963
|
-
uuid: `
|
|
65217
|
+
uuid: `auto-approval-${approval.approval.toolCallId}`
|
|
64964
65218
|
};
|
|
64965
|
-
console.log(JSON.stringify(
|
|
64966
|
-
|
|
64967
|
-
await resolveAllPendingApprovals();
|
|
64968
|
-
stopReason = "error";
|
|
64969
|
-
break;
|
|
64970
|
-
}
|
|
64971
|
-
let shouldOutputChunk = shouldOutput;
|
|
64972
|
-
if (updatedApproval && !autoApprovalEmitted.has(updatedApproval.toolCallId) && updatedApproval.toolName) {
|
|
64973
|
-
const parsedArgs = safeJsonParseOr(updatedApproval.toolArgs || "{}", null);
|
|
64974
|
-
const permission = await checkToolPermission(updatedApproval.toolName, parsedArgs || {});
|
|
64975
|
-
if (permission.decision === "allow" && parsedArgs) {
|
|
64976
|
-
const { getToolSchema: getToolSchema2 } = await init_manager3().then(() => exports_manager2);
|
|
64977
|
-
const schema = getToolSchema2(updatedApproval.toolName);
|
|
64978
|
-
const required = schema?.input_schema?.required || [];
|
|
64979
|
-
const missing = required.filter((key) => !(key in parsedArgs) || parsedArgs[key] == null);
|
|
64980
|
-
if (missing.length === 0) {
|
|
64981
|
-
shouldOutputChunk = false;
|
|
64982
|
-
const autoApprovalMsg = {
|
|
64983
|
-
type: "auto_approval",
|
|
64984
|
-
tool_call: {
|
|
64985
|
-
name: updatedApproval.toolName,
|
|
64986
|
-
tool_call_id: updatedApproval.toolCallId,
|
|
64987
|
-
arguments: updatedApproval.toolArgs || "{}"
|
|
64988
|
-
},
|
|
64989
|
-
reason: permission.reason || "Allowed by permission rule",
|
|
64990
|
-
matched_rule: permission.matchedRule || "auto-approved",
|
|
64991
|
-
session_id: sessionId,
|
|
64992
|
-
uuid: `auto-approval-${updatedApproval.toolCallId}`
|
|
64993
|
-
};
|
|
64994
|
-
console.log(JSON.stringify(autoApprovalMsg));
|
|
64995
|
-
autoApprovalEmitted.add(updatedApproval.toolCallId);
|
|
64996
|
-
}
|
|
65219
|
+
console.log(JSON.stringify(autoApprovalMsg));
|
|
65220
|
+
autoApprovalEmitted.add(approval.approval.toolCallId);
|
|
64997
65221
|
}
|
|
64998
65222
|
}
|
|
64999
65223
|
if (shouldOutputChunk) {
|
|
@@ -65017,17 +65241,15 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65017
65241
|
console.log(JSON.stringify(msg));
|
|
65018
65242
|
}
|
|
65019
65243
|
}
|
|
65020
|
-
|
|
65021
|
-
|
|
65022
|
-
}
|
|
65023
|
-
stopReason =
|
|
65024
|
-
|
|
65025
|
-
|
|
65026
|
-
lastRunId =
|
|
65244
|
+
return { shouldOutput: shouldOutputChunk, shouldAccumulate: true };
|
|
65245
|
+
};
|
|
65246
|
+
const result = await drainStreamWithResume(stream2, buffers, () => {}, undefined, undefined, streamJsonHook);
|
|
65247
|
+
stopReason = result.stopReason;
|
|
65248
|
+
approvals = result.approvals || [];
|
|
65249
|
+
apiDurationMs = result.apiDurationMs;
|
|
65250
|
+
lastRunId = result.lastRunId || null;
|
|
65027
65251
|
if (lastRunId)
|
|
65028
65252
|
lastKnownRunId = lastRunId;
|
|
65029
|
-
const { markCurrentLineAsFinished: markCurrentLineAsFinished2 } = await init_accumulator().then(() => exports_accumulator);
|
|
65030
|
-
markCurrentLineAsFinished2(buffers);
|
|
65031
65253
|
} else {
|
|
65032
65254
|
const result = await drainStreamWithResume(stream2, buffers, () => {});
|
|
65033
65255
|
stopReason = result.stopReason;
|
|
@@ -65038,6 +65260,10 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65038
65260
|
lastKnownRunId = lastRunId;
|
|
65039
65261
|
}
|
|
65040
65262
|
sessionStats.endTurn(apiDurationMs);
|
|
65263
|
+
if (approvalPendingRecovery) {
|
|
65264
|
+
await resolveAllPendingApprovals();
|
|
65265
|
+
continue;
|
|
65266
|
+
}
|
|
65041
65267
|
if (stopReason === "end_turn") {
|
|
65042
65268
|
llmApiErrorRetries = 0;
|
|
65043
65269
|
conversationBusyRetries = 0;
|
|
@@ -65048,45 +65274,26 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65048
65274
|
console.error("Unexpected empty approvals array");
|
|
65049
65275
|
process.exit(1);
|
|
65050
65276
|
}
|
|
65051
|
-
const
|
|
65052
|
-
|
|
65053
|
-
|
|
65054
|
-
|
|
65055
|
-
|
|
65056
|
-
|
|
65057
|
-
|
|
65058
|
-
|
|
65059
|
-
type: "deny",
|
|
65060
|
-
approval: currentApproval,
|
|
65061
|
-
reason: denyReason
|
|
65062
|
-
});
|
|
65063
|
-
continue;
|
|
65064
|
-
}
|
|
65065
|
-
if (permission.decision === "ask") {
|
|
65066
|
-
decisions.push({
|
|
65067
|
-
type: "deny",
|
|
65068
|
-
approval: currentApproval,
|
|
65069
|
-
reason: "Tool requires approval (headless mode)"
|
|
65070
|
-
});
|
|
65071
|
-
continue;
|
|
65072
|
-
}
|
|
65073
|
-
const { getToolSchema: getToolSchema2 } = await init_manager3().then(() => exports_manager2);
|
|
65074
|
-
const schema = getToolSchema2(toolName);
|
|
65075
|
-
const required = schema?.input_schema?.required || [];
|
|
65076
|
-
const missing = required.filter((key) => !(key in parsedArgs) || parsedArgs[key] == null);
|
|
65077
|
-
if (missing.length > 0) {
|
|
65078
|
-
decisions.push({
|
|
65079
|
-
type: "deny",
|
|
65080
|
-
approval: currentApproval,
|
|
65081
|
-
reason: `Missing required parameter${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`
|
|
65082
|
-
});
|
|
65083
|
-
continue;
|
|
65084
|
-
}
|
|
65085
|
-
decisions.push({
|
|
65277
|
+
const { autoAllowed, autoDenied } = await classifyApprovals(approvals, {
|
|
65278
|
+
treatAskAsDeny: true,
|
|
65279
|
+
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
65280
|
+
requireArgsForAutoApprove: true,
|
|
65281
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65282
|
+
});
|
|
65283
|
+
const decisions = [
|
|
65284
|
+
...autoAllowed.map((ac) => ({
|
|
65086
65285
|
type: "approve",
|
|
65087
|
-
approval:
|
|
65088
|
-
})
|
|
65089
|
-
|
|
65286
|
+
approval: ac.approval
|
|
65287
|
+
})),
|
|
65288
|
+
...autoDenied.map((ac) => {
|
|
65289
|
+
const fallback = "matchedRule" in ac.permission && ac.permission.matchedRule ? `Permission denied: ${ac.permission.matchedRule}` : ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : "Permission denied: Unknown reason";
|
|
65290
|
+
return {
|
|
65291
|
+
type: "deny",
|
|
65292
|
+
approval: ac.approval,
|
|
65293
|
+
reason: ac.denyReason ?? fallback
|
|
65294
|
+
};
|
|
65295
|
+
})
|
|
65296
|
+
];
|
|
65090
65297
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
65091
65298
|
const executedResults = await executeApprovalBatch2(decisions);
|
|
65092
65299
|
currentInput = [
|
|
@@ -65505,6 +65712,8 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
65505
65712
|
const buffers = createBuffers(agent.id);
|
|
65506
65713
|
const startTime = performance.now();
|
|
65507
65714
|
let numTurns = 0;
|
|
65715
|
+
let lastStopReason = null;
|
|
65716
|
+
let sawStreamError = false;
|
|
65508
65717
|
let currentInput = [
|
|
65509
65718
|
{ role: "user", content: userContent }
|
|
65510
65719
|
];
|
|
@@ -65516,109 +65725,138 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
65516
65725
|
const stream2 = await sendMessageStream(conversationId, currentInput, {
|
|
65517
65726
|
agentId: agent.id
|
|
65518
65727
|
});
|
|
65519
|
-
const
|
|
65520
|
-
|
|
65521
|
-
|
|
65522
|
-
|
|
65728
|
+
const streamJsonHook = ({
|
|
65729
|
+
chunk,
|
|
65730
|
+
shouldOutput,
|
|
65731
|
+
errorInfo
|
|
65732
|
+
}) => {
|
|
65733
|
+
if (errorInfo && shouldOutput) {
|
|
65734
|
+
sawStreamError = true;
|
|
65735
|
+
const errorEvent = {
|
|
65736
|
+
type: "error",
|
|
65737
|
+
message: errorInfo.message,
|
|
65738
|
+
stop_reason: "error",
|
|
65739
|
+
run_id: errorInfo.run_id,
|
|
65740
|
+
session_id: sessionId,
|
|
65741
|
+
uuid: crypto.randomUUID(),
|
|
65742
|
+
...errorInfo.error_type && errorInfo.run_id && {
|
|
65743
|
+
api_error: {
|
|
65744
|
+
message_type: "error_message",
|
|
65745
|
+
message: errorInfo.message,
|
|
65746
|
+
error_type: errorInfo.error_type,
|
|
65747
|
+
detail: errorInfo.detail,
|
|
65748
|
+
run_id: errorInfo.run_id
|
|
65749
|
+
}
|
|
65750
|
+
}
|
|
65751
|
+
};
|
|
65752
|
+
console.log(JSON.stringify(errorEvent));
|
|
65753
|
+
return { shouldAccumulate: true };
|
|
65523
65754
|
}
|
|
65524
|
-
|
|
65525
|
-
|
|
65526
|
-
const chunkWithIds = chunk;
|
|
65527
|
-
const uuid = chunkWithIds.otid || chunkWithIds.id;
|
|
65528
|
-
if (includePartialMessages) {
|
|
65529
|
-
const streamEvent = {
|
|
65530
|
-
type: "stream_event",
|
|
65531
|
-
event: chunk,
|
|
65532
|
-
session_id: sessionId,
|
|
65533
|
-
uuid: uuid || crypto.randomUUID()
|
|
65534
|
-
};
|
|
65535
|
-
console.log(JSON.stringify(streamEvent));
|
|
65536
|
-
} else {
|
|
65537
|
-
const msg = {
|
|
65538
|
-
type: "message",
|
|
65539
|
-
...chunk,
|
|
65540
|
-
session_id: sessionId,
|
|
65541
|
-
uuid: uuid || crypto.randomUUID()
|
|
65542
|
-
};
|
|
65543
|
-
console.log(JSON.stringify(msg));
|
|
65544
|
-
}
|
|
65755
|
+
if (!shouldOutput) {
|
|
65756
|
+
return { shouldAccumulate: true };
|
|
65545
65757
|
}
|
|
65546
|
-
const
|
|
65547
|
-
|
|
65548
|
-
|
|
65549
|
-
|
|
65758
|
+
const chunkWithIds = chunk;
|
|
65759
|
+
const uuid = chunkWithIds.otid || chunkWithIds.id;
|
|
65760
|
+
if (includePartialMessages) {
|
|
65761
|
+
const streamEvent = {
|
|
65762
|
+
type: "stream_event",
|
|
65763
|
+
event: chunk,
|
|
65764
|
+
session_id: sessionId,
|
|
65765
|
+
uuid: uuid || crypto.randomUUID()
|
|
65766
|
+
};
|
|
65767
|
+
console.log(JSON.stringify(streamEvent));
|
|
65768
|
+
} else {
|
|
65769
|
+
const msg = {
|
|
65770
|
+
type: "message",
|
|
65771
|
+
...chunk,
|
|
65772
|
+
session_id: sessionId,
|
|
65773
|
+
uuid: uuid || crypto.randomUUID()
|
|
65774
|
+
};
|
|
65775
|
+
console.log(JSON.stringify(msg));
|
|
65776
|
+
}
|
|
65777
|
+
return { shouldAccumulate: true };
|
|
65778
|
+
};
|
|
65779
|
+
const result = await drainStreamWithResume(stream2, buffers, () => {}, currentAbortController?.signal, undefined, streamJsonHook);
|
|
65780
|
+
const stopReason = result.stopReason;
|
|
65781
|
+
lastStopReason = stopReason;
|
|
65782
|
+
const approvals = result.approvals || [];
|
|
65550
65783
|
if (stopReason === "end_turn") {
|
|
65551
65784
|
break;
|
|
65552
65785
|
}
|
|
65553
|
-
if (currentAbortController?.signal.aborted) {
|
|
65786
|
+
if (currentAbortController?.signal.aborted || stopReason === "cancelled") {
|
|
65554
65787
|
break;
|
|
65555
65788
|
}
|
|
65556
65789
|
if (stopReason === "requires_approval") {
|
|
65557
|
-
const approvals = streamProcessor.getApprovals();
|
|
65558
65790
|
if (approvals.length === 0) {
|
|
65791
|
+
lastStopReason = "error";
|
|
65559
65792
|
break;
|
|
65560
65793
|
}
|
|
65561
|
-
const
|
|
65562
|
-
|
|
65563
|
-
|
|
65564
|
-
|
|
65565
|
-
|
|
65794
|
+
const { autoAllowed, autoDenied, needsUserInput } = await classifyApprovals(approvals, {
|
|
65795
|
+
requireArgsForAutoApprove: true,
|
|
65796
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65797
|
+
});
|
|
65798
|
+
const decisions = [
|
|
65799
|
+
...autoAllowed.map((ac) => ({
|
|
65800
|
+
type: "approve",
|
|
65801
|
+
approval: ac.approval,
|
|
65802
|
+
matchedRule: "matchedRule" in ac.permission && ac.permission.matchedRule ? ac.permission.matchedRule : "auto-approved"
|
|
65803
|
+
})),
|
|
65804
|
+
...autoDenied.map((ac) => {
|
|
65805
|
+
const fallback = "matchedRule" in ac.permission && ac.permission.matchedRule ? `Permission denied: ${ac.permission.matchedRule}` : ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : "Permission denied: Unknown reason";
|
|
65806
|
+
return {
|
|
65807
|
+
type: "deny",
|
|
65808
|
+
approval: ac.approval,
|
|
65809
|
+
reason: ac.denyReason ?? fallback
|
|
65810
|
+
};
|
|
65811
|
+
})
|
|
65812
|
+
];
|
|
65813
|
+
for (const approvalItem of autoAllowed) {
|
|
65814
|
+
const permission = approvalItem.permission;
|
|
65815
|
+
const autoApprovalMsg = {
|
|
65816
|
+
type: "auto_approval",
|
|
65817
|
+
tool_call: {
|
|
65818
|
+
name: approvalItem.approval.toolName,
|
|
65819
|
+
tool_call_id: approvalItem.approval.toolCallId,
|
|
65820
|
+
arguments: approvalItem.approval.toolArgs
|
|
65821
|
+
},
|
|
65822
|
+
reason: permission.reason || "auto-approved",
|
|
65823
|
+
matched_rule: "matchedRule" in permission && permission.matchedRule ? permission.matchedRule : "auto-approved",
|
|
65824
|
+
session_id: sessionId,
|
|
65825
|
+
uuid: `auto-approval-${approvalItem.approval.toolCallId}`
|
|
65826
|
+
};
|
|
65827
|
+
console.log(JSON.stringify(autoApprovalMsg));
|
|
65828
|
+
}
|
|
65829
|
+
for (const ac of needsUserInput) {
|
|
65830
|
+
const permResponse = await requestPermission(ac.approval.toolCallId, ac.approval.toolName, ac.parsedArgs);
|
|
65831
|
+
if (permResponse.decision === "allow") {
|
|
65832
|
+
const finalApproval = permResponse.updatedInput ? {
|
|
65833
|
+
...ac.approval,
|
|
65834
|
+
toolArgs: JSON.stringify(permResponse.updatedInput)
|
|
65835
|
+
} : ac.approval;
|
|
65566
65836
|
decisions.push({
|
|
65567
65837
|
type: "approve",
|
|
65568
|
-
approval,
|
|
65569
|
-
matchedRule:
|
|
65838
|
+
approval: finalApproval,
|
|
65839
|
+
matchedRule: "SDK callback approved"
|
|
65570
65840
|
});
|
|
65571
65841
|
const autoApprovalMsg = {
|
|
65572
65842
|
type: "auto_approval",
|
|
65573
65843
|
tool_call: {
|
|
65574
|
-
name:
|
|
65575
|
-
tool_call_id:
|
|
65576
|
-
arguments:
|
|
65844
|
+
name: finalApproval.toolName,
|
|
65845
|
+
tool_call_id: finalApproval.toolCallId,
|
|
65846
|
+
arguments: finalApproval.toolArgs
|
|
65577
65847
|
},
|
|
65578
|
-
reason:
|
|
65579
|
-
matched_rule:
|
|
65848
|
+
reason: permResponse.reason || "SDK callback approved",
|
|
65849
|
+
matched_rule: "canUseTool callback",
|
|
65580
65850
|
session_id: sessionId,
|
|
65581
|
-
uuid: `auto-approval-${approval.toolCallId}`
|
|
65851
|
+
uuid: `auto-approval-${ac.approval.toolCallId}`
|
|
65582
65852
|
};
|
|
65583
65853
|
console.log(JSON.stringify(autoApprovalMsg));
|
|
65584
|
-
} else
|
|
65854
|
+
} else {
|
|
65585
65855
|
decisions.push({
|
|
65586
65856
|
type: "deny",
|
|
65587
|
-
approval,
|
|
65588
|
-
reason:
|
|
65857
|
+
approval: ac.approval,
|
|
65858
|
+
reason: permResponse.reason || "Denied by SDK callback"
|
|
65589
65859
|
});
|
|
65590
|
-
} else {
|
|
65591
|
-
const permResponse = await requestPermission(approval.toolCallId, approval.toolName, parsedArgs);
|
|
65592
|
-
if (permResponse.decision === "allow") {
|
|
65593
|
-
const finalApproval = permResponse.updatedInput ? {
|
|
65594
|
-
...approval,
|
|
65595
|
-
toolArgs: JSON.stringify(permResponse.updatedInput)
|
|
65596
|
-
} : approval;
|
|
65597
|
-
decisions.push({
|
|
65598
|
-
type: "approve",
|
|
65599
|
-
approval: finalApproval,
|
|
65600
|
-
matchedRule: "SDK callback approved"
|
|
65601
|
-
});
|
|
65602
|
-
const autoApprovalMsg = {
|
|
65603
|
-
type: "auto_approval",
|
|
65604
|
-
tool_call: {
|
|
65605
|
-
name: finalApproval.toolName,
|
|
65606
|
-
tool_call_id: finalApproval.toolCallId,
|
|
65607
|
-
arguments: finalApproval.toolArgs
|
|
65608
|
-
},
|
|
65609
|
-
reason: permResponse.reason || "SDK callback approved",
|
|
65610
|
-
matched_rule: "canUseTool callback",
|
|
65611
|
-
session_id: sessionId,
|
|
65612
|
-
uuid: `auto-approval-${approval.toolCallId}`
|
|
65613
|
-
};
|
|
65614
|
-
console.log(JSON.stringify(autoApprovalMsg));
|
|
65615
|
-
} else {
|
|
65616
|
-
decisions.push({
|
|
65617
|
-
type: "deny",
|
|
65618
|
-
approval,
|
|
65619
|
-
reason: permResponse.reason || "Denied by SDK callback"
|
|
65620
|
-
});
|
|
65621
|
-
}
|
|
65622
65860
|
}
|
|
65623
65861
|
}
|
|
65624
65862
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
@@ -65640,9 +65878,12 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
65640
65878
|
const lastReasoning = reversed.find((line2) => line2.kind === "reasoning" && ("text" in line2) && typeof line2.text === "string" && line2.text.trim().length > 0);
|
|
65641
65879
|
const lastToolResult = reversed.find((line2) => line2.kind === "tool_call" && ("resultText" in line2) && typeof line2.resultText === "string" && (line2.resultText ?? "").trim().length > 0);
|
|
65642
65880
|
const resultText = lastAssistant?.text || lastReasoning?.text || lastToolResult?.resultText || "";
|
|
65881
|
+
const isAborted = currentAbortController?.signal.aborted;
|
|
65882
|
+
const isError = sawStreamError || lastStopReason && lastStopReason !== "end_turn" && lastStopReason !== "requires_approval";
|
|
65883
|
+
const subtype = isAborted ? "interrupted" : isError ? "error" : "success";
|
|
65643
65884
|
const resultMsg = {
|
|
65644
65885
|
type: "result",
|
|
65645
|
-
subtype
|
|
65886
|
+
subtype,
|
|
65646
65887
|
session_id: sessionId,
|
|
65647
65888
|
duration_ms: Math.round(durationMs),
|
|
65648
65889
|
duration_api_ms: 0,
|
|
@@ -65652,18 +65893,38 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
65652
65893
|
conversation_id: conversationId,
|
|
65653
65894
|
run_ids: [],
|
|
65654
65895
|
usage: null,
|
|
65655
|
-
uuid: `result-${agent.id}-${Date.now()}
|
|
65896
|
+
uuid: `result-${agent.id}-${Date.now()}`,
|
|
65897
|
+
...subtype === "error" && {
|
|
65898
|
+
stop_reason: lastStopReason && lastStopReason !== "end_turn" ? lastStopReason : "error"
|
|
65899
|
+
}
|
|
65656
65900
|
};
|
|
65657
65901
|
console.log(JSON.stringify(resultMsg));
|
|
65658
65902
|
} catch (error) {
|
|
65903
|
+
const errorDetails = formatErrorDetails(error, agent.id);
|
|
65659
65904
|
const errorMsg2 = {
|
|
65660
65905
|
type: "error",
|
|
65661
|
-
message:
|
|
65906
|
+
message: errorDetails,
|
|
65662
65907
|
stop_reason: "error",
|
|
65663
65908
|
session_id: sessionId,
|
|
65664
65909
|
uuid: crypto.randomUUID()
|
|
65665
65910
|
};
|
|
65666
65911
|
console.log(JSON.stringify(errorMsg2));
|
|
65912
|
+
const errorResultMsg = {
|
|
65913
|
+
type: "result",
|
|
65914
|
+
subtype: "error",
|
|
65915
|
+
session_id: sessionId,
|
|
65916
|
+
duration_ms: 0,
|
|
65917
|
+
duration_api_ms: 0,
|
|
65918
|
+
num_turns: 0,
|
|
65919
|
+
result: null,
|
|
65920
|
+
agent_id: agent.id,
|
|
65921
|
+
conversation_id: conversationId,
|
|
65922
|
+
run_ids: [],
|
|
65923
|
+
usage: null,
|
|
65924
|
+
uuid: `result-error-${agent.id}-${Date.now()}`,
|
|
65925
|
+
stop_reason: "error"
|
|
65926
|
+
};
|
|
65927
|
+
console.log(JSON.stringify(errorResultMsg));
|
|
65667
65928
|
} finally {
|
|
65668
65929
|
currentAbortController = null;
|
|
65669
65930
|
}
|
|
@@ -65696,9 +65957,9 @@ var init_headless = __esm(async () => {
|
|
|
65696
65957
|
init_memoryFilesystem(),
|
|
65697
65958
|
init_message(),
|
|
65698
65959
|
init_accumulator(),
|
|
65960
|
+
init_approvalClassification(),
|
|
65699
65961
|
init_stream(),
|
|
65700
|
-
init_settings_manager()
|
|
65701
|
-
init_manager3()
|
|
65962
|
+
init_settings_manager()
|
|
65702
65963
|
]);
|
|
65703
65964
|
});
|
|
65704
65965
|
|
|
@@ -69710,7 +69971,8 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
69710
69971
|
onCancel,
|
|
69711
69972
|
isFocused = true,
|
|
69712
69973
|
approveAlwaysText,
|
|
69713
|
-
allowPersistence = true
|
|
69974
|
+
allowPersistence = true,
|
|
69975
|
+
showPreview = true
|
|
69714
69976
|
}) => {
|
|
69715
69977
|
const [selectedOption, setSelectedOption] = import_react36.useState(0);
|
|
69716
69978
|
const {
|
|
@@ -69768,6 +70030,15 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
69768
70030
|
}
|
|
69769
70031
|
if (key.escape) {
|
|
69770
70032
|
onCancel?.();
|
|
70033
|
+
return;
|
|
70034
|
+
}
|
|
70035
|
+
if (input === "1") {
|
|
70036
|
+
onApprove();
|
|
70037
|
+
return;
|
|
70038
|
+
}
|
|
70039
|
+
if (input === "2" && allowPersistence) {
|
|
70040
|
+
onApproveAlways("project");
|
|
70041
|
+
return;
|
|
69771
70042
|
}
|
|
69772
70043
|
}, { isActive: isFocused });
|
|
69773
70044
|
const solidLine = SOLID_LINE6.repeat(Math.max(columns, 10));
|
|
@@ -69801,12 +70072,13 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
69801
70072
|
]
|
|
69802
70073
|
}, undefined, true, undefined, this), [bashInfo.command, bashInfo.description, solidLine]);
|
|
69803
70074
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70075
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
69804
70076
|
return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
69805
70077
|
flexDirection: "column",
|
|
69806
70078
|
children: [
|
|
69807
|
-
memoizedCommandContent,
|
|
70079
|
+
showPreview && memoizedCommandContent,
|
|
69808
70080
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
69809
|
-
marginTop:
|
|
70081
|
+
marginTop: optionsMarginTop,
|
|
69810
70082
|
flexDirection: "column",
|
|
69811
70083
|
children: [
|
|
69812
70084
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
@@ -70126,7 +70398,8 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
70126
70398
|
onCancel,
|
|
70127
70399
|
isFocused = true,
|
|
70128
70400
|
approveAlwaysText,
|
|
70129
|
-
allowPersistence = true
|
|
70401
|
+
allowPersistence = true,
|
|
70402
|
+
showPreview = true
|
|
70130
70403
|
}) => {
|
|
70131
70404
|
const [selectedOption, setSelectedOption] = import_react38.useState(0);
|
|
70132
70405
|
const {
|
|
@@ -70217,6 +70490,15 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
70217
70490
|
}
|
|
70218
70491
|
if (key.escape) {
|
|
70219
70492
|
onCancel?.();
|
|
70493
|
+
return;
|
|
70494
|
+
}
|
|
70495
|
+
if (input === "1") {
|
|
70496
|
+
onApprove(diffsToPass.size > 0 ? diffsToPass : undefined);
|
|
70497
|
+
return;
|
|
70498
|
+
}
|
|
70499
|
+
if (input === "2" && allowPersistence) {
|
|
70500
|
+
onApproveAlways("project", diffsToPass.size > 0 ? diffsToPass : undefined);
|
|
70501
|
+
return;
|
|
70220
70502
|
}
|
|
70221
70503
|
}, { isActive: isFocused });
|
|
70222
70504
|
const solidLine = SOLID_LINE8.repeat(Math.max(columns, 10));
|
|
@@ -70354,12 +70636,13 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
70354
70636
|
diffKind
|
|
70355
70637
|
]);
|
|
70356
70638
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70639
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
70357
70640
|
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
70358
70641
|
flexDirection: "column",
|
|
70359
70642
|
children: [
|
|
70360
|
-
memoizedDiffContent,
|
|
70643
|
+
showPreview && memoizedDiffContent,
|
|
70361
70644
|
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
70362
|
-
marginTop:
|
|
70645
|
+
marginTop: optionsMarginTop,
|
|
70363
70646
|
flexDirection: "column",
|
|
70364
70647
|
children: [
|
|
70365
70648
|
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
@@ -70499,7 +70782,8 @@ var init_InlineGenericApproval = __esm(async () => {
|
|
|
70499
70782
|
onCancel,
|
|
70500
70783
|
isFocused = true,
|
|
70501
70784
|
approveAlwaysText,
|
|
70502
|
-
allowPersistence = true
|
|
70785
|
+
allowPersistence = true,
|
|
70786
|
+
showPreview = true
|
|
70503
70787
|
}) => {
|
|
70504
70788
|
const [selectedOption, setSelectedOption] = import_react39.useState(0);
|
|
70505
70789
|
const {
|
|
@@ -70557,6 +70841,15 @@ var init_InlineGenericApproval = __esm(async () => {
|
|
|
70557
70841
|
}
|
|
70558
70842
|
if (key.escape) {
|
|
70559
70843
|
onCancel?.();
|
|
70844
|
+
return;
|
|
70845
|
+
}
|
|
70846
|
+
if (input === "1") {
|
|
70847
|
+
onApprove();
|
|
70848
|
+
return;
|
|
70849
|
+
}
|
|
70850
|
+
if (input === "2" && allowPersistence) {
|
|
70851
|
+
onApproveAlways("project");
|
|
70852
|
+
return;
|
|
70560
70853
|
}
|
|
70561
70854
|
}, { isActive: isFocused });
|
|
70562
70855
|
const solidLine = SOLID_LINE9.repeat(Math.max(columns, 10));
|
|
@@ -70590,12 +70883,13 @@ var init_InlineGenericApproval = __esm(async () => {
|
|
|
70590
70883
|
]
|
|
70591
70884
|
}, undefined, true, undefined, this), [toolName, formattedArgs, solidLine]);
|
|
70592
70885
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70886
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
70593
70887
|
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
70594
70888
|
flexDirection: "column",
|
|
70595
70889
|
children: [
|
|
70596
|
-
memoizedToolContent,
|
|
70890
|
+
showPreview && memoizedToolContent,
|
|
70597
70891
|
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
70598
|
-
marginTop:
|
|
70892
|
+
marginTop: optionsMarginTop,
|
|
70599
70893
|
flexDirection: "column",
|
|
70600
70894
|
children: [
|
|
70601
70895
|
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
@@ -71149,6 +71443,15 @@ var init_InlineTaskApproval = __esm(async () => {
|
|
|
71149
71443
|
}
|
|
71150
71444
|
if (key.escape) {
|
|
71151
71445
|
onCancel?.();
|
|
71446
|
+
return;
|
|
71447
|
+
}
|
|
71448
|
+
if (input === "1") {
|
|
71449
|
+
onApprove();
|
|
71450
|
+
return;
|
|
71451
|
+
}
|
|
71452
|
+
if (input === "2" && allowPersistence) {
|
|
71453
|
+
onApproveAlways("session");
|
|
71454
|
+
return;
|
|
71152
71455
|
}
|
|
71153
71456
|
}, { isActive: isFocused });
|
|
71154
71457
|
const solidLine = SOLID_LINE11.repeat(Math.max(columns, 10));
|
|
@@ -71453,6 +71756,15 @@ var init_StaticPlanApproval = __esm(async () => {
|
|
|
71453
71756
|
}
|
|
71454
71757
|
if (key.escape) {
|
|
71455
71758
|
onKeepPlanning("User cancelled");
|
|
71759
|
+
return;
|
|
71760
|
+
}
|
|
71761
|
+
if (input === "1") {
|
|
71762
|
+
onApproveAndAcceptEdits();
|
|
71763
|
+
return;
|
|
71764
|
+
}
|
|
71765
|
+
if (input === "2") {
|
|
71766
|
+
onApprove();
|
|
71767
|
+
return;
|
|
71456
71768
|
}
|
|
71457
71769
|
}, { isActive: isFocused });
|
|
71458
71770
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type feedback · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
@@ -71670,7 +71982,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71670
71982
|
onEnterPlanModeApprove,
|
|
71671
71983
|
onEnterPlanModeReject,
|
|
71672
71984
|
precomputedDiff,
|
|
71673
|
-
allDiffs
|
|
71985
|
+
allDiffs,
|
|
71986
|
+
showPreview = true
|
|
71674
71987
|
}) => {
|
|
71675
71988
|
const toolName = approval.toolName;
|
|
71676
71989
|
if (toolName === "ExitPlanMode" && onPlanApprove && onPlanKeepPlanning) {
|
|
@@ -71695,7 +72008,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71695
72008
|
onCancel,
|
|
71696
72009
|
isFocused,
|
|
71697
72010
|
approveAlwaysText,
|
|
71698
|
-
allowPersistence
|
|
72011
|
+
allowPersistence,
|
|
72012
|
+
showPreview
|
|
71699
72013
|
}, undefined, false, undefined, this);
|
|
71700
72014
|
}
|
|
71701
72015
|
}
|
|
@@ -71710,7 +72024,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71710
72024
|
onCancel,
|
|
71711
72025
|
isFocused,
|
|
71712
72026
|
approveAlwaysText,
|
|
71713
|
-
allowPersistence
|
|
72027
|
+
allowPersistence,
|
|
72028
|
+
showPreview
|
|
71714
72029
|
}, undefined, false, undefined, this);
|
|
71715
72030
|
}
|
|
71716
72031
|
}
|
|
@@ -71723,12 +72038,14 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71723
72038
|
}
|
|
71724
72039
|
if (toolName === "AskUserQuestion" && onQuestionSubmit) {
|
|
71725
72040
|
const questions = getQuestions(approval);
|
|
71726
|
-
|
|
71727
|
-
|
|
71728
|
-
|
|
71729
|
-
|
|
71730
|
-
|
|
71731
|
-
|
|
72041
|
+
if (questions.length > 0) {
|
|
72042
|
+
return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(InlineQuestionApproval, {
|
|
72043
|
+
questions,
|
|
72044
|
+
onSubmit: onQuestionSubmit,
|
|
72045
|
+
onCancel,
|
|
72046
|
+
isFocused
|
|
72047
|
+
}, undefined, false, undefined, this);
|
|
72048
|
+
}
|
|
71732
72049
|
}
|
|
71733
72050
|
if (isTaskTool(toolName)) {
|
|
71734
72051
|
const taskInfo = getTaskInfo(approval);
|
|
@@ -71754,7 +72071,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71754
72071
|
onCancel,
|
|
71755
72072
|
isFocused,
|
|
71756
72073
|
approveAlwaysText,
|
|
71757
|
-
allowPersistence
|
|
72074
|
+
allowPersistence,
|
|
72075
|
+
showPreview
|
|
71758
72076
|
}, undefined, false, undefined, this);
|
|
71759
72077
|
});
|
|
71760
72078
|
ApprovalSwitch.displayName = "ApprovalSwitch";
|
|
@@ -71762,9 +72080,9 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71762
72080
|
|
|
71763
72081
|
// src/cli/components/AssistantMessageRich.tsx
|
|
71764
72082
|
var import_react44, jsx_dev_runtime23, normalize6 = (s) => s.replace(/\r\n/g, `
|
|
71765
|
-
`).replace(
|
|
72083
|
+
`).replace(/\n{3,}/g, `
|
|
71766
72084
|
|
|
71767
|
-
`).replace(/^\n
|
|
72085
|
+
`).replace(/^\n+/g, ""), AssistantMessage;
|
|
71768
72086
|
var init_AssistantMessageRich = __esm(async () => {
|
|
71769
72087
|
init_useTerminalWidth();
|
|
71770
72088
|
await __promiseAll([
|
|
@@ -72900,14 +73218,6 @@ var init_EventMessage = __esm(async () => {
|
|
|
72900
73218
|
color: colors.tool.completed,
|
|
72901
73219
|
children: "●"
|
|
72902
73220
|
}, undefined, false, undefined, this);
|
|
72903
|
-
const formatArgs2 = () => {
|
|
72904
|
-
const stats = line.stats;
|
|
72905
|
-
if (stats?.messagesCountBefore !== undefined && stats?.messagesCountAfter !== undefined) {
|
|
72906
|
-
return `${stats.messagesCountBefore} → ${stats.messagesCountAfter} messages`;
|
|
72907
|
-
}
|
|
72908
|
-
return "...";
|
|
72909
|
-
};
|
|
72910
|
-
const argsDisplay = formatArgs2();
|
|
72911
73221
|
return /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Box_default, {
|
|
72912
73222
|
flexDirection: "column",
|
|
72913
73223
|
children: [
|
|
@@ -72924,16 +73234,12 @@ var init_EventMessage = __esm(async () => {
|
|
|
72924
73234
|
width: rightWidth,
|
|
72925
73235
|
children: isRunning ? /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(CompactingAnimation, {}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Text2, {
|
|
72926
73236
|
bold: true,
|
|
72927
|
-
children:
|
|
72928
|
-
|
|
72929
|
-
argsDisplay,
|
|
72930
|
-
")"
|
|
72931
|
-
]
|
|
72932
|
-
}, undefined, true, undefined, this)
|
|
73237
|
+
children: "Conversation compacted"
|
|
73238
|
+
}, undefined, false, undefined, this)
|
|
72933
73239
|
}, undefined, false, undefined, this)
|
|
72934
73240
|
]
|
|
72935
73241
|
}, undefined, true, undefined, this),
|
|
72936
|
-
!isRunning && line.summary && /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(jsx_dev_runtime33.Fragment, {
|
|
73242
|
+
!isRunning && line.summary && (process.env.LETTA_DEBUG === "1" || process.env.LETTA_DEBUG === "true") && /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(jsx_dev_runtime33.Fragment, {
|
|
72937
73243
|
children: [
|
|
72938
73244
|
/* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Box_default, {
|
|
72939
73245
|
flexDirection: "row",
|
|
@@ -74389,10 +74695,10 @@ var init_registry = __esm(() => {
|
|
|
74389
74695
|
}
|
|
74390
74696
|
},
|
|
74391
74697
|
"/rename": {
|
|
74392
|
-
desc: "Rename
|
|
74698
|
+
desc: "Rename agent or conversation (/rename agent|convo <name>)",
|
|
74393
74699
|
order: 24,
|
|
74394
74700
|
handler: () => {
|
|
74395
|
-
return "Renaming
|
|
74701
|
+
return "Renaming...";
|
|
74396
74702
|
}
|
|
74397
74703
|
},
|
|
74398
74704
|
"/description": {
|
|
@@ -75052,7 +75358,8 @@ function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
|
75052
75358
|
case "project-local":
|
|
75053
75359
|
return settingsManager.getLocalProjectSettings(workingDirectory)?.hooks || {};
|
|
75054
75360
|
}
|
|
75055
|
-
} catch {
|
|
75361
|
+
} catch (error) {
|
|
75362
|
+
debugLog("hooks", "loadHooksFromLocation: Settings not loaded yet", error);
|
|
75056
75363
|
return {};
|
|
75057
75364
|
}
|
|
75058
75365
|
}
|
|
@@ -75204,7 +75511,8 @@ function countHooksForEvent(event, workingDirectory = process.cwd()) {
|
|
|
75204
75511
|
function isUserHooksDisabled() {
|
|
75205
75512
|
try {
|
|
75206
75513
|
return settingsManager.getSettings().hooks?.disabled === true;
|
|
75207
|
-
} catch {
|
|
75514
|
+
} catch (error) {
|
|
75515
|
+
debugLog("hooks", "isUserHooksDisabled: Failed to check user hooks disabled status", error);
|
|
75208
75516
|
return false;
|
|
75209
75517
|
}
|
|
75210
75518
|
}
|
|
@@ -75218,6 +75526,7 @@ function setHooksDisabled(disabled) {
|
|
|
75218
75526
|
});
|
|
75219
75527
|
}
|
|
75220
75528
|
var init_writer = __esm(async () => {
|
|
75529
|
+
init_debug();
|
|
75221
75530
|
init_types();
|
|
75222
75531
|
await init_settings_manager();
|
|
75223
75532
|
});
|
|
@@ -75261,6 +75570,7 @@ var init_HooksManager = __esm(async () => {
|
|
|
75261
75570
|
HOOK_EVENTS = [
|
|
75262
75571
|
{ event: "PreToolUse", description: "Before tool execution" },
|
|
75263
75572
|
{ event: "PostToolUse", description: "After tool execution" },
|
|
75573
|
+
{ event: "PostToolUseFailure", description: "After tool execution fails" },
|
|
75264
75574
|
{ event: "PermissionRequest", description: "When permission is requested" },
|
|
75265
75575
|
{ event: "UserPromptSubmit", description: "When user submits a prompt" },
|
|
75266
75576
|
{ event: "Notification", description: "When notifications are sent" },
|
|
@@ -77738,28 +78048,28 @@ var require_react_jsx_runtime_development = __commonJS((exports) => {
|
|
|
77738
78048
|
return null;
|
|
77739
78049
|
}
|
|
77740
78050
|
var ReactSharedInternals = React14.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
77741
|
-
function error(
|
|
78051
|
+
function error(format2) {
|
|
77742
78052
|
{
|
|
77743
78053
|
{
|
|
77744
78054
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
77745
78055
|
args[_key2 - 1] = arguments[_key2];
|
|
77746
78056
|
}
|
|
77747
|
-
printWarning("error",
|
|
78057
|
+
printWarning("error", format2, args);
|
|
77748
78058
|
}
|
|
77749
78059
|
}
|
|
77750
78060
|
}
|
|
77751
|
-
function printWarning(level,
|
|
78061
|
+
function printWarning(level, format2, args) {
|
|
77752
78062
|
{
|
|
77753
78063
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
77754
78064
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
77755
78065
|
if (stack !== "") {
|
|
77756
|
-
|
|
78066
|
+
format2 += "%s";
|
|
77757
78067
|
args = args.concat([stack]);
|
|
77758
78068
|
}
|
|
77759
78069
|
var argsWithFormat = args.map(function(item) {
|
|
77760
78070
|
return String(item);
|
|
77761
78071
|
});
|
|
77762
|
-
argsWithFormat.unshift("Warning: " +
|
|
78072
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
77763
78073
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
77764
78074
|
}
|
|
77765
78075
|
}
|
|
@@ -85409,9 +85719,9 @@ var init_ProviderSelector = __esm(async () => {
|
|
|
85409
85719
|
|
|
85410
85720
|
// src/cli/components/ReasoningMessageRich.tsx
|
|
85411
85721
|
var import_react79, jsx_dev_runtime56, normalize7 = (s) => s.replace(/\r\n/g, `
|
|
85412
|
-
`).replace(
|
|
85722
|
+
`).replace(/\n{3,}/g, `
|
|
85413
85723
|
|
|
85414
|
-
`).replace(/^\n
|
|
85724
|
+
`).replace(/^\n+/g, ""), ReasoningMessage;
|
|
85415
85725
|
var init_ReasoningMessageRich = __esm(async () => {
|
|
85416
85726
|
init_useTerminalWidth();
|
|
85417
85727
|
await __promiseAll([
|
|
@@ -87386,38 +87696,21 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
87386
87696
|
}
|
|
87387
87697
|
}
|
|
87388
87698
|
const fallback = displayName.length >= rightWidth;
|
|
87389
|
-
const
|
|
87699
|
+
const dotColor = (() => {
|
|
87390
87700
|
switch (line.phase) {
|
|
87391
87701
|
case "streaming":
|
|
87392
|
-
return
|
|
87393
|
-
color: colors.tool.streaming,
|
|
87394
|
-
children: "●"
|
|
87395
|
-
}, undefined, false, undefined, this);
|
|
87702
|
+
return colors.tool.streaming;
|
|
87396
87703
|
case "ready":
|
|
87397
|
-
return
|
|
87398
|
-
color: colors.tool.pending
|
|
87399
|
-
}, undefined, false, undefined, this);
|
|
87704
|
+
return colors.tool.pending;
|
|
87400
87705
|
case "running":
|
|
87401
|
-
return
|
|
87402
|
-
color: colors.tool.running
|
|
87403
|
-
}, undefined, false, undefined, this);
|
|
87706
|
+
return colors.tool.running;
|
|
87404
87707
|
case "finished":
|
|
87405
|
-
|
|
87406
|
-
return /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(Text2, {
|
|
87407
|
-
color: colors.tool.error,
|
|
87408
|
-
children: "●"
|
|
87409
|
-
}, undefined, false, undefined, this);
|
|
87410
|
-
}
|
|
87411
|
-
return /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(Text2, {
|
|
87412
|
-
color: colors.tool.completed,
|
|
87413
|
-
children: "●"
|
|
87414
|
-
}, undefined, false, undefined, this);
|
|
87708
|
+
return line.resultOk === false ? colors.tool.error : colors.tool.completed;
|
|
87415
87709
|
default:
|
|
87416
|
-
return
|
|
87417
|
-
children: "●"
|
|
87418
|
-
}, undefined, false, undefined, this);
|
|
87710
|
+
return;
|
|
87419
87711
|
}
|
|
87420
|
-
};
|
|
87712
|
+
})();
|
|
87713
|
+
const dotShouldAnimate = line.phase === "ready" || line.phase === "running";
|
|
87421
87714
|
const getResultElement = () => {
|
|
87422
87715
|
if (!line.resultText)
|
|
87423
87716
|
return null;
|
|
@@ -88003,7 +88296,10 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
88003
88296
|
width: 2,
|
|
88004
88297
|
flexShrink: 0,
|
|
88005
88298
|
children: [
|
|
88006
|
-
|
|
88299
|
+
/* @__PURE__ */ jsx_dev_runtime65.jsxDEV(BlinkDot, {
|
|
88300
|
+
color: dotColor,
|
|
88301
|
+
shouldAnimate: dotShouldAnimate
|
|
88302
|
+
}, undefined, false, undefined, this),
|
|
88007
88303
|
/* @__PURE__ */ jsx_dev_runtime65.jsxDEV(Text2, {}, undefined, false, undefined, this)
|
|
88008
88304
|
]
|
|
88009
88305
|
}, undefined, true, undefined, this),
|
|
@@ -90008,12 +90304,48 @@ function isNonStateCommand(msg) {
|
|
|
90008
90304
|
}
|
|
90009
90305
|
return false;
|
|
90010
90306
|
}
|
|
90307
|
+
function countWrappedLines(text, width) {
|
|
90308
|
+
if (!text)
|
|
90309
|
+
return 0;
|
|
90310
|
+
const wrapWidth = Math.max(1, width);
|
|
90311
|
+
return text.split(/\r?\n/).reduce((sum, line) => {
|
|
90312
|
+
const len = line.length;
|
|
90313
|
+
const wrapped = Math.max(1, Math.ceil(len / wrapWidth));
|
|
90314
|
+
return sum + wrapped;
|
|
90315
|
+
}, 0);
|
|
90316
|
+
}
|
|
90317
|
+
function countWrappedLinesFromList(lines, width) {
|
|
90318
|
+
if (!lines.length)
|
|
90319
|
+
return 0;
|
|
90320
|
+
const wrapWidth = Math.max(1, width);
|
|
90321
|
+
return lines.reduce((sum, line) => {
|
|
90322
|
+
const len = line.length;
|
|
90323
|
+
const wrapped = Math.max(1, Math.ceil(len / wrapWidth));
|
|
90324
|
+
return sum + wrapped;
|
|
90325
|
+
}, 0);
|
|
90326
|
+
}
|
|
90327
|
+
function estimateAdvancedDiffLines(diff2, width) {
|
|
90328
|
+
const wrapWidth = Math.max(1, width);
|
|
90329
|
+
let total = 0;
|
|
90330
|
+
for (const hunk of diff2.hunks) {
|
|
90331
|
+
for (const line of hunk.lines) {
|
|
90332
|
+
const raw = line.raw || "";
|
|
90333
|
+
if (raw.startsWith("\\"))
|
|
90334
|
+
continue;
|
|
90335
|
+
const text = raw.slice(1);
|
|
90336
|
+
total += Math.max(1, Math.ceil(text.length / wrapWidth));
|
|
90337
|
+
}
|
|
90338
|
+
}
|
|
90339
|
+
return total;
|
|
90340
|
+
}
|
|
90011
90341
|
function uid4(prefix) {
|
|
90012
90342
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
90013
90343
|
}
|
|
90014
90344
|
function sendDesktopNotification(message = "Awaiting your input", level = "info") {
|
|
90015
90345
|
process.stdout.write("\x07");
|
|
90016
|
-
runNotificationHooks(message, level).catch(() => {
|
|
90346
|
+
runNotificationHooks(message, level).catch((error) => {
|
|
90347
|
+
debugLog("hooks", "Notification hook error", error);
|
|
90348
|
+
});
|
|
90017
90349
|
}
|
|
90018
90350
|
async function isRetriableError(stopReason, lastRunId) {
|
|
90019
90351
|
if (stopReason === "llm_api_error")
|
|
@@ -90498,18 +90830,23 @@ function App2({
|
|
|
90498
90830
|
closeTrajectorySegment,
|
|
90499
90831
|
syncTrajectoryElapsedBase
|
|
90500
90832
|
]);
|
|
90833
|
+
const sessionStartFeedbackRef = import_react91.useRef([]);
|
|
90501
90834
|
import_react91.useEffect(() => {
|
|
90502
|
-
if (agentId && !sessionHooksRanRef.current) {
|
|
90835
|
+
if (agentId && agentId !== "loading" && !sessionHooksRanRef.current) {
|
|
90503
90836
|
sessionHooksRanRef.current = true;
|
|
90504
90837
|
const isNewSession = !initialConversationId;
|
|
90505
|
-
runSessionStartHooks(isNewSession, agentId, agentName ?? undefined, conversationIdRef.current ?? undefined).
|
|
90838
|
+
runSessionStartHooks(isNewSession, agentId, agentName ?? undefined, conversationIdRef.current ?? undefined).then((result) => {
|
|
90839
|
+
if (result.feedback.length > 0) {
|
|
90840
|
+
sessionStartFeedbackRef.current = result.feedback;
|
|
90841
|
+
}
|
|
90842
|
+
}).catch(() => {});
|
|
90506
90843
|
}
|
|
90507
90844
|
}, [agentId, agentName, initialConversationId]);
|
|
90508
|
-
import_react91.
|
|
90509
|
-
|
|
90510
|
-
|
|
90511
|
-
runSessionEndHooks(durationMs, undefined, undefined, agentIdRef.current ?? undefined, conversationIdRef.current ?? undefined)
|
|
90512
|
-
}
|
|
90845
|
+
const runEndHooks = import_react91.useCallback(async () => {
|
|
90846
|
+
const durationMs = Date.now() - sessionStartTimeRef.current;
|
|
90847
|
+
try {
|
|
90848
|
+
await runSessionEndHooks(durationMs, undefined, undefined, agentIdRef.current ?? undefined, conversationIdRef.current ?? undefined);
|
|
90849
|
+
} catch {}
|
|
90513
90850
|
}, []);
|
|
90514
90851
|
import_react91.useEffect(() => {
|
|
90515
90852
|
return () => {
|
|
@@ -90652,9 +90989,34 @@ function App2({
|
|
|
90652
90989
|
setStaticRenderEpoch((epoch) => epoch + 1);
|
|
90653
90990
|
lastClearedColumnsRef.current = pendingColumns;
|
|
90654
90991
|
}, [columns, streaming]);
|
|
90655
|
-
const
|
|
90992
|
+
const deferredToolCallCommitsRef = import_react91.useRef(new Map);
|
|
90993
|
+
const [deferredCommitAt, setDeferredCommitAt] = import_react91.useState(null);
|
|
90994
|
+
const resetDeferredToolCallCommits = import_react91.useCallback(() => {
|
|
90995
|
+
deferredToolCallCommitsRef.current.clear();
|
|
90996
|
+
setDeferredCommitAt(null);
|
|
90997
|
+
}, []);
|
|
90998
|
+
const commitEligibleLines = import_react91.useCallback((b, opts) => {
|
|
90999
|
+
const deferToolCalls = opts?.deferToolCalls !== false;
|
|
90656
91000
|
const newlyCommitted = [];
|
|
90657
91001
|
let firstTaskIndex = -1;
|
|
91002
|
+
const deferredCommits = deferredToolCallCommitsRef.current;
|
|
91003
|
+
const now = Date.now();
|
|
91004
|
+
let blockedByDeferred = false;
|
|
91005
|
+
const shouldSkipCommittedToolCall = (ln) => {
|
|
91006
|
+
if (ln.kind !== "tool_call")
|
|
91007
|
+
return false;
|
|
91008
|
+
if (!ln.toolCallId || !ln.name)
|
|
91009
|
+
return false;
|
|
91010
|
+
if (ln.phase !== "finished" || ln.resultOk === false)
|
|
91011
|
+
return false;
|
|
91012
|
+
if (!eagerCommittedPreviewsRef.current.has(ln.toolCallId))
|
|
91013
|
+
return false;
|
|
91014
|
+
return isFileEditTool(ln.name) || isFileWriteTool(ln.name) || isPatchTool(ln.name);
|
|
91015
|
+
};
|
|
91016
|
+
if (!deferToolCalls && deferredCommits.size > 0) {
|
|
91017
|
+
deferredCommits.clear();
|
|
91018
|
+
setDeferredCommitAt(null);
|
|
91019
|
+
}
|
|
90658
91020
|
const hasInProgress = hasInProgressTaskToolCalls(b.order, b.byId, emittedIdsRef.current);
|
|
90659
91021
|
const finishedTaskToolCalls = collectFinishedTaskToolCalls(b.order, b.byId, emittedIdsRef.current, hasInProgress);
|
|
90660
91022
|
for (const id of b.order) {
|
|
@@ -90695,11 +91057,32 @@ function App2({
|
|
|
90695
91057
|
continue;
|
|
90696
91058
|
}
|
|
90697
91059
|
if ("phase" in ln && ln.phase === "finished") {
|
|
91060
|
+
if (shouldSkipCommittedToolCall(ln)) {
|
|
91061
|
+
deferredCommits.delete(id);
|
|
91062
|
+
emittedIdsRef.current.add(id);
|
|
91063
|
+
continue;
|
|
91064
|
+
}
|
|
91065
|
+
if (deferToolCalls && ln.kind === "tool_call" && (!ln.name || !isTaskTool(ln.name))) {
|
|
91066
|
+
const commitAt = deferredCommits.get(id);
|
|
91067
|
+
if (commitAt === undefined) {
|
|
91068
|
+
const nextCommitAt = now + TOOL_CALL_COMMIT_DEFER_MS;
|
|
91069
|
+
deferredCommits.set(id, nextCommitAt);
|
|
91070
|
+
setDeferredCommitAt(nextCommitAt);
|
|
91071
|
+
blockedByDeferred = true;
|
|
91072
|
+
break;
|
|
91073
|
+
}
|
|
91074
|
+
if (commitAt > now) {
|
|
91075
|
+
setDeferredCommitAt(commitAt);
|
|
91076
|
+
blockedByDeferred = true;
|
|
91077
|
+
break;
|
|
91078
|
+
}
|
|
91079
|
+
deferredCommits.delete(id);
|
|
91080
|
+
}
|
|
90698
91081
|
emittedIdsRef.current.add(id);
|
|
90699
91082
|
newlyCommitted.push({ ...ln });
|
|
90700
91083
|
}
|
|
90701
91084
|
}
|
|
90702
|
-
if (finishedTaskToolCalls.length > 0) {
|
|
91085
|
+
if (!blockedByDeferred && finishedTaskToolCalls.length > 0) {
|
|
90703
91086
|
for (const tc of finishedTaskToolCalls) {
|
|
90704
91087
|
emittedIdsRef.current.add(tc.lineId);
|
|
90705
91088
|
}
|
|
@@ -90707,6 +91090,9 @@ function App2({
|
|
|
90707
91090
|
newlyCommitted.splice(firstTaskIndex >= 0 ? firstTaskIndex : newlyCommitted.length, 0, groupItem);
|
|
90708
91091
|
clearSubagentsByIds(groupItem.agents.map((a) => a.id));
|
|
90709
91092
|
}
|
|
91093
|
+
if (deferredCommits.size === 0) {
|
|
91094
|
+
setDeferredCommitAt(null);
|
|
91095
|
+
}
|
|
90710
91096
|
if (newlyCommitted.length > 0) {
|
|
90711
91097
|
setStaticItems((prev) => [...prev, ...newlyCommitted]);
|
|
90712
91098
|
}
|
|
@@ -90723,6 +91109,108 @@ function App2({
|
|
|
90723
91109
|
const precomputedDiffsRef = import_react91.useRef(new Map);
|
|
90724
91110
|
const lastPlanFilePathRef = import_react91.useRef(null);
|
|
90725
91111
|
const eagerCommittedPreviewsRef = import_react91.useRef(new Set);
|
|
91112
|
+
const estimateApprovalPreviewLines = import_react91.useCallback((approval) => {
|
|
91113
|
+
const toolName = approval.toolName;
|
|
91114
|
+
if (!toolName)
|
|
91115
|
+
return 0;
|
|
91116
|
+
const args = safeJsonParseOr(approval.toolArgs || "{}", {});
|
|
91117
|
+
const wrapWidth = Math.max(MIN_WRAP_WIDTH, columns - TEXT_WRAP_GUTTER);
|
|
91118
|
+
const diffWrapWidth = Math.max(MIN_WRAP_WIDTH, columns - DIFF_WRAP_GUTTER);
|
|
91119
|
+
if (isShellTool(toolName)) {
|
|
91120
|
+
const t = toolName.toLowerCase();
|
|
91121
|
+
let command = "(no command)";
|
|
91122
|
+
let description = "";
|
|
91123
|
+
if (t === "shell") {
|
|
91124
|
+
const cmdVal = args.command;
|
|
91125
|
+
command = Array.isArray(cmdVal) ? cmdVal.join(" ") : typeof cmdVal === "string" ? cmdVal : "(no command)";
|
|
91126
|
+
description = typeof args.justification === "string" ? args.justification : "";
|
|
91127
|
+
} else {
|
|
91128
|
+
command = typeof args.command === "string" ? args.command : "(no command)";
|
|
91129
|
+
description = typeof args.description === "string" ? args.description : typeof args.justification === "string" ? args.justification : "";
|
|
91130
|
+
}
|
|
91131
|
+
let lines2 = 3;
|
|
91132
|
+
lines2 += countWrappedLines(command, wrapWidth);
|
|
91133
|
+
if (description) {
|
|
91134
|
+
lines2 += countWrappedLines(description, wrapWidth);
|
|
91135
|
+
}
|
|
91136
|
+
return lines2;
|
|
91137
|
+
}
|
|
91138
|
+
if (isFileEditTool(toolName) || isFileWriteTool(toolName) || isPatchTool(toolName)) {
|
|
91139
|
+
const headerLines = 4;
|
|
91140
|
+
let diffLines2 = 0;
|
|
91141
|
+
const toolCallId = approval.toolCallId;
|
|
91142
|
+
if (isPatchTool(toolName) && typeof args.input === "string") {
|
|
91143
|
+
const operations = parsePatchOperations(args.input);
|
|
91144
|
+
operations.forEach((op, idx) => {
|
|
91145
|
+
if (idx > 0)
|
|
91146
|
+
diffLines2 += 1;
|
|
91147
|
+
diffLines2 += 1;
|
|
91148
|
+
const diffKey = toolCallId ? `${toolCallId}:${op.path}` : undefined;
|
|
91149
|
+
const opDiff = diffKey && precomputedDiffsRef.current.has(diffKey) ? precomputedDiffsRef.current.get(diffKey) : undefined;
|
|
91150
|
+
if (opDiff) {
|
|
91151
|
+
diffLines2 += estimateAdvancedDiffLines(opDiff, diffWrapWidth);
|
|
91152
|
+
return;
|
|
91153
|
+
}
|
|
91154
|
+
if (op.kind === "add") {
|
|
91155
|
+
diffLines2 += countWrappedLines(op.content, wrapWidth);
|
|
91156
|
+
return;
|
|
91157
|
+
}
|
|
91158
|
+
if (op.kind === "update") {
|
|
91159
|
+
if (op.patchLines?.length) {
|
|
91160
|
+
diffLines2 += countWrappedLinesFromList(op.patchLines, wrapWidth);
|
|
91161
|
+
} else {
|
|
91162
|
+
diffLines2 += countWrappedLines(op.oldString || "", wrapWidth);
|
|
91163
|
+
diffLines2 += countWrappedLines(op.newString || "", wrapWidth);
|
|
91164
|
+
}
|
|
91165
|
+
return;
|
|
91166
|
+
}
|
|
91167
|
+
diffLines2 += 1;
|
|
91168
|
+
});
|
|
91169
|
+
return headerLines + diffLines2;
|
|
91170
|
+
}
|
|
91171
|
+
const diff2 = toolCallId && precomputedDiffsRef.current.has(toolCallId) ? precomputedDiffsRef.current.get(toolCallId) : undefined;
|
|
91172
|
+
if (diff2) {
|
|
91173
|
+
diffLines2 += estimateAdvancedDiffLines(diff2, diffWrapWidth);
|
|
91174
|
+
return headerLines + diffLines2;
|
|
91175
|
+
}
|
|
91176
|
+
if (Array.isArray(args.edits)) {
|
|
91177
|
+
for (const edit2 of args.edits) {
|
|
91178
|
+
if (!edit2 || typeof edit2 !== "object")
|
|
91179
|
+
continue;
|
|
91180
|
+
const oldString2 = typeof edit2.old_string === "string" ? edit2.old_string : "";
|
|
91181
|
+
const newString2 = typeof edit2.new_string === "string" ? edit2.new_string : "";
|
|
91182
|
+
diffLines2 += countWrappedLines(oldString2, wrapWidth);
|
|
91183
|
+
diffLines2 += countWrappedLines(newString2, wrapWidth);
|
|
91184
|
+
}
|
|
91185
|
+
return headerLines + diffLines2;
|
|
91186
|
+
}
|
|
91187
|
+
if (typeof args.content === "string") {
|
|
91188
|
+
diffLines2 += countWrappedLines(args.content, wrapWidth);
|
|
91189
|
+
return headerLines + diffLines2;
|
|
91190
|
+
}
|
|
91191
|
+
const oldString = typeof args.old_string === "string" ? args.old_string : "";
|
|
91192
|
+
const newString = typeof args.new_string === "string" ? args.new_string : "";
|
|
91193
|
+
diffLines2 += countWrappedLines(oldString, wrapWidth);
|
|
91194
|
+
diffLines2 += countWrappedLines(newString, wrapWidth);
|
|
91195
|
+
return headerLines + diffLines2;
|
|
91196
|
+
}
|
|
91197
|
+
return 0;
|
|
91198
|
+
}, [columns]);
|
|
91199
|
+
const shouldEagerCommitApprovalPreview = import_react91.useCallback((approval) => {
|
|
91200
|
+
if (!terminalRows)
|
|
91201
|
+
return false;
|
|
91202
|
+
const previewLines = estimateApprovalPreviewLines(approval);
|
|
91203
|
+
if (previewLines === 0)
|
|
91204
|
+
return false;
|
|
91205
|
+
return previewLines + APPROVAL_OPTIONS_HEIGHT + APPROVAL_PREVIEW_BUFFER >= terminalRows;
|
|
91206
|
+
}, [estimateApprovalPreviewLines, terminalRows]);
|
|
91207
|
+
const currentApprovalShouldCommitPreview = import_react91.useMemo(() => {
|
|
91208
|
+
if (!currentApproval)
|
|
91209
|
+
return false;
|
|
91210
|
+
if (currentApproval.toolName === "ExitPlanMode")
|
|
91211
|
+
return false;
|
|
91212
|
+
return shouldEagerCommitApprovalPreview(currentApproval);
|
|
91213
|
+
}, [currentApproval, shouldEagerCommitApprovalPreview]);
|
|
90726
91214
|
const refreshDerived = import_react91.useCallback(() => {
|
|
90727
91215
|
const b = buffersRef.current;
|
|
90728
91216
|
setTokenCount(b.tokenCount);
|
|
@@ -90730,6 +91218,16 @@ function App2({
|
|
|
90730
91218
|
setLines(newLines);
|
|
90731
91219
|
commitEligibleLines(b);
|
|
90732
91220
|
}, [commitEligibleLines]);
|
|
91221
|
+
import_react91.useEffect(() => {
|
|
91222
|
+
if (deferredCommitAt === null)
|
|
91223
|
+
return;
|
|
91224
|
+
const delay = Math.max(0, deferredCommitAt - Date.now());
|
|
91225
|
+
const timer = setTimeout(() => {
|
|
91226
|
+
setDeferredCommitAt(null);
|
|
91227
|
+
refreshDerived();
|
|
91228
|
+
}, delay);
|
|
91229
|
+
return () => clearTimeout(timer);
|
|
91230
|
+
}, [deferredCommitAt, refreshDerived]);
|
|
90733
91231
|
const streamingRefreshTimeoutRef = import_react91.useRef(null);
|
|
90734
91232
|
const refreshDerivedStreaming = import_react91.useCallback(() => {
|
|
90735
91233
|
if (streamingRefreshTimeoutRef.current) {
|
|
@@ -90825,6 +91323,31 @@ function App2({
|
|
|
90825
91323
|
lastPlanFilePathRef.current = planFilePath;
|
|
90826
91324
|
} catch {}
|
|
90827
91325
|
}, [currentApproval]);
|
|
91326
|
+
import_react91.useEffect(() => {
|
|
91327
|
+
if (!currentApproval)
|
|
91328
|
+
return;
|
|
91329
|
+
if (currentApproval.toolName === "ExitPlanMode")
|
|
91330
|
+
return;
|
|
91331
|
+
const toolCallId = currentApproval.toolCallId;
|
|
91332
|
+
if (!toolCallId)
|
|
91333
|
+
return;
|
|
91334
|
+
if (eagerCommittedPreviewsRef.current.has(toolCallId))
|
|
91335
|
+
return;
|
|
91336
|
+
if (!currentApprovalShouldCommitPreview)
|
|
91337
|
+
return;
|
|
91338
|
+
const previewItem = {
|
|
91339
|
+
kind: "approval_preview",
|
|
91340
|
+
id: `approval-preview-${toolCallId}`,
|
|
91341
|
+
toolCallId,
|
|
91342
|
+
toolName: currentApproval.toolName,
|
|
91343
|
+
toolArgs: currentApproval.toolArgs || "{}"
|
|
91344
|
+
};
|
|
91345
|
+
if ((isFileEditTool(currentApproval.toolName) || isFileWriteTool(currentApproval.toolName)) && precomputedDiffsRef.current.has(toolCallId)) {
|
|
91346
|
+
previewItem.precomputedDiff = precomputedDiffsRef.current.get(toolCallId);
|
|
91347
|
+
}
|
|
91348
|
+
setStaticItems((prev) => [...prev, previewItem]);
|
|
91349
|
+
eagerCommittedPreviewsRef.current.add(toolCallId);
|
|
91350
|
+
}, [currentApproval, currentApprovalShouldCommitPreview]);
|
|
90828
91351
|
import_react91.useEffect(() => {
|
|
90829
91352
|
if (loadingState === "ready" && messageHistory.length > 0 && !hasBackfilledRef.current) {
|
|
90830
91353
|
hasBackfilledRef.current = true;
|
|
@@ -90886,7 +91409,7 @@ function App2({
|
|
|
90886
91409
|
});
|
|
90887
91410
|
buffersRef.current.order.push(statusId);
|
|
90888
91411
|
refreshDerived();
|
|
90889
|
-
commitEligibleLines(buffersRef.current);
|
|
91412
|
+
commitEligibleLines(buffersRef.current, { deferToolCalls: false });
|
|
90890
91413
|
}
|
|
90891
91414
|
}, [
|
|
90892
91415
|
loadingState,
|
|
@@ -91303,6 +91826,7 @@ ${newState.originalPrompt}`
|
|
|
91303
91826
|
}
|
|
91304
91827
|
if (isConversationBusyError(errorDetail) && conversationBusyRetriesRef.current < CONVERSATION_BUSY_MAX_RETRIES2) {
|
|
91305
91828
|
conversationBusyRetriesRef.current += 1;
|
|
91829
|
+
const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS * 2 ** (conversationBusyRetriesRef.current - 1);
|
|
91306
91830
|
const statusId = uid4("status");
|
|
91307
91831
|
buffersRef.current.byId.set(statusId, {
|
|
91308
91832
|
kind: "status",
|
|
@@ -91313,7 +91837,7 @@ ${newState.originalPrompt}`
|
|
|
91313
91837
|
refreshDerived();
|
|
91314
91838
|
let cancelled = false;
|
|
91315
91839
|
const startTime = Date.now();
|
|
91316
|
-
while (Date.now() - startTime <
|
|
91840
|
+
while (Date.now() - startTime < retryDelayMs) {
|
|
91317
91841
|
if (abortControllerRef.current?.signal.aborted || userCancelledRef.current) {
|
|
91318
91842
|
cancelled = true;
|
|
91319
91843
|
break;
|
|
@@ -91616,39 +92140,11 @@ ${feedback}
|
|
|
91616
92140
|
refreshDerived();
|
|
91617
92141
|
return;
|
|
91618
92142
|
}
|
|
91619
|
-
const
|
|
91620
|
-
|
|
91621
|
-
|
|
91622
|
-
|
|
91623
|
-
|
|
91624
|
-
decision: "deny",
|
|
91625
|
-
reason: "Tool call incomplete - missing name or arguments"
|
|
91626
|
-
},
|
|
91627
|
-
context: null
|
|
91628
|
-
};
|
|
91629
|
-
}
|
|
91630
|
-
const parsedArgs = safeJsonParseOr(approvalItem.toolArgs, {});
|
|
91631
|
-
const permission = await checkToolPermission(approvalItem.toolName, parsedArgs);
|
|
91632
|
-
const context3 = await analyzeToolApproval(approvalItem.toolName, parsedArgs);
|
|
91633
|
-
return { approval: approvalItem, permission, context: context3 };
|
|
91634
|
-
}));
|
|
91635
|
-
const needsUserInput = [];
|
|
91636
|
-
const autoDenied = [];
|
|
91637
|
-
const autoAllowed = [];
|
|
91638
|
-
for (const ac of approvalResults2) {
|
|
91639
|
-
const { approval: approval2, permission } = ac;
|
|
91640
|
-
let decision = permission.decision;
|
|
91641
|
-
if (alwaysRequiresUserInput(approval2.toolName) && decision === "allow") {
|
|
91642
|
-
decision = "ask";
|
|
91643
|
-
}
|
|
91644
|
-
if (decision === "ask") {
|
|
91645
|
-
needsUserInput.push(ac);
|
|
91646
|
-
} else if (decision === "deny") {
|
|
91647
|
-
autoDenied.push(ac);
|
|
91648
|
-
} else {
|
|
91649
|
-
autoAllowed.push(ac);
|
|
91650
|
-
}
|
|
91651
|
-
}
|
|
92143
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(approvalsToProcess, {
|
|
92144
|
+
getContext: analyzeToolApproval,
|
|
92145
|
+
alwaysRequiresUserInput,
|
|
92146
|
+
missingNameReason: "Tool call incomplete - missing name or arguments"
|
|
92147
|
+
});
|
|
91652
92148
|
for (const ac of [...autoAllowed, ...needsUserInput]) {
|
|
91653
92149
|
const toolName = ac.approval.toolName;
|
|
91654
92150
|
const toolCallId = ac.approval.toolCallId;
|
|
@@ -92133,6 +92629,7 @@ ${feedback}
|
|
|
92133
92629
|
]);
|
|
92134
92630
|
const handleExit = import_react91.useCallback(async () => {
|
|
92135
92631
|
saveLastAgentBeforeExit();
|
|
92632
|
+
await runEndHooks();
|
|
92136
92633
|
const stats = sessionStatsRef.current.getSnapshot();
|
|
92137
92634
|
telemetry2.trackSessionEnd(stats, "exit_command");
|
|
92138
92635
|
await telemetry2.flush();
|
|
@@ -92140,7 +92637,7 @@ ${feedback}
|
|
|
92140
92637
|
setTimeout(() => {
|
|
92141
92638
|
process.exit(0);
|
|
92142
92639
|
}, 100);
|
|
92143
|
-
}, []);
|
|
92640
|
+
}, [runEndHooks]);
|
|
92144
92641
|
const handleEnterQueueEditMode = import_react91.useCallback(() => {
|
|
92145
92642
|
setMessageQueue([]);
|
|
92146
92643
|
}, []);
|
|
@@ -92364,6 +92861,7 @@ ${feedback}
|
|
|
92364
92861
|
buffersRef.current.order = [];
|
|
92365
92862
|
buffersRef.current.tokenCount = 0;
|
|
92366
92863
|
emittedIdsRef.current.clear();
|
|
92864
|
+
resetDeferredToolCallCommits();
|
|
92367
92865
|
setStaticItems([]);
|
|
92368
92866
|
setStaticRenderEpoch((e) => e + 1);
|
|
92369
92867
|
resetTrajectoryBases();
|
|
@@ -92421,6 +92919,7 @@ ${feedback}
|
|
|
92421
92919
|
agentName,
|
|
92422
92920
|
setCommandRunning,
|
|
92423
92921
|
isAgentBusy,
|
|
92922
|
+
resetDeferredToolCallCommits,
|
|
92424
92923
|
resetTrajectoryBases
|
|
92425
92924
|
]);
|
|
92426
92925
|
const handleCreateNewAgent = import_react91.useCallback(async (name) => {
|
|
@@ -92444,6 +92943,7 @@ ${feedback}
|
|
|
92444
92943
|
buffersRef.current.order = [];
|
|
92445
92944
|
buffersRef.current.tokenCount = 0;
|
|
92446
92945
|
emittedIdsRef.current.clear();
|
|
92946
|
+
resetDeferredToolCallCommits();
|
|
92447
92947
|
setStaticItems([]);
|
|
92448
92948
|
setStaticRenderEpoch((e) => e + 1);
|
|
92449
92949
|
resetTrajectoryBases();
|
|
@@ -92487,7 +92987,13 @@ ${feedback}
|
|
|
92487
92987
|
} finally {
|
|
92488
92988
|
setCommandRunning(false);
|
|
92489
92989
|
}
|
|
92490
|
-
}, [
|
|
92990
|
+
}, [
|
|
92991
|
+
refreshDerived,
|
|
92992
|
+
agentId,
|
|
92993
|
+
setCommandRunning,
|
|
92994
|
+
resetDeferredToolCallCommits,
|
|
92995
|
+
resetTrajectoryBases
|
|
92996
|
+
]);
|
|
92491
92997
|
const handleBashSubmit = import_react91.useCallback(async (command) => {
|
|
92492
92998
|
if (bashRunning)
|
|
92493
92999
|
return;
|
|
@@ -92592,39 +93098,11 @@ ${expanded.command}` : expanded.command;
|
|
|
92592
93098
|
if (!existingApprovals || existingApprovals.length === 0) {
|
|
92593
93099
|
return { blocked: false };
|
|
92594
93100
|
}
|
|
92595
|
-
const
|
|
92596
|
-
|
|
92597
|
-
|
|
92598
|
-
|
|
92599
|
-
|
|
92600
|
-
decision: "deny",
|
|
92601
|
-
reason: "Tool call incomplete - missing name"
|
|
92602
|
-
},
|
|
92603
|
-
context: null
|
|
92604
|
-
};
|
|
92605
|
-
}
|
|
92606
|
-
const parsedArgs = safeJsonParseOr(approvalItem.toolArgs, {});
|
|
92607
|
-
const permission = await checkToolPermission(approvalItem.toolName, parsedArgs);
|
|
92608
|
-
const context3 = await analyzeToolApproval(approvalItem.toolName, parsedArgs);
|
|
92609
|
-
return { approval: approvalItem, permission, context: context3 };
|
|
92610
|
-
}));
|
|
92611
|
-
const needsUserInput = [];
|
|
92612
|
-
const autoAllowed = [];
|
|
92613
|
-
const autoDenied = [];
|
|
92614
|
-
for (const ac of approvalResults2) {
|
|
92615
|
-
const { approval, permission } = ac;
|
|
92616
|
-
let decision = permission.decision;
|
|
92617
|
-
if (alwaysRequiresUserInput(approval.toolName) && decision === "allow") {
|
|
92618
|
-
decision = "ask";
|
|
92619
|
-
}
|
|
92620
|
-
if (decision === "ask") {
|
|
92621
|
-
needsUserInput.push(ac);
|
|
92622
|
-
} else if (decision === "deny") {
|
|
92623
|
-
autoDenied.push(ac);
|
|
92624
|
-
} else {
|
|
92625
|
-
autoAllowed.push(ac);
|
|
92626
|
-
}
|
|
92627
|
-
}
|
|
93101
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(existingApprovals, {
|
|
93102
|
+
getContext: analyzeToolApproval,
|
|
93103
|
+
alwaysRequiresUserInput,
|
|
93104
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
93105
|
+
});
|
|
92628
93106
|
if (needsUserInput.length > 0) {
|
|
92629
93107
|
setPendingApprovals(needsUserInput.map((ac) => ac.approval));
|
|
92630
93108
|
setApprovalContexts(needsUserInput.map((ac) => ac.context).filter((ctx) => ctx !== null));
|
|
@@ -93181,6 +93659,7 @@ Type your task to begin the loop.`,
|
|
|
93181
93659
|
buffersRef.current.order.push(cmdId);
|
|
93182
93660
|
refreshDerived();
|
|
93183
93661
|
setCommandRunning(true);
|
|
93662
|
+
await runEndHooks();
|
|
93184
93663
|
try {
|
|
93185
93664
|
const client = await getClient2();
|
|
93186
93665
|
const conversation = await client.conversations.create({
|
|
@@ -93194,6 +93673,13 @@ Type your task to begin the loop.`,
|
|
|
93194
93673
|
conversationId: conversation.id
|
|
93195
93674
|
});
|
|
93196
93675
|
turnCountRef.current = 0;
|
|
93676
|
+
sessionHooksRanRef.current = false;
|
|
93677
|
+
runSessionStartHooks(true, agentId, agentName ?? undefined, conversation.id).then((result2) => {
|
|
93678
|
+
if (result2.feedback.length > 0) {
|
|
93679
|
+
sessionStartFeedbackRef.current = result2.feedback;
|
|
93680
|
+
}
|
|
93681
|
+
}).catch(() => {});
|
|
93682
|
+
sessionHooksRanRef.current = true;
|
|
93197
93683
|
buffersRef.current.byId.set(cmdId, {
|
|
93198
93684
|
kind: "command",
|
|
93199
93685
|
id: cmdId,
|
|
@@ -93232,6 +93718,7 @@ Type your task to begin the loop.`,
|
|
|
93232
93718
|
buffersRef.current.order.push(cmdId);
|
|
93233
93719
|
refreshDerived();
|
|
93234
93720
|
setCommandRunning(true);
|
|
93721
|
+
await runEndHooks();
|
|
93235
93722
|
try {
|
|
93236
93723
|
const client = await getClient2();
|
|
93237
93724
|
await client.agents.messages.reset(agentId, {
|
|
@@ -93248,6 +93735,13 @@ Type your task to begin the loop.`,
|
|
|
93248
93735
|
conversationId: conversation.id
|
|
93249
93736
|
});
|
|
93250
93737
|
turnCountRef.current = 0;
|
|
93738
|
+
sessionHooksRanRef.current = false;
|
|
93739
|
+
runSessionStartHooks(true, agentId, agentName ?? undefined, conversation.id).then((result2) => {
|
|
93740
|
+
if (result2.feedback.length > 0) {
|
|
93741
|
+
sessionStartFeedbackRef.current = result2.feedback;
|
|
93742
|
+
}
|
|
93743
|
+
}).catch(() => {});
|
|
93744
|
+
sessionHooksRanRef.current = true;
|
|
93251
93745
|
buffersRef.current.byId.set(cmdId, {
|
|
93252
93746
|
kind: "command",
|
|
93253
93747
|
id: cmdId,
|
|
@@ -93354,14 +93848,29 @@ Type your task to begin the loop.`,
|
|
|
93354
93848
|
}
|
|
93355
93849
|
if (msg.trim().startsWith("/rename")) {
|
|
93356
93850
|
const parts = msg.trim().split(/\s+/);
|
|
93357
|
-
const
|
|
93358
|
-
if (!
|
|
93851
|
+
const subcommand = parts[1]?.toLowerCase();
|
|
93852
|
+
if (!subcommand || subcommand !== "agent" && subcommand !== "convo") {
|
|
93853
|
+
const cmdId2 = uid4("cmd");
|
|
93854
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93855
|
+
kind: "command",
|
|
93856
|
+
id: cmdId2,
|
|
93857
|
+
input: msg,
|
|
93858
|
+
output: "Usage: /rename agent <name> or /rename convo <summary>",
|
|
93859
|
+
phase: "finished",
|
|
93860
|
+
success: false
|
|
93861
|
+
});
|
|
93862
|
+
buffersRef.current.order.push(cmdId2);
|
|
93863
|
+
refreshDerived();
|
|
93864
|
+
return { submitted: true };
|
|
93865
|
+
}
|
|
93866
|
+
const newValue = parts.slice(2).join(" ");
|
|
93867
|
+
if (!newValue) {
|
|
93359
93868
|
const cmdId2 = uid4("cmd");
|
|
93360
93869
|
buffersRef.current.byId.set(cmdId2, {
|
|
93361
93870
|
kind: "command",
|
|
93362
93871
|
id: cmdId2,
|
|
93363
93872
|
input: msg,
|
|
93364
|
-
output: "Please provide a
|
|
93873
|
+
output: subcommand === "convo" ? "Please provide a summary: /rename convo <summary>" : "Please provide a name: /rename agent <name>",
|
|
93365
93874
|
phase: "finished",
|
|
93366
93875
|
success: false
|
|
93367
93876
|
});
|
|
@@ -93369,7 +93878,49 @@ Type your task to begin the loop.`,
|
|
|
93369
93878
|
refreshDerived();
|
|
93370
93879
|
return { submitted: true };
|
|
93371
93880
|
}
|
|
93372
|
-
|
|
93881
|
+
if (subcommand === "convo") {
|
|
93882
|
+
const cmdId2 = uid4("cmd");
|
|
93883
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93884
|
+
kind: "command",
|
|
93885
|
+
id: cmdId2,
|
|
93886
|
+
input: msg,
|
|
93887
|
+
output: `Renaming conversation to "${newValue}"...`,
|
|
93888
|
+
phase: "running"
|
|
93889
|
+
});
|
|
93890
|
+
buffersRef.current.order.push(cmdId2);
|
|
93891
|
+
refreshDerived();
|
|
93892
|
+
setCommandRunning(true);
|
|
93893
|
+
try {
|
|
93894
|
+
const client = await getClient2();
|
|
93895
|
+
await client.conversations.update(conversationId, {
|
|
93896
|
+
summary: newValue
|
|
93897
|
+
});
|
|
93898
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93899
|
+
kind: "command",
|
|
93900
|
+
id: cmdId2,
|
|
93901
|
+
input: msg,
|
|
93902
|
+
output: `Conversation renamed to "${newValue}"`,
|
|
93903
|
+
phase: "finished",
|
|
93904
|
+
success: true
|
|
93905
|
+
});
|
|
93906
|
+
refreshDerived();
|
|
93907
|
+
} catch (error) {
|
|
93908
|
+
const errorDetails = formatErrorDetails(error, agentId);
|
|
93909
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93910
|
+
kind: "command",
|
|
93911
|
+
id: cmdId2,
|
|
93912
|
+
input: msg,
|
|
93913
|
+
output: `Failed: ${errorDetails}`,
|
|
93914
|
+
phase: "finished",
|
|
93915
|
+
success: false
|
|
93916
|
+
});
|
|
93917
|
+
refreshDerived();
|
|
93918
|
+
} finally {
|
|
93919
|
+
setCommandRunning(false);
|
|
93920
|
+
}
|
|
93921
|
+
return { submitted: true };
|
|
93922
|
+
}
|
|
93923
|
+
const validationError = validateAgentName(newValue);
|
|
93373
93924
|
if (validationError) {
|
|
93374
93925
|
const cmdId2 = uid4("cmd");
|
|
93375
93926
|
buffersRef.current.byId.set(cmdId2, {
|
|
@@ -93389,7 +93940,7 @@ Type your task to begin the loop.`,
|
|
|
93389
93940
|
kind: "command",
|
|
93390
93941
|
id: cmdId,
|
|
93391
93942
|
input: msg,
|
|
93392
|
-
output: `Renaming agent to "${
|
|
93943
|
+
output: `Renaming agent to "${newValue}"...`,
|
|
93393
93944
|
phase: "running"
|
|
93394
93945
|
});
|
|
93395
93946
|
buffersRef.current.order.push(cmdId);
|
|
@@ -93397,13 +93948,13 @@ Type your task to begin the loop.`,
|
|
|
93397
93948
|
setCommandRunning(true);
|
|
93398
93949
|
try {
|
|
93399
93950
|
const client = await getClient2();
|
|
93400
|
-
await client.agents.update(agentId, { name:
|
|
93401
|
-
updateAgentName(
|
|
93951
|
+
await client.agents.update(agentId, { name: newValue });
|
|
93952
|
+
updateAgentName(newValue);
|
|
93402
93953
|
buffersRef.current.byId.set(cmdId, {
|
|
93403
93954
|
kind: "command",
|
|
93404
93955
|
id: cmdId,
|
|
93405
93956
|
input: msg,
|
|
93406
|
-
output: `Agent renamed to "${
|
|
93957
|
+
output: `Agent renamed to "${newValue}"`,
|
|
93407
93958
|
phase: "finished",
|
|
93408
93959
|
success: true
|
|
93409
93960
|
});
|
|
@@ -93529,6 +94080,7 @@ Type your task to begin the loop.`,
|
|
|
93529
94080
|
buffersRef.current.order = [];
|
|
93530
94081
|
buffersRef.current.tokenCount = 0;
|
|
93531
94082
|
emittedIdsRef.current.clear();
|
|
94083
|
+
resetDeferredToolCallCommits();
|
|
93532
94084
|
setStaticItems([]);
|
|
93533
94085
|
setStaticRenderEpoch((e) => e + 1);
|
|
93534
94086
|
resetTrajectoryBases();
|
|
@@ -94357,6 +94909,17 @@ ${SYSTEM_REMINDER_CLOSE}`
|
|
|
94357
94909
|
});
|
|
94358
94910
|
hasSentSessionContextRef.current = true;
|
|
94359
94911
|
}
|
|
94912
|
+
let sessionStartHookFeedback = "";
|
|
94913
|
+
if (sessionStartFeedbackRef.current.length > 0) {
|
|
94914
|
+
sessionStartHookFeedback = `${SYSTEM_REMINDER_OPEN}
|
|
94915
|
+
[SessionStart hook context]:
|
|
94916
|
+
${sessionStartFeedbackRef.current.join(`
|
|
94917
|
+
`)}
|
|
94918
|
+
${SYSTEM_REMINDER_CLOSE}
|
|
94919
|
+
|
|
94920
|
+
`;
|
|
94921
|
+
sessionStartFeedbackRef.current = [];
|
|
94922
|
+
}
|
|
94360
94923
|
let bashCommandPrefix = "";
|
|
94361
94924
|
if (bashCommandCacheRef.current.length > 0) {
|
|
94362
94925
|
bashCommandPrefix = `${SYSTEM_REMINDER_OPEN}
|
|
@@ -94419,7 +94982,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94419
94982
|
`;
|
|
94420
94983
|
lastNotifiedModeRef.current = currentMode;
|
|
94421
94984
|
}
|
|
94422
|
-
const allReminders = sessionContextReminder + permissionModeAlert + planModeReminder + ralphModeReminder + skillUnloadReminder + bashCommandPrefix + userPromptSubmitHookFeedback + memoryReminderContent + memfsConflictReminder;
|
|
94985
|
+
const allReminders = sessionContextReminder + sessionStartHookFeedback + permissionModeAlert + planModeReminder + ralphModeReminder + skillUnloadReminder + bashCommandPrefix + userPromptSubmitHookFeedback + memoryReminderContent + memfsConflictReminder;
|
|
94423
94986
|
const messageContent = allReminders && typeof contentParts === "string" ? allReminders + contentParts : Array.isArray(contentParts) && allReminders ? [{ type: "text", text: allReminders }, ...contentParts] : contentParts;
|
|
94424
94987
|
const userId = uid4("user");
|
|
94425
94988
|
buffersRef.current.byId.set(userId, {
|
|
@@ -94467,22 +95030,11 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94467
95030
|
return { submitted: false };
|
|
94468
95031
|
}
|
|
94469
95032
|
if (existingApprovals && existingApprovals.length > 0) {
|
|
94470
|
-
const
|
|
94471
|
-
|
|
94472
|
-
|
|
94473
|
-
|
|
94474
|
-
|
|
94475
|
-
decision: "deny",
|
|
94476
|
-
reason: "Tool call incomplete - missing name"
|
|
94477
|
-
},
|
|
94478
|
-
context: null
|
|
94479
|
-
};
|
|
94480
|
-
}
|
|
94481
|
-
const parsedArgs = safeJsonParseOr(approvalItem.toolArgs, {});
|
|
94482
|
-
const permission = await checkToolPermission(approvalItem.toolName, parsedArgs);
|
|
94483
|
-
const context3 = await analyzeToolApproval(approvalItem.toolName, parsedArgs);
|
|
94484
|
-
return { approval: approvalItem, permission, context: context3 };
|
|
94485
|
-
}));
|
|
95033
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(existingApprovals, {
|
|
95034
|
+
getContext: analyzeToolApproval,
|
|
95035
|
+
alwaysRequiresUserInput,
|
|
95036
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
95037
|
+
});
|
|
94486
95038
|
if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
|
|
94487
95039
|
buffersRef.current.byId.delete(userId);
|
|
94488
95040
|
const orderIndex = buffersRef.current.order.indexOf(userId);
|
|
@@ -94493,23 +95045,6 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94493
95045
|
refreshDerived();
|
|
94494
95046
|
return { submitted: false };
|
|
94495
95047
|
}
|
|
94496
|
-
const needsUserInput = [];
|
|
94497
|
-
const autoAllowed = [];
|
|
94498
|
-
const autoDenied = [];
|
|
94499
|
-
for (const ac of approvalResults2) {
|
|
94500
|
-
const { approval, permission } = ac;
|
|
94501
|
-
let decision = permission.decision;
|
|
94502
|
-
if (alwaysRequiresUserInput(approval.toolName) && decision === "allow") {
|
|
94503
|
-
decision = "ask";
|
|
94504
|
-
}
|
|
94505
|
-
if (decision === "ask") {
|
|
94506
|
-
needsUserInput.push(ac);
|
|
94507
|
-
} else if (decision === "deny") {
|
|
94508
|
-
autoDenied.push(ac);
|
|
94509
|
-
} else {
|
|
94510
|
-
autoAllowed.push(ac);
|
|
94511
|
-
}
|
|
94512
|
-
}
|
|
94513
95048
|
if (needsUserInput.length === 0) {
|
|
94514
95049
|
for (const ac of [...autoAllowed, ...needsUserInput]) {
|
|
94515
95050
|
const toolName = ac.approval.toolName;
|
|
@@ -94925,8 +95460,12 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94925
95460
|
...approvalResultsSnapshot,
|
|
94926
95461
|
...additionalDecision ? [additionalDecision] : []
|
|
94927
95462
|
];
|
|
94928
|
-
|
|
94929
|
-
|
|
95463
|
+
const approvedDecisions = allDecisions.filter((decision) => decision.type === "approve");
|
|
95464
|
+
const runningDecisions = approvedDecisions.filter((decision) => !decision.precomputedResult);
|
|
95465
|
+
executingToolCallIdsRef.current = runningDecisions.map((decision) => decision.approval.toolCallId);
|
|
95466
|
+
if (runningDecisions.length > 0) {
|
|
95467
|
+
setToolCallsRunning(buffersRef.current, runningDecisions.map((d) => d.approval.toolCallId));
|
|
95468
|
+
}
|
|
94930
95469
|
refreshDerived();
|
|
94931
95470
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
94932
95471
|
sessionStatsRef.current.startTrajectory();
|
|
@@ -95278,7 +95817,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
95278
95817
|
let selectedModel = models2.find((m) => m.id === modelId);
|
|
95279
95818
|
if (!selectedModel && modelId.includes("/")) {
|
|
95280
95819
|
const { getModelContextWindow: getModelContextWindow2 } = await init_available_models().then(() => exports_available_models);
|
|
95281
|
-
const apiContextWindow = getModelContextWindow2(modelId);
|
|
95820
|
+
const apiContextWindow = await getModelContextWindow2(modelId);
|
|
95282
95821
|
selectedModel = {
|
|
95283
95822
|
id: modelId,
|
|
95284
95823
|
handle: modelId,
|
|
@@ -95942,9 +96481,6 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
95942
96481
|
});
|
|
95943
96482
|
setThinkingMessage(getRandomThinkingVerb());
|
|
95944
96483
|
refreshDerived();
|
|
95945
|
-
if (approval.toolCallId) {
|
|
95946
|
-
eagerCommittedPreviewsRef.current.add(approval.toolCallId);
|
|
95947
|
-
}
|
|
95948
96484
|
const decision = {
|
|
95949
96485
|
type: "approve",
|
|
95950
96486
|
approval,
|
|
@@ -96031,6 +96567,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96031
96567
|
return lines.filter((ln) => {
|
|
96032
96568
|
if (!("phase" in ln))
|
|
96033
96569
|
return false;
|
|
96570
|
+
if (emittedIdsRef.current.has(ln.id))
|
|
96571
|
+
return false;
|
|
96034
96572
|
if (ln.kind === "command" || ln.kind === "bash_command") {
|
|
96035
96573
|
return ln.phase === "running";
|
|
96036
96574
|
}
|
|
@@ -96038,7 +96576,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96038
96576
|
if (ln.name && isTaskTool(ln.name)) {
|
|
96039
96577
|
return ln.phase === "ready" || ln.phase === "streaming";
|
|
96040
96578
|
}
|
|
96041
|
-
return ln.phase !== "finished";
|
|
96579
|
+
return ln.phase !== "finished" || deferredToolCallCommitsRef.current.has(ln.id);
|
|
96042
96580
|
}
|
|
96043
96581
|
if (ln.kind === "event") {
|
|
96044
96582
|
return ln.phase === "running";
|
|
@@ -96047,7 +96585,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96047
96585
|
return false;
|
|
96048
96586
|
return ln.phase === "streaming";
|
|
96049
96587
|
});
|
|
96050
|
-
}, [lines, tokenStreamingEnabled]);
|
|
96588
|
+
}, [lines, tokenStreamingEnabled, staticItems.length, deferredCommitAt]);
|
|
96051
96589
|
const { agents: subagents } = import_react91.useSyncExternalStore(subscribe2, getSnapshot2);
|
|
96052
96590
|
const shouldAnimate = import_react91.useMemo(() => {
|
|
96053
96591
|
const countLines4 = (text) => {
|
|
@@ -96125,7 +96663,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96125
96663
|
});
|
|
96126
96664
|
buffersRef.current.order.push(statusId);
|
|
96127
96665
|
refreshDerived();
|
|
96128
|
-
commitEligibleLines(buffersRef.current);
|
|
96666
|
+
commitEligibleLines(buffersRef.current, { deferToolCalls: false });
|
|
96129
96667
|
}
|
|
96130
96668
|
}, [
|
|
96131
96669
|
loadingState,
|
|
@@ -96146,6 +96684,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96146
96684
|
const trajectoryTokenDisplay = Math.max(liveTrajectoryTokenBase + runTokenDelta, trajectoryTokenDisplayRef.current);
|
|
96147
96685
|
const inputVisible = !showExitStats;
|
|
96148
96686
|
const inputEnabled = !showExitStats && pendingApprovals.length === 0 && !anySelectorOpen;
|
|
96687
|
+
const currentApprovalPreviewCommitted = currentApproval?.toolCallId ? eagerCommittedPreviewsRef.current.has(currentApproval.toolCallId) : false;
|
|
96688
|
+
const showApprovalPreview = !currentApprovalShouldCommitPreview && !currentApprovalPreviewCommitted;
|
|
96149
96689
|
import_react91.useEffect(() => {
|
|
96150
96690
|
trajectoryTokenDisplayRef.current = trajectoryTokenDisplay;
|
|
96151
96691
|
}, [trajectoryTokenDisplay]);
|
|
@@ -96155,51 +96695,53 @@ Plan file path: ${planFilePath}`;
|
|
|
96155
96695
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Static, {
|
|
96156
96696
|
items: staticItems,
|
|
96157
96697
|
style: { flexDirection: "column" },
|
|
96158
|
-
children: (item, index) =>
|
|
96159
|
-
|
|
96160
|
-
|
|
96161
|
-
|
|
96162
|
-
|
|
96163
|
-
|
|
96164
|
-
|
|
96165
|
-
|
|
96166
|
-
|
|
96167
|
-
|
|
96168
|
-
|
|
96169
|
-
|
|
96170
|
-
|
|
96171
|
-
|
|
96172
|
-
|
|
96173
|
-
|
|
96174
|
-
|
|
96175
|
-
|
|
96176
|
-
|
|
96177
|
-
|
|
96178
|
-
|
|
96179
|
-
|
|
96180
|
-
|
|
96181
|
-
|
|
96182
|
-
|
|
96183
|
-
|
|
96184
|
-
|
|
96185
|
-
|
|
96186
|
-
|
|
96187
|
-
|
|
96188
|
-
|
|
96189
|
-
|
|
96190
|
-
|
|
96191
|
-
|
|
96192
|
-
|
|
96193
|
-
|
|
96194
|
-
|
|
96195
|
-
|
|
96196
|
-
|
|
96197
|
-
|
|
96198
|
-
|
|
96199
|
-
|
|
96200
|
-
|
|
96201
|
-
|
|
96202
|
-
|
|
96698
|
+
children: (item, index) => {
|
|
96699
|
+
return /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96700
|
+
marginTop: index > 0 ? 1 : 0,
|
|
96701
|
+
children: item.kind === "welcome" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(WelcomeScreen, {
|
|
96702
|
+
loadingState: "ready",
|
|
96703
|
+
...item.snapshot
|
|
96704
|
+
}, undefined, false, undefined, this) : item.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(UserMessage, {
|
|
96705
|
+
line: item
|
|
96706
|
+
}, undefined, false, undefined, this) : item.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ReasoningMessage, {
|
|
96707
|
+
line: item
|
|
96708
|
+
}, undefined, false, undefined, this) : item.kind === "assistant" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(AssistantMessage, {
|
|
96709
|
+
line: item
|
|
96710
|
+
}, undefined, false, undefined, this) : item.kind === "tool_call" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ToolCallMessage, {
|
|
96711
|
+
line: item,
|
|
96712
|
+
precomputedDiffs: precomputedDiffsRef.current,
|
|
96713
|
+
lastPlanFilePath: lastPlanFilePathRef.current
|
|
96714
|
+
}, undefined, false, undefined, this) : item.kind === "subagent_group" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(SubagentGroupStatic, {
|
|
96715
|
+
agents: item.agents
|
|
96716
|
+
}, undefined, false, undefined, this) : item.kind === "error" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ErrorMessage, {
|
|
96717
|
+
line: item
|
|
96718
|
+
}, undefined, false, undefined, this) : item.kind === "status" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(StatusMessage, {
|
|
96719
|
+
line: item
|
|
96720
|
+
}, undefined, false, undefined, this) : item.kind === "event" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(EventMessage, {
|
|
96721
|
+
line: item
|
|
96722
|
+
}, undefined, false, undefined, this) : item.kind === "separator" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96723
|
+
marginTop: 1,
|
|
96724
|
+
children: /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Text2, {
|
|
96725
|
+
dimColor: true,
|
|
96726
|
+
children: "─".repeat(columns)
|
|
96727
|
+
}, undefined, false, undefined, this)
|
|
96728
|
+
}, undefined, false, undefined, this) : item.kind === "command" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(CommandMessage, {
|
|
96729
|
+
line: item
|
|
96730
|
+
}, undefined, false, undefined, this) : item.kind === "bash_command" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(BashCommandMessage, {
|
|
96731
|
+
line: item
|
|
96732
|
+
}, undefined, false, undefined, this) : item.kind === "trajectory_summary" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(TrajectorySummary, {
|
|
96733
|
+
line: item
|
|
96734
|
+
}, undefined, false, undefined, this) : item.kind === "approval_preview" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ApprovalPreview, {
|
|
96735
|
+
toolName: item.toolName,
|
|
96736
|
+
toolArgs: item.toolArgs,
|
|
96737
|
+
precomputedDiff: item.precomputedDiff,
|
|
96738
|
+
allDiffs: precomputedDiffsRef.current,
|
|
96739
|
+
planContent: item.planContent,
|
|
96740
|
+
planFilePath: item.planFilePath,
|
|
96741
|
+
toolCallId: item.toolCallId
|
|
96742
|
+
}, undefined, false, undefined, this) : null
|
|
96743
|
+
}, item.id, false, undefined, this);
|
|
96744
|
+
}
|
|
96203
96745
|
}, staticRenderEpoch, false, undefined, this),
|
|
96204
96746
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96205
96747
|
flexDirection: "column",
|
|
@@ -96217,10 +96759,12 @@ Plan file path: ${planFilePath}`;
|
|
|
96217
96759
|
liveItems.length > 0 && /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96218
96760
|
flexDirection: "column",
|
|
96219
96761
|
children: liveItems.map((ln) => {
|
|
96220
|
-
|
|
96762
|
+
const isFileTool = ln.kind === "tool_call" && ln.name && (isFileEditTool(ln.name) || isFileWriteTool(ln.name) || isPatchTool(ln.name));
|
|
96763
|
+
const isApprovalTracked = ln.kind === "tool_call" && ln.toolCallId && (ln.toolCallId === currentApproval?.toolCallId || pendingIds.has(ln.toolCallId) || queuedIds.has(ln.toolCallId));
|
|
96764
|
+
if (isFileTool && !isApprovalTracked) {
|
|
96221
96765
|
return null;
|
|
96222
96766
|
}
|
|
96223
|
-
if (ln.kind === "tool_call" && ln.toolCallId &&
|
|
96767
|
+
if (ln.kind === "tool_call" && ln.name && isTaskTool(ln.name) && ln.toolCallId && !pendingIds.has(ln.toolCallId) && ln.toolCallId !== currentApproval?.toolCallId) {
|
|
96224
96768
|
return null;
|
|
96225
96769
|
}
|
|
96226
96770
|
const matchesCurrentApproval = ln.kind === "tool_call" && currentApproval && ln.toolCallId === currentApproval.toolCallId;
|
|
@@ -96242,7 +96786,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96242
96786
|
allDiffs: precomputedDiffsRef.current,
|
|
96243
96787
|
isFocused: true,
|
|
96244
96788
|
approveAlwaysText: currentApprovalContext?.approveAlwaysText,
|
|
96245
|
-
allowPersistence: currentApprovalContext?.allowPersistence ?? true
|
|
96789
|
+
allowPersistence: currentApprovalContext?.allowPersistence ?? true,
|
|
96790
|
+
showPreview: showApprovalPreview
|
|
96246
96791
|
}, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(UserMessage, {
|
|
96247
96792
|
line: ln
|
|
96248
96793
|
}, undefined, false, undefined, this) : ln.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ReasoningMessage, {
|
|
@@ -96291,7 +96836,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96291
96836
|
allDiffs: precomputedDiffsRef.current,
|
|
96292
96837
|
isFocused: true,
|
|
96293
96838
|
approveAlwaysText: currentApprovalContext?.approveAlwaysText,
|
|
96294
|
-
allowPersistence: currentApprovalContext?.allowPersistence ?? true
|
|
96839
|
+
allowPersistence: currentApprovalContext?.allowPersistence ?? true,
|
|
96840
|
+
showPreview: showApprovalPreview
|
|
96295
96841
|
}, undefined, false, undefined, this)
|
|
96296
96842
|
}, undefined, false, undefined, this),
|
|
96297
96843
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
|
|
@@ -96543,6 +97089,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96543
97089
|
buffersRef.current.order = [];
|
|
96544
97090
|
buffersRef.current.tokenCount = 0;
|
|
96545
97091
|
emittedIdsRef.current.clear();
|
|
97092
|
+
resetDeferredToolCallCommits();
|
|
96546
97093
|
setStaticItems([]);
|
|
96547
97094
|
setStaticRenderEpoch((e) => e + 1);
|
|
96548
97095
|
resetTrajectoryBases();
|
|
@@ -96665,6 +97212,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96665
97212
|
buffersRef.current.order = [];
|
|
96666
97213
|
buffersRef.current.tokenCount = 0;
|
|
96667
97214
|
emittedIdsRef.current.clear();
|
|
97215
|
+
resetDeferredToolCallCommits();
|
|
96668
97216
|
setStaticItems([]);
|
|
96669
97217
|
setStaticRenderEpoch((e) => e + 1);
|
|
96670
97218
|
resetTrajectoryBases();
|
|
@@ -96764,6 +97312,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96764
97312
|
buffersRef.current.order = [];
|
|
96765
97313
|
buffersRef.current.tokenCount = 0;
|
|
96766
97314
|
emittedIdsRef.current.clear();
|
|
97315
|
+
resetDeferredToolCallCommits();
|
|
96767
97316
|
setStaticItems([]);
|
|
96768
97317
|
setStaticRenderEpoch((e) => e + 1);
|
|
96769
97318
|
resetTrajectoryBases();
|
|
@@ -96982,7 +97531,7 @@ Open /mcp to attach or detach tools for this server.`,
|
|
|
96982
97531
|
]
|
|
96983
97532
|
}, resumeKey, true, undefined, this);
|
|
96984
97533
|
}
|
|
96985
|
-
var import_react91, jsx_dev_runtime69, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES2 = 3, CONVERSATION_BUSY_MAX_RETRIES2 =
|
|
97534
|
+
var import_react91, jsx_dev_runtime69, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, TOOL_CALL_COMMIT_DEFER_MS = 50, EAGER_CANCEL = true, LLM_API_ERROR_MAX_RETRIES2 = 3, CONVERSATION_BUSY_MAX_RETRIES2 = 3, CONVERSATION_BUSY_RETRY_BASE_DELAY_MS = 2500, INTERRUPT_MESSAGE = "Interrupted – tell the agent what to do differently. Something went wrong? Use /feedback to report issues.", ERROR_FEEDBACK_HINT = "Something went wrong? Use /feedback to report issues.", OPUS_BEDROCK_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to Bedrock Opus 4.5", PROVIDER_FALLBACK_HINT = "Downstream provider issues? Use /model to switch to another provider", INTERACTIVE_SLASH_COMMANDS, NON_STATE_COMMANDS, APPROVAL_OPTIONS_HEIGHT = 8, APPROVAL_PREVIEW_BUFFER = 4, MIN_WRAP_WIDTH = 10, TEXT_WRAP_GUTTER = 6, DIFF_WRAP_GUTTER = 12;
|
|
96986
97535
|
var init_App2 = __esm(async () => {
|
|
96987
97536
|
init_error();
|
|
96988
97537
|
init_check_approval();
|
|
@@ -96995,6 +97544,7 @@ var init_App2 = __esm(async () => {
|
|
|
96995
97544
|
init_mode();
|
|
96996
97545
|
init_mode2();
|
|
96997
97546
|
init_settings();
|
|
97547
|
+
init_debug();
|
|
96998
97548
|
init_colors();
|
|
96999
97549
|
init_SessionStats();
|
|
97000
97550
|
init_AnimationContext();
|
|
@@ -97062,6 +97612,7 @@ var init_App2 = __esm(async () => {
|
|
|
97062
97612
|
init_UserMessageRich(),
|
|
97063
97613
|
init_WelcomeScreen(),
|
|
97064
97614
|
init_accumulator(),
|
|
97615
|
+
init_approvalClassification(),
|
|
97065
97616
|
init_memoryReminder(),
|
|
97066
97617
|
init_sessionContext(),
|
|
97067
97618
|
init_stream(),
|
|
@@ -97853,7 +98404,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
97853
98404
|
blockProvenance.push({ label: blockId, source: "shared" });
|
|
97854
98405
|
}
|
|
97855
98406
|
const modelUpdateArgs = getModelUpdateArgs(modelHandle);
|
|
97856
|
-
const contextWindow = modelUpdateArgs?.context_window;
|
|
98407
|
+
const contextWindow = modelUpdateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
97857
98408
|
let systemPromptContent;
|
|
97858
98409
|
if (options.systemPromptCustom) {
|
|
97859
98410
|
systemPromptContent = options.systemPromptCustom;
|
|
@@ -97926,6 +98477,7 @@ var init_create3 = __esm(async () => {
|
|
|
97926
98477
|
init_promptAssets();
|
|
97927
98478
|
init_skills2();
|
|
97928
98479
|
await __promiseAll([
|
|
98480
|
+
init_available_models(),
|
|
97929
98481
|
init_client2(),
|
|
97930
98482
|
init_modify()
|
|
97931
98483
|
]);
|
|
@@ -98069,7 +98621,7 @@ function buildModelSettings2(modelHandle, updateArgs) {
|
|
|
98069
98621
|
async function updateAgentLLMConfig2(agentId, modelHandle, updateArgs) {
|
|
98070
98622
|
const client = await getClient2();
|
|
98071
98623
|
const modelSettings = buildModelSettings2(modelHandle, updateArgs);
|
|
98072
|
-
const contextWindow = updateArgs?.context_window;
|
|
98624
|
+
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
98073
98625
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
98074
98626
|
await client.agents.update(agentId, {
|
|
98075
98627
|
model: modelHandle,
|
|
@@ -98151,6 +98703,7 @@ async function updateAgentSystemPromptMemfs2(agentId, enableMemfs) {
|
|
|
98151
98703
|
var init_modify2 = __esm(async () => {
|
|
98152
98704
|
await __promiseAll([
|
|
98153
98705
|
init_openai_codex_provider(),
|
|
98706
|
+
init_available_models(),
|
|
98154
98707
|
init_client2()
|
|
98155
98708
|
]);
|
|
98156
98709
|
});
|
|
@@ -98247,6 +98800,7 @@ class InternalServerError extends APIError {
|
|
|
98247
98800
|
|
|
98248
98801
|
// src/agent/check-approval.ts
|
|
98249
98802
|
init_error();
|
|
98803
|
+
init_debug();
|
|
98250
98804
|
var MESSAGE_HISTORY_LIMIT = 15;
|
|
98251
98805
|
function isBackfillEnabled() {
|
|
98252
98806
|
const val = process.env.LETTA_BACKFILL;
|
|
@@ -100815,6 +101369,7 @@ class PermissionModeManager {
|
|
|
100815
101369
|
var permissionMode = new PermissionModeManager;
|
|
100816
101370
|
|
|
100817
101371
|
// src/settings-manager.ts
|
|
101372
|
+
init_debug();
|
|
100818
101373
|
init_fs();
|
|
100819
101374
|
await init_secrets();
|
|
100820
101375
|
import { homedir as homedir6 } from "node:os";
|
|
@@ -100914,7 +101469,7 @@ class SettingsManager2 {
|
|
|
100914
101469
|
}
|
|
100915
101470
|
this.settings = updatedSettings;
|
|
100916
101471
|
await this.persistSettings();
|
|
100917
|
-
|
|
101472
|
+
debugWarn("settings", "Successfully migrated tokens to secrets");
|
|
100918
101473
|
} catch (error) {
|
|
100919
101474
|
console.warn("Failed to migrate tokens to secrets:", error);
|
|
100920
101475
|
console.warn("Tokens will remain in settings file for persistence");
|
|
@@ -101843,6 +102398,7 @@ var telemetry = new TelemetryManager;
|
|
|
101843
102398
|
init_model();
|
|
101844
102399
|
init_subagents();
|
|
101845
102400
|
init_constants();
|
|
102401
|
+
init_debug();
|
|
101846
102402
|
await __promiseAll([
|
|
101847
102403
|
init_approval_execution(),
|
|
101848
102404
|
init_hooks(),
|
|
@@ -103415,4 +103971,4 @@ Error during initialization: ${message}`);
|
|
|
103415
103971
|
}
|
|
103416
103972
|
main();
|
|
103417
103973
|
|
|
103418
|
-
//# debugId=
|
|
103974
|
+
//# debugId=E6B9011D5A418C2E64756E2164756E21
|