@letta-ai/letta-code 0.14.7 → 0.14.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +1085 -640
- package/package.json +2 -2
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.8",
|
|
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": {
|
|
@@ -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
|
}
|
|
@@ -31094,28 +31114,28 @@ var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
|
|
|
31094
31114
|
return null;
|
|
31095
31115
|
}
|
|
31096
31116
|
var ReactSharedInternals = React10.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
31097
|
-
function error(
|
|
31117
|
+
function error(format2) {
|
|
31098
31118
|
{
|
|
31099
31119
|
{
|
|
31100
31120
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
31101
31121
|
args[_key2 - 1] = arguments[_key2];
|
|
31102
31122
|
}
|
|
31103
|
-
printWarning("error",
|
|
31123
|
+
printWarning("error", format2, args);
|
|
31104
31124
|
}
|
|
31105
31125
|
}
|
|
31106
31126
|
}
|
|
31107
|
-
function printWarning(level,
|
|
31127
|
+
function printWarning(level, format2, args) {
|
|
31108
31128
|
{
|
|
31109
31129
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
31110
31130
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
31111
31131
|
if (stack !== "") {
|
|
31112
|
-
|
|
31132
|
+
format2 += "%s";
|
|
31113
31133
|
args = args.concat([stack]);
|
|
31114
31134
|
}
|
|
31115
31135
|
var argsWithFormat = args.map(function(item) {
|
|
31116
31136
|
return String(item);
|
|
31117
31137
|
});
|
|
31118
|
-
argsWithFormat.unshift("Warning: " +
|
|
31138
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
31119
31139
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
31120
31140
|
}
|
|
31121
31141
|
}
|
|
@@ -33252,10 +33272,11 @@ function getSnapshot() {
|
|
|
33252
33272
|
return tick;
|
|
33253
33273
|
}
|
|
33254
33274
|
function AnimatedLogo({
|
|
33255
|
-
color = colors.welcome.accent
|
|
33275
|
+
color = colors.welcome.accent,
|
|
33276
|
+
animate = true
|
|
33256
33277
|
}) {
|
|
33257
33278
|
const tick2 = import_react24.useSyncExternalStore(subscribe, getSnapshot);
|
|
33258
|
-
const frame = tick2 % logoFrames.length;
|
|
33279
|
+
const frame = animate ? tick2 % logoFrames.length : 0;
|
|
33259
33280
|
const logoLines = logoFrames[frame]?.split(`
|
|
33260
33281
|
`) ?? [];
|
|
33261
33282
|
return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(jsx_dev_runtime5.Fragment, {
|
|
@@ -33409,7 +33430,8 @@ function WelcomeScreen({
|
|
|
33409
33430
|
paddingLeft: 1,
|
|
33410
33431
|
paddingRight: 2,
|
|
33411
33432
|
children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AnimatedLogo, {
|
|
33412
|
-
color: colors.welcome.accent
|
|
33433
|
+
color: colors.welcome.accent,
|
|
33434
|
+
animate: loadingState !== "ready"
|
|
33413
33435
|
}, undefined, false, undefined, this)
|
|
33414
33436
|
}, undefined, false, undefined, this),
|
|
33415
33437
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
|
|
@@ -34598,13 +34620,19 @@ function windowsLaunchers(command) {
|
|
|
34598
34620
|
return [];
|
|
34599
34621
|
const launchers = [];
|
|
34600
34622
|
const seen = new Set;
|
|
34623
|
+
const powerShellCommand = trimmed.startsWith("&") || trimmed.startsWith('"') || trimmed.startsWith("'") ? trimmed.startsWith("&") ? trimmed : `& ${trimmed}` : trimmed;
|
|
34601
34624
|
pushUnique(launchers, seen, [
|
|
34602
34625
|
"powershell.exe",
|
|
34603
34626
|
"-NoProfile",
|
|
34604
34627
|
"-Command",
|
|
34605
|
-
|
|
34628
|
+
powerShellCommand
|
|
34629
|
+
]);
|
|
34630
|
+
pushUnique(launchers, seen, [
|
|
34631
|
+
"pwsh",
|
|
34632
|
+
"-NoProfile",
|
|
34633
|
+
"-Command",
|
|
34634
|
+
powerShellCommand
|
|
34606
34635
|
]);
|
|
34607
|
-
pushUnique(launchers, seen, ["pwsh", "-NoProfile", "-Command", trimmed]);
|
|
34608
34636
|
const envComSpecRaw = process.env.ComSpec || process.env.COMSPEC;
|
|
34609
34637
|
const envComSpec = envComSpecRaw?.trim();
|
|
34610
34638
|
if (envComSpec) {
|
|
@@ -34667,6 +34695,7 @@ var init_types = __esm(() => {
|
|
|
34667
34695
|
TOOL_EVENTS = new Set([
|
|
34668
34696
|
"PreToolUse",
|
|
34669
34697
|
"PostToolUse",
|
|
34698
|
+
"PostToolUseFailure",
|
|
34670
34699
|
"PermissionRequest"
|
|
34671
34700
|
]);
|
|
34672
34701
|
});
|
|
@@ -34737,8 +34766,10 @@ function executeWithLauncher(launcher, inputJson, workingDirectory, input, timeo
|
|
|
34737
34766
|
const safeResolve = (result) => {
|
|
34738
34767
|
if (!resolved) {
|
|
34739
34768
|
resolved = true;
|
|
34740
|
-
const
|
|
34741
|
-
|
|
34769
|
+
const exitCode = result.exitCode === 0 /* ALLOW */ ? 0 : result.exitCode === 2 /* BLOCK */ ? 2 : 1;
|
|
34770
|
+
const exitColor = result.exitCode === 0 /* ALLOW */ ? "\x1B[32m" : result.exitCode === 2 /* BLOCK */ ? "\x1B[31m" : "\x1B[33m";
|
|
34771
|
+
const exitLabel = result.timedOut ? `${exitColor}timeout\x1B[0m` : `${exitColor}exit ${exitCode}\x1B[0m`;
|
|
34772
|
+
console.log(`\x1B[90m[hook:${input.event_type}] ${command}\x1B[0m`);
|
|
34742
34773
|
console.log(`\x1B[90m ⎿ ${exitLabel} (${result.durationMs}ms)\x1B[0m`);
|
|
34743
34774
|
if (result.stdout) {
|
|
34744
34775
|
console.log(`\x1B[90m ⎿ (stdout)\x1B[0m`);
|
|
@@ -34908,7 +34939,8 @@ var init_executor = __esm(() => {
|
|
|
34908
34939
|
function loadGlobalHooks() {
|
|
34909
34940
|
try {
|
|
34910
34941
|
return settingsManager.getSettings().hooks || {};
|
|
34911
|
-
} catch {
|
|
34942
|
+
} catch (error) {
|
|
34943
|
+
debugLog("hooks", "loadGlobalHooks: Settings not initialized yet", error);
|
|
34912
34944
|
return {};
|
|
34913
34945
|
}
|
|
34914
34946
|
}
|
|
@@ -34920,7 +34952,8 @@ async function loadProjectHooks(workingDirectory = process.cwd()) {
|
|
|
34920
34952
|
await settingsManager.loadProjectSettings(workingDirectory);
|
|
34921
34953
|
}
|
|
34922
34954
|
return settingsManager.getProjectSettings(workingDirectory)?.hooks || {};
|
|
34923
|
-
} catch {
|
|
34955
|
+
} catch (error) {
|
|
34956
|
+
debugLog("hooks", "loadProjectHooks: Settings not available", error);
|
|
34924
34957
|
return {};
|
|
34925
34958
|
}
|
|
34926
34959
|
}
|
|
@@ -34932,7 +34965,8 @@ async function loadProjectLocalHooks(workingDirectory = process.cwd()) {
|
|
|
34932
34965
|
await settingsManager.loadLocalProjectSettings(workingDirectory);
|
|
34933
34966
|
}
|
|
34934
34967
|
return settingsManager.getLocalProjectSettings(workingDirectory)?.hooks || {};
|
|
34935
|
-
} catch {
|
|
34968
|
+
} catch (error) {
|
|
34969
|
+
debugLog("hooks", "loadProjectLocalHooks: Settings not available", error);
|
|
34936
34970
|
return {};
|
|
34937
34971
|
}
|
|
34938
34972
|
}
|
|
@@ -34983,7 +35017,8 @@ function matchesTool(pattern, toolName) {
|
|
|
34983
35017
|
try {
|
|
34984
35018
|
const regex2 = new RegExp(`^(?:${pattern})$`);
|
|
34985
35019
|
return regex2.test(toolName);
|
|
34986
|
-
} catch {
|
|
35020
|
+
} catch (error) {
|
|
35021
|
+
debugLog("hooks", `matchesTool: Invalid regex pattern "${pattern}", falling back to exact match`, error);
|
|
34987
35022
|
return pattern === toolName;
|
|
34988
35023
|
}
|
|
34989
35024
|
}
|
|
@@ -35026,15 +35061,20 @@ function areHooksDisabled(workingDirectory = process.cwd()) {
|
|
|
35026
35061
|
if (projectDisabled === true) {
|
|
35027
35062
|
return true;
|
|
35028
35063
|
}
|
|
35029
|
-
} catch {
|
|
35064
|
+
} catch (error) {
|
|
35065
|
+
debugLog("hooks", "areHooksDisabled: Project settings not loaded, skipping", error);
|
|
35066
|
+
}
|
|
35030
35067
|
try {
|
|
35031
35068
|
const localDisabled = settingsManager.getLocalProjectSettings(workingDirectory)?.hooks?.disabled;
|
|
35032
35069
|
if (localDisabled === true) {
|
|
35033
35070
|
return true;
|
|
35034
35071
|
}
|
|
35035
|
-
} catch {
|
|
35072
|
+
} catch (error) {
|
|
35073
|
+
debugLog("hooks", "areHooksDisabled: Local project settings not loaded, skipping", error);
|
|
35074
|
+
}
|
|
35036
35075
|
return false;
|
|
35037
|
-
} catch {
|
|
35076
|
+
} catch (error) {
|
|
35077
|
+
debugLog("hooks", "areHooksDisabled: Failed to check hooks disabled status", error);
|
|
35038
35078
|
return false;
|
|
35039
35079
|
}
|
|
35040
35080
|
}
|
|
@@ -35046,6 +35086,7 @@ async function getHooksForEvent(event, toolName, workingDirectory = process.cwd(
|
|
|
35046
35086
|
return getMatchingHooks(config, event, toolName);
|
|
35047
35087
|
}
|
|
35048
35088
|
var init_loader = __esm(async () => {
|
|
35089
|
+
init_debug();
|
|
35049
35090
|
init_types();
|
|
35050
35091
|
await init_settings_manager();
|
|
35051
35092
|
});
|
|
@@ -35084,6 +35125,31 @@ async function runPostToolUseHooks(toolName, toolInput, toolResult, toolCallId,
|
|
|
35084
35125
|
};
|
|
35085
35126
|
return executeHooksParallel(hooks, input, workingDirectory);
|
|
35086
35127
|
}
|
|
35128
|
+
async function runPostToolUseFailureHooks(toolName, toolInput, errorMessage, errorType, toolCallId, workingDirectory = process.cwd(), agentId, precedingReasoning, precedingAssistantMessage) {
|
|
35129
|
+
const hooks = await getHooksForEvent("PostToolUseFailure", toolName, workingDirectory);
|
|
35130
|
+
if (hooks.length === 0) {
|
|
35131
|
+
return { blocked: false, errored: false, feedback: [], results: [] };
|
|
35132
|
+
}
|
|
35133
|
+
const input = {
|
|
35134
|
+
event_type: "PostToolUseFailure",
|
|
35135
|
+
working_directory: workingDirectory,
|
|
35136
|
+
tool_name: toolName,
|
|
35137
|
+
tool_input: toolInput,
|
|
35138
|
+
tool_call_id: toolCallId,
|
|
35139
|
+
error_message: errorMessage,
|
|
35140
|
+
error_type: errorType,
|
|
35141
|
+
agent_id: agentId,
|
|
35142
|
+
preceding_reasoning: precedingReasoning,
|
|
35143
|
+
preceding_assistant_message: precedingAssistantMessage
|
|
35144
|
+
};
|
|
35145
|
+
const result = await executeHooksParallel(hooks, input, workingDirectory);
|
|
35146
|
+
return {
|
|
35147
|
+
blocked: false,
|
|
35148
|
+
errored: result.errored,
|
|
35149
|
+
feedback: result.feedback,
|
|
35150
|
+
results: result.results
|
|
35151
|
+
};
|
|
35152
|
+
}
|
|
35087
35153
|
async function runPermissionRequestHooks(toolName, toolInput, permissionType, scope, workingDirectory = process.cwd()) {
|
|
35088
35154
|
const hooks = await getHooksForEvent("PermissionRequest", toolName, workingDirectory);
|
|
35089
35155
|
if (hooks.length === 0) {
|
|
@@ -35194,7 +35260,19 @@ async function runSessionStartHooks(isNewSession, agentId, agentName, conversati
|
|
|
35194
35260
|
agent_name: agentName,
|
|
35195
35261
|
conversation_id: conversationId
|
|
35196
35262
|
};
|
|
35197
|
-
|
|
35263
|
+
const result = await executeHooks(hooks, input, workingDirectory);
|
|
35264
|
+
const feedback = [];
|
|
35265
|
+
for (const hookResult of result.results) {
|
|
35266
|
+
if (hookResult.stdout?.trim()) {
|
|
35267
|
+
feedback.push(hookResult.stdout.trim());
|
|
35268
|
+
}
|
|
35269
|
+
}
|
|
35270
|
+
return {
|
|
35271
|
+
blocked: false,
|
|
35272
|
+
errored: result.errored,
|
|
35273
|
+
feedback,
|
|
35274
|
+
results: result.results
|
|
35275
|
+
};
|
|
35198
35276
|
}
|
|
35199
35277
|
async function runSessionEndHooks(durationMs, messageCount, toolCallCount, agentId, conversationId, workingDirectory = process.cwd()) {
|
|
35200
35278
|
const hooks = await getHooksForEvent("SessionEnd", undefined, workingDirectory);
|
|
@@ -36939,8 +37017,8 @@ function getShellEnv() {
|
|
|
36939
37017
|
const env3 = { ...process.env };
|
|
36940
37018
|
const rgBinDir = getRipgrepBinDir();
|
|
36941
37019
|
if (rgBinDir) {
|
|
36942
|
-
const
|
|
36943
|
-
env3
|
|
37020
|
+
const pathKey = Object.keys(env3).find((k) => k.toUpperCase() === "PATH") || "PATH";
|
|
37021
|
+
env3[pathKey] = `${rgBinDir}${path3.delimiter}${env3[pathKey] || ""}`;
|
|
36944
37022
|
}
|
|
36945
37023
|
try {
|
|
36946
37024
|
env3.LETTA_AGENT_ID = getCurrentAgentId();
|
|
@@ -39701,11 +39779,11 @@ var require_picomatch = __commonJS((exports, module) => {
|
|
|
39701
39779
|
return { isMatch: false, output: "" };
|
|
39702
39780
|
}
|
|
39703
39781
|
const opts = options || {};
|
|
39704
|
-
const
|
|
39782
|
+
const format2 = opts.format || (posix ? utils.toPosixSlashes : null);
|
|
39705
39783
|
let match = input === glob2;
|
|
39706
|
-
let output = match &&
|
|
39784
|
+
let output = match && format2 ? format2(input) : input;
|
|
39707
39785
|
if (match === false) {
|
|
39708
|
-
output =
|
|
39786
|
+
output = format2 ? format2(input) : input;
|
|
39709
39787
|
match = output === glob2;
|
|
39710
39788
|
}
|
|
39711
39789
|
if (match === false || opts.capture === true) {
|
|
@@ -39979,14 +40057,14 @@ async function getImageDimensions(buffer) {
|
|
|
39979
40057
|
const output = execSync(`magick identify -format "%w %h %m" "${tempInput}"`, {
|
|
39980
40058
|
encoding: "utf-8"
|
|
39981
40059
|
});
|
|
39982
|
-
const [width, height,
|
|
39983
|
-
if (!width || !height || !
|
|
40060
|
+
const [width, height, format2] = output.trim().split(" ");
|
|
40061
|
+
if (!width || !height || !format2) {
|
|
39984
40062
|
throw new Error("Failed to get image dimensions");
|
|
39985
40063
|
}
|
|
39986
40064
|
return {
|
|
39987
40065
|
width: parseInt(width, 10),
|
|
39988
40066
|
height: parseInt(height, 10),
|
|
39989
|
-
format:
|
|
40067
|
+
format: format2.toLowerCase()
|
|
39990
40068
|
};
|
|
39991
40069
|
} finally {
|
|
39992
40070
|
unlinkSync2(tempInput);
|
|
@@ -40055,9 +40133,9 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40055
40133
|
}
|
|
40056
40134
|
}
|
|
40057
40135
|
async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
40058
|
-
const { width, height, format } = await getImageDimensions(buffer);
|
|
40136
|
+
const { width, height, format: format2 } = await getImageDimensions(buffer);
|
|
40059
40137
|
const needsResize = width > MAX_IMAGE_WIDTH || height > MAX_IMAGE_HEIGHT;
|
|
40060
|
-
const isPassthroughFormat =
|
|
40138
|
+
const isPassthroughFormat = format2 === "png" || format2 === "jpeg" || format2 === "jpg";
|
|
40061
40139
|
if (!needsResize && isPassthroughFormat) {
|
|
40062
40140
|
const compressed = await compressToFitByteLimit(buffer, width, height);
|
|
40063
40141
|
if (compressed) {
|
|
@@ -40078,7 +40156,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
40078
40156
|
const tempOutput2 = join12(tmpdir(), `resize-output-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
40079
40157
|
let outputBuffer2;
|
|
40080
40158
|
let outputMediaType;
|
|
40081
|
-
if (
|
|
40159
|
+
if (format2 === "jpeg" || format2 === "jpg") {
|
|
40082
40160
|
execSync(`magick "${tempInput}" -resize ${MAX_IMAGE_WIDTH}x${MAX_IMAGE_HEIGHT}> -quality 85 "${tempOutput2}.jpg"`, {
|
|
40083
40161
|
stdio: "ignore"
|
|
40084
40162
|
});
|
|
@@ -45680,10 +45758,10 @@ var require_output = __commonJS((exports, module) => {
|
|
|
45680
45758
|
}
|
|
45681
45759
|
return this;
|
|
45682
45760
|
}
|
|
45683
|
-
function toFormat(
|
|
45684
|
-
const actualFormat = formats.get((is.object(
|
|
45761
|
+
function toFormat(format2, options) {
|
|
45762
|
+
const actualFormat = formats.get((is.object(format2) && is.string(format2.id) ? format2.id : format2).toLowerCase());
|
|
45685
45763
|
if (!actualFormat) {
|
|
45686
|
-
throw is.invalidParameterError("format", `one of: ${[...formats.keys()].join(", ")}`,
|
|
45764
|
+
throw is.invalidParameterError("format", `one of: ${[...formats.keys()].join(", ")}`, format2);
|
|
45687
45765
|
}
|
|
45688
45766
|
return this[actualFormat](options);
|
|
45689
45767
|
}
|
|
@@ -46405,11 +46483,11 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46405
46483
|
var sharp = require_sharp();
|
|
46406
46484
|
var runtimePlatform = runtimePlatformArch();
|
|
46407
46485
|
var libvipsVersion = sharp.libvipsVersion();
|
|
46408
|
-
var
|
|
46409
|
-
|
|
46410
|
-
|
|
46411
|
-
|
|
46412
|
-
|
|
46486
|
+
var format2 = sharp.format();
|
|
46487
|
+
format2.heif.output.alias = ["avif", "heic"];
|
|
46488
|
+
format2.jpeg.output.alias = ["jpe", "jpg"];
|
|
46489
|
+
format2.tiff.output.alias = ["tif"];
|
|
46490
|
+
format2.jp2k.output.alias = ["j2c", "j2k", "jp2", "jpx"];
|
|
46413
46491
|
var interpolators = {
|
|
46414
46492
|
nearest: "nearest",
|
|
46415
46493
|
bilinear: "bilinear",
|
|
@@ -46437,9 +46515,9 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46437
46515
|
}
|
|
46438
46516
|
}
|
|
46439
46517
|
versions.sharp = require_package().version;
|
|
46440
|
-
if (versions.heif &&
|
|
46441
|
-
|
|
46442
|
-
|
|
46518
|
+
if (versions.heif && format2.heif) {
|
|
46519
|
+
format2.heif.input.fileSuffix = [".avif"];
|
|
46520
|
+
format2.heif.output.alias = ["avif"];
|
|
46443
46521
|
}
|
|
46444
46522
|
function cache4(options) {
|
|
46445
46523
|
if (is.bool(options)) {
|
|
@@ -46497,7 +46575,7 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
46497
46575
|
Sharp.concurrency = concurrency;
|
|
46498
46576
|
Sharp.counters = counters;
|
|
46499
46577
|
Sharp.simd = simd;
|
|
46500
|
-
Sharp.format =
|
|
46578
|
+
Sharp.format = format2;
|
|
46501
46579
|
Sharp.interpolators = interpolators;
|
|
46502
46580
|
Sharp.versions = versions;
|
|
46503
46581
|
Sharp.queue = queue;
|
|
@@ -46576,9 +46654,9 @@ async function resizeImageIfNeeded2(buffer, inputMediaType) {
|
|
|
46576
46654
|
const metadata = await image2.metadata();
|
|
46577
46655
|
const width = metadata.width ?? 0;
|
|
46578
46656
|
const height = metadata.height ?? 0;
|
|
46579
|
-
const
|
|
46657
|
+
const format2 = metadata.format;
|
|
46580
46658
|
const needsResize = width > MAX_IMAGE_WIDTH2 || height > MAX_IMAGE_HEIGHT2;
|
|
46581
|
-
const isPassthroughFormat =
|
|
46659
|
+
const isPassthroughFormat = format2 === "png" || format2 === "jpeg";
|
|
46582
46660
|
if (!needsResize && isPassthroughFormat) {
|
|
46583
46661
|
const compressed2 = await compressToFitByteLimit2(buffer, width, height);
|
|
46584
46662
|
if (compressed2) {
|
|
@@ -46599,7 +46677,7 @@ async function resizeImageIfNeeded2(buffer, inputMediaType) {
|
|
|
46599
46677
|
});
|
|
46600
46678
|
let outputBuffer2;
|
|
46601
46679
|
let outputMediaType;
|
|
46602
|
-
if (
|
|
46680
|
+
if (format2 === "jpeg") {
|
|
46603
46681
|
outputBuffer2 = await resized.jpeg({ quality: 85 }).toBuffer();
|
|
46604
46682
|
outputMediaType = "image/jpeg";
|
|
46605
46683
|
} else {
|
|
@@ -54363,7 +54441,10 @@ async function getAvailableModelHandles(options) {
|
|
|
54363
54441
|
function prefetchAvailableModelHandles() {
|
|
54364
54442
|
getAvailableModelHandles().catch(() => {});
|
|
54365
54443
|
}
|
|
54366
|
-
function getModelContextWindow(handle) {
|
|
54444
|
+
async function getModelContextWindow(handle) {
|
|
54445
|
+
if (!cache4) {
|
|
54446
|
+
await getAvailableModelHandles();
|
|
54447
|
+
}
|
|
54367
54448
|
return cache4?.contextWindows.get(handle);
|
|
54368
54449
|
}
|
|
54369
54450
|
var CACHE_TTL_MS, cache4 = null, inflight = null;
|
|
@@ -57621,19 +57702,22 @@ var init_esm7 = __esm(() => {
|
|
|
57621
57702
|
|
|
57622
57703
|
// src/permissions/matcher.ts
|
|
57623
57704
|
import { resolve as resolve13 } from "node:path";
|
|
57705
|
+
function normalizePath(p) {
|
|
57706
|
+
return p.replace(/\\/g, "/");
|
|
57707
|
+
}
|
|
57624
57708
|
function matchesFilePattern(query, pattern, workingDirectory) {
|
|
57625
57709
|
const queryMatch = query.match(/^([^(]+)\((.+)\)$/);
|
|
57626
57710
|
if (!queryMatch || !queryMatch[1] || !queryMatch[2]) {
|
|
57627
57711
|
return false;
|
|
57628
57712
|
}
|
|
57629
57713
|
const queryTool = queryMatch[1];
|
|
57630
|
-
const filePath = queryMatch[2];
|
|
57714
|
+
const filePath = normalizePath(queryMatch[2]);
|
|
57631
57715
|
const patternMatch = pattern.match(/^([^(]+)\((.+)\)$/);
|
|
57632
57716
|
if (!patternMatch || !patternMatch[1] || !patternMatch[2]) {
|
|
57633
57717
|
return false;
|
|
57634
57718
|
}
|
|
57635
57719
|
const patternTool = patternMatch[1];
|
|
57636
|
-
let globPattern = patternMatch[2];
|
|
57720
|
+
let globPattern = normalizePath(patternMatch[2]);
|
|
57637
57721
|
if (queryTool !== patternTool) {
|
|
57638
57722
|
return false;
|
|
57639
57723
|
}
|
|
@@ -57647,11 +57731,12 @@ function matchesFilePattern(query, pattern, workingDirectory) {
|
|
|
57647
57731
|
if (globPattern.startsWith("//")) {
|
|
57648
57732
|
globPattern = globPattern.slice(1);
|
|
57649
57733
|
}
|
|
57650
|
-
const absoluteFilePath = resolve13(workingDirectory, filePath);
|
|
57734
|
+
const absoluteFilePath = normalizePath(resolve13(workingDirectory, filePath));
|
|
57651
57735
|
if (globPattern.startsWith("/")) {
|
|
57652
57736
|
return minimatch2(absoluteFilePath, globPattern);
|
|
57653
57737
|
}
|
|
57654
|
-
const
|
|
57738
|
+
const normalizedWorkingDir = normalizePath(workingDirectory);
|
|
57739
|
+
const relativeFilePath = filePath.startsWith("/") ? absoluteFilePath.replace(`${normalizedWorkingDir}/`, "") : filePath;
|
|
57655
57740
|
return minimatch2(relativeFilePath, globPattern) || minimatch2(absoluteFilePath, globPattern);
|
|
57656
57741
|
}
|
|
57657
57742
|
function extractActualCommand(command) {
|
|
@@ -58971,10 +59056,51 @@ async function executeTool(name, args, options) {
|
|
|
58971
59056
|
const responseSize = typeof flattenedResponse === "string" ? flattenedResponse.length : JSON.stringify(flattenedResponse).length;
|
|
58972
59057
|
telemetry2.trackToolUsage(internalName, toolStatus === "success", duration, responseSize, toolStatus === "error" ? "tool_error" : undefined, stderr ? stderr.join(`
|
|
58973
59058
|
`) : undefined);
|
|
58974
|
-
|
|
58975
|
-
|
|
58976
|
-
|
|
58977
|
-
|
|
59059
|
+
let postToolUseFeedback = [];
|
|
59060
|
+
try {
|
|
59061
|
+
const postHookResult = await runPostToolUseHooks(internalName, args, {
|
|
59062
|
+
status: toolStatus,
|
|
59063
|
+
output: getDisplayableToolReturn(flattenedResponse)
|
|
59064
|
+
}, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59065
|
+
postToolUseFeedback = postHookResult.feedback;
|
|
59066
|
+
} catch (error) {
|
|
59067
|
+
debugLog("hooks", "PostToolUse hook error (success path)", error);
|
|
59068
|
+
}
|
|
59069
|
+
let postToolUseFailureFeedback = [];
|
|
59070
|
+
if (toolStatus === "error") {
|
|
59071
|
+
const errorOutput = typeof flattenedResponse === "string" ? flattenedResponse : JSON.stringify(flattenedResponse);
|
|
59072
|
+
try {
|
|
59073
|
+
const failureHookResult = await runPostToolUseFailureHooks(internalName, args, errorOutput, "tool_error", options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59074
|
+
postToolUseFailureFeedback = failureHookResult.feedback;
|
|
59075
|
+
} catch (error) {
|
|
59076
|
+
debugLog("hooks", "PostToolUseFailure hook error (tool returned error)", error);
|
|
59077
|
+
}
|
|
59078
|
+
}
|
|
59079
|
+
const allFeedback = [...postToolUseFeedback, ...postToolUseFailureFeedback];
|
|
59080
|
+
if (allFeedback.length > 0) {
|
|
59081
|
+
const feedbackMessage = `
|
|
59082
|
+
|
|
59083
|
+
[Hook feedback]:
|
|
59084
|
+
${allFeedback.join(`
|
|
59085
|
+
`)}`;
|
|
59086
|
+
let finalToolReturn;
|
|
59087
|
+
if (typeof flattenedResponse === "string") {
|
|
59088
|
+
finalToolReturn = flattenedResponse + feedbackMessage;
|
|
59089
|
+
} else if (Array.isArray(flattenedResponse)) {
|
|
59090
|
+
finalToolReturn = [
|
|
59091
|
+
...flattenedResponse,
|
|
59092
|
+
{ type: "text", text: feedbackMessage }
|
|
59093
|
+
];
|
|
59094
|
+
} else {
|
|
59095
|
+
finalToolReturn = flattenedResponse;
|
|
59096
|
+
}
|
|
59097
|
+
return {
|
|
59098
|
+
toolReturn: finalToolReturn,
|
|
59099
|
+
status: toolStatus,
|
|
59100
|
+
...stdout && { stdout },
|
|
59101
|
+
...stderr && { stderr }
|
|
59102
|
+
};
|
|
59103
|
+
}
|
|
58978
59104
|
return {
|
|
58979
59105
|
toolReturn: flattenedResponse,
|
|
58980
59106
|
status: toolStatus,
|
|
@@ -58987,9 +59113,28 @@ async function executeTool(name, args, options) {
|
|
|
58987
59113
|
const errorType = isAbort ? "abort" : error instanceof Error ? error.name : "unknown";
|
|
58988
59114
|
const errorMessage = isAbort ? INTERRUPTED_BY_USER : error instanceof Error ? error.message : String(error);
|
|
58989
59115
|
telemetry2.trackToolUsage(internalName, false, duration, errorMessage.length, errorType, errorMessage);
|
|
58990
|
-
|
|
59116
|
+
let postToolUseFeedback = [];
|
|
59117
|
+
try {
|
|
59118
|
+
const postHookResult = await runPostToolUseHooks(internalName, args, { status: "error", output: errorMessage }, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59119
|
+
postToolUseFeedback = postHookResult.feedback;
|
|
59120
|
+
} catch (error2) {
|
|
59121
|
+
debugLog("hooks", "PostToolUse hook error (error path)", error2);
|
|
59122
|
+
}
|
|
59123
|
+
let postToolUseFailureFeedback = [];
|
|
59124
|
+
try {
|
|
59125
|
+
const failureHookResult = await runPostToolUseFailureHooks(internalName, args, errorMessage, errorType, options?.toolCallId, undefined, undefined, undefined, undefined);
|
|
59126
|
+
postToolUseFailureFeedback = failureHookResult.feedback;
|
|
59127
|
+
} catch (error2) {
|
|
59128
|
+
debugLog("hooks", "PostToolUseFailure hook error (exception path)", error2);
|
|
59129
|
+
}
|
|
59130
|
+
const allFeedback = [...postToolUseFeedback, ...postToolUseFailureFeedback];
|
|
59131
|
+
const finalErrorMessage = allFeedback.length > 0 ? `${errorMessage}
|
|
59132
|
+
|
|
59133
|
+
[Hook feedback]:
|
|
59134
|
+
${allFeedback.join(`
|
|
59135
|
+
`)}` : errorMessage;
|
|
58991
59136
|
return {
|
|
58992
|
-
toolReturn:
|
|
59137
|
+
toolReturn: finalErrorMessage,
|
|
58993
59138
|
status: "error"
|
|
58994
59139
|
};
|
|
58995
59140
|
}
|
|
@@ -59025,6 +59170,7 @@ var init_manager3 = __esm(async () => {
|
|
|
59025
59170
|
init_model();
|
|
59026
59171
|
init_subagents();
|
|
59027
59172
|
init_constants();
|
|
59173
|
+
init_debug();
|
|
59028
59174
|
await __promiseAll([
|
|
59029
59175
|
init_approval_execution(),
|
|
59030
59176
|
init_hooks(),
|
|
@@ -61856,7 +62002,7 @@ function buildModelSettings(modelHandle, updateArgs) {
|
|
|
61856
62002
|
async function updateAgentLLMConfig(agentId, modelHandle, updateArgs) {
|
|
61857
62003
|
const client = await getClient2();
|
|
61858
62004
|
const modelSettings = buildModelSettings(modelHandle, updateArgs);
|
|
61859
|
-
const contextWindow = updateArgs?.context_window;
|
|
62005
|
+
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
61860
62006
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
61861
62007
|
await client.agents.update(agentId, {
|
|
61862
62008
|
model: modelHandle,
|
|
@@ -61938,6 +62084,7 @@ async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
|
61938
62084
|
var init_modify = __esm(async () => {
|
|
61939
62085
|
await __promiseAll([
|
|
61940
62086
|
init_openai_codex_provider(),
|
|
62087
|
+
init_available_models(),
|
|
61941
62088
|
init_client2()
|
|
61942
62089
|
]);
|
|
61943
62090
|
});
|
|
@@ -62109,7 +62256,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
62109
62256
|
blockProvenance.push({ label: blockId, source: "shared" });
|
|
62110
62257
|
}
|
|
62111
62258
|
const modelUpdateArgs = getModelUpdateArgs(modelHandle);
|
|
62112
|
-
const contextWindow = modelUpdateArgs?.context_window;
|
|
62259
|
+
const contextWindow = modelUpdateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
62113
62260
|
let systemPromptContent;
|
|
62114
62261
|
if (options.systemPromptCustom) {
|
|
62115
62262
|
systemPromptContent = options.systemPromptCustom;
|
|
@@ -62182,6 +62329,7 @@ var init_create = __esm(async () => {
|
|
|
62182
62329
|
init_promptAssets();
|
|
62183
62330
|
init_skills2();
|
|
62184
62331
|
await __promiseAll([
|
|
62332
|
+
init_available_models(),
|
|
62185
62333
|
init_client2(),
|
|
62186
62334
|
init_modify()
|
|
62187
62335
|
]);
|
|
@@ -62853,16 +63001,6 @@ function isGlobTool(name) {
|
|
|
62853
63001
|
}
|
|
62854
63002
|
|
|
62855
63003
|
// 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
63004
|
function appendStreamingOutput(state, chunk, startTime, isStderr = false) {
|
|
62867
63005
|
const current = state || {
|
|
62868
63006
|
tailLines: [],
|
|
@@ -62963,7 +63101,7 @@ function markCurrentLineAsFinished(b) {
|
|
|
62963
63101
|
if (!b.lastOtid) {
|
|
62964
63102
|
return;
|
|
62965
63103
|
}
|
|
62966
|
-
const prev = b.byId.get(b.lastOtid)
|
|
63104
|
+
const prev = b.byId.get(b.lastOtid);
|
|
62967
63105
|
if (prev && (prev.kind === "assistant" || prev.kind === "reasoning")) {
|
|
62968
63106
|
markAsFinished(b, b.lastOtid);
|
|
62969
63107
|
} else {}
|
|
@@ -63109,48 +63247,33 @@ function onChunk(b, chunk) {
|
|
|
63109
63247
|
}
|
|
63110
63248
|
case "tool_call_message":
|
|
63111
63249
|
case "approval_request_message": {
|
|
63112
|
-
|
|
63250
|
+
handleOtidTransition(b, chunk.otid ?? undefined);
|
|
63113
63251
|
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)
|
|
63252
|
+
if (!toolCall || !toolCall.tool_call_id)
|
|
63145
63253
|
break;
|
|
63254
|
+
const toolCallId = toolCall.tool_call_id;
|
|
63255
|
+
const name = toolCall.name;
|
|
63256
|
+
const argsText = toolCall.arguments;
|
|
63257
|
+
const id = b.toolCallIdToLineId.get(toolCallId) ?? toolCallId;
|
|
63258
|
+
if (!b.toolCallIdToLineId.has(toolCallId)) {
|
|
63259
|
+
b.toolCallIdToLineId.set(toolCallId, id);
|
|
63260
|
+
}
|
|
63146
63261
|
const desiredPhase = "ready";
|
|
63147
|
-
|
|
63262
|
+
let line = ensure(b, id, () => ({
|
|
63148
63263
|
kind: "tool_call",
|
|
63149
63264
|
id,
|
|
63150
|
-
toolCallId
|
|
63265
|
+
toolCallId,
|
|
63151
63266
|
name: name ?? undefined,
|
|
63152
63267
|
phase: desiredPhase
|
|
63153
63268
|
}));
|
|
63269
|
+
if (name && !line.name || line.toolCallId !== toolCallId) {
|
|
63270
|
+
line = {
|
|
63271
|
+
...line,
|
|
63272
|
+
toolCallId,
|
|
63273
|
+
name: line.name ?? name ?? undefined
|
|
63274
|
+
};
|
|
63275
|
+
b.byId.set(id, line);
|
|
63276
|
+
}
|
|
63154
63277
|
if (chunk.message_type === "approval_request_message" && line.phase !== "finished") {
|
|
63155
63278
|
b.byId.set(id, { ...line, phase: "ready" });
|
|
63156
63279
|
}
|
|
@@ -63182,7 +63305,9 @@ function onChunk(b, chunk) {
|
|
|
63182
63305
|
parsedArgs = JSON.parse(toolInfo.toolArgs);
|
|
63183
63306
|
}
|
|
63184
63307
|
} catch {}
|
|
63185
|
-
runPreToolUseHooks(toolInfo.toolName, parsedArgs, toolCallId, undefined, b.agentId).catch(() => {
|
|
63308
|
+
runPreToolUseHooks(toolInfo.toolName, parsedArgs, toolCallId, undefined, b.agentId).catch((error) => {
|
|
63309
|
+
debugLog("hooks", "PreToolUse hook error (accumulator)", error);
|
|
63310
|
+
});
|
|
63186
63311
|
}
|
|
63187
63312
|
}
|
|
63188
63313
|
break;
|
|
@@ -63231,7 +63356,9 @@ function onChunk(b, chunk) {
|
|
|
63231
63356
|
runPostToolUseHooks(serverToolInfo.toolName, parsedArgs, {
|
|
63232
63357
|
status: status === "success" ? "success" : "error",
|
|
63233
63358
|
output: resultText
|
|
63234
|
-
}, toolCallId, undefined, b.agentId, precedingReasoning, precedingAssistantMessage).catch(() => {
|
|
63359
|
+
}, toolCallId, undefined, b.agentId, precedingReasoning, precedingAssistantMessage).catch((error) => {
|
|
63360
|
+
debugLog("hooks", "PostToolUse hook error (accumulator)", error);
|
|
63361
|
+
});
|
|
63235
63362
|
b.serverToolCalls.delete(toolCallId);
|
|
63236
63363
|
}
|
|
63237
63364
|
}
|
|
@@ -63337,6 +63464,7 @@ function setToolCallsRunning(b, toolCallIds) {
|
|
|
63337
63464
|
var MAX_TAIL_LINES = 5, MAX_BUFFER_SIZE = 1e5, CANCEL_REASON_TEXT;
|
|
63338
63465
|
var init_accumulator = __esm(async () => {
|
|
63339
63466
|
init_constants();
|
|
63467
|
+
init_debug();
|
|
63340
63468
|
init_backfill();
|
|
63341
63469
|
await init_hooks();
|
|
63342
63470
|
CANCEL_REASON_TEXT = {
|
|
@@ -63347,6 +63475,99 @@ var init_accumulator = __esm(async () => {
|
|
|
63347
63475
|
};
|
|
63348
63476
|
});
|
|
63349
63477
|
|
|
63478
|
+
// src/cli/helpers/safeJsonParse.ts
|
|
63479
|
+
function safeJsonParse(json) {
|
|
63480
|
+
try {
|
|
63481
|
+
const data = JSON.parse(json);
|
|
63482
|
+
return { success: true, data };
|
|
63483
|
+
} catch (error) {
|
|
63484
|
+
return {
|
|
63485
|
+
success: false,
|
|
63486
|
+
error: error instanceof Error ? error.message : String(error)
|
|
63487
|
+
};
|
|
63488
|
+
}
|
|
63489
|
+
}
|
|
63490
|
+
function safeJsonParseOr(json, defaultValue) {
|
|
63491
|
+
const result = safeJsonParse(json);
|
|
63492
|
+
return result.success ? result.data : defaultValue;
|
|
63493
|
+
}
|
|
63494
|
+
|
|
63495
|
+
// src/cli/helpers/approvalClassification.ts
|
|
63496
|
+
async function getMissingRequiredArgs(toolName, parsedArgs) {
|
|
63497
|
+
const schema = getToolSchema(toolName);
|
|
63498
|
+
const required = schema?.input_schema?.required || [];
|
|
63499
|
+
return required.filter((key) => !(key in parsedArgs) || parsedArgs[key] == null);
|
|
63500
|
+
}
|
|
63501
|
+
async function classifyApprovals(approvals, opts = {}) {
|
|
63502
|
+
const needsUserInput = [];
|
|
63503
|
+
const autoAllowed = [];
|
|
63504
|
+
const autoDenied = [];
|
|
63505
|
+
const denyReasonForAsk = opts.denyReasonForAsk ?? "Tool requires approval (headless mode)";
|
|
63506
|
+
const missingNameReason = opts.missingNameReason ?? "Tool call incomplete - missing name";
|
|
63507
|
+
for (const approval of approvals) {
|
|
63508
|
+
const toolName = approval.toolName;
|
|
63509
|
+
if (!toolName) {
|
|
63510
|
+
autoDenied.push({
|
|
63511
|
+
approval,
|
|
63512
|
+
permission: { decision: "deny", reason: missingNameReason },
|
|
63513
|
+
context: null,
|
|
63514
|
+
parsedArgs: {},
|
|
63515
|
+
denyReason: missingNameReason
|
|
63516
|
+
});
|
|
63517
|
+
continue;
|
|
63518
|
+
}
|
|
63519
|
+
const parsedArgs = safeJsonParseOr(approval.toolArgs || "{}", {});
|
|
63520
|
+
const permission = await checkToolPermission(toolName, parsedArgs);
|
|
63521
|
+
const context3 = opts.getContext ? await opts.getContext(toolName, parsedArgs) : null;
|
|
63522
|
+
let decision = permission.decision;
|
|
63523
|
+
if (opts.alwaysRequiresUserInput?.(toolName) && decision === "allow") {
|
|
63524
|
+
decision = "ask";
|
|
63525
|
+
}
|
|
63526
|
+
if (decision === "ask" && opts.treatAskAsDeny) {
|
|
63527
|
+
autoDenied.push({
|
|
63528
|
+
approval,
|
|
63529
|
+
permission,
|
|
63530
|
+
context: context3,
|
|
63531
|
+
parsedArgs,
|
|
63532
|
+
denyReason: denyReasonForAsk
|
|
63533
|
+
});
|
|
63534
|
+
continue;
|
|
63535
|
+
}
|
|
63536
|
+
if (decision === "allow" && opts.requireArgsForAutoApprove) {
|
|
63537
|
+
const missingRequiredArgs = await getMissingRequiredArgs(toolName, parsedArgs);
|
|
63538
|
+
if (missingRequiredArgs.length > 0) {
|
|
63539
|
+
const denyReason = opts.missingArgsReason ? opts.missingArgsReason(missingRequiredArgs) : `Missing required parameter${missingRequiredArgs.length > 1 ? "s" : ""}: ${missingRequiredArgs.join(", ")}`;
|
|
63540
|
+
autoDenied.push({
|
|
63541
|
+
approval,
|
|
63542
|
+
permission,
|
|
63543
|
+
context: context3,
|
|
63544
|
+
parsedArgs,
|
|
63545
|
+
missingRequiredArgs,
|
|
63546
|
+
denyReason
|
|
63547
|
+
});
|
|
63548
|
+
continue;
|
|
63549
|
+
}
|
|
63550
|
+
}
|
|
63551
|
+
const entry = {
|
|
63552
|
+
approval,
|
|
63553
|
+
permission,
|
|
63554
|
+
context: context3,
|
|
63555
|
+
parsedArgs
|
|
63556
|
+
};
|
|
63557
|
+
if (decision === "ask") {
|
|
63558
|
+
needsUserInput.push(entry);
|
|
63559
|
+
} else if (decision === "deny") {
|
|
63560
|
+
autoDenied.push(entry);
|
|
63561
|
+
} else {
|
|
63562
|
+
autoAllowed.push(entry);
|
|
63563
|
+
}
|
|
63564
|
+
}
|
|
63565
|
+
return { needsUserInput, autoAllowed, autoDenied };
|
|
63566
|
+
}
|
|
63567
|
+
var init_approvalClassification = __esm(async () => {
|
|
63568
|
+
await init_manager3();
|
|
63569
|
+
});
|
|
63570
|
+
|
|
63350
63571
|
// src/cli/helpers/errorContext.ts
|
|
63351
63572
|
function setErrorContext(context3) {
|
|
63352
63573
|
currentContext = { ...currentContext, ...context3 };
|
|
@@ -63543,23 +63764,6 @@ var init_errorFormatter = __esm(() => {
|
|
|
63543
63764
|
init_errorContext();
|
|
63544
63765
|
});
|
|
63545
63766
|
|
|
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
63767
|
// src/cli/helpers/streamProcessor.ts
|
|
63564
63768
|
class StreamProcessor {
|
|
63565
63769
|
pendingApprovals = new Map;
|
|
@@ -63567,7 +63771,6 @@ class StreamProcessor {
|
|
|
63567
63771
|
lastRunId = null;
|
|
63568
63772
|
lastSeqId = null;
|
|
63569
63773
|
stopReason = null;
|
|
63570
|
-
lastApprovalId = null;
|
|
63571
63774
|
processChunk(chunk) {
|
|
63572
63775
|
let errorInfo;
|
|
63573
63776
|
let updatedApproval;
|
|
@@ -63607,21 +63810,13 @@ class StreamProcessor {
|
|
|
63607
63810
|
this.pendingApprovals.delete(chunk.tool_call_id);
|
|
63608
63811
|
}
|
|
63609
63812
|
}
|
|
63610
|
-
if (chunk.message_type === "approval_request_message") {
|
|
63611
|
-
this.lastApprovalId = chunk.id;
|
|
63612
|
-
}
|
|
63613
63813
|
if (chunk.message_type === "approval_request_message") {
|
|
63614
63814
|
const toolCalls = Array.isArray(chunk.tool_calls) ? chunk.tool_calls : chunk.tool_call ? [chunk.tool_call] : [];
|
|
63615
63815
|
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)
|
|
63816
|
+
const toolCallId = toolCall?.tool_call_id;
|
|
63817
|
+
if (!toolCallId)
|
|
63623
63818
|
continue;
|
|
63624
|
-
|
|
63819
|
+
const id = toolCallId;
|
|
63625
63820
|
const existing = this.pendingApprovals.get(id) || {
|
|
63626
63821
|
toolCallId: id,
|
|
63627
63822
|
toolName: "",
|
|
@@ -63652,7 +63847,7 @@ class StreamProcessor {
|
|
|
63652
63847
|
}
|
|
63653
63848
|
|
|
63654
63849
|
// src/cli/helpers/stream.ts
|
|
63655
|
-
async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage) {
|
|
63850
|
+
async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed) {
|
|
63656
63851
|
const startTime = performance.now();
|
|
63657
63852
|
const requestStartTime = stream2[STREAM_REQUEST_START_TIME];
|
|
63658
63853
|
let hasLoggedTTFT = false;
|
|
@@ -63702,17 +63897,44 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
63702
63897
|
const ttft = performance.now() - requestStartTime;
|
|
63703
63898
|
logTiming(`TTFT: ${formatDuration(ttft)} (from POST to first content)`);
|
|
63704
63899
|
}
|
|
63705
|
-
const { shouldOutput } = streamProcessor.processChunk(chunk);
|
|
63900
|
+
const { shouldOutput, errorInfo, updatedApproval } = streamProcessor.processChunk(chunk);
|
|
63706
63901
|
if (abortSignal?.aborted) {
|
|
63707
63902
|
stopReason = "cancelled";
|
|
63708
63903
|
markIncompleteToolsAsCancelled(buffers, true, "user_interrupt");
|
|
63709
63904
|
queueMicrotask(refresh);
|
|
63710
63905
|
break;
|
|
63711
63906
|
}
|
|
63712
|
-
|
|
63907
|
+
let shouldOutputChunk = shouldOutput;
|
|
63908
|
+
let shouldAccumulate = shouldOutput;
|
|
63909
|
+
if (onChunkProcessed) {
|
|
63910
|
+
const hookResult = await onChunkProcessed({
|
|
63911
|
+
chunk,
|
|
63912
|
+
shouldOutput: shouldOutputChunk,
|
|
63913
|
+
errorInfo,
|
|
63914
|
+
updatedApproval,
|
|
63915
|
+
streamProcessor
|
|
63916
|
+
});
|
|
63917
|
+
if (hookResult?.shouldOutput !== undefined) {
|
|
63918
|
+
shouldOutputChunk = hookResult.shouldOutput;
|
|
63919
|
+
}
|
|
63920
|
+
if (hookResult?.shouldAccumulate !== undefined) {
|
|
63921
|
+
shouldAccumulate = hookResult.shouldAccumulate;
|
|
63922
|
+
} else {
|
|
63923
|
+
shouldAccumulate = shouldOutputChunk;
|
|
63924
|
+
}
|
|
63925
|
+
if (hookResult?.stopReason) {
|
|
63926
|
+
stopReason = hookResult.stopReason;
|
|
63927
|
+
}
|
|
63928
|
+
} else {
|
|
63929
|
+
shouldAccumulate = shouldOutputChunk;
|
|
63930
|
+
}
|
|
63931
|
+
if (shouldAccumulate) {
|
|
63713
63932
|
onChunk(buffers, chunk);
|
|
63714
63933
|
queueMicrotask(refresh);
|
|
63715
63934
|
}
|
|
63935
|
+
if (stopReason) {
|
|
63936
|
+
break;
|
|
63937
|
+
}
|
|
63716
63938
|
}
|
|
63717
63939
|
} catch (e) {
|
|
63718
63940
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
@@ -63779,9 +64001,9 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
63779
64001
|
fallbackError
|
|
63780
64002
|
};
|
|
63781
64003
|
}
|
|
63782
|
-
async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onFirstMessage) {
|
|
64004
|
+
async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed) {
|
|
63783
64005
|
const overallStartTime = performance.now();
|
|
63784
|
-
let result = await drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage);
|
|
64006
|
+
let result = await drainStream(stream2, buffers, refresh, abortSignal, onFirstMessage, onChunkProcessed);
|
|
63785
64007
|
if (result.stopReason === "error" && result.lastRunId && result.lastSeqId !== null && abortSignal && !abortSignal.aborted) {
|
|
63786
64008
|
const originalFallbackError = result.fallbackError;
|
|
63787
64009
|
try {
|
|
@@ -63792,7 +64014,7 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
63792
64014
|
starting_after: result.lastSeqId,
|
|
63793
64015
|
batch_size: 1000
|
|
63794
64016
|
});
|
|
63795
|
-
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal);
|
|
64017
|
+
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal, undefined, onChunkProcessed);
|
|
63796
64018
|
result = resumeResult;
|
|
63797
64019
|
} catch (_e) {
|
|
63798
64020
|
result.fallbackError = originalFallbackError;
|
|
@@ -63803,6 +64025,7 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
63803
64025
|
}
|
|
63804
64026
|
var init_stream = __esm(async () => {
|
|
63805
64027
|
init_error();
|
|
64028
|
+
init_debug();
|
|
63806
64029
|
init_timing();
|
|
63807
64030
|
await __promiseAll([
|
|
63808
64031
|
init_client2(),
|
|
@@ -64227,6 +64450,7 @@ async function getResumeData2(client, agent, conversationId) {
|
|
|
64227
64450
|
var MESSAGE_HISTORY_LIMIT2 = 15;
|
|
64228
64451
|
var init_check_approval = __esm(() => {
|
|
64229
64452
|
init_error();
|
|
64453
|
+
init_debug();
|
|
64230
64454
|
});
|
|
64231
64455
|
|
|
64232
64456
|
// src/headless.ts
|
|
@@ -64313,6 +64537,13 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
|
|
|
64313
64537
|
}
|
|
64314
64538
|
const inputFormat = values["input-format"];
|
|
64315
64539
|
const isBidirectionalMode = inputFormat === "stream-json";
|
|
64540
|
+
process.stdout.on("error", (err) => {
|
|
64541
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : undefined;
|
|
64542
|
+
if (code === "EPIPE") {
|
|
64543
|
+
process.exit(0);
|
|
64544
|
+
}
|
|
64545
|
+
throw err;
|
|
64546
|
+
});
|
|
64316
64547
|
let prompt = positionals.slice(2).join(" ");
|
|
64317
64548
|
if (!prompt && !isBidirectionalMode) {
|
|
64318
64549
|
if (!process.stdin.isTTY) {
|
|
@@ -64617,10 +64848,7 @@ In headless mode, use:
|
|
|
64617
64848
|
const noSkillsFlag = values["no-skills"];
|
|
64618
64849
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
64619
64850
|
if (!noSkillsFlag && !isSubagent) {
|
|
64620
|
-
|
|
64621
|
-
if (createdBlocks.length > 0) {
|
|
64622
|
-
console.log("Created missing skills blocks for agent compatibility");
|
|
64623
|
-
}
|
|
64851
|
+
await ensureSkillsBlocks(agent.id);
|
|
64624
64852
|
}
|
|
64625
64853
|
if (memfsFlag) {
|
|
64626
64854
|
settingsManager.setMemfsEnabled(agent.id, true);
|
|
@@ -64638,9 +64866,6 @@ In headless mode, use:
|
|
|
64638
64866
|
process.exit(1);
|
|
64639
64867
|
}
|
|
64640
64868
|
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
64869
|
} catch (error) {
|
|
64645
64870
|
console.error(`Memory filesystem sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
64646
64871
|
process.exit(1);
|
|
@@ -64771,39 +64996,28 @@ In headless mode, use:
|
|
|
64771
64996
|
const pendingApprovals = resume.pendingApprovals || [];
|
|
64772
64997
|
if (pendingApprovals.length === 0)
|
|
64773
64998
|
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({
|
|
64999
|
+
const { autoAllowed, autoDenied } = await classifyApprovals(pendingApprovals, {
|
|
65000
|
+
treatAskAsDeny: true,
|
|
65001
|
+
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
65002
|
+
requireArgsForAutoApprove: true,
|
|
65003
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65004
|
+
});
|
|
65005
|
+
const decisions = [
|
|
65006
|
+
...autoAllowed.map((ac) => ({
|
|
64801
65007
|
type: "approve",
|
|
64802
|
-
approval:
|
|
64803
|
-
reason: permission.reason || "Allowed by permission rule",
|
|
64804
|
-
matchedRule: permission.matchedRule
|
|
64805
|
-
})
|
|
64806
|
-
|
|
65008
|
+
approval: ac.approval,
|
|
65009
|
+
reason: ac.permission.reason || "Allowed by permission rule",
|
|
65010
|
+
matchedRule: "matchedRule" in ac.permission && ac.permission.matchedRule ? ac.permission.matchedRule : "auto-approved"
|
|
65011
|
+
})),
|
|
65012
|
+
...autoDenied.map((ac) => {
|
|
65013
|
+
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";
|
|
65014
|
+
return {
|
|
65015
|
+
type: "deny",
|
|
65016
|
+
approval: ac.approval,
|
|
65017
|
+
reason: ac.denyReason ?? fallback
|
|
65018
|
+
};
|
|
65019
|
+
})
|
|
65020
|
+
];
|
|
64807
65021
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
64808
65022
|
if (outputFormat === "stream-json") {
|
|
64809
65023
|
for (const decision of decisions) {
|
|
@@ -64923,12 +65137,16 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
64923
65137
|
let approvals = [];
|
|
64924
65138
|
let apiDurationMs;
|
|
64925
65139
|
let lastRunId = null;
|
|
65140
|
+
let approvalPendingRecovery = false;
|
|
64926
65141
|
if (outputFormat === "stream-json") {
|
|
64927
|
-
const startTime = performance.now();
|
|
64928
65142
|
const autoApprovalEmitted = new Set;
|
|
64929
|
-
const
|
|
64930
|
-
|
|
64931
|
-
|
|
65143
|
+
const streamJsonHook = async ({
|
|
65144
|
+
chunk,
|
|
65145
|
+
shouldOutput,
|
|
65146
|
+
errorInfo,
|
|
65147
|
+
updatedApproval
|
|
65148
|
+
}) => {
|
|
65149
|
+
let shouldOutputChunk = shouldOutput;
|
|
64932
65150
|
if (errorInfo && shouldOutput) {
|
|
64933
65151
|
const errorEvent = {
|
|
64934
65152
|
type: "error",
|
|
@@ -64948,52 +65166,45 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
64948
65166
|
}
|
|
64949
65167
|
};
|
|
64950
65168
|
console.log(JSON.stringify(errorEvent));
|
|
64951
|
-
|
|
64952
|
-
accumulatorOnChunk(buffers, chunk);
|
|
64953
|
-
continue;
|
|
65169
|
+
shouldOutputChunk = false;
|
|
64954
65170
|
}
|
|
64955
65171
|
if (isApprovalPendingError(errorInfo?.detail) || isApprovalPendingError(errorInfo?.message)) {
|
|
64956
|
-
|
|
64957
|
-
|
|
64958
|
-
|
|
64959
|
-
|
|
64960
|
-
|
|
64961
|
-
|
|
65172
|
+
const recoveryRunId = errorInfo?.run_id;
|
|
65173
|
+
const recoveryMsg = {
|
|
65174
|
+
type: "recovery",
|
|
65175
|
+
recovery_type: "approval_pending",
|
|
65176
|
+
message: "Detected pending approval conflict; auto-denying stale approval and retrying",
|
|
65177
|
+
run_id: recoveryRunId ?? undefined,
|
|
65178
|
+
session_id: sessionId,
|
|
65179
|
+
uuid: `recovery-${recoveryRunId || crypto.randomUUID()}`
|
|
65180
|
+
};
|
|
65181
|
+
console.log(JSON.stringify(recoveryMsg));
|
|
65182
|
+
approvalPendingRecovery = true;
|
|
65183
|
+
return { stopReason: "error", shouldAccumulate: true };
|
|
65184
|
+
}
|
|
65185
|
+
if (updatedApproval && !autoApprovalEmitted.has(updatedApproval.toolCallId)) {
|
|
65186
|
+
const { autoAllowed } = await classifyApprovals([updatedApproval], {
|
|
65187
|
+
requireArgsForAutoApprove: true,
|
|
65188
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65189
|
+
});
|
|
65190
|
+
const [approval] = autoAllowed;
|
|
65191
|
+
if (approval) {
|
|
65192
|
+
const permission = approval.permission;
|
|
65193
|
+
shouldOutputChunk = false;
|
|
65194
|
+
const autoApprovalMsg = {
|
|
65195
|
+
type: "auto_approval",
|
|
65196
|
+
tool_call: {
|
|
65197
|
+
name: approval.approval.toolName,
|
|
65198
|
+
tool_call_id: approval.approval.toolCallId,
|
|
65199
|
+
arguments: approval.approval.toolArgs || "{}"
|
|
65200
|
+
},
|
|
65201
|
+
reason: permission.reason || "Allowed by permission rule",
|
|
65202
|
+
matched_rule: "matchedRule" in permission && permission.matchedRule ? permission.matchedRule : "auto-approved",
|
|
64962
65203
|
session_id: sessionId,
|
|
64963
|
-
uuid: `
|
|
65204
|
+
uuid: `auto-approval-${approval.approval.toolCallId}`
|
|
64964
65205
|
};
|
|
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
|
-
}
|
|
65206
|
+
console.log(JSON.stringify(autoApprovalMsg));
|
|
65207
|
+
autoApprovalEmitted.add(approval.approval.toolCallId);
|
|
64997
65208
|
}
|
|
64998
65209
|
}
|
|
64999
65210
|
if (shouldOutputChunk) {
|
|
@@ -65017,17 +65228,15 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65017
65228
|
console.log(JSON.stringify(msg));
|
|
65018
65229
|
}
|
|
65019
65230
|
}
|
|
65020
|
-
|
|
65021
|
-
|
|
65022
|
-
}
|
|
65023
|
-
stopReason =
|
|
65024
|
-
|
|
65025
|
-
|
|
65026
|
-
lastRunId =
|
|
65231
|
+
return { shouldOutput: shouldOutputChunk, shouldAccumulate: true };
|
|
65232
|
+
};
|
|
65233
|
+
const result = await drainStreamWithResume(stream2, buffers, () => {}, undefined, undefined, streamJsonHook);
|
|
65234
|
+
stopReason = result.stopReason;
|
|
65235
|
+
approvals = result.approvals || [];
|
|
65236
|
+
apiDurationMs = result.apiDurationMs;
|
|
65237
|
+
lastRunId = result.lastRunId || null;
|
|
65027
65238
|
if (lastRunId)
|
|
65028
65239
|
lastKnownRunId = lastRunId;
|
|
65029
|
-
const { markCurrentLineAsFinished: markCurrentLineAsFinished2 } = await init_accumulator().then(() => exports_accumulator);
|
|
65030
|
-
markCurrentLineAsFinished2(buffers);
|
|
65031
65240
|
} else {
|
|
65032
65241
|
const result = await drainStreamWithResume(stream2, buffers, () => {});
|
|
65033
65242
|
stopReason = result.stopReason;
|
|
@@ -65038,6 +65247,10 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65038
65247
|
lastKnownRunId = lastRunId;
|
|
65039
65248
|
}
|
|
65040
65249
|
sessionStats.endTurn(apiDurationMs);
|
|
65250
|
+
if (approvalPendingRecovery) {
|
|
65251
|
+
await resolveAllPendingApprovals();
|
|
65252
|
+
continue;
|
|
65253
|
+
}
|
|
65041
65254
|
if (stopReason === "end_turn") {
|
|
65042
65255
|
llmApiErrorRetries = 0;
|
|
65043
65256
|
conversationBusyRetries = 0;
|
|
@@ -65048,45 +65261,26 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65048
65261
|
console.error("Unexpected empty approvals array");
|
|
65049
65262
|
process.exit(1);
|
|
65050
65263
|
}
|
|
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({
|
|
65264
|
+
const { autoAllowed, autoDenied } = await classifyApprovals(approvals, {
|
|
65265
|
+
treatAskAsDeny: true,
|
|
65266
|
+
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
65267
|
+
requireArgsForAutoApprove: true,
|
|
65268
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65269
|
+
});
|
|
65270
|
+
const decisions = [
|
|
65271
|
+
...autoAllowed.map((ac) => ({
|
|
65086
65272
|
type: "approve",
|
|
65087
|
-
approval:
|
|
65088
|
-
})
|
|
65089
|
-
|
|
65273
|
+
approval: ac.approval
|
|
65274
|
+
})),
|
|
65275
|
+
...autoDenied.map((ac) => {
|
|
65276
|
+
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";
|
|
65277
|
+
return {
|
|
65278
|
+
type: "deny",
|
|
65279
|
+
approval: ac.approval,
|
|
65280
|
+
reason: ac.denyReason ?? fallback
|
|
65281
|
+
};
|
|
65282
|
+
})
|
|
65283
|
+
];
|
|
65090
65284
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
65091
65285
|
const executedResults = await executeApprovalBatch2(decisions);
|
|
65092
65286
|
currentInput = [
|
|
@@ -65516,109 +65710,110 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
65516
65710
|
const stream2 = await sendMessageStream(conversationId, currentInput, {
|
|
65517
65711
|
agentId: agent.id
|
|
65518
65712
|
});
|
|
65519
|
-
const
|
|
65520
|
-
|
|
65521
|
-
|
|
65522
|
-
break;
|
|
65713
|
+
const streamJsonHook = ({ chunk, shouldOutput }) => {
|
|
65714
|
+
if (!shouldOutput) {
|
|
65715
|
+
return { shouldAccumulate: true };
|
|
65523
65716
|
}
|
|
65524
|
-
const
|
|
65525
|
-
|
|
65526
|
-
|
|
65527
|
-
const
|
|
65528
|
-
|
|
65529
|
-
|
|
65530
|
-
|
|
65531
|
-
|
|
65532
|
-
|
|
65533
|
-
|
|
65534
|
-
|
|
65535
|
-
|
|
65536
|
-
|
|
65537
|
-
|
|
65538
|
-
|
|
65539
|
-
|
|
65540
|
-
|
|
65541
|
-
|
|
65542
|
-
};
|
|
65543
|
-
console.log(JSON.stringify(msg));
|
|
65544
|
-
}
|
|
65717
|
+
const chunkWithIds = chunk;
|
|
65718
|
+
const uuid = chunkWithIds.otid || chunkWithIds.id;
|
|
65719
|
+
if (includePartialMessages) {
|
|
65720
|
+
const streamEvent = {
|
|
65721
|
+
type: "stream_event",
|
|
65722
|
+
event: chunk,
|
|
65723
|
+
session_id: sessionId,
|
|
65724
|
+
uuid: uuid || crypto.randomUUID()
|
|
65725
|
+
};
|
|
65726
|
+
console.log(JSON.stringify(streamEvent));
|
|
65727
|
+
} else {
|
|
65728
|
+
const msg = {
|
|
65729
|
+
type: "message",
|
|
65730
|
+
...chunk,
|
|
65731
|
+
session_id: sessionId,
|
|
65732
|
+
uuid: uuid || crypto.randomUUID()
|
|
65733
|
+
};
|
|
65734
|
+
console.log(JSON.stringify(msg));
|
|
65545
65735
|
}
|
|
65546
|
-
|
|
65547
|
-
|
|
65548
|
-
}
|
|
65549
|
-
const stopReason =
|
|
65736
|
+
return { shouldAccumulate: true };
|
|
65737
|
+
};
|
|
65738
|
+
const result = await drainStreamWithResume(stream2, buffers, () => {}, currentAbortController?.signal, undefined, streamJsonHook);
|
|
65739
|
+
const stopReason = result.stopReason;
|
|
65740
|
+
const approvals = result.approvals || [];
|
|
65550
65741
|
if (stopReason === "end_turn") {
|
|
65551
65742
|
break;
|
|
65552
65743
|
}
|
|
65553
|
-
if (currentAbortController?.signal.aborted) {
|
|
65744
|
+
if (currentAbortController?.signal.aborted || stopReason === "cancelled") {
|
|
65554
65745
|
break;
|
|
65555
65746
|
}
|
|
65556
65747
|
if (stopReason === "requires_approval") {
|
|
65557
|
-
const approvals = streamProcessor.getApprovals();
|
|
65558
65748
|
if (approvals.length === 0) {
|
|
65559
65749
|
break;
|
|
65560
65750
|
}
|
|
65561
|
-
const
|
|
65562
|
-
|
|
65563
|
-
|
|
65564
|
-
|
|
65565
|
-
|
|
65751
|
+
const { autoAllowed, autoDenied, needsUserInput } = await classifyApprovals(approvals, {
|
|
65752
|
+
requireArgsForAutoApprove: true,
|
|
65753
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
65754
|
+
});
|
|
65755
|
+
const decisions = [
|
|
65756
|
+
...autoAllowed.map((ac) => ({
|
|
65757
|
+
type: "approve",
|
|
65758
|
+
approval: ac.approval,
|
|
65759
|
+
matchedRule: "matchedRule" in ac.permission && ac.permission.matchedRule ? ac.permission.matchedRule : "auto-approved"
|
|
65760
|
+
})),
|
|
65761
|
+
...autoDenied.map((ac) => {
|
|
65762
|
+
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";
|
|
65763
|
+
return {
|
|
65764
|
+
type: "deny",
|
|
65765
|
+
approval: ac.approval,
|
|
65766
|
+
reason: ac.denyReason ?? fallback
|
|
65767
|
+
};
|
|
65768
|
+
})
|
|
65769
|
+
];
|
|
65770
|
+
for (const approvalItem of autoAllowed) {
|
|
65771
|
+
const permission = approvalItem.permission;
|
|
65772
|
+
const autoApprovalMsg = {
|
|
65773
|
+
type: "auto_approval",
|
|
65774
|
+
tool_call: {
|
|
65775
|
+
name: approvalItem.approval.toolName,
|
|
65776
|
+
tool_call_id: approvalItem.approval.toolCallId,
|
|
65777
|
+
arguments: approvalItem.approval.toolArgs
|
|
65778
|
+
},
|
|
65779
|
+
reason: permission.reason || "auto-approved",
|
|
65780
|
+
matched_rule: "matchedRule" in permission && permission.matchedRule ? permission.matchedRule : "auto-approved",
|
|
65781
|
+
session_id: sessionId,
|
|
65782
|
+
uuid: `auto-approval-${approvalItem.approval.toolCallId}`
|
|
65783
|
+
};
|
|
65784
|
+
console.log(JSON.stringify(autoApprovalMsg));
|
|
65785
|
+
}
|
|
65786
|
+
for (const ac of needsUserInput) {
|
|
65787
|
+
const permResponse = await requestPermission(ac.approval.toolCallId, ac.approval.toolName, ac.parsedArgs);
|
|
65788
|
+
if (permResponse.decision === "allow") {
|
|
65789
|
+
const finalApproval = permResponse.updatedInput ? {
|
|
65790
|
+
...ac.approval,
|
|
65791
|
+
toolArgs: JSON.stringify(permResponse.updatedInput)
|
|
65792
|
+
} : ac.approval;
|
|
65566
65793
|
decisions.push({
|
|
65567
65794
|
type: "approve",
|
|
65568
|
-
approval,
|
|
65569
|
-
matchedRule:
|
|
65795
|
+
approval: finalApproval,
|
|
65796
|
+
matchedRule: "SDK callback approved"
|
|
65570
65797
|
});
|
|
65571
65798
|
const autoApprovalMsg = {
|
|
65572
65799
|
type: "auto_approval",
|
|
65573
65800
|
tool_call: {
|
|
65574
|
-
name:
|
|
65575
|
-
tool_call_id:
|
|
65576
|
-
arguments:
|
|
65801
|
+
name: finalApproval.toolName,
|
|
65802
|
+
tool_call_id: finalApproval.toolCallId,
|
|
65803
|
+
arguments: finalApproval.toolArgs
|
|
65577
65804
|
},
|
|
65578
|
-
reason:
|
|
65579
|
-
matched_rule:
|
|
65805
|
+
reason: permResponse.reason || "SDK callback approved",
|
|
65806
|
+
matched_rule: "canUseTool callback",
|
|
65580
65807
|
session_id: sessionId,
|
|
65581
|
-
uuid: `auto-approval-${approval.toolCallId}`
|
|
65808
|
+
uuid: `auto-approval-${ac.approval.toolCallId}`
|
|
65582
65809
|
};
|
|
65583
65810
|
console.log(JSON.stringify(autoApprovalMsg));
|
|
65584
|
-
} else
|
|
65811
|
+
} else {
|
|
65585
65812
|
decisions.push({
|
|
65586
65813
|
type: "deny",
|
|
65587
|
-
approval,
|
|
65588
|
-
reason:
|
|
65814
|
+
approval: ac.approval,
|
|
65815
|
+
reason: permResponse.reason || "Denied by SDK callback"
|
|
65589
65816
|
});
|
|
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
65817
|
}
|
|
65623
65818
|
}
|
|
65624
65819
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
@@ -65696,9 +65891,9 @@ var init_headless = __esm(async () => {
|
|
|
65696
65891
|
init_memoryFilesystem(),
|
|
65697
65892
|
init_message(),
|
|
65698
65893
|
init_accumulator(),
|
|
65894
|
+
init_approvalClassification(),
|
|
65699
65895
|
init_stream(),
|
|
65700
|
-
init_settings_manager()
|
|
65701
|
-
init_manager3()
|
|
65896
|
+
init_settings_manager()
|
|
65702
65897
|
]);
|
|
65703
65898
|
});
|
|
65704
65899
|
|
|
@@ -69710,7 +69905,8 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
69710
69905
|
onCancel,
|
|
69711
69906
|
isFocused = true,
|
|
69712
69907
|
approveAlwaysText,
|
|
69713
|
-
allowPersistence = true
|
|
69908
|
+
allowPersistence = true,
|
|
69909
|
+
showPreview = true
|
|
69714
69910
|
}) => {
|
|
69715
69911
|
const [selectedOption, setSelectedOption] = import_react36.useState(0);
|
|
69716
69912
|
const {
|
|
@@ -69801,12 +69997,13 @@ var init_InlineBashApproval = __esm(async () => {
|
|
|
69801
69997
|
]
|
|
69802
69998
|
}, undefined, true, undefined, this), [bashInfo.command, bashInfo.description, solidLine]);
|
|
69803
69999
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70000
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
69804
70001
|
return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
69805
70002
|
flexDirection: "column",
|
|
69806
70003
|
children: [
|
|
69807
|
-
memoizedCommandContent,
|
|
70004
|
+
showPreview && memoizedCommandContent,
|
|
69808
70005
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
69809
|
-
marginTop:
|
|
70006
|
+
marginTop: optionsMarginTop,
|
|
69810
70007
|
flexDirection: "column",
|
|
69811
70008
|
children: [
|
|
69812
70009
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
@@ -70126,7 +70323,8 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
70126
70323
|
onCancel,
|
|
70127
70324
|
isFocused = true,
|
|
70128
70325
|
approveAlwaysText,
|
|
70129
|
-
allowPersistence = true
|
|
70326
|
+
allowPersistence = true,
|
|
70327
|
+
showPreview = true
|
|
70130
70328
|
}) => {
|
|
70131
70329
|
const [selectedOption, setSelectedOption] = import_react38.useState(0);
|
|
70132
70330
|
const {
|
|
@@ -70354,12 +70552,13 @@ var init_InlineFileEditApproval = __esm(async () => {
|
|
|
70354
70552
|
diffKind
|
|
70355
70553
|
]);
|
|
70356
70554
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70555
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
70357
70556
|
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
70358
70557
|
flexDirection: "column",
|
|
70359
70558
|
children: [
|
|
70360
|
-
memoizedDiffContent,
|
|
70559
|
+
showPreview && memoizedDiffContent,
|
|
70361
70560
|
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
70362
|
-
marginTop:
|
|
70561
|
+
marginTop: optionsMarginTop,
|
|
70363
70562
|
flexDirection: "column",
|
|
70364
70563
|
children: [
|
|
70365
70564
|
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
|
|
@@ -70499,7 +70698,8 @@ var init_InlineGenericApproval = __esm(async () => {
|
|
|
70499
70698
|
onCancel,
|
|
70500
70699
|
isFocused = true,
|
|
70501
70700
|
approveAlwaysText,
|
|
70502
|
-
allowPersistence = true
|
|
70701
|
+
allowPersistence = true,
|
|
70702
|
+
showPreview = true
|
|
70503
70703
|
}) => {
|
|
70504
70704
|
const [selectedOption, setSelectedOption] = import_react39.useState(0);
|
|
70505
70705
|
const {
|
|
@@ -70590,12 +70790,13 @@ var init_InlineGenericApproval = __esm(async () => {
|
|
|
70590
70790
|
]
|
|
70591
70791
|
}, undefined, true, undefined, this), [toolName, formattedArgs, solidLine]);
|
|
70592
70792
|
const hintText = isOnCustomOption ? customReason ? "Enter to submit · Esc to clear" : "Type reason · Esc to cancel" : "Enter to select · Esc to cancel";
|
|
70793
|
+
const optionsMarginTop = showPreview ? 1 : 0;
|
|
70593
70794
|
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
70594
70795
|
flexDirection: "column",
|
|
70595
70796
|
children: [
|
|
70596
|
-
memoizedToolContent,
|
|
70797
|
+
showPreview && memoizedToolContent,
|
|
70597
70798
|
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
70598
|
-
marginTop:
|
|
70799
|
+
marginTop: optionsMarginTop,
|
|
70599
70800
|
flexDirection: "column",
|
|
70600
70801
|
children: [
|
|
70601
70802
|
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
|
|
@@ -71670,7 +71871,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71670
71871
|
onEnterPlanModeApprove,
|
|
71671
71872
|
onEnterPlanModeReject,
|
|
71672
71873
|
precomputedDiff,
|
|
71673
|
-
allDiffs
|
|
71874
|
+
allDiffs,
|
|
71875
|
+
showPreview = true
|
|
71674
71876
|
}) => {
|
|
71675
71877
|
const toolName = approval.toolName;
|
|
71676
71878
|
if (toolName === "ExitPlanMode" && onPlanApprove && onPlanKeepPlanning) {
|
|
@@ -71695,7 +71897,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71695
71897
|
onCancel,
|
|
71696
71898
|
isFocused,
|
|
71697
71899
|
approveAlwaysText,
|
|
71698
|
-
allowPersistence
|
|
71900
|
+
allowPersistence,
|
|
71901
|
+
showPreview
|
|
71699
71902
|
}, undefined, false, undefined, this);
|
|
71700
71903
|
}
|
|
71701
71904
|
}
|
|
@@ -71710,7 +71913,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71710
71913
|
onCancel,
|
|
71711
71914
|
isFocused,
|
|
71712
71915
|
approveAlwaysText,
|
|
71713
|
-
allowPersistence
|
|
71916
|
+
allowPersistence,
|
|
71917
|
+
showPreview
|
|
71714
71918
|
}, undefined, false, undefined, this);
|
|
71715
71919
|
}
|
|
71716
71920
|
}
|
|
@@ -71723,12 +71927,14 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71723
71927
|
}
|
|
71724
71928
|
if (toolName === "AskUserQuestion" && onQuestionSubmit) {
|
|
71725
71929
|
const questions = getQuestions(approval);
|
|
71726
|
-
|
|
71727
|
-
|
|
71728
|
-
|
|
71729
|
-
|
|
71730
|
-
|
|
71731
|
-
|
|
71930
|
+
if (questions.length > 0) {
|
|
71931
|
+
return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(InlineQuestionApproval, {
|
|
71932
|
+
questions,
|
|
71933
|
+
onSubmit: onQuestionSubmit,
|
|
71934
|
+
onCancel,
|
|
71935
|
+
isFocused
|
|
71936
|
+
}, undefined, false, undefined, this);
|
|
71937
|
+
}
|
|
71732
71938
|
}
|
|
71733
71939
|
if (isTaskTool(toolName)) {
|
|
71734
71940
|
const taskInfo = getTaskInfo(approval);
|
|
@@ -71754,7 +71960,8 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71754
71960
|
onCancel,
|
|
71755
71961
|
isFocused,
|
|
71756
71962
|
approveAlwaysText,
|
|
71757
|
-
allowPersistence
|
|
71963
|
+
allowPersistence,
|
|
71964
|
+
showPreview
|
|
71758
71965
|
}, undefined, false, undefined, this);
|
|
71759
71966
|
});
|
|
71760
71967
|
ApprovalSwitch.displayName = "ApprovalSwitch";
|
|
@@ -71762,9 +71969,9 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
71762
71969
|
|
|
71763
71970
|
// src/cli/components/AssistantMessageRich.tsx
|
|
71764
71971
|
var import_react44, jsx_dev_runtime23, normalize6 = (s) => s.replace(/\r\n/g, `
|
|
71765
|
-
`).replace(
|
|
71972
|
+
`).replace(/\n{3,}/g, `
|
|
71766
71973
|
|
|
71767
|
-
`).replace(/^\n
|
|
71974
|
+
`).replace(/^\n+/g, ""), AssistantMessage;
|
|
71768
71975
|
var init_AssistantMessageRich = __esm(async () => {
|
|
71769
71976
|
init_useTerminalWidth();
|
|
71770
71977
|
await __promiseAll([
|
|
@@ -72900,14 +73107,6 @@ var init_EventMessage = __esm(async () => {
|
|
|
72900
73107
|
color: colors.tool.completed,
|
|
72901
73108
|
children: "●"
|
|
72902
73109
|
}, 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
73110
|
return /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Box_default, {
|
|
72912
73111
|
flexDirection: "column",
|
|
72913
73112
|
children: [
|
|
@@ -72924,16 +73123,12 @@ var init_EventMessage = __esm(async () => {
|
|
|
72924
73123
|
width: rightWidth,
|
|
72925
73124
|
children: isRunning ? /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(CompactingAnimation, {}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Text2, {
|
|
72926
73125
|
bold: true,
|
|
72927
|
-
children:
|
|
72928
|
-
|
|
72929
|
-
argsDisplay,
|
|
72930
|
-
")"
|
|
72931
|
-
]
|
|
72932
|
-
}, undefined, true, undefined, this)
|
|
73126
|
+
children: "Conversation compacted"
|
|
73127
|
+
}, undefined, false, undefined, this)
|
|
72933
73128
|
}, undefined, false, undefined, this)
|
|
72934
73129
|
]
|
|
72935
73130
|
}, undefined, true, undefined, this),
|
|
72936
|
-
!isRunning && line.summary && /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(jsx_dev_runtime33.Fragment, {
|
|
73131
|
+
!isRunning && line.summary && (process.env.LETTA_DEBUG === "1" || process.env.LETTA_DEBUG === "true") && /* @__PURE__ */ jsx_dev_runtime33.jsxDEV(jsx_dev_runtime33.Fragment, {
|
|
72937
73132
|
children: [
|
|
72938
73133
|
/* @__PURE__ */ jsx_dev_runtime33.jsxDEV(Box_default, {
|
|
72939
73134
|
flexDirection: "row",
|
|
@@ -74389,10 +74584,10 @@ var init_registry = __esm(() => {
|
|
|
74389
74584
|
}
|
|
74390
74585
|
},
|
|
74391
74586
|
"/rename": {
|
|
74392
|
-
desc: "Rename
|
|
74587
|
+
desc: "Rename agent or conversation (/rename agent|convo <name>)",
|
|
74393
74588
|
order: 24,
|
|
74394
74589
|
handler: () => {
|
|
74395
|
-
return "Renaming
|
|
74590
|
+
return "Renaming...";
|
|
74396
74591
|
}
|
|
74397
74592
|
},
|
|
74398
74593
|
"/description": {
|
|
@@ -75052,7 +75247,8 @@ function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
|
75052
75247
|
case "project-local":
|
|
75053
75248
|
return settingsManager.getLocalProjectSettings(workingDirectory)?.hooks || {};
|
|
75054
75249
|
}
|
|
75055
|
-
} catch {
|
|
75250
|
+
} catch (error) {
|
|
75251
|
+
debugLog("hooks", "loadHooksFromLocation: Settings not loaded yet", error);
|
|
75056
75252
|
return {};
|
|
75057
75253
|
}
|
|
75058
75254
|
}
|
|
@@ -75204,7 +75400,8 @@ function countHooksForEvent(event, workingDirectory = process.cwd()) {
|
|
|
75204
75400
|
function isUserHooksDisabled() {
|
|
75205
75401
|
try {
|
|
75206
75402
|
return settingsManager.getSettings().hooks?.disabled === true;
|
|
75207
|
-
} catch {
|
|
75403
|
+
} catch (error) {
|
|
75404
|
+
debugLog("hooks", "isUserHooksDisabled: Failed to check user hooks disabled status", error);
|
|
75208
75405
|
return false;
|
|
75209
75406
|
}
|
|
75210
75407
|
}
|
|
@@ -75218,6 +75415,7 @@ function setHooksDisabled(disabled) {
|
|
|
75218
75415
|
});
|
|
75219
75416
|
}
|
|
75220
75417
|
var init_writer = __esm(async () => {
|
|
75418
|
+
init_debug();
|
|
75221
75419
|
init_types();
|
|
75222
75420
|
await init_settings_manager();
|
|
75223
75421
|
});
|
|
@@ -75261,6 +75459,7 @@ var init_HooksManager = __esm(async () => {
|
|
|
75261
75459
|
HOOK_EVENTS = [
|
|
75262
75460
|
{ event: "PreToolUse", description: "Before tool execution" },
|
|
75263
75461
|
{ event: "PostToolUse", description: "After tool execution" },
|
|
75462
|
+
{ event: "PostToolUseFailure", description: "After tool execution fails" },
|
|
75264
75463
|
{ event: "PermissionRequest", description: "When permission is requested" },
|
|
75265
75464
|
{ event: "UserPromptSubmit", description: "When user submits a prompt" },
|
|
75266
75465
|
{ event: "Notification", description: "When notifications are sent" },
|
|
@@ -77738,28 +77937,28 @@ var require_react_jsx_runtime_development = __commonJS((exports) => {
|
|
|
77738
77937
|
return null;
|
|
77739
77938
|
}
|
|
77740
77939
|
var ReactSharedInternals = React14.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
77741
|
-
function error(
|
|
77940
|
+
function error(format2) {
|
|
77742
77941
|
{
|
|
77743
77942
|
{
|
|
77744
77943
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1;_key2 < _len2; _key2++) {
|
|
77745
77944
|
args[_key2 - 1] = arguments[_key2];
|
|
77746
77945
|
}
|
|
77747
|
-
printWarning("error",
|
|
77946
|
+
printWarning("error", format2, args);
|
|
77748
77947
|
}
|
|
77749
77948
|
}
|
|
77750
77949
|
}
|
|
77751
|
-
function printWarning(level,
|
|
77950
|
+
function printWarning(level, format2, args) {
|
|
77752
77951
|
{
|
|
77753
77952
|
var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
77754
77953
|
var stack = ReactDebugCurrentFrame2.getStackAddendum();
|
|
77755
77954
|
if (stack !== "") {
|
|
77756
|
-
|
|
77955
|
+
format2 += "%s";
|
|
77757
77956
|
args = args.concat([stack]);
|
|
77758
77957
|
}
|
|
77759
77958
|
var argsWithFormat = args.map(function(item) {
|
|
77760
77959
|
return String(item);
|
|
77761
77960
|
});
|
|
77762
|
-
argsWithFormat.unshift("Warning: " +
|
|
77961
|
+
argsWithFormat.unshift("Warning: " + format2);
|
|
77763
77962
|
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
77764
77963
|
}
|
|
77765
77964
|
}
|
|
@@ -85409,9 +85608,9 @@ var init_ProviderSelector = __esm(async () => {
|
|
|
85409
85608
|
|
|
85410
85609
|
// src/cli/components/ReasoningMessageRich.tsx
|
|
85411
85610
|
var import_react79, jsx_dev_runtime56, normalize7 = (s) => s.replace(/\r\n/g, `
|
|
85412
|
-
`).replace(
|
|
85611
|
+
`).replace(/\n{3,}/g, `
|
|
85413
85612
|
|
|
85414
|
-
`).replace(/^\n
|
|
85613
|
+
`).replace(/^\n+/g, ""), ReasoningMessage;
|
|
85415
85614
|
var init_ReasoningMessageRich = __esm(async () => {
|
|
85416
85615
|
init_useTerminalWidth();
|
|
85417
85616
|
await __promiseAll([
|
|
@@ -87386,38 +87585,21 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
87386
87585
|
}
|
|
87387
87586
|
}
|
|
87388
87587
|
const fallback = displayName.length >= rightWidth;
|
|
87389
|
-
const
|
|
87588
|
+
const dotColor = (() => {
|
|
87390
87589
|
switch (line.phase) {
|
|
87391
87590
|
case "streaming":
|
|
87392
|
-
return
|
|
87393
|
-
color: colors.tool.streaming,
|
|
87394
|
-
children: "●"
|
|
87395
|
-
}, undefined, false, undefined, this);
|
|
87591
|
+
return colors.tool.streaming;
|
|
87396
87592
|
case "ready":
|
|
87397
|
-
return
|
|
87398
|
-
color: colors.tool.pending
|
|
87399
|
-
}, undefined, false, undefined, this);
|
|
87593
|
+
return colors.tool.pending;
|
|
87400
87594
|
case "running":
|
|
87401
|
-
return
|
|
87402
|
-
color: colors.tool.running
|
|
87403
|
-
}, undefined, false, undefined, this);
|
|
87595
|
+
return colors.tool.running;
|
|
87404
87596
|
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);
|
|
87597
|
+
return line.resultOk === false ? colors.tool.error : colors.tool.completed;
|
|
87415
87598
|
default:
|
|
87416
|
-
return
|
|
87417
|
-
children: "●"
|
|
87418
|
-
}, undefined, false, undefined, this);
|
|
87599
|
+
return;
|
|
87419
87600
|
}
|
|
87420
|
-
};
|
|
87601
|
+
})();
|
|
87602
|
+
const dotShouldAnimate = line.phase === "ready" || line.phase === "running";
|
|
87421
87603
|
const getResultElement = () => {
|
|
87422
87604
|
if (!line.resultText)
|
|
87423
87605
|
return null;
|
|
@@ -88003,7 +88185,10 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
88003
88185
|
width: 2,
|
|
88004
88186
|
flexShrink: 0,
|
|
88005
88187
|
children: [
|
|
88006
|
-
|
|
88188
|
+
/* @__PURE__ */ jsx_dev_runtime65.jsxDEV(BlinkDot, {
|
|
88189
|
+
color: dotColor,
|
|
88190
|
+
shouldAnimate: dotShouldAnimate
|
|
88191
|
+
}, undefined, false, undefined, this),
|
|
88007
88192
|
/* @__PURE__ */ jsx_dev_runtime65.jsxDEV(Text2, {}, undefined, false, undefined, this)
|
|
88008
88193
|
]
|
|
88009
88194
|
}, undefined, true, undefined, this),
|
|
@@ -90008,12 +90193,48 @@ function isNonStateCommand(msg) {
|
|
|
90008
90193
|
}
|
|
90009
90194
|
return false;
|
|
90010
90195
|
}
|
|
90196
|
+
function countWrappedLines(text, width) {
|
|
90197
|
+
if (!text)
|
|
90198
|
+
return 0;
|
|
90199
|
+
const wrapWidth = Math.max(1, width);
|
|
90200
|
+
return text.split(/\r?\n/).reduce((sum, line) => {
|
|
90201
|
+
const len = line.length;
|
|
90202
|
+
const wrapped = Math.max(1, Math.ceil(len / wrapWidth));
|
|
90203
|
+
return sum + wrapped;
|
|
90204
|
+
}, 0);
|
|
90205
|
+
}
|
|
90206
|
+
function countWrappedLinesFromList(lines, width) {
|
|
90207
|
+
if (!lines.length)
|
|
90208
|
+
return 0;
|
|
90209
|
+
const wrapWidth = Math.max(1, width);
|
|
90210
|
+
return lines.reduce((sum, line) => {
|
|
90211
|
+
const len = line.length;
|
|
90212
|
+
const wrapped = Math.max(1, Math.ceil(len / wrapWidth));
|
|
90213
|
+
return sum + wrapped;
|
|
90214
|
+
}, 0);
|
|
90215
|
+
}
|
|
90216
|
+
function estimateAdvancedDiffLines(diff2, width) {
|
|
90217
|
+
const wrapWidth = Math.max(1, width);
|
|
90218
|
+
let total = 0;
|
|
90219
|
+
for (const hunk of diff2.hunks) {
|
|
90220
|
+
for (const line of hunk.lines) {
|
|
90221
|
+
const raw = line.raw || "";
|
|
90222
|
+
if (raw.startsWith("\\"))
|
|
90223
|
+
continue;
|
|
90224
|
+
const text = raw.slice(1);
|
|
90225
|
+
total += Math.max(1, Math.ceil(text.length / wrapWidth));
|
|
90226
|
+
}
|
|
90227
|
+
}
|
|
90228
|
+
return total;
|
|
90229
|
+
}
|
|
90011
90230
|
function uid4(prefix) {
|
|
90012
90231
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
90013
90232
|
}
|
|
90014
90233
|
function sendDesktopNotification(message = "Awaiting your input", level = "info") {
|
|
90015
90234
|
process.stdout.write("\x07");
|
|
90016
|
-
runNotificationHooks(message, level).catch(() => {
|
|
90235
|
+
runNotificationHooks(message, level).catch((error) => {
|
|
90236
|
+
debugLog("hooks", "Notification hook error", error);
|
|
90237
|
+
});
|
|
90017
90238
|
}
|
|
90018
90239
|
async function isRetriableError(stopReason, lastRunId) {
|
|
90019
90240
|
if (stopReason === "llm_api_error")
|
|
@@ -90498,18 +90719,23 @@ function App2({
|
|
|
90498
90719
|
closeTrajectorySegment,
|
|
90499
90720
|
syncTrajectoryElapsedBase
|
|
90500
90721
|
]);
|
|
90722
|
+
const sessionStartFeedbackRef = import_react91.useRef([]);
|
|
90501
90723
|
import_react91.useEffect(() => {
|
|
90502
|
-
if (agentId && !sessionHooksRanRef.current) {
|
|
90724
|
+
if (agentId && agentId !== "loading" && !sessionHooksRanRef.current) {
|
|
90503
90725
|
sessionHooksRanRef.current = true;
|
|
90504
90726
|
const isNewSession = !initialConversationId;
|
|
90505
|
-
runSessionStartHooks(isNewSession, agentId, agentName ?? undefined, conversationIdRef.current ?? undefined).
|
|
90727
|
+
runSessionStartHooks(isNewSession, agentId, agentName ?? undefined, conversationIdRef.current ?? undefined).then((result) => {
|
|
90728
|
+
if (result.feedback.length > 0) {
|
|
90729
|
+
sessionStartFeedbackRef.current = result.feedback;
|
|
90730
|
+
}
|
|
90731
|
+
}).catch(() => {});
|
|
90506
90732
|
}
|
|
90507
90733
|
}, [agentId, agentName, initialConversationId]);
|
|
90508
|
-
import_react91.
|
|
90509
|
-
|
|
90510
|
-
|
|
90511
|
-
runSessionEndHooks(durationMs, undefined, undefined, agentIdRef.current ?? undefined, conversationIdRef.current ?? undefined)
|
|
90512
|
-
}
|
|
90734
|
+
const runEndHooks = import_react91.useCallback(async () => {
|
|
90735
|
+
const durationMs = Date.now() - sessionStartTimeRef.current;
|
|
90736
|
+
try {
|
|
90737
|
+
await runSessionEndHooks(durationMs, undefined, undefined, agentIdRef.current ?? undefined, conversationIdRef.current ?? undefined);
|
|
90738
|
+
} catch {}
|
|
90513
90739
|
}, []);
|
|
90514
90740
|
import_react91.useEffect(() => {
|
|
90515
90741
|
return () => {
|
|
@@ -90652,9 +90878,34 @@ function App2({
|
|
|
90652
90878
|
setStaticRenderEpoch((epoch) => epoch + 1);
|
|
90653
90879
|
lastClearedColumnsRef.current = pendingColumns;
|
|
90654
90880
|
}, [columns, streaming]);
|
|
90655
|
-
const
|
|
90881
|
+
const deferredToolCallCommitsRef = import_react91.useRef(new Map);
|
|
90882
|
+
const [deferredCommitAt, setDeferredCommitAt] = import_react91.useState(null);
|
|
90883
|
+
const resetDeferredToolCallCommits = import_react91.useCallback(() => {
|
|
90884
|
+
deferredToolCallCommitsRef.current.clear();
|
|
90885
|
+
setDeferredCommitAt(null);
|
|
90886
|
+
}, []);
|
|
90887
|
+
const commitEligibleLines = import_react91.useCallback((b, opts) => {
|
|
90888
|
+
const deferToolCalls = opts?.deferToolCalls !== false;
|
|
90656
90889
|
const newlyCommitted = [];
|
|
90657
90890
|
let firstTaskIndex = -1;
|
|
90891
|
+
const deferredCommits = deferredToolCallCommitsRef.current;
|
|
90892
|
+
const now = Date.now();
|
|
90893
|
+
let blockedByDeferred = false;
|
|
90894
|
+
const shouldSkipCommittedToolCall = (ln) => {
|
|
90895
|
+
if (ln.kind !== "tool_call")
|
|
90896
|
+
return false;
|
|
90897
|
+
if (!ln.toolCallId || !ln.name)
|
|
90898
|
+
return false;
|
|
90899
|
+
if (ln.phase !== "finished" || ln.resultOk === false)
|
|
90900
|
+
return false;
|
|
90901
|
+
if (!eagerCommittedPreviewsRef.current.has(ln.toolCallId))
|
|
90902
|
+
return false;
|
|
90903
|
+
return isFileEditTool(ln.name) || isFileWriteTool(ln.name) || isPatchTool(ln.name);
|
|
90904
|
+
};
|
|
90905
|
+
if (!deferToolCalls && deferredCommits.size > 0) {
|
|
90906
|
+
deferredCommits.clear();
|
|
90907
|
+
setDeferredCommitAt(null);
|
|
90908
|
+
}
|
|
90658
90909
|
const hasInProgress = hasInProgressTaskToolCalls(b.order, b.byId, emittedIdsRef.current);
|
|
90659
90910
|
const finishedTaskToolCalls = collectFinishedTaskToolCalls(b.order, b.byId, emittedIdsRef.current, hasInProgress);
|
|
90660
90911
|
for (const id of b.order) {
|
|
@@ -90695,11 +90946,32 @@ function App2({
|
|
|
90695
90946
|
continue;
|
|
90696
90947
|
}
|
|
90697
90948
|
if ("phase" in ln && ln.phase === "finished") {
|
|
90949
|
+
if (shouldSkipCommittedToolCall(ln)) {
|
|
90950
|
+
deferredCommits.delete(id);
|
|
90951
|
+
emittedIdsRef.current.add(id);
|
|
90952
|
+
continue;
|
|
90953
|
+
}
|
|
90954
|
+
if (deferToolCalls && ln.kind === "tool_call" && (!ln.name || !isTaskTool(ln.name))) {
|
|
90955
|
+
const commitAt = deferredCommits.get(id);
|
|
90956
|
+
if (commitAt === undefined) {
|
|
90957
|
+
const nextCommitAt = now + TOOL_CALL_COMMIT_DEFER_MS;
|
|
90958
|
+
deferredCommits.set(id, nextCommitAt);
|
|
90959
|
+
setDeferredCommitAt(nextCommitAt);
|
|
90960
|
+
blockedByDeferred = true;
|
|
90961
|
+
break;
|
|
90962
|
+
}
|
|
90963
|
+
if (commitAt > now) {
|
|
90964
|
+
setDeferredCommitAt(commitAt);
|
|
90965
|
+
blockedByDeferred = true;
|
|
90966
|
+
break;
|
|
90967
|
+
}
|
|
90968
|
+
deferredCommits.delete(id);
|
|
90969
|
+
}
|
|
90698
90970
|
emittedIdsRef.current.add(id);
|
|
90699
90971
|
newlyCommitted.push({ ...ln });
|
|
90700
90972
|
}
|
|
90701
90973
|
}
|
|
90702
|
-
if (finishedTaskToolCalls.length > 0) {
|
|
90974
|
+
if (!blockedByDeferred && finishedTaskToolCalls.length > 0) {
|
|
90703
90975
|
for (const tc of finishedTaskToolCalls) {
|
|
90704
90976
|
emittedIdsRef.current.add(tc.lineId);
|
|
90705
90977
|
}
|
|
@@ -90707,6 +90979,9 @@ function App2({
|
|
|
90707
90979
|
newlyCommitted.splice(firstTaskIndex >= 0 ? firstTaskIndex : newlyCommitted.length, 0, groupItem);
|
|
90708
90980
|
clearSubagentsByIds(groupItem.agents.map((a) => a.id));
|
|
90709
90981
|
}
|
|
90982
|
+
if (deferredCommits.size === 0) {
|
|
90983
|
+
setDeferredCommitAt(null);
|
|
90984
|
+
}
|
|
90710
90985
|
if (newlyCommitted.length > 0) {
|
|
90711
90986
|
setStaticItems((prev) => [...prev, ...newlyCommitted]);
|
|
90712
90987
|
}
|
|
@@ -90723,6 +90998,108 @@ function App2({
|
|
|
90723
90998
|
const precomputedDiffsRef = import_react91.useRef(new Map);
|
|
90724
90999
|
const lastPlanFilePathRef = import_react91.useRef(null);
|
|
90725
91000
|
const eagerCommittedPreviewsRef = import_react91.useRef(new Set);
|
|
91001
|
+
const estimateApprovalPreviewLines = import_react91.useCallback((approval) => {
|
|
91002
|
+
const toolName = approval.toolName;
|
|
91003
|
+
if (!toolName)
|
|
91004
|
+
return 0;
|
|
91005
|
+
const args = safeJsonParseOr(approval.toolArgs || "{}", {});
|
|
91006
|
+
const wrapWidth = Math.max(MIN_WRAP_WIDTH, columns - TEXT_WRAP_GUTTER);
|
|
91007
|
+
const diffWrapWidth = Math.max(MIN_WRAP_WIDTH, columns - DIFF_WRAP_GUTTER);
|
|
91008
|
+
if (isShellTool(toolName)) {
|
|
91009
|
+
const t = toolName.toLowerCase();
|
|
91010
|
+
let command = "(no command)";
|
|
91011
|
+
let description = "";
|
|
91012
|
+
if (t === "shell") {
|
|
91013
|
+
const cmdVal = args.command;
|
|
91014
|
+
command = Array.isArray(cmdVal) ? cmdVal.join(" ") : typeof cmdVal === "string" ? cmdVal : "(no command)";
|
|
91015
|
+
description = typeof args.justification === "string" ? args.justification : "";
|
|
91016
|
+
} else {
|
|
91017
|
+
command = typeof args.command === "string" ? args.command : "(no command)";
|
|
91018
|
+
description = typeof args.description === "string" ? args.description : typeof args.justification === "string" ? args.justification : "";
|
|
91019
|
+
}
|
|
91020
|
+
let lines2 = 3;
|
|
91021
|
+
lines2 += countWrappedLines(command, wrapWidth);
|
|
91022
|
+
if (description) {
|
|
91023
|
+
lines2 += countWrappedLines(description, wrapWidth);
|
|
91024
|
+
}
|
|
91025
|
+
return lines2;
|
|
91026
|
+
}
|
|
91027
|
+
if (isFileEditTool(toolName) || isFileWriteTool(toolName) || isPatchTool(toolName)) {
|
|
91028
|
+
const headerLines = 4;
|
|
91029
|
+
let diffLines2 = 0;
|
|
91030
|
+
const toolCallId = approval.toolCallId;
|
|
91031
|
+
if (isPatchTool(toolName) && typeof args.input === "string") {
|
|
91032
|
+
const operations = parsePatchOperations(args.input);
|
|
91033
|
+
operations.forEach((op, idx) => {
|
|
91034
|
+
if (idx > 0)
|
|
91035
|
+
diffLines2 += 1;
|
|
91036
|
+
diffLines2 += 1;
|
|
91037
|
+
const diffKey = toolCallId ? `${toolCallId}:${op.path}` : undefined;
|
|
91038
|
+
const opDiff = diffKey && precomputedDiffsRef.current.has(diffKey) ? precomputedDiffsRef.current.get(diffKey) : undefined;
|
|
91039
|
+
if (opDiff) {
|
|
91040
|
+
diffLines2 += estimateAdvancedDiffLines(opDiff, diffWrapWidth);
|
|
91041
|
+
return;
|
|
91042
|
+
}
|
|
91043
|
+
if (op.kind === "add") {
|
|
91044
|
+
diffLines2 += countWrappedLines(op.content, wrapWidth);
|
|
91045
|
+
return;
|
|
91046
|
+
}
|
|
91047
|
+
if (op.kind === "update") {
|
|
91048
|
+
if (op.patchLines?.length) {
|
|
91049
|
+
diffLines2 += countWrappedLinesFromList(op.patchLines, wrapWidth);
|
|
91050
|
+
} else {
|
|
91051
|
+
diffLines2 += countWrappedLines(op.oldString || "", wrapWidth);
|
|
91052
|
+
diffLines2 += countWrappedLines(op.newString || "", wrapWidth);
|
|
91053
|
+
}
|
|
91054
|
+
return;
|
|
91055
|
+
}
|
|
91056
|
+
diffLines2 += 1;
|
|
91057
|
+
});
|
|
91058
|
+
return headerLines + diffLines2;
|
|
91059
|
+
}
|
|
91060
|
+
const diff2 = toolCallId && precomputedDiffsRef.current.has(toolCallId) ? precomputedDiffsRef.current.get(toolCallId) : undefined;
|
|
91061
|
+
if (diff2) {
|
|
91062
|
+
diffLines2 += estimateAdvancedDiffLines(diff2, diffWrapWidth);
|
|
91063
|
+
return headerLines + diffLines2;
|
|
91064
|
+
}
|
|
91065
|
+
if (Array.isArray(args.edits)) {
|
|
91066
|
+
for (const edit2 of args.edits) {
|
|
91067
|
+
if (!edit2 || typeof edit2 !== "object")
|
|
91068
|
+
continue;
|
|
91069
|
+
const oldString2 = typeof edit2.old_string === "string" ? edit2.old_string : "";
|
|
91070
|
+
const newString2 = typeof edit2.new_string === "string" ? edit2.new_string : "";
|
|
91071
|
+
diffLines2 += countWrappedLines(oldString2, wrapWidth);
|
|
91072
|
+
diffLines2 += countWrappedLines(newString2, wrapWidth);
|
|
91073
|
+
}
|
|
91074
|
+
return headerLines + diffLines2;
|
|
91075
|
+
}
|
|
91076
|
+
if (typeof args.content === "string") {
|
|
91077
|
+
diffLines2 += countWrappedLines(args.content, wrapWidth);
|
|
91078
|
+
return headerLines + diffLines2;
|
|
91079
|
+
}
|
|
91080
|
+
const oldString = typeof args.old_string === "string" ? args.old_string : "";
|
|
91081
|
+
const newString = typeof args.new_string === "string" ? args.new_string : "";
|
|
91082
|
+
diffLines2 += countWrappedLines(oldString, wrapWidth);
|
|
91083
|
+
diffLines2 += countWrappedLines(newString, wrapWidth);
|
|
91084
|
+
return headerLines + diffLines2;
|
|
91085
|
+
}
|
|
91086
|
+
return 0;
|
|
91087
|
+
}, [columns]);
|
|
91088
|
+
const shouldEagerCommitApprovalPreview = import_react91.useCallback((approval) => {
|
|
91089
|
+
if (!terminalRows)
|
|
91090
|
+
return false;
|
|
91091
|
+
const previewLines = estimateApprovalPreviewLines(approval);
|
|
91092
|
+
if (previewLines === 0)
|
|
91093
|
+
return false;
|
|
91094
|
+
return previewLines + APPROVAL_OPTIONS_HEIGHT + APPROVAL_PREVIEW_BUFFER >= terminalRows;
|
|
91095
|
+
}, [estimateApprovalPreviewLines, terminalRows]);
|
|
91096
|
+
const currentApprovalShouldCommitPreview = import_react91.useMemo(() => {
|
|
91097
|
+
if (!currentApproval)
|
|
91098
|
+
return false;
|
|
91099
|
+
if (currentApproval.toolName === "ExitPlanMode")
|
|
91100
|
+
return false;
|
|
91101
|
+
return shouldEagerCommitApprovalPreview(currentApproval);
|
|
91102
|
+
}, [currentApproval, shouldEagerCommitApprovalPreview]);
|
|
90726
91103
|
const refreshDerived = import_react91.useCallback(() => {
|
|
90727
91104
|
const b = buffersRef.current;
|
|
90728
91105
|
setTokenCount(b.tokenCount);
|
|
@@ -90730,6 +91107,16 @@ function App2({
|
|
|
90730
91107
|
setLines(newLines);
|
|
90731
91108
|
commitEligibleLines(b);
|
|
90732
91109
|
}, [commitEligibleLines]);
|
|
91110
|
+
import_react91.useEffect(() => {
|
|
91111
|
+
if (deferredCommitAt === null)
|
|
91112
|
+
return;
|
|
91113
|
+
const delay = Math.max(0, deferredCommitAt - Date.now());
|
|
91114
|
+
const timer = setTimeout(() => {
|
|
91115
|
+
setDeferredCommitAt(null);
|
|
91116
|
+
refreshDerived();
|
|
91117
|
+
}, delay);
|
|
91118
|
+
return () => clearTimeout(timer);
|
|
91119
|
+
}, [deferredCommitAt, refreshDerived]);
|
|
90733
91120
|
const streamingRefreshTimeoutRef = import_react91.useRef(null);
|
|
90734
91121
|
const refreshDerivedStreaming = import_react91.useCallback(() => {
|
|
90735
91122
|
if (streamingRefreshTimeoutRef.current) {
|
|
@@ -90825,6 +91212,31 @@ function App2({
|
|
|
90825
91212
|
lastPlanFilePathRef.current = planFilePath;
|
|
90826
91213
|
} catch {}
|
|
90827
91214
|
}, [currentApproval]);
|
|
91215
|
+
import_react91.useEffect(() => {
|
|
91216
|
+
if (!currentApproval)
|
|
91217
|
+
return;
|
|
91218
|
+
if (currentApproval.toolName === "ExitPlanMode")
|
|
91219
|
+
return;
|
|
91220
|
+
const toolCallId = currentApproval.toolCallId;
|
|
91221
|
+
if (!toolCallId)
|
|
91222
|
+
return;
|
|
91223
|
+
if (eagerCommittedPreviewsRef.current.has(toolCallId))
|
|
91224
|
+
return;
|
|
91225
|
+
if (!currentApprovalShouldCommitPreview)
|
|
91226
|
+
return;
|
|
91227
|
+
const previewItem = {
|
|
91228
|
+
kind: "approval_preview",
|
|
91229
|
+
id: `approval-preview-${toolCallId}`,
|
|
91230
|
+
toolCallId,
|
|
91231
|
+
toolName: currentApproval.toolName,
|
|
91232
|
+
toolArgs: currentApproval.toolArgs || "{}"
|
|
91233
|
+
};
|
|
91234
|
+
if ((isFileEditTool(currentApproval.toolName) || isFileWriteTool(currentApproval.toolName)) && precomputedDiffsRef.current.has(toolCallId)) {
|
|
91235
|
+
previewItem.precomputedDiff = precomputedDiffsRef.current.get(toolCallId);
|
|
91236
|
+
}
|
|
91237
|
+
setStaticItems((prev) => [...prev, previewItem]);
|
|
91238
|
+
eagerCommittedPreviewsRef.current.add(toolCallId);
|
|
91239
|
+
}, [currentApproval, currentApprovalShouldCommitPreview]);
|
|
90828
91240
|
import_react91.useEffect(() => {
|
|
90829
91241
|
if (loadingState === "ready" && messageHistory.length > 0 && !hasBackfilledRef.current) {
|
|
90830
91242
|
hasBackfilledRef.current = true;
|
|
@@ -90886,7 +91298,7 @@ function App2({
|
|
|
90886
91298
|
});
|
|
90887
91299
|
buffersRef.current.order.push(statusId);
|
|
90888
91300
|
refreshDerived();
|
|
90889
|
-
commitEligibleLines(buffersRef.current);
|
|
91301
|
+
commitEligibleLines(buffersRef.current, { deferToolCalls: false });
|
|
90890
91302
|
}
|
|
90891
91303
|
}, [
|
|
90892
91304
|
loadingState,
|
|
@@ -91303,6 +91715,7 @@ ${newState.originalPrompt}`
|
|
|
91303
91715
|
}
|
|
91304
91716
|
if (isConversationBusyError(errorDetail) && conversationBusyRetriesRef.current < CONVERSATION_BUSY_MAX_RETRIES2) {
|
|
91305
91717
|
conversationBusyRetriesRef.current += 1;
|
|
91718
|
+
const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS * 2 ** (conversationBusyRetriesRef.current - 1);
|
|
91306
91719
|
const statusId = uid4("status");
|
|
91307
91720
|
buffersRef.current.byId.set(statusId, {
|
|
91308
91721
|
kind: "status",
|
|
@@ -91313,7 +91726,7 @@ ${newState.originalPrompt}`
|
|
|
91313
91726
|
refreshDerived();
|
|
91314
91727
|
let cancelled = false;
|
|
91315
91728
|
const startTime = Date.now();
|
|
91316
|
-
while (Date.now() - startTime <
|
|
91729
|
+
while (Date.now() - startTime < retryDelayMs) {
|
|
91317
91730
|
if (abortControllerRef.current?.signal.aborted || userCancelledRef.current) {
|
|
91318
91731
|
cancelled = true;
|
|
91319
91732
|
break;
|
|
@@ -91616,39 +92029,11 @@ ${feedback}
|
|
|
91616
92029
|
refreshDerived();
|
|
91617
92030
|
return;
|
|
91618
92031
|
}
|
|
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
|
-
}
|
|
92032
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(approvalsToProcess, {
|
|
92033
|
+
getContext: analyzeToolApproval,
|
|
92034
|
+
alwaysRequiresUserInput,
|
|
92035
|
+
missingNameReason: "Tool call incomplete - missing name or arguments"
|
|
92036
|
+
});
|
|
91652
92037
|
for (const ac of [...autoAllowed, ...needsUserInput]) {
|
|
91653
92038
|
const toolName = ac.approval.toolName;
|
|
91654
92039
|
const toolCallId = ac.approval.toolCallId;
|
|
@@ -92133,6 +92518,7 @@ ${feedback}
|
|
|
92133
92518
|
]);
|
|
92134
92519
|
const handleExit = import_react91.useCallback(async () => {
|
|
92135
92520
|
saveLastAgentBeforeExit();
|
|
92521
|
+
await runEndHooks();
|
|
92136
92522
|
const stats = sessionStatsRef.current.getSnapshot();
|
|
92137
92523
|
telemetry2.trackSessionEnd(stats, "exit_command");
|
|
92138
92524
|
await telemetry2.flush();
|
|
@@ -92140,7 +92526,7 @@ ${feedback}
|
|
|
92140
92526
|
setTimeout(() => {
|
|
92141
92527
|
process.exit(0);
|
|
92142
92528
|
}, 100);
|
|
92143
|
-
}, []);
|
|
92529
|
+
}, [runEndHooks]);
|
|
92144
92530
|
const handleEnterQueueEditMode = import_react91.useCallback(() => {
|
|
92145
92531
|
setMessageQueue([]);
|
|
92146
92532
|
}, []);
|
|
@@ -92364,6 +92750,7 @@ ${feedback}
|
|
|
92364
92750
|
buffersRef.current.order = [];
|
|
92365
92751
|
buffersRef.current.tokenCount = 0;
|
|
92366
92752
|
emittedIdsRef.current.clear();
|
|
92753
|
+
resetDeferredToolCallCommits();
|
|
92367
92754
|
setStaticItems([]);
|
|
92368
92755
|
setStaticRenderEpoch((e) => e + 1);
|
|
92369
92756
|
resetTrajectoryBases();
|
|
@@ -92421,6 +92808,7 @@ ${feedback}
|
|
|
92421
92808
|
agentName,
|
|
92422
92809
|
setCommandRunning,
|
|
92423
92810
|
isAgentBusy,
|
|
92811
|
+
resetDeferredToolCallCommits,
|
|
92424
92812
|
resetTrajectoryBases
|
|
92425
92813
|
]);
|
|
92426
92814
|
const handleCreateNewAgent = import_react91.useCallback(async (name) => {
|
|
@@ -92444,6 +92832,7 @@ ${feedback}
|
|
|
92444
92832
|
buffersRef.current.order = [];
|
|
92445
92833
|
buffersRef.current.tokenCount = 0;
|
|
92446
92834
|
emittedIdsRef.current.clear();
|
|
92835
|
+
resetDeferredToolCallCommits();
|
|
92447
92836
|
setStaticItems([]);
|
|
92448
92837
|
setStaticRenderEpoch((e) => e + 1);
|
|
92449
92838
|
resetTrajectoryBases();
|
|
@@ -92487,7 +92876,13 @@ ${feedback}
|
|
|
92487
92876
|
} finally {
|
|
92488
92877
|
setCommandRunning(false);
|
|
92489
92878
|
}
|
|
92490
|
-
}, [
|
|
92879
|
+
}, [
|
|
92880
|
+
refreshDerived,
|
|
92881
|
+
agentId,
|
|
92882
|
+
setCommandRunning,
|
|
92883
|
+
resetDeferredToolCallCommits,
|
|
92884
|
+
resetTrajectoryBases
|
|
92885
|
+
]);
|
|
92491
92886
|
const handleBashSubmit = import_react91.useCallback(async (command) => {
|
|
92492
92887
|
if (bashRunning)
|
|
92493
92888
|
return;
|
|
@@ -92592,39 +92987,11 @@ ${expanded.command}` : expanded.command;
|
|
|
92592
92987
|
if (!existingApprovals || existingApprovals.length === 0) {
|
|
92593
92988
|
return { blocked: false };
|
|
92594
92989
|
}
|
|
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
|
-
}
|
|
92990
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(existingApprovals, {
|
|
92991
|
+
getContext: analyzeToolApproval,
|
|
92992
|
+
alwaysRequiresUserInput,
|
|
92993
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
92994
|
+
});
|
|
92628
92995
|
if (needsUserInput.length > 0) {
|
|
92629
92996
|
setPendingApprovals(needsUserInput.map((ac) => ac.approval));
|
|
92630
92997
|
setApprovalContexts(needsUserInput.map((ac) => ac.context).filter((ctx) => ctx !== null));
|
|
@@ -93181,6 +93548,7 @@ Type your task to begin the loop.`,
|
|
|
93181
93548
|
buffersRef.current.order.push(cmdId);
|
|
93182
93549
|
refreshDerived();
|
|
93183
93550
|
setCommandRunning(true);
|
|
93551
|
+
await runEndHooks();
|
|
93184
93552
|
try {
|
|
93185
93553
|
const client = await getClient2();
|
|
93186
93554
|
const conversation = await client.conversations.create({
|
|
@@ -93194,6 +93562,13 @@ Type your task to begin the loop.`,
|
|
|
93194
93562
|
conversationId: conversation.id
|
|
93195
93563
|
});
|
|
93196
93564
|
turnCountRef.current = 0;
|
|
93565
|
+
sessionHooksRanRef.current = false;
|
|
93566
|
+
runSessionStartHooks(true, agentId, agentName ?? undefined, conversation.id).then((result2) => {
|
|
93567
|
+
if (result2.feedback.length > 0) {
|
|
93568
|
+
sessionStartFeedbackRef.current = result2.feedback;
|
|
93569
|
+
}
|
|
93570
|
+
}).catch(() => {});
|
|
93571
|
+
sessionHooksRanRef.current = true;
|
|
93197
93572
|
buffersRef.current.byId.set(cmdId, {
|
|
93198
93573
|
kind: "command",
|
|
93199
93574
|
id: cmdId,
|
|
@@ -93232,6 +93607,7 @@ Type your task to begin the loop.`,
|
|
|
93232
93607
|
buffersRef.current.order.push(cmdId);
|
|
93233
93608
|
refreshDerived();
|
|
93234
93609
|
setCommandRunning(true);
|
|
93610
|
+
await runEndHooks();
|
|
93235
93611
|
try {
|
|
93236
93612
|
const client = await getClient2();
|
|
93237
93613
|
await client.agents.messages.reset(agentId, {
|
|
@@ -93248,6 +93624,13 @@ Type your task to begin the loop.`,
|
|
|
93248
93624
|
conversationId: conversation.id
|
|
93249
93625
|
});
|
|
93250
93626
|
turnCountRef.current = 0;
|
|
93627
|
+
sessionHooksRanRef.current = false;
|
|
93628
|
+
runSessionStartHooks(true, agentId, agentName ?? undefined, conversation.id).then((result2) => {
|
|
93629
|
+
if (result2.feedback.length > 0) {
|
|
93630
|
+
sessionStartFeedbackRef.current = result2.feedback;
|
|
93631
|
+
}
|
|
93632
|
+
}).catch(() => {});
|
|
93633
|
+
sessionHooksRanRef.current = true;
|
|
93251
93634
|
buffersRef.current.byId.set(cmdId, {
|
|
93252
93635
|
kind: "command",
|
|
93253
93636
|
id: cmdId,
|
|
@@ -93354,14 +93737,29 @@ Type your task to begin the loop.`,
|
|
|
93354
93737
|
}
|
|
93355
93738
|
if (msg.trim().startsWith("/rename")) {
|
|
93356
93739
|
const parts = msg.trim().split(/\s+/);
|
|
93357
|
-
const
|
|
93358
|
-
if (!
|
|
93740
|
+
const subcommand = parts[1]?.toLowerCase();
|
|
93741
|
+
if (!subcommand || subcommand !== "agent" && subcommand !== "convo") {
|
|
93742
|
+
const cmdId2 = uid4("cmd");
|
|
93743
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93744
|
+
kind: "command",
|
|
93745
|
+
id: cmdId2,
|
|
93746
|
+
input: msg,
|
|
93747
|
+
output: "Usage: /rename agent <name> or /rename convo <summary>",
|
|
93748
|
+
phase: "finished",
|
|
93749
|
+
success: false
|
|
93750
|
+
});
|
|
93751
|
+
buffersRef.current.order.push(cmdId2);
|
|
93752
|
+
refreshDerived();
|
|
93753
|
+
return { submitted: true };
|
|
93754
|
+
}
|
|
93755
|
+
const newValue = parts.slice(2).join(" ");
|
|
93756
|
+
if (!newValue) {
|
|
93359
93757
|
const cmdId2 = uid4("cmd");
|
|
93360
93758
|
buffersRef.current.byId.set(cmdId2, {
|
|
93361
93759
|
kind: "command",
|
|
93362
93760
|
id: cmdId2,
|
|
93363
93761
|
input: msg,
|
|
93364
|
-
output: "Please provide a
|
|
93762
|
+
output: subcommand === "convo" ? "Please provide a summary: /rename convo <summary>" : "Please provide a name: /rename agent <name>",
|
|
93365
93763
|
phase: "finished",
|
|
93366
93764
|
success: false
|
|
93367
93765
|
});
|
|
@@ -93369,7 +93767,49 @@ Type your task to begin the loop.`,
|
|
|
93369
93767
|
refreshDerived();
|
|
93370
93768
|
return { submitted: true };
|
|
93371
93769
|
}
|
|
93372
|
-
|
|
93770
|
+
if (subcommand === "convo") {
|
|
93771
|
+
const cmdId2 = uid4("cmd");
|
|
93772
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93773
|
+
kind: "command",
|
|
93774
|
+
id: cmdId2,
|
|
93775
|
+
input: msg,
|
|
93776
|
+
output: `Renaming conversation to "${newValue}"...`,
|
|
93777
|
+
phase: "running"
|
|
93778
|
+
});
|
|
93779
|
+
buffersRef.current.order.push(cmdId2);
|
|
93780
|
+
refreshDerived();
|
|
93781
|
+
setCommandRunning(true);
|
|
93782
|
+
try {
|
|
93783
|
+
const client = await getClient2();
|
|
93784
|
+
await client.conversations.update(conversationId, {
|
|
93785
|
+
summary: newValue
|
|
93786
|
+
});
|
|
93787
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93788
|
+
kind: "command",
|
|
93789
|
+
id: cmdId2,
|
|
93790
|
+
input: msg,
|
|
93791
|
+
output: `Conversation renamed to "${newValue}"`,
|
|
93792
|
+
phase: "finished",
|
|
93793
|
+
success: true
|
|
93794
|
+
});
|
|
93795
|
+
refreshDerived();
|
|
93796
|
+
} catch (error) {
|
|
93797
|
+
const errorDetails = formatErrorDetails(error, agentId);
|
|
93798
|
+
buffersRef.current.byId.set(cmdId2, {
|
|
93799
|
+
kind: "command",
|
|
93800
|
+
id: cmdId2,
|
|
93801
|
+
input: msg,
|
|
93802
|
+
output: `Failed: ${errorDetails}`,
|
|
93803
|
+
phase: "finished",
|
|
93804
|
+
success: false
|
|
93805
|
+
});
|
|
93806
|
+
refreshDerived();
|
|
93807
|
+
} finally {
|
|
93808
|
+
setCommandRunning(false);
|
|
93809
|
+
}
|
|
93810
|
+
return { submitted: true };
|
|
93811
|
+
}
|
|
93812
|
+
const validationError = validateAgentName(newValue);
|
|
93373
93813
|
if (validationError) {
|
|
93374
93814
|
const cmdId2 = uid4("cmd");
|
|
93375
93815
|
buffersRef.current.byId.set(cmdId2, {
|
|
@@ -93389,7 +93829,7 @@ Type your task to begin the loop.`,
|
|
|
93389
93829
|
kind: "command",
|
|
93390
93830
|
id: cmdId,
|
|
93391
93831
|
input: msg,
|
|
93392
|
-
output: `Renaming agent to "${
|
|
93832
|
+
output: `Renaming agent to "${newValue}"...`,
|
|
93393
93833
|
phase: "running"
|
|
93394
93834
|
});
|
|
93395
93835
|
buffersRef.current.order.push(cmdId);
|
|
@@ -93397,13 +93837,13 @@ Type your task to begin the loop.`,
|
|
|
93397
93837
|
setCommandRunning(true);
|
|
93398
93838
|
try {
|
|
93399
93839
|
const client = await getClient2();
|
|
93400
|
-
await client.agents.update(agentId, { name:
|
|
93401
|
-
updateAgentName(
|
|
93840
|
+
await client.agents.update(agentId, { name: newValue });
|
|
93841
|
+
updateAgentName(newValue);
|
|
93402
93842
|
buffersRef.current.byId.set(cmdId, {
|
|
93403
93843
|
kind: "command",
|
|
93404
93844
|
id: cmdId,
|
|
93405
93845
|
input: msg,
|
|
93406
|
-
output: `Agent renamed to "${
|
|
93846
|
+
output: `Agent renamed to "${newValue}"`,
|
|
93407
93847
|
phase: "finished",
|
|
93408
93848
|
success: true
|
|
93409
93849
|
});
|
|
@@ -93529,6 +93969,7 @@ Type your task to begin the loop.`,
|
|
|
93529
93969
|
buffersRef.current.order = [];
|
|
93530
93970
|
buffersRef.current.tokenCount = 0;
|
|
93531
93971
|
emittedIdsRef.current.clear();
|
|
93972
|
+
resetDeferredToolCallCommits();
|
|
93532
93973
|
setStaticItems([]);
|
|
93533
93974
|
setStaticRenderEpoch((e) => e + 1);
|
|
93534
93975
|
resetTrajectoryBases();
|
|
@@ -94357,6 +94798,17 @@ ${SYSTEM_REMINDER_CLOSE}`
|
|
|
94357
94798
|
});
|
|
94358
94799
|
hasSentSessionContextRef.current = true;
|
|
94359
94800
|
}
|
|
94801
|
+
let sessionStartHookFeedback = "";
|
|
94802
|
+
if (sessionStartFeedbackRef.current.length > 0) {
|
|
94803
|
+
sessionStartHookFeedback = `${SYSTEM_REMINDER_OPEN}
|
|
94804
|
+
[SessionStart hook context]:
|
|
94805
|
+
${sessionStartFeedbackRef.current.join(`
|
|
94806
|
+
`)}
|
|
94807
|
+
${SYSTEM_REMINDER_CLOSE}
|
|
94808
|
+
|
|
94809
|
+
`;
|
|
94810
|
+
sessionStartFeedbackRef.current = [];
|
|
94811
|
+
}
|
|
94360
94812
|
let bashCommandPrefix = "";
|
|
94361
94813
|
if (bashCommandCacheRef.current.length > 0) {
|
|
94362
94814
|
bashCommandPrefix = `${SYSTEM_REMINDER_OPEN}
|
|
@@ -94419,7 +94871,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94419
94871
|
`;
|
|
94420
94872
|
lastNotifiedModeRef.current = currentMode;
|
|
94421
94873
|
}
|
|
94422
|
-
const allReminders = sessionContextReminder + permissionModeAlert + planModeReminder + ralphModeReminder + skillUnloadReminder + bashCommandPrefix + userPromptSubmitHookFeedback + memoryReminderContent + memfsConflictReminder;
|
|
94874
|
+
const allReminders = sessionContextReminder + sessionStartHookFeedback + permissionModeAlert + planModeReminder + ralphModeReminder + skillUnloadReminder + bashCommandPrefix + userPromptSubmitHookFeedback + memoryReminderContent + memfsConflictReminder;
|
|
94423
94875
|
const messageContent = allReminders && typeof contentParts === "string" ? allReminders + contentParts : Array.isArray(contentParts) && allReminders ? [{ type: "text", text: allReminders }, ...contentParts] : contentParts;
|
|
94424
94876
|
const userId = uid4("user");
|
|
94425
94877
|
buffersRef.current.byId.set(userId, {
|
|
@@ -94467,22 +94919,11 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94467
94919
|
return { submitted: false };
|
|
94468
94920
|
}
|
|
94469
94921
|
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
|
-
}));
|
|
94922
|
+
const { needsUserInput, autoAllowed, autoDenied } = await classifyApprovals(existingApprovals, {
|
|
94923
|
+
getContext: analyzeToolApproval,
|
|
94924
|
+
alwaysRequiresUserInput,
|
|
94925
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
94926
|
+
});
|
|
94486
94927
|
if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
|
|
94487
94928
|
buffersRef.current.byId.delete(userId);
|
|
94488
94929
|
const orderIndex = buffersRef.current.order.indexOf(userId);
|
|
@@ -94493,23 +94934,6 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94493
94934
|
refreshDerived();
|
|
94494
94935
|
return { submitted: false };
|
|
94495
94936
|
}
|
|
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
94937
|
if (needsUserInput.length === 0) {
|
|
94514
94938
|
for (const ac of [...autoAllowed, ...needsUserInput]) {
|
|
94515
94939
|
const toolName = ac.approval.toolName;
|
|
@@ -94925,8 +95349,12 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
94925
95349
|
...approvalResultsSnapshot,
|
|
94926
95350
|
...additionalDecision ? [additionalDecision] : []
|
|
94927
95351
|
];
|
|
94928
|
-
|
|
94929
|
-
|
|
95352
|
+
const approvedDecisions = allDecisions.filter((decision) => decision.type === "approve");
|
|
95353
|
+
const runningDecisions = approvedDecisions.filter((decision) => !decision.precomputedResult);
|
|
95354
|
+
executingToolCallIdsRef.current = runningDecisions.map((decision) => decision.approval.toolCallId);
|
|
95355
|
+
if (runningDecisions.length > 0) {
|
|
95356
|
+
setToolCallsRunning(buffersRef.current, runningDecisions.map((d) => d.approval.toolCallId));
|
|
95357
|
+
}
|
|
94930
95358
|
refreshDerived();
|
|
94931
95359
|
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
94932
95360
|
sessionStatsRef.current.startTrajectory();
|
|
@@ -95278,7 +95706,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
95278
95706
|
let selectedModel = models2.find((m) => m.id === modelId);
|
|
95279
95707
|
if (!selectedModel && modelId.includes("/")) {
|
|
95280
95708
|
const { getModelContextWindow: getModelContextWindow2 } = await init_available_models().then(() => exports_available_models);
|
|
95281
|
-
const apiContextWindow = getModelContextWindow2(modelId);
|
|
95709
|
+
const apiContextWindow = await getModelContextWindow2(modelId);
|
|
95282
95710
|
selectedModel = {
|
|
95283
95711
|
id: modelId,
|
|
95284
95712
|
handle: modelId,
|
|
@@ -95942,9 +96370,6 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
95942
96370
|
});
|
|
95943
96371
|
setThinkingMessage(getRandomThinkingVerb());
|
|
95944
96372
|
refreshDerived();
|
|
95945
|
-
if (approval.toolCallId) {
|
|
95946
|
-
eagerCommittedPreviewsRef.current.add(approval.toolCallId);
|
|
95947
|
-
}
|
|
95948
96373
|
const decision = {
|
|
95949
96374
|
type: "approve",
|
|
95950
96375
|
approval,
|
|
@@ -96031,6 +96456,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96031
96456
|
return lines.filter((ln) => {
|
|
96032
96457
|
if (!("phase" in ln))
|
|
96033
96458
|
return false;
|
|
96459
|
+
if (emittedIdsRef.current.has(ln.id))
|
|
96460
|
+
return false;
|
|
96034
96461
|
if (ln.kind === "command" || ln.kind === "bash_command") {
|
|
96035
96462
|
return ln.phase === "running";
|
|
96036
96463
|
}
|
|
@@ -96038,7 +96465,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96038
96465
|
if (ln.name && isTaskTool(ln.name)) {
|
|
96039
96466
|
return ln.phase === "ready" || ln.phase === "streaming";
|
|
96040
96467
|
}
|
|
96041
|
-
return ln.phase !== "finished";
|
|
96468
|
+
return ln.phase !== "finished" || deferredToolCallCommitsRef.current.has(ln.id);
|
|
96042
96469
|
}
|
|
96043
96470
|
if (ln.kind === "event") {
|
|
96044
96471
|
return ln.phase === "running";
|
|
@@ -96047,7 +96474,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96047
96474
|
return false;
|
|
96048
96475
|
return ln.phase === "streaming";
|
|
96049
96476
|
});
|
|
96050
|
-
}, [lines, tokenStreamingEnabled]);
|
|
96477
|
+
}, [lines, tokenStreamingEnabled, staticItems.length, deferredCommitAt]);
|
|
96051
96478
|
const { agents: subagents } = import_react91.useSyncExternalStore(subscribe2, getSnapshot2);
|
|
96052
96479
|
const shouldAnimate = import_react91.useMemo(() => {
|
|
96053
96480
|
const countLines4 = (text) => {
|
|
@@ -96125,7 +96552,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96125
96552
|
});
|
|
96126
96553
|
buffersRef.current.order.push(statusId);
|
|
96127
96554
|
refreshDerived();
|
|
96128
|
-
commitEligibleLines(buffersRef.current);
|
|
96555
|
+
commitEligibleLines(buffersRef.current, { deferToolCalls: false });
|
|
96129
96556
|
}
|
|
96130
96557
|
}, [
|
|
96131
96558
|
loadingState,
|
|
@@ -96146,6 +96573,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96146
96573
|
const trajectoryTokenDisplay = Math.max(liveTrajectoryTokenBase + runTokenDelta, trajectoryTokenDisplayRef.current);
|
|
96147
96574
|
const inputVisible = !showExitStats;
|
|
96148
96575
|
const inputEnabled = !showExitStats && pendingApprovals.length === 0 && !anySelectorOpen;
|
|
96576
|
+
const currentApprovalPreviewCommitted = currentApproval?.toolCallId ? eagerCommittedPreviewsRef.current.has(currentApproval.toolCallId) : false;
|
|
96577
|
+
const showApprovalPreview = !currentApprovalShouldCommitPreview && !currentApprovalPreviewCommitted;
|
|
96149
96578
|
import_react91.useEffect(() => {
|
|
96150
96579
|
trajectoryTokenDisplayRef.current = trajectoryTokenDisplay;
|
|
96151
96580
|
}, [trajectoryTokenDisplay]);
|
|
@@ -96155,51 +96584,53 @@ Plan file path: ${planFilePath}`;
|
|
|
96155
96584
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Static, {
|
|
96156
96585
|
items: staticItems,
|
|
96157
96586
|
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
|
-
|
|
96587
|
+
children: (item, index) => {
|
|
96588
|
+
return /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96589
|
+
marginTop: index > 0 ? 1 : 0,
|
|
96590
|
+
children: item.kind === "welcome" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(WelcomeScreen, {
|
|
96591
|
+
loadingState: "ready",
|
|
96592
|
+
...item.snapshot
|
|
96593
|
+
}, undefined, false, undefined, this) : item.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(UserMessage, {
|
|
96594
|
+
line: item
|
|
96595
|
+
}, undefined, false, undefined, this) : item.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ReasoningMessage, {
|
|
96596
|
+
line: item
|
|
96597
|
+
}, undefined, false, undefined, this) : item.kind === "assistant" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(AssistantMessage, {
|
|
96598
|
+
line: item
|
|
96599
|
+
}, undefined, false, undefined, this) : item.kind === "tool_call" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ToolCallMessage, {
|
|
96600
|
+
line: item,
|
|
96601
|
+
precomputedDiffs: precomputedDiffsRef.current,
|
|
96602
|
+
lastPlanFilePath: lastPlanFilePathRef.current
|
|
96603
|
+
}, undefined, false, undefined, this) : item.kind === "subagent_group" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(SubagentGroupStatic, {
|
|
96604
|
+
agents: item.agents
|
|
96605
|
+
}, undefined, false, undefined, this) : item.kind === "error" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ErrorMessage, {
|
|
96606
|
+
line: item
|
|
96607
|
+
}, undefined, false, undefined, this) : item.kind === "status" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(StatusMessage, {
|
|
96608
|
+
line: item
|
|
96609
|
+
}, undefined, false, undefined, this) : item.kind === "event" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(EventMessage, {
|
|
96610
|
+
line: item
|
|
96611
|
+
}, undefined, false, undefined, this) : item.kind === "separator" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96612
|
+
marginTop: 1,
|
|
96613
|
+
children: /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Text2, {
|
|
96614
|
+
dimColor: true,
|
|
96615
|
+
children: "─".repeat(columns)
|
|
96616
|
+
}, undefined, false, undefined, this)
|
|
96617
|
+
}, undefined, false, undefined, this) : item.kind === "command" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(CommandMessage, {
|
|
96618
|
+
line: item
|
|
96619
|
+
}, undefined, false, undefined, this) : item.kind === "bash_command" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(BashCommandMessage, {
|
|
96620
|
+
line: item
|
|
96621
|
+
}, undefined, false, undefined, this) : item.kind === "trajectory_summary" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(TrajectorySummary, {
|
|
96622
|
+
line: item
|
|
96623
|
+
}, undefined, false, undefined, this) : item.kind === "approval_preview" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ApprovalPreview, {
|
|
96624
|
+
toolName: item.toolName,
|
|
96625
|
+
toolArgs: item.toolArgs,
|
|
96626
|
+
precomputedDiff: item.precomputedDiff,
|
|
96627
|
+
allDiffs: precomputedDiffsRef.current,
|
|
96628
|
+
planContent: item.planContent,
|
|
96629
|
+
planFilePath: item.planFilePath,
|
|
96630
|
+
toolCallId: item.toolCallId
|
|
96631
|
+
}, undefined, false, undefined, this) : null
|
|
96632
|
+
}, item.id, false, undefined, this);
|
|
96633
|
+
}
|
|
96203
96634
|
}, staticRenderEpoch, false, undefined, this),
|
|
96204
96635
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96205
96636
|
flexDirection: "column",
|
|
@@ -96217,10 +96648,12 @@ Plan file path: ${planFilePath}`;
|
|
|
96217
96648
|
liveItems.length > 0 && /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Box_default, {
|
|
96218
96649
|
flexDirection: "column",
|
|
96219
96650
|
children: liveItems.map((ln) => {
|
|
96220
|
-
|
|
96651
|
+
const isFileTool = ln.kind === "tool_call" && ln.name && (isFileEditTool(ln.name) || isFileWriteTool(ln.name) || isPatchTool(ln.name));
|
|
96652
|
+
const isApprovalTracked = ln.kind === "tool_call" && ln.toolCallId && (ln.toolCallId === currentApproval?.toolCallId || pendingIds.has(ln.toolCallId) || queuedIds.has(ln.toolCallId));
|
|
96653
|
+
if (isFileTool && !isApprovalTracked) {
|
|
96221
96654
|
return null;
|
|
96222
96655
|
}
|
|
96223
|
-
if (ln.kind === "tool_call" && ln.toolCallId &&
|
|
96656
|
+
if (ln.kind === "tool_call" && ln.name && isTaskTool(ln.name) && ln.toolCallId && !pendingIds.has(ln.toolCallId) && ln.toolCallId !== currentApproval?.toolCallId) {
|
|
96224
96657
|
return null;
|
|
96225
96658
|
}
|
|
96226
96659
|
const matchesCurrentApproval = ln.kind === "tool_call" && currentApproval && ln.toolCallId === currentApproval.toolCallId;
|
|
@@ -96242,7 +96675,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96242
96675
|
allDiffs: precomputedDiffsRef.current,
|
|
96243
96676
|
isFocused: true,
|
|
96244
96677
|
approveAlwaysText: currentApprovalContext?.approveAlwaysText,
|
|
96245
|
-
allowPersistence: currentApprovalContext?.allowPersistence ?? true
|
|
96678
|
+
allowPersistence: currentApprovalContext?.allowPersistence ?? true,
|
|
96679
|
+
showPreview: showApprovalPreview
|
|
96246
96680
|
}, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(UserMessage, {
|
|
96247
96681
|
line: ln
|
|
96248
96682
|
}, undefined, false, undefined, this) : ln.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ReasoningMessage, {
|
|
@@ -96291,7 +96725,8 @@ Plan file path: ${planFilePath}`;
|
|
|
96291
96725
|
allDiffs: precomputedDiffsRef.current,
|
|
96292
96726
|
isFocused: true,
|
|
96293
96727
|
approveAlwaysText: currentApprovalContext?.approveAlwaysText,
|
|
96294
|
-
allowPersistence: currentApprovalContext?.allowPersistence ?? true
|
|
96728
|
+
allowPersistence: currentApprovalContext?.allowPersistence ?? true,
|
|
96729
|
+
showPreview: showApprovalPreview
|
|
96295
96730
|
}, undefined, false, undefined, this)
|
|
96296
96731
|
}, undefined, false, undefined, this),
|
|
96297
96732
|
/* @__PURE__ */ jsx_dev_runtime69.jsxDEV(SubagentGroupDisplay, {}, undefined, false, undefined, this)
|
|
@@ -96543,6 +96978,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96543
96978
|
buffersRef.current.order = [];
|
|
96544
96979
|
buffersRef.current.tokenCount = 0;
|
|
96545
96980
|
emittedIdsRef.current.clear();
|
|
96981
|
+
resetDeferredToolCallCommits();
|
|
96546
96982
|
setStaticItems([]);
|
|
96547
96983
|
setStaticRenderEpoch((e) => e + 1);
|
|
96548
96984
|
resetTrajectoryBases();
|
|
@@ -96665,6 +97101,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96665
97101
|
buffersRef.current.order = [];
|
|
96666
97102
|
buffersRef.current.tokenCount = 0;
|
|
96667
97103
|
emittedIdsRef.current.clear();
|
|
97104
|
+
resetDeferredToolCallCommits();
|
|
96668
97105
|
setStaticItems([]);
|
|
96669
97106
|
setStaticRenderEpoch((e) => e + 1);
|
|
96670
97107
|
resetTrajectoryBases();
|
|
@@ -96764,6 +97201,7 @@ Plan file path: ${planFilePath}`;
|
|
|
96764
97201
|
buffersRef.current.order = [];
|
|
96765
97202
|
buffersRef.current.tokenCount = 0;
|
|
96766
97203
|
emittedIdsRef.current.clear();
|
|
97204
|
+
resetDeferredToolCallCommits();
|
|
96767
97205
|
setStaticItems([]);
|
|
96768
97206
|
setStaticRenderEpoch((e) => e + 1);
|
|
96769
97207
|
resetTrajectoryBases();
|
|
@@ -96982,7 +97420,7 @@ Open /mcp to attach or detach tools for this server.`,
|
|
|
96982
97420
|
]
|
|
96983
97421
|
}, resumeKey, true, undefined, this);
|
|
96984
97422
|
}
|
|
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 =
|
|
97423
|
+
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
97424
|
var init_App2 = __esm(async () => {
|
|
96987
97425
|
init_error();
|
|
96988
97426
|
init_check_approval();
|
|
@@ -96995,6 +97433,7 @@ var init_App2 = __esm(async () => {
|
|
|
96995
97433
|
init_mode();
|
|
96996
97434
|
init_mode2();
|
|
96997
97435
|
init_settings();
|
|
97436
|
+
init_debug();
|
|
96998
97437
|
init_colors();
|
|
96999
97438
|
init_SessionStats();
|
|
97000
97439
|
init_AnimationContext();
|
|
@@ -97062,6 +97501,7 @@ var init_App2 = __esm(async () => {
|
|
|
97062
97501
|
init_UserMessageRich(),
|
|
97063
97502
|
init_WelcomeScreen(),
|
|
97064
97503
|
init_accumulator(),
|
|
97504
|
+
init_approvalClassification(),
|
|
97065
97505
|
init_memoryReminder(),
|
|
97066
97506
|
init_sessionContext(),
|
|
97067
97507
|
init_stream(),
|
|
@@ -97853,7 +98293,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
97853
98293
|
blockProvenance.push({ label: blockId, source: "shared" });
|
|
97854
98294
|
}
|
|
97855
98295
|
const modelUpdateArgs = getModelUpdateArgs(modelHandle);
|
|
97856
|
-
const contextWindow = modelUpdateArgs?.context_window;
|
|
98296
|
+
const contextWindow = modelUpdateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
97857
98297
|
let systemPromptContent;
|
|
97858
98298
|
if (options.systemPromptCustom) {
|
|
97859
98299
|
systemPromptContent = options.systemPromptCustom;
|
|
@@ -97926,6 +98366,7 @@ var init_create3 = __esm(async () => {
|
|
|
97926
98366
|
init_promptAssets();
|
|
97927
98367
|
init_skills2();
|
|
97928
98368
|
await __promiseAll([
|
|
98369
|
+
init_available_models(),
|
|
97929
98370
|
init_client2(),
|
|
97930
98371
|
init_modify()
|
|
97931
98372
|
]);
|
|
@@ -98069,7 +98510,7 @@ function buildModelSettings2(modelHandle, updateArgs) {
|
|
|
98069
98510
|
async function updateAgentLLMConfig2(agentId, modelHandle, updateArgs) {
|
|
98070
98511
|
const client = await getClient2();
|
|
98071
98512
|
const modelSettings = buildModelSettings2(modelHandle, updateArgs);
|
|
98072
|
-
const contextWindow = updateArgs?.context_window;
|
|
98513
|
+
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
98073
98514
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
98074
98515
|
await client.agents.update(agentId, {
|
|
98075
98516
|
model: modelHandle,
|
|
@@ -98151,6 +98592,7 @@ async function updateAgentSystemPromptMemfs2(agentId, enableMemfs) {
|
|
|
98151
98592
|
var init_modify2 = __esm(async () => {
|
|
98152
98593
|
await __promiseAll([
|
|
98153
98594
|
init_openai_codex_provider(),
|
|
98595
|
+
init_available_models(),
|
|
98154
98596
|
init_client2()
|
|
98155
98597
|
]);
|
|
98156
98598
|
});
|
|
@@ -98247,6 +98689,7 @@ class InternalServerError extends APIError {
|
|
|
98247
98689
|
|
|
98248
98690
|
// src/agent/check-approval.ts
|
|
98249
98691
|
init_error();
|
|
98692
|
+
init_debug();
|
|
98250
98693
|
var MESSAGE_HISTORY_LIMIT = 15;
|
|
98251
98694
|
function isBackfillEnabled() {
|
|
98252
98695
|
const val = process.env.LETTA_BACKFILL;
|
|
@@ -100815,6 +101258,7 @@ class PermissionModeManager {
|
|
|
100815
101258
|
var permissionMode = new PermissionModeManager;
|
|
100816
101259
|
|
|
100817
101260
|
// src/settings-manager.ts
|
|
101261
|
+
init_debug();
|
|
100818
101262
|
init_fs();
|
|
100819
101263
|
await init_secrets();
|
|
100820
101264
|
import { homedir as homedir6 } from "node:os";
|
|
@@ -101843,6 +102287,7 @@ var telemetry = new TelemetryManager;
|
|
|
101843
102287
|
init_model();
|
|
101844
102288
|
init_subagents();
|
|
101845
102289
|
init_constants();
|
|
102290
|
+
init_debug();
|
|
101846
102291
|
await __promiseAll([
|
|
101847
102292
|
init_approval_execution(),
|
|
101848
102293
|
init_hooks(),
|
|
@@ -103415,4 +103860,4 @@ Error during initialization: ${message}`);
|
|
|
103415
103860
|
}
|
|
103416
103861
|
main();
|
|
103417
103862
|
|
|
103418
|
-
//# debugId=
|
|
103863
|
+
//# debugId=B1589B59DC2C974664756E2164756E21
|