@letta-ai/letta-code 0.14.14 → 0.14.16
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
CHANGED
|
@@ -3122,7 +3122,7 @@ var package_default;
|
|
|
3122
3122
|
var init_package = __esm(() => {
|
|
3123
3123
|
package_default = {
|
|
3124
3124
|
name: "@letta-ai/letta-code",
|
|
3125
|
-
version: "0.14.
|
|
3125
|
+
version: "0.14.16",
|
|
3126
3126
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3127
3127
|
type: "module",
|
|
3128
3128
|
bin: {
|
|
@@ -5649,7 +5649,6 @@ Your memory consists of memory blocks and external memory:
|
|
|
5649
5649
|
- Memory Blocks: Stored as memory blocks, each containing a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and remain constantly available in-context.
|
|
5650
5650
|
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
5651
5651
|
|
|
5652
|
-
Memory management tools allow you to edit existing memory blocks and query for external memories.
|
|
5653
5652
|
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
5654
5653
|
They are the foundation which makes you *you*.
|
|
5655
5654
|
|
|
@@ -29235,6 +29234,12 @@ var create = (stream, { showCursor = false } = {}) => {
|
|
|
29235
29234
|
let previousLineCount = 0;
|
|
29236
29235
|
let previousOutput = "";
|
|
29237
29236
|
let hasHiddenCursor = false;
|
|
29237
|
+
const renderWithClearedLineEnds = (output) => {
|
|
29238
|
+
const lines = output.split(`
|
|
29239
|
+
`);
|
|
29240
|
+
return lines.map((line) => line + exports_base.eraseEndLine).join(`
|
|
29241
|
+
`);
|
|
29242
|
+
};
|
|
29238
29243
|
const render = (str) => {
|
|
29239
29244
|
if (!showCursor && !hasHiddenCursor) {
|
|
29240
29245
|
cli_cursor_default.hide();
|
|
@@ -29245,10 +29250,17 @@ var create = (stream, { showCursor = false } = {}) => {
|
|
|
29245
29250
|
if (output === previousOutput) {
|
|
29246
29251
|
return;
|
|
29247
29252
|
}
|
|
29248
|
-
|
|
29249
|
-
stream.write(exports_base.eraseLines(previousLineCount) + output);
|
|
29250
|
-
previousLineCount = output.split(`
|
|
29253
|
+
const nextLineCount = output.split(`
|
|
29251
29254
|
`).length;
|
|
29255
|
+
if (previousLineCount > 1) {
|
|
29256
|
+
stream.write(exports_base.cursorUp(previousLineCount - 1));
|
|
29257
|
+
}
|
|
29258
|
+
stream.write(renderWithClearedLineEnds(output));
|
|
29259
|
+
if (nextLineCount < previousLineCount) {
|
|
29260
|
+
stream.write(exports_base.eraseDown);
|
|
29261
|
+
}
|
|
29262
|
+
previousOutput = output;
|
|
29263
|
+
previousLineCount = nextLineCount;
|
|
29252
29264
|
};
|
|
29253
29265
|
render.clear = () => {
|
|
29254
29266
|
stream.write(exports_base.eraseLines(previousLineCount));
|
|
@@ -31103,7 +31115,7 @@ var init_colors = __esm(() => {
|
|
|
31103
31115
|
inline: "green"
|
|
31104
31116
|
},
|
|
31105
31117
|
link: {
|
|
31106
|
-
text:
|
|
31118
|
+
text: brandColors.primaryAccentLight,
|
|
31107
31119
|
url: brandColors.primaryAccent
|
|
31108
31120
|
},
|
|
31109
31121
|
heading: {
|
|
@@ -33160,7 +33172,8 @@ var init_models2 = __esm(() => {
|
|
|
33160
33172
|
isFeatured: true,
|
|
33161
33173
|
free: true,
|
|
33162
33174
|
updateArgs: {
|
|
33163
|
-
context_window:
|
|
33175
|
+
context_window: 160000,
|
|
33176
|
+
max_output_tokens: 64000
|
|
33164
33177
|
}
|
|
33165
33178
|
},
|
|
33166
33179
|
{
|
|
@@ -33169,7 +33182,8 @@ var init_models2 = __esm(() => {
|
|
|
33169
33182
|
label: "Minimax M2",
|
|
33170
33183
|
description: "Minimax's latest model",
|
|
33171
33184
|
updateArgs: {
|
|
33172
|
-
context_window:
|
|
33185
|
+
context_window: 160000,
|
|
33186
|
+
max_output_tokens: 64000
|
|
33173
33187
|
}
|
|
33174
33188
|
},
|
|
33175
33189
|
{
|
|
@@ -38450,6 +38464,10 @@ var init_EnterPlanMode2 = __esm(() => {
|
|
|
38450
38464
|
|
|
38451
38465
|
// src/tools/impl/ExitPlanMode.ts
|
|
38452
38466
|
async function exit_plan_mode() {
|
|
38467
|
+
if (permissionMode2.getMode() === "plan") {
|
|
38468
|
+
const restoredMode = permissionMode2.getModeBeforePlan() ?? "default";
|
|
38469
|
+
permissionMode2.setMode(restoredMode);
|
|
38470
|
+
}
|
|
38453
38471
|
return {
|
|
38454
38472
|
message: `User has approved your plan. You can now start coding.
|
|
38455
38473
|
` + `Start with updating your todo list if applicable.
|
|
@@ -38457,6 +38475,9 @@ async function exit_plan_mode() {
|
|
|
38457
38475
|
` + "Tip: If this plan will be referenced in the future by your future-self, " + "other agents, or humans, consider renaming the plan file to something easily " + "identifiable with a timestamp (e.g., `2026-01-auth-refactor.md`) rather than the random name."
|
|
38458
38476
|
};
|
|
38459
38477
|
}
|
|
38478
|
+
var init_ExitPlanMode2 = __esm(() => {
|
|
38479
|
+
init_mode();
|
|
38480
|
+
});
|
|
38460
38481
|
|
|
38461
38482
|
// src/tools/impl/Glob.ts
|
|
38462
38483
|
import { execFile } from "node:child_process";
|
|
@@ -54856,12 +54877,14 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
54856
54877
|
return executeSubagent(type, config, primaryModel, userPrompt, baseURL, subagentId, true, signal, undefined, undefined, maxTurns);
|
|
54857
54878
|
}
|
|
54858
54879
|
}
|
|
54880
|
+
const propagatedError = state.finalError?.trim();
|
|
54881
|
+
const fallbackError = stderr || `Subagent exited with code ${exitCode}`;
|
|
54859
54882
|
return {
|
|
54860
54883
|
agentId: state.agentId || "",
|
|
54861
54884
|
conversationId: state.conversationId || undefined,
|
|
54862
54885
|
report: "",
|
|
54863
54886
|
success: false,
|
|
54864
|
-
error:
|
|
54887
|
+
error: propagatedError || fallbackError
|
|
54865
54888
|
};
|
|
54866
54889
|
}
|
|
54867
54890
|
if (state.finalResult !== null) {
|
|
@@ -55053,6 +55076,34 @@ function extractTaskNotificationsForDisplay(message) {
|
|
|
55053
55076
|
}
|
|
55054
55077
|
|
|
55055
55078
|
// src/tools/impl/Task.ts
|
|
55079
|
+
function buildTaskResultHeader(subagentType, result) {
|
|
55080
|
+
return [
|
|
55081
|
+
`subagent_type=${subagentType}`,
|
|
55082
|
+
result.agentId ? `agent_id=${result.agentId}` : undefined,
|
|
55083
|
+
result.conversationId ? `conversation_id=${result.conversationId}` : undefined
|
|
55084
|
+
].filter(Boolean).join(" ");
|
|
55085
|
+
}
|
|
55086
|
+
function writeTaskTranscriptStart(outputFile, description, subagentType) {
|
|
55087
|
+
appendToOutputFile(outputFile, `[Task started: ${description}]
|
|
55088
|
+
[subagent_type: ${subagentType}]
|
|
55089
|
+
|
|
55090
|
+
`);
|
|
55091
|
+
}
|
|
55092
|
+
function writeTaskTranscriptResult(outputFile, result, header) {
|
|
55093
|
+
if (result.success) {
|
|
55094
|
+
appendToOutputFile(outputFile, `${header}
|
|
55095
|
+
|
|
55096
|
+
${result.report}
|
|
55097
|
+
|
|
55098
|
+
[Task completed]
|
|
55099
|
+
`);
|
|
55100
|
+
return;
|
|
55101
|
+
}
|
|
55102
|
+
appendToOutputFile(outputFile, `[error] ${result.error || "Subagent execution failed"}
|
|
55103
|
+
|
|
55104
|
+
[Task failed]
|
|
55105
|
+
`);
|
|
55106
|
+
}
|
|
55056
55107
|
async function task(args) {
|
|
55057
55108
|
const { command = "run", model, toolCallId, signal } = args;
|
|
55058
55109
|
if (command === "refresh") {
|
|
@@ -55091,7 +55142,7 @@ async function task(args) {
|
|
|
55091
55142
|
registerSubagent(subagentId, subagent_type, description, toolCallId, isBackground);
|
|
55092
55143
|
if (isBackground) {
|
|
55093
55144
|
const taskId = getNextTaskId();
|
|
55094
|
-
const
|
|
55145
|
+
const outputFile2 = createBackgroundOutputFile(taskId);
|
|
55095
55146
|
const abortController = new AbortController;
|
|
55096
55147
|
const bgTask = {
|
|
55097
55148
|
description,
|
|
@@ -55100,37 +55151,21 @@ async function task(args) {
|
|
|
55100
55151
|
status: "running",
|
|
55101
55152
|
output: [],
|
|
55102
55153
|
startTime: new Date,
|
|
55103
|
-
outputFile,
|
|
55154
|
+
outputFile: outputFile2,
|
|
55104
55155
|
abortController
|
|
55105
55156
|
};
|
|
55106
55157
|
backgroundTasks.set(taskId, bgTask);
|
|
55107
|
-
|
|
55108
|
-
[subagent_type: ${subagent_type}]
|
|
55109
|
-
|
|
55110
|
-
`);
|
|
55158
|
+
writeTaskTranscriptStart(outputFile2, description, subagent_type);
|
|
55111
55159
|
spawnSubagent(subagent_type, prompt, model, subagentId, abortController.signal, args.agent_id, args.conversation_id, args.max_turns).then((result) => {
|
|
55112
55160
|
bgTask.status = result.success ? "completed" : "failed";
|
|
55113
55161
|
if (result.error) {
|
|
55114
55162
|
bgTask.error = result.error;
|
|
55115
55163
|
}
|
|
55116
|
-
const header =
|
|
55117
|
-
|
|
55118
|
-
result.agentId ? `agent_id=${result.agentId}` : undefined,
|
|
55119
|
-
result.conversationId ? `conversation_id=${result.conversationId}` : undefined
|
|
55120
|
-
].filter(Boolean).join(" ");
|
|
55164
|
+
const header = buildTaskResultHeader(subagent_type, result);
|
|
55165
|
+
writeTaskTranscriptResult(outputFile2, result, header);
|
|
55121
55166
|
if (result.success) {
|
|
55122
|
-
appendToOutputFile(outputFile, `${header}
|
|
55123
|
-
|
|
55124
|
-
${result.report}
|
|
55125
|
-
`);
|
|
55126
55167
|
bgTask.output.push(result.report || "");
|
|
55127
|
-
} else {
|
|
55128
|
-
appendToOutputFile(outputFile, `[error] ${result.error || "Subagent execution failed"}
|
|
55129
|
-
`);
|
|
55130
55168
|
}
|
|
55131
|
-
appendToOutputFile(outputFile, `
|
|
55132
|
-
[Task ${result.success ? "completed" : "failed"}]
|
|
55133
|
-
`);
|
|
55134
55169
|
completeSubagent(subagentId, {
|
|
55135
55170
|
success: result.success,
|
|
55136
55171
|
error: result.error,
|
|
@@ -55149,7 +55184,7 @@ ${result.report || ""}` : result.error || "Subagent execution failed";
|
|
|
55149
55184
|
status: result.success ? "completed" : "failed",
|
|
55150
55185
|
summary: `Agent "${description}" ${result.success ? "completed" : "failed"}`,
|
|
55151
55186
|
result: truncatedResult,
|
|
55152
|
-
outputFile,
|
|
55187
|
+
outputFile: outputFile2,
|
|
55153
55188
|
usage: {
|
|
55154
55189
|
totalTokens: result.totalTokens,
|
|
55155
55190
|
toolUses,
|
|
@@ -55162,7 +55197,7 @@ ${result.report || ""}` : result.error || "Subagent execution failed";
|
|
|
55162
55197
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
55163
55198
|
bgTask.status = "failed";
|
|
55164
55199
|
bgTask.error = errorMessage;
|
|
55165
|
-
appendToOutputFile(
|
|
55200
|
+
appendToOutputFile(outputFile2, `[error] ${errorMessage}
|
|
55166
55201
|
`);
|
|
55167
55202
|
completeSubagent(subagentId, { success: false, error: errorMessage });
|
|
55168
55203
|
const subagentSnapshot = getSnapshot2();
|
|
@@ -55173,7 +55208,7 @@ ${result.report || ""}` : result.error || "Subagent execution failed";
|
|
|
55173
55208
|
status: "failed",
|
|
55174
55209
|
summary: `Agent "${description}" failed`,
|
|
55175
55210
|
result: errorMessage,
|
|
55176
|
-
outputFile,
|
|
55211
|
+
outputFile: outputFile2,
|
|
55177
55212
|
usage: {
|
|
55178
55213
|
toolUses,
|
|
55179
55214
|
durationMs
|
|
@@ -55183,8 +55218,11 @@ ${result.report || ""}` : result.error || "Subagent execution failed";
|
|
|
55183
55218
|
runSubagentStopHooks(subagent_type, subagentId, false, errorMessage, args.agent_id, args.conversation_id).catch(() => {});
|
|
55184
55219
|
});
|
|
55185
55220
|
return `Task running in background with ID: ${taskId}
|
|
55186
|
-
Output file: ${
|
|
55221
|
+
Output file: ${outputFile2}`;
|
|
55187
55222
|
}
|
|
55223
|
+
const foregroundTaskId = getNextTaskId();
|
|
55224
|
+
const outputFile = createBackgroundOutputFile(foregroundTaskId);
|
|
55225
|
+
writeTaskTranscriptStart(outputFile, description, subagent_type);
|
|
55188
55226
|
try {
|
|
55189
55227
|
const result = await spawnSubagent(subagent_type, prompt, model, subagentId, signal, args.agent_id, args.conversation_id, args.max_turns);
|
|
55190
55228
|
completeSubagent(subagentId, {
|
|
@@ -55194,24 +55232,34 @@ Output file: ${outputFile}`;
|
|
|
55194
55232
|
});
|
|
55195
55233
|
runSubagentStopHooks(subagent_type, subagentId, result.success, result.error, result.agentId, result.conversationId).catch(() => {});
|
|
55196
55234
|
if (!result.success) {
|
|
55197
|
-
|
|
55235
|
+
const errorMessage = result.error || "Subagent execution failed";
|
|
55236
|
+
const failedResult = {
|
|
55237
|
+
...result,
|
|
55238
|
+
error: errorMessage
|
|
55239
|
+
};
|
|
55240
|
+
writeTaskTranscriptResult(outputFile, failedResult, "");
|
|
55241
|
+
return `Error: ${errorMessage}
|
|
55242
|
+
Output file: ${outputFile}`;
|
|
55198
55243
|
}
|
|
55199
|
-
const header =
|
|
55200
|
-
`subagent_type=${subagent_type}`,
|
|
55201
|
-
result.agentId ? `agent_id=${result.agentId}` : undefined,
|
|
55202
|
-
result.conversationId ? `conversation_id=${result.conversationId}` : undefined
|
|
55203
|
-
].filter(Boolean).join(" ");
|
|
55244
|
+
const header = buildTaskResultHeader(subagent_type, result);
|
|
55204
55245
|
const fullOutput = `${header}
|
|
55205
55246
|
|
|
55206
55247
|
${result.report}`;
|
|
55248
|
+
writeTaskTranscriptResult(outputFile, result, header);
|
|
55207
55249
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
55208
55250
|
const { content: truncatedOutput } = truncateByChars(fullOutput, LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: userCwd, toolName: "Task" });
|
|
55209
|
-
return truncatedOutput
|
|
55251
|
+
return `${truncatedOutput}
|
|
55252
|
+
Output file: ${outputFile}`;
|
|
55210
55253
|
} catch (error) {
|
|
55211
55254
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
55212
55255
|
completeSubagent(subagentId, { success: false, error: errorMessage });
|
|
55213
55256
|
runSubagentStopHooks(subagent_type, subagentId, false, errorMessage, args.agent_id, args.conversation_id).catch(() => {});
|
|
55214
|
-
|
|
55257
|
+
appendToOutputFile(outputFile, `[error] ${errorMessage}
|
|
55258
|
+
|
|
55259
|
+
[Task failed]
|
|
55260
|
+
`);
|
|
55261
|
+
return `Error: ${errorMessage}
|
|
55262
|
+
Output file: ${outputFile}`;
|
|
55215
55263
|
}
|
|
55216
55264
|
}
|
|
55217
55265
|
var VALID_DEPLOY_TYPES;
|
|
@@ -55584,7 +55632,7 @@ var init_EnterPlanMode3 = __esm(() => {
|
|
|
55584
55632
|
|
|
55585
55633
|
// src/tools/schemas/ExitPlanMode.json
|
|
55586
55634
|
var ExitPlanMode_default2;
|
|
55587
|
-
var
|
|
55635
|
+
var init_ExitPlanMode3 = __esm(() => {
|
|
55588
55636
|
ExitPlanMode_default2 = {
|
|
55589
55637
|
type: "object",
|
|
55590
55638
|
properties: {},
|
|
@@ -56535,6 +56583,7 @@ var init_toolDefinitions = __esm(async () => {
|
|
|
56535
56583
|
init_BashOutput2();
|
|
56536
56584
|
init_Edit2();
|
|
56537
56585
|
init_EnterPlanMode2();
|
|
56586
|
+
init_ExitPlanMode2();
|
|
56538
56587
|
init_Glob2();
|
|
56539
56588
|
init_GlobGemini2();
|
|
56540
56589
|
init_Grep2();
|
|
@@ -56559,7 +56608,7 @@ var init_toolDefinitions = __esm(async () => {
|
|
|
56559
56608
|
init_BashOutput3();
|
|
56560
56609
|
init_Edit3();
|
|
56561
56610
|
init_EnterPlanMode3();
|
|
56562
|
-
|
|
56611
|
+
init_ExitPlanMode3();
|
|
56563
56612
|
init_Glob3();
|
|
56564
56613
|
init_GlobGemini3();
|
|
56565
56614
|
init_Grep3();
|
|
@@ -58591,6 +58640,7 @@ var exports_analyzer = {};
|
|
|
58591
58640
|
__export(exports_analyzer, {
|
|
58592
58641
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
58593
58642
|
});
|
|
58643
|
+
import { homedir as homedir11 } from "node:os";
|
|
58594
58644
|
import { dirname as dirname8, resolve as resolve15 } from "node:path";
|
|
58595
58645
|
function analyzeApprovalContext(toolName, toolArgs, workingDirectory) {
|
|
58596
58646
|
const resolveFilePath = () => {
|
|
@@ -58691,7 +58741,85 @@ function containsDangerousCommand(command) {
|
|
|
58691
58741
|
}
|
|
58692
58742
|
return false;
|
|
58693
58743
|
}
|
|
58694
|
-
function
|
|
58744
|
+
function escapeRegex(text) {
|
|
58745
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
58746
|
+
}
|
|
58747
|
+
function normalizePathSeparators(path18) {
|
|
58748
|
+
return path18.replace(/\\/g, "/");
|
|
58749
|
+
}
|
|
58750
|
+
function parseAbsoluteCommandPaths(command) {
|
|
58751
|
+
const normalized = command.replace(/\\"/g, '"').replace(/\\'/g, "'");
|
|
58752
|
+
const candidates = [];
|
|
58753
|
+
const quotedRegex = /["']((?:[A-Za-z]:)?\/[^"']+)["']/g;
|
|
58754
|
+
let quotedMatch = quotedRegex.exec(normalized);
|
|
58755
|
+
while (quotedMatch) {
|
|
58756
|
+
if (quotedMatch[1]) {
|
|
58757
|
+
candidates.push(normalizePathSeparators(quotedMatch[1]));
|
|
58758
|
+
}
|
|
58759
|
+
quotedMatch = quotedRegex.exec(normalized);
|
|
58760
|
+
}
|
|
58761
|
+
const tokens = normalized.split(/\s+/);
|
|
58762
|
+
for (const token of tokens) {
|
|
58763
|
+
const cleaned = token.replace(/^["'`([{]+/, "").replace(/["'`),;|\]}]+$/g, "");
|
|
58764
|
+
if (/^(?:[A-Za-z]:)?\//.test(cleaned)) {
|
|
58765
|
+
candidates.push(normalizePathSeparators(cleaned));
|
|
58766
|
+
}
|
|
58767
|
+
}
|
|
58768
|
+
return Array.from(new Set(candidates));
|
|
58769
|
+
}
|
|
58770
|
+
function detectSkillScript(command, workingDir) {
|
|
58771
|
+
const pathCandidates = parseAbsoluteCommandPaths(command);
|
|
58772
|
+
if (pathCandidates.length === 0) {
|
|
58773
|
+
return null;
|
|
58774
|
+
}
|
|
58775
|
+
const normalizedWorkingDir = normalizePathSeparators(workingDir).replace(/\/$/, "");
|
|
58776
|
+
const normalizedHomeDir = normalizePathSeparators(homedir11()).replace(/\/$/, "");
|
|
58777
|
+
const detect = (source, regex2) => {
|
|
58778
|
+
for (const candidate of pathCandidates) {
|
|
58779
|
+
const match3 = candidate.match(regex2);
|
|
58780
|
+
if (!match3?.[1]) {
|
|
58781
|
+
continue;
|
|
58782
|
+
}
|
|
58783
|
+
const skillName = match3[1];
|
|
58784
|
+
const skillRootPath = match3[0].replace(/\/scripts\/$/, "");
|
|
58785
|
+
return { source, skillName, skillRootPath };
|
|
58786
|
+
}
|
|
58787
|
+
return null;
|
|
58788
|
+
};
|
|
58789
|
+
const projectRegex = new RegExp(`^${escapeRegex(normalizedWorkingDir)}/\\.skills/(.+?)/scripts/`);
|
|
58790
|
+
const projectSkill = detect("project", projectRegex);
|
|
58791
|
+
if (projectSkill) {
|
|
58792
|
+
return projectSkill;
|
|
58793
|
+
}
|
|
58794
|
+
const agentRegex = new RegExp(`^${escapeRegex(normalizedHomeDir)}/\\.letta/agents/[^/]+/skills/(.+?)/scripts/`);
|
|
58795
|
+
const agentSkill = detect("agent-scoped", agentRegex);
|
|
58796
|
+
if (agentSkill) {
|
|
58797
|
+
return agentSkill;
|
|
58798
|
+
}
|
|
58799
|
+
const globalRegex = new RegExp(`^${escapeRegex(normalizedHomeDir)}/\\.letta/skills/(.+?)/scripts/`);
|
|
58800
|
+
const globalSkill = detect("global", globalRegex);
|
|
58801
|
+
if (globalSkill) {
|
|
58802
|
+
return globalSkill;
|
|
58803
|
+
}
|
|
58804
|
+
const bundledSkill = detect("bundled", /\/skills\/builtin\/([^/]+)\/scripts\//);
|
|
58805
|
+
if (bundledSkill) {
|
|
58806
|
+
return bundledSkill;
|
|
58807
|
+
}
|
|
58808
|
+
return null;
|
|
58809
|
+
}
|
|
58810
|
+
function buildSkillScriptRule(command, skillRootPath) {
|
|
58811
|
+
const normalizedCommand = normalizePathSeparators(command).trim();
|
|
58812
|
+
const rootIndex = normalizedCommand.indexOf(skillRootPath);
|
|
58813
|
+
if (rootIndex === -1) {
|
|
58814
|
+
return `Bash(${normalizedCommand})`;
|
|
58815
|
+
}
|
|
58816
|
+
const rulePrefix = normalizedCommand.slice(0, rootIndex + skillRootPath.length);
|
|
58817
|
+
return `Bash(${rulePrefix}:*)`;
|
|
58818
|
+
}
|
|
58819
|
+
function getSkillApprovalText(source, skillName) {
|
|
58820
|
+
return `Yes, and don't ask again for scripts in ${source} skill '${skillName}'`;
|
|
58821
|
+
}
|
|
58822
|
+
function analyzeBashApproval(command, workingDir) {
|
|
58695
58823
|
const parts = command.trim().split(/\s+/);
|
|
58696
58824
|
const baseCommand = parts[0] || "";
|
|
58697
58825
|
const firstArg = parts[1] || "";
|
|
@@ -58715,6 +58843,18 @@ function analyzeBashApproval(command, _workingDir) {
|
|
|
58715
58843
|
safetyLevel: "dangerous"
|
|
58716
58844
|
};
|
|
58717
58845
|
}
|
|
58846
|
+
const skillScript = detectSkillScript(command, workingDir);
|
|
58847
|
+
if (skillScript) {
|
|
58848
|
+
const { source, skillName, skillRootPath } = skillScript;
|
|
58849
|
+
return {
|
|
58850
|
+
recommendedRule: buildSkillScriptRule(command, skillRootPath),
|
|
58851
|
+
ruleDescription: `scripts in ${source} skill '${skillName}'`,
|
|
58852
|
+
approveAlwaysText: getSkillApprovalText(source, skillName),
|
|
58853
|
+
defaultScope: "project",
|
|
58854
|
+
allowPersistence: true,
|
|
58855
|
+
safetyLevel: "moderate"
|
|
58856
|
+
};
|
|
58857
|
+
}
|
|
58718
58858
|
if (baseCommand === "git") {
|
|
58719
58859
|
const gitSubcommand = firstArg;
|
|
58720
58860
|
const safeGitCommands = ["status", "diff", "log", "show", "branch"];
|
|
@@ -58995,25 +59135,32 @@ var init_filter = __esm(() => {
|
|
|
58995
59135
|
var exports_manager2 = {};
|
|
58996
59136
|
__export(exports_manager2, {
|
|
58997
59137
|
waitForToolsetReady: () => waitForToolsetReady,
|
|
59138
|
+
setExternalToolExecutor: () => setExternalToolExecutor,
|
|
58998
59139
|
savePermissionRule: () => savePermissionRule2,
|
|
58999
59140
|
requiresApproval: () => requiresApproval,
|
|
59141
|
+
registerExternalTools: () => registerExternalTools,
|
|
59000
59142
|
loadTools: () => loadTools,
|
|
59001
59143
|
loadSpecificTools: () => loadSpecificTools,
|
|
59002
59144
|
isToolsetSwitchInProgress: () => isToolsetSwitchInProgress,
|
|
59003
59145
|
isOpenAIModel: () => isOpenAIModel,
|
|
59004
59146
|
isGeminiModel: () => isGeminiModel,
|
|
59147
|
+
isExternalTool: () => isExternalTool,
|
|
59005
59148
|
getToolSchemas: () => getToolSchemas,
|
|
59006
59149
|
getToolSchema: () => getToolSchema,
|
|
59007
59150
|
getToolPermissions: () => getToolPermissions,
|
|
59008
59151
|
getToolNames: () => getToolNames,
|
|
59009
59152
|
getServerToolName: () => getServerToolName,
|
|
59010
59153
|
getInternalToolName: () => getInternalToolName,
|
|
59154
|
+
getExternalToolsAsClientTools: () => getExternalToolsAsClientTools,
|
|
59155
|
+
getExternalToolDefinition: () => getExternalToolDefinition,
|
|
59011
59156
|
getClientToolsFromRegistry: () => getClientToolsFromRegistry,
|
|
59012
59157
|
getAllLettaToolNames: () => getAllLettaToolNames,
|
|
59013
59158
|
executeTool: () => executeTool,
|
|
59159
|
+
executeExternalTool: () => executeExternalTool,
|
|
59014
59160
|
clipToolReturn: () => clipToolReturn,
|
|
59015
59161
|
clearToolsWithLock: () => clearToolsWithLock,
|
|
59016
59162
|
clearTools: () => clearTools,
|
|
59163
|
+
clearExternalTools: () => clearExternalTools,
|
|
59017
59164
|
checkToolPermission: () => checkToolPermission,
|
|
59018
59165
|
analyzeToolApproval: () => analyzeToolApproval,
|
|
59019
59166
|
TOOL_NAMES: () => TOOL_NAMES,
|
|
@@ -59087,8 +59234,65 @@ function resolveInternalToolName(name) {
|
|
|
59087
59234
|
}
|
|
59088
59235
|
return;
|
|
59089
59236
|
}
|
|
59237
|
+
function getExternalToolsRegistry() {
|
|
59238
|
+
const global2 = globalThis;
|
|
59239
|
+
if (!global2[EXTERNAL_TOOLS_KEY]) {
|
|
59240
|
+
global2[EXTERNAL_TOOLS_KEY] = new Map;
|
|
59241
|
+
}
|
|
59242
|
+
return global2[EXTERNAL_TOOLS_KEY];
|
|
59243
|
+
}
|
|
59244
|
+
function registerExternalTools(tools) {
|
|
59245
|
+
const registry = getExternalToolsRegistry();
|
|
59246
|
+
for (const tool of tools) {
|
|
59247
|
+
registry.set(tool.name, tool);
|
|
59248
|
+
}
|
|
59249
|
+
}
|
|
59250
|
+
function setExternalToolExecutor(executor) {
|
|
59251
|
+
globalThis[EXTERNAL_EXECUTOR_KEY] = executor;
|
|
59252
|
+
}
|
|
59253
|
+
function clearExternalTools() {
|
|
59254
|
+
getExternalToolsRegistry().clear();
|
|
59255
|
+
delete globalThis[EXTERNAL_EXECUTOR_KEY];
|
|
59256
|
+
}
|
|
59257
|
+
function isExternalTool(name) {
|
|
59258
|
+
return getExternalToolsRegistry().has(name);
|
|
59259
|
+
}
|
|
59260
|
+
function getExternalToolDefinition(name) {
|
|
59261
|
+
return getExternalToolsRegistry().get(name);
|
|
59262
|
+
}
|
|
59263
|
+
function getExternalToolsAsClientTools() {
|
|
59264
|
+
return Array.from(getExternalToolsRegistry().values()).map((tool) => ({
|
|
59265
|
+
name: tool.name,
|
|
59266
|
+
description: tool.description,
|
|
59267
|
+
parameters: tool.parameters
|
|
59268
|
+
}));
|
|
59269
|
+
}
|
|
59270
|
+
async function executeExternalTool(toolCallId, toolName, input) {
|
|
59271
|
+
const executor = globalThis[EXTERNAL_EXECUTOR_KEY];
|
|
59272
|
+
if (!executor) {
|
|
59273
|
+
return {
|
|
59274
|
+
toolReturn: `External tool executor not set for tool: ${toolName}`,
|
|
59275
|
+
status: "error"
|
|
59276
|
+
};
|
|
59277
|
+
}
|
|
59278
|
+
try {
|
|
59279
|
+
const result = await executor(toolCallId, toolName, input);
|
|
59280
|
+
const textContent = result.content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join(`
|
|
59281
|
+
`);
|
|
59282
|
+
return {
|
|
59283
|
+
toolReturn: textContent || JSON.stringify(result.content),
|
|
59284
|
+
status: result.isError ? "error" : "success"
|
|
59285
|
+
};
|
|
59286
|
+
} catch (error) {
|
|
59287
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
59288
|
+
return {
|
|
59289
|
+
toolReturn: `External tool execution error: ${errorMessage}`,
|
|
59290
|
+
status: "error"
|
|
59291
|
+
};
|
|
59292
|
+
}
|
|
59293
|
+
}
|
|
59090
59294
|
function getClientToolsFromRegistry() {
|
|
59091
|
-
|
|
59295
|
+
const builtInTools = Array.from(toolRegistry.entries()).map(([name, tool]) => {
|
|
59092
59296
|
const serverName = getServerToolName(name);
|
|
59093
59297
|
return {
|
|
59094
59298
|
name: serverName,
|
|
@@ -59096,6 +59300,8 @@ function getClientToolsFromRegistry() {
|
|
|
59096
59300
|
parameters: tool.schema.input_schema
|
|
59097
59301
|
};
|
|
59098
59302
|
});
|
|
59303
|
+
const externalTools = getExternalToolsAsClientTools();
|
|
59304
|
+
return [...builtInTools, ...externalTools];
|
|
59099
59305
|
}
|
|
59100
59306
|
function getToolPermissions(toolName) {
|
|
59101
59307
|
return TOOL_PERMISSIONS[toolName] || { requiresApproval: false };
|
|
@@ -59357,6 +59563,9 @@ ${files.join(`
|
|
|
59357
59563
|
return JSON.stringify(result);
|
|
59358
59564
|
}
|
|
59359
59565
|
async function executeTool(name, args, options) {
|
|
59566
|
+
if (isExternalTool(name)) {
|
|
59567
|
+
return executeExternalTool(options?.toolCallId ?? `ext-${Date.now()}`, name, args);
|
|
59568
|
+
}
|
|
59360
59569
|
const internalName = resolveInternalToolName(name);
|
|
59361
59570
|
if (!internalName) {
|
|
59362
59571
|
return {
|
|
@@ -59523,7 +59732,7 @@ function clearToolsWithLock() {
|
|
|
59523
59732
|
releaseSwitchLock();
|
|
59524
59733
|
}
|
|
59525
59734
|
}
|
|
59526
|
-
var TOOL_NAMES, STREAMING_SHELL_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, TOOL_PERMISSIONS, REGISTRY_KEY, SWITCH_LOCK_KEY, toolRegistry;
|
|
59735
|
+
var TOOL_NAMES, STREAMING_SHELL_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, TOOL_PERMISSIONS, REGISTRY_KEY, SWITCH_LOCK_KEY, toolRegistry, EXTERNAL_TOOLS_KEY, EXTERNAL_EXECUTOR_KEY;
|
|
59527
59736
|
var init_manager3 = __esm(async () => {
|
|
59528
59737
|
init_model();
|
|
59529
59738
|
init_subagents();
|
|
@@ -59685,6 +59894,8 @@ var init_manager3 = __esm(async () => {
|
|
|
59685
59894
|
REGISTRY_KEY = Symbol.for("@letta/toolRegistry");
|
|
59686
59895
|
SWITCH_LOCK_KEY = Symbol.for("@letta/toolSwitchLock");
|
|
59687
59896
|
toolRegistry = getRegistry();
|
|
59897
|
+
EXTERNAL_TOOLS_KEY = Symbol.for("@letta/externalTools");
|
|
59898
|
+
EXTERNAL_EXECUTOR_KEY = Symbol.for("@letta/externalToolExecutor");
|
|
59688
59899
|
});
|
|
59689
59900
|
|
|
59690
59901
|
// src/agent/approval-execution.ts
|
|
@@ -61980,6 +62191,23 @@ function isConversationBusyError(detail) {
|
|
|
61980
62191
|
return false;
|
|
61981
62192
|
return detail.toLowerCase().includes(CONVERSATION_BUSY_DETAIL_FRAGMENT);
|
|
61982
62193
|
}
|
|
62194
|
+
function classifyPreStreamConflict(detail) {
|
|
62195
|
+
if (isApprovalPendingError(detail))
|
|
62196
|
+
return "approval_pending";
|
|
62197
|
+
if (isConversationBusyError(detail))
|
|
62198
|
+
return "conversation_busy";
|
|
62199
|
+
return null;
|
|
62200
|
+
}
|
|
62201
|
+
function getPreStreamErrorAction(detail, conversationBusyRetries, maxConversationBusyRetries) {
|
|
62202
|
+
const kind = classifyPreStreamConflict(detail);
|
|
62203
|
+
if (kind === "approval_pending") {
|
|
62204
|
+
return "resolve_approval_pending";
|
|
62205
|
+
}
|
|
62206
|
+
if (kind === "conversation_busy" && conversationBusyRetries < maxConversationBusyRetries) {
|
|
62207
|
+
return "retry_conversation_busy";
|
|
62208
|
+
}
|
|
62209
|
+
return "rethrow";
|
|
62210
|
+
}
|
|
61983
62211
|
async function fetchRunErrorDetail(runId) {
|
|
61984
62212
|
if (!runId)
|
|
61985
62213
|
return null;
|
|
@@ -61992,7 +62220,7 @@ async function fetchRunErrorDetail(runId) {
|
|
|
61992
62220
|
return null;
|
|
61993
62221
|
}
|
|
61994
62222
|
}
|
|
61995
|
-
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "
|
|
62223
|
+
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENT = "another request is currently being processed";
|
|
61996
62224
|
var init_approval_recovery = __esm(async () => {
|
|
61997
62225
|
await init_client2();
|
|
61998
62226
|
});
|
|
@@ -62224,7 +62452,7 @@ function buildModelSettings(modelHandle, updateArgs) {
|
|
|
62224
62452
|
} else {
|
|
62225
62453
|
settings = {};
|
|
62226
62454
|
}
|
|
62227
|
-
if (typeof updateArgs?.max_output_tokens === "number") {
|
|
62455
|
+
if (typeof updateArgs?.max_output_tokens === "number" && "provider_type" in settings) {
|
|
62228
62456
|
settings.max_output_tokens = updateArgs.max_output_tokens;
|
|
62229
62457
|
}
|
|
62230
62458
|
return settings;
|
|
@@ -62237,7 +62465,10 @@ async function updateAgentLLMConfig(agentId, modelHandle, updateArgs) {
|
|
|
62237
62465
|
await client.agents.update(agentId, {
|
|
62238
62466
|
model: modelHandle,
|
|
62239
62467
|
...hasModelSettings && { model_settings: modelSettings },
|
|
62240
|
-
...contextWindow && { context_window_limit: contextWindow }
|
|
62468
|
+
...contextWindow && { context_window_limit: contextWindow },
|
|
62469
|
+
...typeof updateArgs?.max_output_tokens === "number" && {
|
|
62470
|
+
max_tokens: updateArgs.max_output_tokens
|
|
62471
|
+
}
|
|
62241
62472
|
});
|
|
62242
62473
|
const finalAgent = await client.agents.retrieve(agentId);
|
|
62243
62474
|
return finalAgent.llm_config;
|
|
@@ -63117,6 +63348,181 @@ function findLastSafeSplitPoint(content) {
|
|
|
63117
63348
|
}
|
|
63118
63349
|
var MIN_SPLIT_LENGTH = 1500;
|
|
63119
63350
|
|
|
63351
|
+
// src/tools/interactivePolicy.ts
|
|
63352
|
+
function isInteractiveApprovalTool(toolName) {
|
|
63353
|
+
return INTERACTIVE_APPROVAL_TOOLS.has(toolName);
|
|
63354
|
+
}
|
|
63355
|
+
function isHeadlessAutoAllowTool(toolName) {
|
|
63356
|
+
return HEADLESS_AUTO_ALLOW_TOOLS.has(toolName);
|
|
63357
|
+
}
|
|
63358
|
+
var INTERACTIVE_APPROVAL_TOOLS, RUNTIME_USER_INPUT_TOOLS, HEADLESS_AUTO_ALLOW_TOOLS;
|
|
63359
|
+
var init_interactivePolicy = __esm(() => {
|
|
63360
|
+
INTERACTIVE_APPROVAL_TOOLS = new Set([
|
|
63361
|
+
"AskUserQuestion",
|
|
63362
|
+
"EnterPlanMode",
|
|
63363
|
+
"ExitPlanMode"
|
|
63364
|
+
]);
|
|
63365
|
+
RUNTIME_USER_INPUT_TOOLS = new Set(["AskUserQuestion", "ExitPlanMode"]);
|
|
63366
|
+
HEADLESS_AUTO_ALLOW_TOOLS = new Set(["EnterPlanMode"]);
|
|
63367
|
+
});
|
|
63368
|
+
|
|
63369
|
+
// src/tools/toolset.ts
|
|
63370
|
+
var exports_toolset = {};
|
|
63371
|
+
__export(exports_toolset, {
|
|
63372
|
+
switchToolsetForModel: () => switchToolsetForModel,
|
|
63373
|
+
reattachMemoryTool: () => reattachMemoryTool,
|
|
63374
|
+
forceToolsetSwitch: () => forceToolsetSwitch,
|
|
63375
|
+
ensureCorrectMemoryTool: () => ensureCorrectMemoryTool,
|
|
63376
|
+
detachMemoryTools: () => detachMemoryTools,
|
|
63377
|
+
MEMORY_TOOL_NAMES: () => MEMORY_TOOL_NAMES
|
|
63378
|
+
});
|
|
63379
|
+
async function ensureCorrectMemoryTool(agentId, modelIdentifier, useMemoryPatch) {
|
|
63380
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
63381
|
+
const client = await getClient2();
|
|
63382
|
+
const shouldUsePatch = useMemoryPatch !== undefined ? useMemoryPatch : isOpenAIModel(resolvedModel);
|
|
63383
|
+
try {
|
|
63384
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
63385
|
+
include: ["agent.tools"]
|
|
63386
|
+
});
|
|
63387
|
+
const currentTools = agentWithTools.tools || [];
|
|
63388
|
+
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
63389
|
+
const hasAnyMemoryTool = mapByName.has("memory") || mapByName.has("memory_apply_patch");
|
|
63390
|
+
if (!hasAnyMemoryTool) {
|
|
63391
|
+
return;
|
|
63392
|
+
}
|
|
63393
|
+
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
63394
|
+
const otherMemoryTool = desiredMemoryTool === "memory" ? "memory_apply_patch" : "memory";
|
|
63395
|
+
let desiredId = mapByName.get(desiredMemoryTool);
|
|
63396
|
+
if (!desiredId) {
|
|
63397
|
+
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
63398
|
+
desiredId = resp.items[0]?.id;
|
|
63399
|
+
}
|
|
63400
|
+
if (!desiredId) {
|
|
63401
|
+
return;
|
|
63402
|
+
}
|
|
63403
|
+
const otherId = mapByName.get(otherMemoryTool);
|
|
63404
|
+
if (mapByName.has(desiredMemoryTool) && !otherId) {
|
|
63405
|
+
return;
|
|
63406
|
+
}
|
|
63407
|
+
const currentIds = currentTools.map((t) => t.id).filter((id) => typeof id === "string");
|
|
63408
|
+
const newIds = new Set(currentIds);
|
|
63409
|
+
if (otherId)
|
|
63410
|
+
newIds.delete(otherId);
|
|
63411
|
+
newIds.add(desiredId);
|
|
63412
|
+
const updatedRules = (agentWithTools.tool_rules || []).map((r) => r.tool_name === otherMemoryTool ? { ...r, tool_name: desiredMemoryTool } : r);
|
|
63413
|
+
await client.agents.update(agentId, {
|
|
63414
|
+
tool_ids: Array.from(newIds),
|
|
63415
|
+
tool_rules: updatedRules
|
|
63416
|
+
});
|
|
63417
|
+
} catch (err) {
|
|
63418
|
+
console.warn(`Warning: Failed to sync memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
63419
|
+
}
|
|
63420
|
+
}
|
|
63421
|
+
async function detachMemoryTools(agentId) {
|
|
63422
|
+
const client = await getClient2();
|
|
63423
|
+
try {
|
|
63424
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
63425
|
+
include: ["agent.tools"]
|
|
63426
|
+
});
|
|
63427
|
+
const currentTools = agentWithTools.tools || [];
|
|
63428
|
+
let detachedAny = false;
|
|
63429
|
+
for (const tool of currentTools) {
|
|
63430
|
+
if (tool.name && MEMORY_TOOL_NAMES.has(tool.name)) {
|
|
63431
|
+
if (tool.id) {
|
|
63432
|
+
await client.agents.tools.detach(tool.id, { agent_id: agentId });
|
|
63433
|
+
detachedAny = true;
|
|
63434
|
+
}
|
|
63435
|
+
}
|
|
63436
|
+
}
|
|
63437
|
+
return detachedAny;
|
|
63438
|
+
} catch (err) {
|
|
63439
|
+
console.warn(`Warning: Failed to detach memory tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
63440
|
+
return false;
|
|
63441
|
+
}
|
|
63442
|
+
}
|
|
63443
|
+
async function reattachMemoryTool(agentId, modelIdentifier) {
|
|
63444
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
63445
|
+
const client = await getClient2();
|
|
63446
|
+
const shouldUsePatch = isOpenAIModel(resolvedModel);
|
|
63447
|
+
try {
|
|
63448
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
63449
|
+
include: ["agent.tools"]
|
|
63450
|
+
});
|
|
63451
|
+
const currentTools = agentWithTools.tools || [];
|
|
63452
|
+
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
63453
|
+
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
63454
|
+
if (mapByName.has(desiredMemoryTool)) {
|
|
63455
|
+
return;
|
|
63456
|
+
}
|
|
63457
|
+
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
63458
|
+
const toolId = resp.items[0]?.id;
|
|
63459
|
+
if (!toolId) {
|
|
63460
|
+
console.warn(`Memory tool "${desiredMemoryTool}" not found on server`);
|
|
63461
|
+
return;
|
|
63462
|
+
}
|
|
63463
|
+
await client.agents.tools.attach(toolId, { agent_id: agentId });
|
|
63464
|
+
} catch (err) {
|
|
63465
|
+
console.warn(`Warning: Failed to reattach memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
63466
|
+
}
|
|
63467
|
+
}
|
|
63468
|
+
async function forceToolsetSwitch(toolsetName, agentId) {
|
|
63469
|
+
let modelForLoading;
|
|
63470
|
+
if (toolsetName === "none") {
|
|
63471
|
+
clearToolsWithLock();
|
|
63472
|
+
return;
|
|
63473
|
+
} else if (toolsetName === "codex") {
|
|
63474
|
+
await loadSpecificTools([...CODEX_TOOLS]);
|
|
63475
|
+
modelForLoading = "openai/gpt-4";
|
|
63476
|
+
} else if (toolsetName === "codex_snake") {
|
|
63477
|
+
await loadTools("openai/gpt-4");
|
|
63478
|
+
modelForLoading = "openai/gpt-4";
|
|
63479
|
+
} else if (toolsetName === "gemini") {
|
|
63480
|
+
await loadSpecificTools([...GEMINI_TOOLS]);
|
|
63481
|
+
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
63482
|
+
} else if (toolsetName === "gemini_snake") {
|
|
63483
|
+
await loadTools("google_ai/gemini-3-pro-preview");
|
|
63484
|
+
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
63485
|
+
} else {
|
|
63486
|
+
await loadTools("anthropic/claude-sonnet-4");
|
|
63487
|
+
modelForLoading = "anthropic/claude-sonnet-4";
|
|
63488
|
+
}
|
|
63489
|
+
const useMemoryPatch = toolsetName === "codex" || toolsetName === "codex_snake";
|
|
63490
|
+
await ensureCorrectMemoryTool(agentId, modelForLoading, useMemoryPatch);
|
|
63491
|
+
}
|
|
63492
|
+
async function switchToolsetForModel(modelIdentifier, agentId) {
|
|
63493
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
63494
|
+
await loadTools(resolvedModel);
|
|
63495
|
+
const loadedAfterPrimary = getToolNames().length;
|
|
63496
|
+
if (loadedAfterPrimary === 0 && !toolFilter.isActive()) {
|
|
63497
|
+
await loadTools();
|
|
63498
|
+
if (getToolNames().length === 0) {
|
|
63499
|
+
throw new Error(`Failed to load any Letta tools for model "${resolvedModel}".`);
|
|
63500
|
+
}
|
|
63501
|
+
}
|
|
63502
|
+
await ensureCorrectMemoryTool(agentId, resolvedModel);
|
|
63503
|
+
const { isGeminiModel: isGeminiModel3 } = await init_manager3().then(() => exports_manager2);
|
|
63504
|
+
const toolsetName = isOpenAIModel(resolvedModel) ? "codex" : isGeminiModel3(resolvedModel) ? "gemini" : "default";
|
|
63505
|
+
return toolsetName;
|
|
63506
|
+
}
|
|
63507
|
+
var CODEX_TOOLS, GEMINI_TOOLS, MEMORY_TOOL_NAMES;
|
|
63508
|
+
var init_toolset = __esm(async () => {
|
|
63509
|
+
init_model();
|
|
63510
|
+
init_filter();
|
|
63511
|
+
await __promiseAll([
|
|
63512
|
+
init_client2(),
|
|
63513
|
+
init_manager3()
|
|
63514
|
+
]);
|
|
63515
|
+
CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
|
|
63516
|
+
GEMINI_TOOLS = GEMINI_PASCAL_TOOLS;
|
|
63517
|
+
MEMORY_TOOL_NAMES = new Set([
|
|
63518
|
+
"memory",
|
|
63519
|
+
"memory_apply_patch",
|
|
63520
|
+
"memory_insert",
|
|
63521
|
+
"memory_replace",
|
|
63522
|
+
"memory_rethink"
|
|
63523
|
+
]);
|
|
63524
|
+
});
|
|
63525
|
+
|
|
63120
63526
|
// src/cli/helpers/toolNameMapping.ts
|
|
63121
63527
|
function getDisplayToolName(rawName) {
|
|
63122
63528
|
if (rawName === "write")
|
|
@@ -63219,10 +63625,10 @@ function isPlanTool(rawName, displayName) {
|
|
|
63219
63625
|
return rawName === "update_plan" || rawName === "UpdatePlan" || displayName === "Planning";
|
|
63220
63626
|
}
|
|
63221
63627
|
function alwaysRequiresUserInput(name) {
|
|
63222
|
-
return name
|
|
63628
|
+
return isInteractiveApprovalTool(name);
|
|
63223
63629
|
}
|
|
63224
63630
|
function isMemoryTool(name) {
|
|
63225
|
-
return name
|
|
63631
|
+
return MEMORY_TOOL_NAMES.has(name);
|
|
63226
63632
|
}
|
|
63227
63633
|
function isFileEditTool(name) {
|
|
63228
63634
|
return name === "edit" || name === "Edit" || name === "multi_edit" || name === "MultiEdit" || name === "Replace" || name === "replace";
|
|
@@ -63246,6 +63652,10 @@ function isSearchTool(name) {
|
|
|
63246
63652
|
function isGlobTool(name) {
|
|
63247
63653
|
return name === "glob" || name === "Glob" || name === "glob_gemini" || name === "GlobGemini";
|
|
63248
63654
|
}
|
|
63655
|
+
var init_toolNameMapping = __esm(async () => {
|
|
63656
|
+
init_interactivePolicy();
|
|
63657
|
+
await init_toolset();
|
|
63658
|
+
});
|
|
63249
63659
|
|
|
63250
63660
|
// src/cli/helpers/accumulator.ts
|
|
63251
63661
|
function appendStreamingOutput(state, chunk, startTime, isStderr = false) {
|
|
@@ -63705,6 +64115,11 @@ function onChunk(b, chunk, ctx) {
|
|
|
63705
64115
|
eventData: eventChunk.event_data || {},
|
|
63706
64116
|
phase: "running"
|
|
63707
64117
|
}));
|
|
64118
|
+
if (eventType === "compaction") {
|
|
64119
|
+
runPreCompactHooks(ctx?.lastContextTokens, undefined, b.agentId, undefined).catch((error) => {
|
|
64120
|
+
debugLog("hooks", "PreCompact hook error (accumulator)", error);
|
|
64121
|
+
});
|
|
64122
|
+
}
|
|
63708
64123
|
break;
|
|
63709
64124
|
}
|
|
63710
64125
|
break;
|
|
@@ -63749,7 +64164,10 @@ var init_accumulator = __esm(async () => {
|
|
|
63749
64164
|
init_constants();
|
|
63750
64165
|
init_debug();
|
|
63751
64166
|
init_backfill();
|
|
63752
|
-
await
|
|
64167
|
+
await __promiseAll([
|
|
64168
|
+
init_hooks(),
|
|
64169
|
+
init_toolNameMapping()
|
|
64170
|
+
]);
|
|
63753
64171
|
CANCEL_REASON_TEXT = {
|
|
63754
64172
|
user_interrupt: INTERRUPTED_BY_USER,
|
|
63755
64173
|
stream_error: "Stream error",
|
|
@@ -63864,6 +64282,49 @@ var init_errorContext = __esm(() => {
|
|
|
63864
64282
|
});
|
|
63865
64283
|
|
|
63866
64284
|
// src/cli/helpers/errorFormatter.ts
|
|
64285
|
+
function extractReasonList(value) {
|
|
64286
|
+
if (!Array.isArray(value))
|
|
64287
|
+
return [];
|
|
64288
|
+
return value.filter((reason) => typeof reason === "string").map((reason) => reason.toLowerCase());
|
|
64289
|
+
}
|
|
64290
|
+
function getErrorReasons(e) {
|
|
64291
|
+
const reasons = new Set;
|
|
64292
|
+
const errorBody = e.error;
|
|
64293
|
+
if (errorBody && typeof errorBody === "object") {
|
|
64294
|
+
const body = errorBody;
|
|
64295
|
+
for (const reason of extractReasonList(body.reasons)) {
|
|
64296
|
+
reasons.add(reason);
|
|
64297
|
+
}
|
|
64298
|
+
if (body.error && typeof body.error === "object") {
|
|
64299
|
+
const nested = body.error;
|
|
64300
|
+
for (const reason of extractReasonList(nested.reasons)) {
|
|
64301
|
+
reasons.add(reason);
|
|
64302
|
+
}
|
|
64303
|
+
}
|
|
64304
|
+
}
|
|
64305
|
+
const message = e.message?.toLowerCase() ?? "";
|
|
64306
|
+
for (const knownReason of [
|
|
64307
|
+
"not-enough-credits",
|
|
64308
|
+
"model-unknown",
|
|
64309
|
+
"byok-not-available-on-free-tier",
|
|
64310
|
+
"free-usage-exceeded",
|
|
64311
|
+
"premium-usage-exceeded",
|
|
64312
|
+
"standard-usage-exceeded",
|
|
64313
|
+
"basic-usage-exceeded",
|
|
64314
|
+
"context-window-size-not-supported",
|
|
64315
|
+
"agents-limit-exceeded",
|
|
64316
|
+
"exceeded-quota"
|
|
64317
|
+
]) {
|
|
64318
|
+
if (message.includes(knownReason)) {
|
|
64319
|
+
reasons.add(knownReason);
|
|
64320
|
+
}
|
|
64321
|
+
}
|
|
64322
|
+
return Array.from(reasons);
|
|
64323
|
+
}
|
|
64324
|
+
function hasErrorReason(e, reason, reasons) {
|
|
64325
|
+
const allReasons = reasons ?? getErrorReasons(e);
|
|
64326
|
+
return allReasons.includes(reason.toLowerCase());
|
|
64327
|
+
}
|
|
63867
64328
|
function getRateLimitResetMs(e) {
|
|
63868
64329
|
if (e.status !== 429)
|
|
63869
64330
|
return;
|
|
@@ -63917,52 +64378,87 @@ function getResourceLimitMessage(e) {
|
|
|
63917
64378
|
}
|
|
63918
64379
|
return;
|
|
63919
64380
|
}
|
|
63920
|
-
function isAgentLimitError(e) {
|
|
64381
|
+
function isAgentLimitError(e, reasons) {
|
|
63921
64382
|
if (e.status !== 429)
|
|
63922
64383
|
return false;
|
|
63923
|
-
|
|
63924
|
-
if (errorBody && typeof errorBody === "object") {
|
|
63925
|
-
if ("reasons" in errorBody && Array.isArray(errorBody.reasons)) {
|
|
63926
|
-
if (errorBody.reasons.includes("agents-limit-exceeded")) {
|
|
63927
|
-
return true;
|
|
63928
|
-
}
|
|
63929
|
-
}
|
|
63930
|
-
}
|
|
63931
|
-
return false;
|
|
64384
|
+
return hasErrorReason(e, "agents-limit-exceeded", reasons);
|
|
63932
64385
|
}
|
|
63933
|
-
function isCreditExhaustedError(e) {
|
|
64386
|
+
function isCreditExhaustedError(e, reasons) {
|
|
63934
64387
|
if (e.status !== 402)
|
|
63935
64388
|
return false;
|
|
63936
|
-
|
|
63937
|
-
|
|
63938
|
-
|
|
63939
|
-
|
|
63940
|
-
|
|
64389
|
+
return hasErrorReason(e, "not-enough-credits", reasons);
|
|
64390
|
+
}
|
|
64391
|
+
function findEncryptedContentDetail(e) {
|
|
64392
|
+
if (typeof e !== "object" || e === null)
|
|
64393
|
+
return;
|
|
64394
|
+
const obj = e;
|
|
64395
|
+
if (typeof obj.detail === "string" && obj.detail.includes("invalid_encrypted_content")) {
|
|
64396
|
+
return obj.detail;
|
|
64397
|
+
}
|
|
64398
|
+
if (obj.error && typeof obj.error === "object") {
|
|
64399
|
+
const errObj = obj.error;
|
|
64400
|
+
if (errObj.error && typeof errObj.error === "object") {
|
|
64401
|
+
const inner = errObj.error;
|
|
64402
|
+
if (typeof inner.detail === "string" && inner.detail.includes("invalid_encrypted_content")) {
|
|
64403
|
+
return inner.detail;
|
|
63941
64404
|
}
|
|
63942
64405
|
}
|
|
63943
|
-
if (
|
|
63944
|
-
|
|
63945
|
-
if ("reasons" in nested && Array.isArray(nested.reasons)) {
|
|
63946
|
-
if (nested.reasons.includes("not-enough-credits")) {
|
|
63947
|
-
return true;
|
|
63948
|
-
}
|
|
63949
|
-
}
|
|
64406
|
+
if (typeof errObj.detail === "string" && errObj.detail.includes("invalid_encrypted_content")) {
|
|
64407
|
+
return errObj.detail;
|
|
63950
64408
|
}
|
|
63951
64409
|
}
|
|
63952
|
-
|
|
63953
|
-
|
|
64410
|
+
return;
|
|
64411
|
+
}
|
|
64412
|
+
function checkEncryptedContentError(e) {
|
|
64413
|
+
const detail = findEncryptedContentDetail(e);
|
|
64414
|
+
if (!detail) {
|
|
64415
|
+
try {
|
|
64416
|
+
const errorStr = typeof e === "string" ? e : JSON.stringify(e);
|
|
64417
|
+
if (!errorStr.includes("invalid_encrypted_content"))
|
|
64418
|
+
return;
|
|
64419
|
+
} catch {
|
|
64420
|
+
return;
|
|
64421
|
+
}
|
|
64422
|
+
return "OpenAI error: Encrypted content could not be verified — organization mismatch." + ENCRYPTED_CONTENT_HINT;
|
|
63954
64423
|
}
|
|
63955
|
-
|
|
64424
|
+
try {
|
|
64425
|
+
const jsonStart = detail.indexOf("{");
|
|
64426
|
+
if (jsonStart >= 0) {
|
|
64427
|
+
const parsed = JSON.parse(detail.slice(jsonStart));
|
|
64428
|
+
const innerError = parsed.error || parsed;
|
|
64429
|
+
if (innerError.code === "invalid_encrypted_content") {
|
|
64430
|
+
const msg = String(innerError.message || "Encrypted content verification failed.").replaceAll('"', "\\\"");
|
|
64431
|
+
return [
|
|
64432
|
+
"OpenAI error:",
|
|
64433
|
+
" {",
|
|
64434
|
+
` type: "${innerError.type || "invalid_request_error"}",`,
|
|
64435
|
+
` code: "${innerError.code}",`,
|
|
64436
|
+
` message: "${msg}"`,
|
|
64437
|
+
" }",
|
|
64438
|
+
ENCRYPTED_CONTENT_HINT
|
|
64439
|
+
].join(`
|
|
64440
|
+
`);
|
|
64441
|
+
}
|
|
64442
|
+
}
|
|
64443
|
+
} catch {}
|
|
64444
|
+
return "OpenAI error: Encrypted content could not be verified — organization mismatch." + ENCRYPTED_CONTENT_HINT;
|
|
64445
|
+
}
|
|
64446
|
+
function isEncryptedContentError(e) {
|
|
64447
|
+
return findEncryptedContentDetail(e) !== undefined;
|
|
63956
64448
|
}
|
|
63957
64449
|
function formatErrorDetails(e, agentId, conversationId) {
|
|
63958
64450
|
let runId;
|
|
64451
|
+
const encryptedContentMsg = checkEncryptedContentError(e);
|
|
64452
|
+
if (encryptedContentMsg)
|
|
64453
|
+
return encryptedContentMsg;
|
|
63959
64454
|
if (e instanceof APIError2) {
|
|
64455
|
+
const reasons = getErrorReasons(e);
|
|
63960
64456
|
const rateLimitResetMs = getRateLimitResetMs(e);
|
|
63961
64457
|
if (rateLimitResetMs !== undefined) {
|
|
63962
64458
|
const resetInfo = rateLimitResetMs > 0 ? formatResetTime(rateLimitResetMs) : "Try again later";
|
|
63963
64459
|
return `You've hit your usage limit. ${resetInfo}. View usage: ${LETTA_USAGE_URL}`;
|
|
63964
64460
|
}
|
|
63965
|
-
if (isAgentLimitError(e)) {
|
|
64461
|
+
if (isAgentLimitError(e, reasons)) {
|
|
63966
64462
|
const { billingTier } = getErrorContext();
|
|
63967
64463
|
if (billingTier?.toLowerCase() === "free") {
|
|
63968
64464
|
return `You've reached the agent limit (3) for the Free Plan. Delete agents at: ${LETTA_AGENTS_URL}
|
|
@@ -63971,6 +64467,12 @@ Or upgrade to Pro for unlimited agents at: ${LETTA_USAGE_URL}`;
|
|
|
63971
64467
|
return `You've reached your agent limit. Delete agents at: ${LETTA_AGENTS_URL}
|
|
63972
64468
|
Or check your plan at: ${LETTA_USAGE_URL}`;
|
|
63973
64469
|
}
|
|
64470
|
+
if (hasErrorReason(e, "model-unknown", reasons)) {
|
|
64471
|
+
return `The selected model is not currently available for this account or provider. Run /model and press R to refresh available models, then choose an available model or connect a provider with /connect.`;
|
|
64472
|
+
}
|
|
64473
|
+
if (hasErrorReason(e, "context-window-size-not-supported", reasons)) {
|
|
64474
|
+
return `The selected context window is not supported for this model. Switch models with /model or pick a model with a larger context window.`;
|
|
64475
|
+
}
|
|
63974
64476
|
const resourceLimitMsg = getResourceLimitMessage(e);
|
|
63975
64477
|
if (resourceLimitMsg) {
|
|
63976
64478
|
const match3 = resourceLimitMsg.match(/limit for (\w+)/);
|
|
@@ -63979,13 +64481,19 @@ Or check your plan at: ${LETTA_USAGE_URL}`;
|
|
|
63979
64481
|
Upgrade at: ${LETTA_USAGE_URL}
|
|
63980
64482
|
Delete ${resourceType} at: ${LETTA_AGENTS_URL}`;
|
|
63981
64483
|
}
|
|
63982
|
-
if (isCreditExhaustedError(e)) {
|
|
63983
|
-
|
|
63984
|
-
|
|
63985
|
-
|
|
63986
|
-
|
|
63987
|
-
|
|
63988
|
-
|
|
64484
|
+
if (isCreditExhaustedError(e, reasons)) {
|
|
64485
|
+
return `Your account is out of credits for hosted inference. Add credits, enable auto-recharge, or upgrade at ${LETTA_USAGE_URL}. You can also connect your own provider keys with /connect.`;
|
|
64486
|
+
}
|
|
64487
|
+
if (hasErrorReason(e, "premium-usage-exceeded", reasons) || hasErrorReason(e, "standard-usage-exceeded", reasons) || hasErrorReason(e, "basic-usage-exceeded", reasons)) {
|
|
64488
|
+
return `You've reached your hosted model usage limit. View your plan and usage at ${LETTA_USAGE_URL}, or connect your own provider keys with /connect.`;
|
|
64489
|
+
}
|
|
64490
|
+
if (hasErrorReason(e, "byok-not-available-on-free-tier", reasons)) {
|
|
64491
|
+
const { modelDisplayName } = getErrorContext();
|
|
64492
|
+
const modelInfo = modelDisplayName ? ` (${modelDisplayName})` : "";
|
|
64493
|
+
return `Selected BYOK model${modelInfo} is not available on the Free plan. Switch to a free hosted model with /model (glm-4.7 or minimax-m2.1), or upgrade at ${LETTA_USAGE_URL}.`;
|
|
64494
|
+
}
|
|
64495
|
+
if (hasErrorReason(e, "free-usage-exceeded", reasons)) {
|
|
64496
|
+
return `You've reached the Free plan hosted model usage limit. Switch to free hosted models with /model (glm-4.7 or minimax-m2.1), upgrade at ${LETTA_USAGE_URL}, or connect your own provider keys with /connect.`;
|
|
63989
64497
|
}
|
|
63990
64498
|
if (e.error && typeof e.error === "object" && "error" in e.error) {
|
|
63991
64499
|
const errorData = e.error.error;
|
|
@@ -64041,10 +64549,18 @@ function createAgentLink(runId, agentId, conversationId) {
|
|
|
64041
64549
|
const url = `https://app.letta.com/agents/${agentId}${conversationId ? `?conversation=${conversationId}` : ""}`;
|
|
64042
64550
|
return `View agent: \x1B]8;;${url}\x1B\\${agentId}\x1B]8;;\x1B\\ (run: ${runId})`;
|
|
64043
64551
|
}
|
|
64044
|
-
var LETTA_USAGE_URL = "https://app.letta.com/settings/organization/usage", LETTA_AGENTS_URL = "https://app.letta.com/projects/default-project/agents";
|
|
64552
|
+
var LETTA_USAGE_URL = "https://app.letta.com/settings/organization/usage", LETTA_AGENTS_URL = "https://app.letta.com/projects/default-project/agents", ENCRYPTED_CONTENT_HINT;
|
|
64045
64553
|
var init_errorFormatter = __esm(() => {
|
|
64046
64554
|
init_error();
|
|
64047
64555
|
init_errorContext();
|
|
64556
|
+
ENCRYPTED_CONTENT_HINT = [
|
|
64557
|
+
"",
|
|
64558
|
+
"This occurs when the conversation contains messages with encrypted",
|
|
64559
|
+
"reasoning from a different OpenAI authentication scope (e.g. switching",
|
|
64560
|
+
"between ChatGPT OAuth and an OpenAI API key).",
|
|
64561
|
+
"Use /clear to start a new conversation."
|
|
64562
|
+
].join(`
|
|
64563
|
+
`);
|
|
64048
64564
|
});
|
|
64049
64565
|
|
|
64050
64566
|
// src/cli/helpers/streamProcessor.ts
|
|
@@ -64317,155 +64833,6 @@ var init_stream = __esm(async () => {
|
|
|
64317
64833
|
]);
|
|
64318
64834
|
});
|
|
64319
64835
|
|
|
64320
|
-
// src/tools/toolset.ts
|
|
64321
|
-
var exports_toolset = {};
|
|
64322
|
-
__export(exports_toolset, {
|
|
64323
|
-
switchToolsetForModel: () => switchToolsetForModel,
|
|
64324
|
-
reattachMemoryTool: () => reattachMemoryTool,
|
|
64325
|
-
forceToolsetSwitch: () => forceToolsetSwitch,
|
|
64326
|
-
ensureCorrectMemoryTool: () => ensureCorrectMemoryTool,
|
|
64327
|
-
detachMemoryTools: () => detachMemoryTools
|
|
64328
|
-
});
|
|
64329
|
-
async function ensureCorrectMemoryTool(agentId, modelIdentifier, useMemoryPatch) {
|
|
64330
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64331
|
-
const client = await getClient2();
|
|
64332
|
-
const shouldUsePatch = useMemoryPatch !== undefined ? useMemoryPatch : isOpenAIModel(resolvedModel);
|
|
64333
|
-
try {
|
|
64334
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64335
|
-
include: ["agent.tools"]
|
|
64336
|
-
});
|
|
64337
|
-
const currentTools = agentWithTools.tools || [];
|
|
64338
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
64339
|
-
const hasAnyMemoryTool = mapByName.has("memory") || mapByName.has("memory_apply_patch");
|
|
64340
|
-
if (!hasAnyMemoryTool) {
|
|
64341
|
-
return;
|
|
64342
|
-
}
|
|
64343
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
64344
|
-
const otherMemoryTool = desiredMemoryTool === "memory" ? "memory_apply_patch" : "memory";
|
|
64345
|
-
let desiredId = mapByName.get(desiredMemoryTool);
|
|
64346
|
-
if (!desiredId) {
|
|
64347
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
64348
|
-
desiredId = resp.items[0]?.id;
|
|
64349
|
-
}
|
|
64350
|
-
if (!desiredId) {
|
|
64351
|
-
return;
|
|
64352
|
-
}
|
|
64353
|
-
const otherId = mapByName.get(otherMemoryTool);
|
|
64354
|
-
if (mapByName.has(desiredMemoryTool) && !otherId) {
|
|
64355
|
-
return;
|
|
64356
|
-
}
|
|
64357
|
-
const currentIds = currentTools.map((t) => t.id).filter((id) => typeof id === "string");
|
|
64358
|
-
const newIds = new Set(currentIds);
|
|
64359
|
-
if (otherId)
|
|
64360
|
-
newIds.delete(otherId);
|
|
64361
|
-
newIds.add(desiredId);
|
|
64362
|
-
const updatedRules = (agentWithTools.tool_rules || []).map((r) => r.tool_name === otherMemoryTool ? { ...r, tool_name: desiredMemoryTool } : r);
|
|
64363
|
-
await client.agents.update(agentId, {
|
|
64364
|
-
tool_ids: Array.from(newIds),
|
|
64365
|
-
tool_rules: updatedRules
|
|
64366
|
-
});
|
|
64367
|
-
} catch (err) {
|
|
64368
|
-
console.warn(`Warning: Failed to sync memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
64369
|
-
}
|
|
64370
|
-
}
|
|
64371
|
-
async function detachMemoryTools(agentId) {
|
|
64372
|
-
const client = await getClient2();
|
|
64373
|
-
try {
|
|
64374
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64375
|
-
include: ["agent.tools"]
|
|
64376
|
-
});
|
|
64377
|
-
const currentTools = agentWithTools.tools || [];
|
|
64378
|
-
let detachedAny = false;
|
|
64379
|
-
for (const tool of currentTools) {
|
|
64380
|
-
if (tool.name === "memory" || tool.name === "memory_apply_patch") {
|
|
64381
|
-
if (tool.id) {
|
|
64382
|
-
await client.agents.tools.detach(tool.id, { agent_id: agentId });
|
|
64383
|
-
detachedAny = true;
|
|
64384
|
-
}
|
|
64385
|
-
}
|
|
64386
|
-
}
|
|
64387
|
-
return detachedAny;
|
|
64388
|
-
} catch (err) {
|
|
64389
|
-
console.warn(`Warning: Failed to detach memory tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
64390
|
-
return false;
|
|
64391
|
-
}
|
|
64392
|
-
}
|
|
64393
|
-
async function reattachMemoryTool(agentId, modelIdentifier) {
|
|
64394
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64395
|
-
const client = await getClient2();
|
|
64396
|
-
const shouldUsePatch = isOpenAIModel(resolvedModel);
|
|
64397
|
-
try {
|
|
64398
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64399
|
-
include: ["agent.tools"]
|
|
64400
|
-
});
|
|
64401
|
-
const currentTools = agentWithTools.tools || [];
|
|
64402
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
64403
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
64404
|
-
if (mapByName.has(desiredMemoryTool)) {
|
|
64405
|
-
return;
|
|
64406
|
-
}
|
|
64407
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
64408
|
-
const toolId = resp.items[0]?.id;
|
|
64409
|
-
if (!toolId) {
|
|
64410
|
-
console.warn(`Memory tool "${desiredMemoryTool}" not found on server`);
|
|
64411
|
-
return;
|
|
64412
|
-
}
|
|
64413
|
-
await client.agents.tools.attach(toolId, { agent_id: agentId });
|
|
64414
|
-
} catch (err) {
|
|
64415
|
-
console.warn(`Warning: Failed to reattach memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
64416
|
-
}
|
|
64417
|
-
}
|
|
64418
|
-
async function forceToolsetSwitch(toolsetName, agentId) {
|
|
64419
|
-
let modelForLoading;
|
|
64420
|
-
if (toolsetName === "none") {
|
|
64421
|
-
clearToolsWithLock();
|
|
64422
|
-
return;
|
|
64423
|
-
} else if (toolsetName === "codex") {
|
|
64424
|
-
await loadSpecificTools([...CODEX_TOOLS]);
|
|
64425
|
-
modelForLoading = "openai/gpt-4";
|
|
64426
|
-
} else if (toolsetName === "codex_snake") {
|
|
64427
|
-
await loadTools("openai/gpt-4");
|
|
64428
|
-
modelForLoading = "openai/gpt-4";
|
|
64429
|
-
} else if (toolsetName === "gemini") {
|
|
64430
|
-
await loadSpecificTools([...GEMINI_TOOLS]);
|
|
64431
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
64432
|
-
} else if (toolsetName === "gemini_snake") {
|
|
64433
|
-
await loadTools("google_ai/gemini-3-pro-preview");
|
|
64434
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
64435
|
-
} else {
|
|
64436
|
-
await loadTools("anthropic/claude-sonnet-4");
|
|
64437
|
-
modelForLoading = "anthropic/claude-sonnet-4";
|
|
64438
|
-
}
|
|
64439
|
-
const useMemoryPatch = toolsetName === "codex" || toolsetName === "codex_snake";
|
|
64440
|
-
await ensureCorrectMemoryTool(agentId, modelForLoading, useMemoryPatch);
|
|
64441
|
-
}
|
|
64442
|
-
async function switchToolsetForModel(modelIdentifier, agentId) {
|
|
64443
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64444
|
-
await loadTools(resolvedModel);
|
|
64445
|
-
const loadedAfterPrimary = getToolNames().length;
|
|
64446
|
-
if (loadedAfterPrimary === 0 && !toolFilter.isActive()) {
|
|
64447
|
-
await loadTools();
|
|
64448
|
-
if (getToolNames().length === 0) {
|
|
64449
|
-
throw new Error(`Failed to load any Letta tools for model "${resolvedModel}".`);
|
|
64450
|
-
}
|
|
64451
|
-
}
|
|
64452
|
-
await ensureCorrectMemoryTool(agentId, resolvedModel);
|
|
64453
|
-
const { isGeminiModel: isGeminiModel3 } = await init_manager3().then(() => exports_manager2);
|
|
64454
|
-
const toolsetName = isOpenAIModel(resolvedModel) ? "codex" : isGeminiModel3(resolvedModel) ? "gemini" : "default";
|
|
64455
|
-
return toolsetName;
|
|
64456
|
-
}
|
|
64457
|
-
var CODEX_TOOLS, GEMINI_TOOLS;
|
|
64458
|
-
var init_toolset = __esm(async () => {
|
|
64459
|
-
init_model();
|
|
64460
|
-
init_filter();
|
|
64461
|
-
await __promiseAll([
|
|
64462
|
-
init_client2(),
|
|
64463
|
-
init_manager3()
|
|
64464
|
-
]);
|
|
64465
|
-
CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
|
|
64466
|
-
GEMINI_TOOLS = GEMINI_PASCAL_TOOLS;
|
|
64467
|
-
});
|
|
64468
|
-
|
|
64469
64836
|
// src/agent/github-utils.ts
|
|
64470
64837
|
var exports_github_utils = {};
|
|
64471
64838
|
__export(exports_github_utils, {
|
|
@@ -64501,6 +64868,7 @@ function parseDirNames(entries) {
|
|
|
64501
64868
|
// src/agent/import.ts
|
|
64502
64869
|
var exports_import = {};
|
|
64503
64870
|
__export(exports_import, {
|
|
64871
|
+
importAgentFromRegistry: () => importAgentFromRegistry,
|
|
64504
64872
|
importAgentFromFile: () => importAgentFromFile,
|
|
64505
64873
|
extractSkillsFromAf: () => extractSkillsFromAf
|
|
64506
64874
|
});
|
|
@@ -64608,6 +64976,45 @@ async function downloadGitHubDirectory(entries, destDir, owner, repo, branch, ba
|
|
|
64608
64976
|
}
|
|
64609
64977
|
}
|
|
64610
64978
|
}
|
|
64979
|
+
function parseRegistryHandle(handle) {
|
|
64980
|
+
const normalized = handle.startsWith("@") ? handle.slice(1) : handle;
|
|
64981
|
+
const parts = normalized.split("/");
|
|
64982
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
64983
|
+
throw new Error(`Invalid import handle "${handle}". Use format: @author/agentname`);
|
|
64984
|
+
}
|
|
64985
|
+
return { author: parts[0], name: parts[1] };
|
|
64986
|
+
}
|
|
64987
|
+
async function importAgentFromRegistry(options) {
|
|
64988
|
+
const { tmpdir: tmpdir2 } = await import("node:os");
|
|
64989
|
+
const { join: join20 } = await import("node:path");
|
|
64990
|
+
const { writeFile: writeFile5, unlink: unlink2 } = await import("node:fs/promises");
|
|
64991
|
+
const { author, name } = parseRegistryHandle(options.handle);
|
|
64992
|
+
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
64993
|
+
const response = await fetch(rawUrl);
|
|
64994
|
+
if (!response.ok) {
|
|
64995
|
+
if (response.status === 404) {
|
|
64996
|
+
throw new Error(`Agent @${author}/${name} not found in registry. Check that the agent exists at https://github.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/tree/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}`);
|
|
64997
|
+
}
|
|
64998
|
+
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
64999
|
+
}
|
|
65000
|
+
const afContent = await response.text();
|
|
65001
|
+
const tempPath = join20(tmpdir2(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
65002
|
+
await writeFile5(tempPath, afContent, "utf-8");
|
|
65003
|
+
try {
|
|
65004
|
+
const result = await importAgentFromFile({
|
|
65005
|
+
filePath: tempPath,
|
|
65006
|
+
modelOverride: options.modelOverride,
|
|
65007
|
+
stripMessages: options.stripMessages ?? true,
|
|
65008
|
+
stripSkills: options.stripSkills ?? false
|
|
65009
|
+
});
|
|
65010
|
+
return result;
|
|
65011
|
+
} finally {
|
|
65012
|
+
try {
|
|
65013
|
+
await unlink2(tempPath);
|
|
65014
|
+
} catch {}
|
|
65015
|
+
}
|
|
65016
|
+
}
|
|
65017
|
+
var AGENT_REGISTRY_OWNER = "letta-ai", AGENT_REGISTRY_REPO = "agent-file", AGENT_REGISTRY_BRANCH = "main";
|
|
64611
65018
|
var init_import = __esm(async () => {
|
|
64612
65019
|
init_model();
|
|
64613
65020
|
await __promiseAll([
|
|
@@ -65059,6 +65466,7 @@ In headless mode, use:
|
|
|
65059
65466
|
process.exit(1);
|
|
65060
65467
|
}
|
|
65061
65468
|
}
|
|
65469
|
+
let isRegistryImport = false;
|
|
65062
65470
|
if (fromAfFile) {
|
|
65063
65471
|
if (specifiedAgentId) {
|
|
65064
65472
|
console.error("Error: --from-af cannot be used with --agent");
|
|
@@ -65072,6 +65480,15 @@ In headless mode, use:
|
|
|
65072
65480
|
console.error("Error: --from-af cannot be used with --new");
|
|
65073
65481
|
process.exit(1);
|
|
65074
65482
|
}
|
|
65483
|
+
if (fromAfFile.startsWith("@")) {
|
|
65484
|
+
isRegistryImport = true;
|
|
65485
|
+
const normalized = fromAfFile.slice(1);
|
|
65486
|
+
const parts = normalized.split("/");
|
|
65487
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
65488
|
+
console.error(`Error: Invalid registry handle "${fromAfFile}". Use format: @author/agentname`);
|
|
65489
|
+
process.exit(1);
|
|
65490
|
+
}
|
|
65491
|
+
}
|
|
65075
65492
|
}
|
|
65076
65493
|
if (initBlocksRaw && !forceNew) {
|
|
65077
65494
|
console.error("Error: --init-blocks can only be used together with --new to control initial memory blocks.");
|
|
@@ -65154,13 +65571,24 @@ In headless mode, use:
|
|
|
65154
65571
|
}
|
|
65155
65572
|
}
|
|
65156
65573
|
if (!agent && fromAfFile) {
|
|
65157
|
-
|
|
65158
|
-
|
|
65159
|
-
|
|
65160
|
-
|
|
65161
|
-
|
|
65162
|
-
|
|
65163
|
-
|
|
65574
|
+
let result;
|
|
65575
|
+
if (isRegistryImport) {
|
|
65576
|
+
const { importAgentFromRegistry: importAgentFromRegistry2 } = await init_import().then(() => exports_import);
|
|
65577
|
+
result = await importAgentFromRegistry2({
|
|
65578
|
+
handle: fromAfFile,
|
|
65579
|
+
modelOverride: model,
|
|
65580
|
+
stripMessages: true,
|
|
65581
|
+
stripSkills: false
|
|
65582
|
+
});
|
|
65583
|
+
} else {
|
|
65584
|
+
const { importAgentFromFile: importAgentFromFile2 } = await init_import().then(() => exports_import);
|
|
65585
|
+
result = await importAgentFromFile2({
|
|
65586
|
+
filePath: fromAfFile,
|
|
65587
|
+
modelOverride: model,
|
|
65588
|
+
stripMessages: true,
|
|
65589
|
+
stripSkills: false
|
|
65590
|
+
});
|
|
65591
|
+
}
|
|
65164
65592
|
agent = result.agent;
|
|
65165
65593
|
isNewlyCreatedAgent = true;
|
|
65166
65594
|
if (result.skills && result.skills.length > 0) {
|
|
@@ -65363,8 +65791,11 @@ In headless mode, use:
|
|
|
65363
65791
|
console.error(`Error: Invalid input format "${inputFormat}". Valid formats: stream-json`);
|
|
65364
65792
|
process.exit(1);
|
|
65365
65793
|
}
|
|
65794
|
+
const { getClientToolsFromRegistry: getClientToolsFromRegistry2 } = await init_manager3().then(() => exports_manager2);
|
|
65795
|
+
const loadedToolNames = getClientToolsFromRegistry2().map((t) => t.name);
|
|
65796
|
+
const availableTools = loadedToolNames.length > 0 ? loadedToolNames : agent.tools?.map((t) => t.name).filter((n) => !!n) || [];
|
|
65366
65797
|
if (isBidirectionalMode) {
|
|
65367
|
-
await runBidirectionalMode(agent, conversationId, client, outputFormat, includePartialMessages);
|
|
65798
|
+
await runBidirectionalMode(agent, conversationId, client, outputFormat, includePartialMessages, availableTools);
|
|
65368
65799
|
return;
|
|
65369
65800
|
}
|
|
65370
65801
|
const buffers = createBuffers(agent.id);
|
|
@@ -65378,7 +65809,7 @@ In headless mode, use:
|
|
|
65378
65809
|
agent_id: agent.id,
|
|
65379
65810
|
conversation_id: conversationId,
|
|
65380
65811
|
model: agent.llm_config?.model ?? "",
|
|
65381
|
-
tools:
|
|
65812
|
+
tools: availableTools,
|
|
65382
65813
|
cwd: process.cwd(),
|
|
65383
65814
|
mcp_servers: [],
|
|
65384
65815
|
permission_mode: "",
|
|
@@ -65404,6 +65835,7 @@ In headless mode, use:
|
|
|
65404
65835
|
if (pendingApprovals.length === 0)
|
|
65405
65836
|
break;
|
|
65406
65837
|
const { autoAllowed, autoDenied } = await classifyApprovals(pendingApprovals, {
|
|
65838
|
+
alwaysRequiresUserInput: isInteractiveApprovalTool,
|
|
65407
65839
|
treatAskAsDeny: true,
|
|
65408
65840
|
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
65409
65841
|
requireArgsForAutoApprove: true,
|
|
@@ -65583,7 +66015,24 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65583
66015
|
if (!errorDetail && preStreamError instanceof Error) {
|
|
65584
66016
|
errorDetail = preStreamError.message;
|
|
65585
66017
|
}
|
|
65586
|
-
|
|
66018
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetries, CONVERSATION_BUSY_MAX_RETRIES);
|
|
66019
|
+
if (preStreamAction === "resolve_approval_pending") {
|
|
66020
|
+
if (outputFormat === "stream-json") {
|
|
66021
|
+
const recoveryMsg = {
|
|
66022
|
+
type: "recovery",
|
|
66023
|
+
recovery_type: "approval_pending",
|
|
66024
|
+
message: "Detected pending approval conflict on send; resolving before retry",
|
|
66025
|
+
session_id: sessionId,
|
|
66026
|
+
uuid: `recovery-pre-stream-${crypto.randomUUID()}`
|
|
66027
|
+
};
|
|
66028
|
+
console.log(JSON.stringify(recoveryMsg));
|
|
66029
|
+
} else {
|
|
66030
|
+
console.error("Pending approval detected, resolving before retry...");
|
|
66031
|
+
}
|
|
66032
|
+
await resolveAllPendingApprovals();
|
|
66033
|
+
continue;
|
|
66034
|
+
}
|
|
66035
|
+
if (preStreamAction === "retry_conversation_busy") {
|
|
65587
66036
|
conversationBusyRetries += 1;
|
|
65588
66037
|
if (outputFormat === "stream-json") {
|
|
65589
66038
|
const retryMsg = {
|
|
@@ -65656,6 +66105,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65656
66105
|
}
|
|
65657
66106
|
if (updatedApproval && !autoApprovalEmitted.has(updatedApproval.toolCallId)) {
|
|
65658
66107
|
const { autoAllowed } = await classifyApprovals([updatedApproval], {
|
|
66108
|
+
alwaysRequiresUserInput: isInteractiveApprovalTool,
|
|
65659
66109
|
requireArgsForAutoApprove: true,
|
|
65660
66110
|
missingNameReason: "Tool call incomplete - missing name"
|
|
65661
66111
|
});
|
|
@@ -65734,9 +66184,8 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65734
66184
|
console.error("Unexpected empty approvals array");
|
|
65735
66185
|
process.exit(1);
|
|
65736
66186
|
}
|
|
65737
|
-
const { autoAllowed, autoDenied } = await classifyApprovals(approvals, {
|
|
65738
|
-
|
|
65739
|
-
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
66187
|
+
const { autoAllowed, autoDenied, needsUserInput } = await classifyApprovals(approvals, {
|
|
66188
|
+
alwaysRequiresUserInput: isInteractiveApprovalTool,
|
|
65740
66189
|
requireArgsForAutoApprove: true,
|
|
65741
66190
|
missingNameReason: "Tool call incomplete - missing name"
|
|
65742
66191
|
});
|
|
@@ -65745,6 +66194,19 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
65745
66194
|
type: "approve",
|
|
65746
66195
|
approval: ac.approval
|
|
65747
66196
|
})),
|
|
66197
|
+
...needsUserInput.map((ac) => {
|
|
66198
|
+
if (isHeadlessAutoAllowTool(ac.approval.toolName)) {
|
|
66199
|
+
return {
|
|
66200
|
+
type: "approve",
|
|
66201
|
+
approval: ac.approval
|
|
66202
|
+
};
|
|
66203
|
+
}
|
|
66204
|
+
return {
|
|
66205
|
+
type: "deny",
|
|
66206
|
+
approval: ac.approval,
|
|
66207
|
+
reason: "Tool requires approval (headless mode)"
|
|
66208
|
+
};
|
|
66209
|
+
}),
|
|
65748
66210
|
...autoDenied.map((ac) => {
|
|
65749
66211
|
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";
|
|
65750
66212
|
return {
|
|
@@ -66007,7 +66469,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
66007
66469
|
markMilestone("HEADLESS_COMPLETE");
|
|
66008
66470
|
reportAllMilestones();
|
|
66009
66471
|
}
|
|
66010
|
-
async function runBidirectionalMode(agent, conversationId,
|
|
66472
|
+
async function runBidirectionalMode(agent, conversationId, client, _outputFormat, includePartialMessages, availableTools) {
|
|
66011
66473
|
const sessionId = agent.id;
|
|
66012
66474
|
const readline = await import("node:readline");
|
|
66013
66475
|
const initEvent = {
|
|
@@ -66017,12 +66479,74 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
66017
66479
|
agent_id: agent.id,
|
|
66018
66480
|
conversation_id: conversationId,
|
|
66019
66481
|
model: agent.llm_config?.model,
|
|
66020
|
-
tools:
|
|
66482
|
+
tools: availableTools,
|
|
66021
66483
|
cwd: process.cwd(),
|
|
66022
66484
|
uuid: `init-${agent.id}`
|
|
66023
66485
|
};
|
|
66024
66486
|
console.log(JSON.stringify(initEvent));
|
|
66025
66487
|
let currentAbortController = null;
|
|
66488
|
+
const resolveAllPendingApprovals = async () => {
|
|
66489
|
+
const { getResumeData: getResumeData3 } = await Promise.resolve().then(() => (init_check_approval(), exports_check_approval));
|
|
66490
|
+
while (true) {
|
|
66491
|
+
const freshAgent = await client.agents.retrieve(agent.id);
|
|
66492
|
+
let resume;
|
|
66493
|
+
try {
|
|
66494
|
+
resume = await getResumeData3(client, freshAgent, conversationId);
|
|
66495
|
+
} catch (error) {
|
|
66496
|
+
if (error instanceof APIError2 && (error.status === 404 || error.status === 422)) {
|
|
66497
|
+
break;
|
|
66498
|
+
}
|
|
66499
|
+
throw error;
|
|
66500
|
+
}
|
|
66501
|
+
const pendingApprovals = resume.pendingApprovals || [];
|
|
66502
|
+
if (pendingApprovals.length === 0)
|
|
66503
|
+
break;
|
|
66504
|
+
const { autoAllowed, autoDenied } = await classifyApprovals(pendingApprovals, {
|
|
66505
|
+
treatAskAsDeny: true,
|
|
66506
|
+
denyReasonForAsk: "Tool requires approval (headless mode)",
|
|
66507
|
+
requireArgsForAutoApprove: true,
|
|
66508
|
+
missingNameReason: "Tool call incomplete - missing name"
|
|
66509
|
+
});
|
|
66510
|
+
const decisions = [
|
|
66511
|
+
...autoAllowed.map((ac) => ({
|
|
66512
|
+
type: "approve",
|
|
66513
|
+
approval: ac.approval,
|
|
66514
|
+
reason: ac.permission.reason || "Allowed by permission rule",
|
|
66515
|
+
matchedRule: "matchedRule" in ac.permission && ac.permission.matchedRule ? ac.permission.matchedRule : "auto-approved"
|
|
66516
|
+
})),
|
|
66517
|
+
...autoDenied.map((ac) => {
|
|
66518
|
+
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";
|
|
66519
|
+
return {
|
|
66520
|
+
type: "deny",
|
|
66521
|
+
approval: ac.approval,
|
|
66522
|
+
reason: ac.denyReason ?? fallback
|
|
66523
|
+
};
|
|
66524
|
+
})
|
|
66525
|
+
];
|
|
66526
|
+
const { executeApprovalBatch: executeApprovalBatch2 } = await init_approval_execution().then(() => exports_approval_execution);
|
|
66527
|
+
const executedResults = await executeApprovalBatch2(decisions);
|
|
66528
|
+
const approvalInput = {
|
|
66529
|
+
type: "approval",
|
|
66530
|
+
approvals: executedResults
|
|
66531
|
+
};
|
|
66532
|
+
const approvalMessages = [approvalInput];
|
|
66533
|
+
{
|
|
66534
|
+
const { consumeQueuedSkillContent: consumeQueuedSkillContent2 } = await Promise.resolve().then(() => (init_skillContentRegistry(), exports_skillContentRegistry));
|
|
66535
|
+
const skillContents = consumeQueuedSkillContent2();
|
|
66536
|
+
if (skillContents.length > 0) {
|
|
66537
|
+
approvalMessages.push({
|
|
66538
|
+
role: "user",
|
|
66539
|
+
content: skillContents.map((sc) => ({
|
|
66540
|
+
type: "text",
|
|
66541
|
+
text: sc.content
|
|
66542
|
+
}))
|
|
66543
|
+
});
|
|
66544
|
+
}
|
|
66545
|
+
}
|
|
66546
|
+
const approvalStream = await sendMessageStream(conversationId, approvalMessages, { agentId: agent.id });
|
|
66547
|
+
await drainStreamWithResume(approvalStream, createBuffers(agent.id), () => {});
|
|
66548
|
+
}
|
|
66549
|
+
};
|
|
66026
66550
|
const rl = readline.createInterface({
|
|
66027
66551
|
input: process.stdin,
|
|
66028
66552
|
terminal: false
|
|
@@ -66142,7 +66666,7 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
66142
66666
|
response: {
|
|
66143
66667
|
agent_id: agent.id,
|
|
66144
66668
|
model: agent.llm_config?.model,
|
|
66145
|
-
tools:
|
|
66669
|
+
tools: availableTools
|
|
66146
66670
|
}
|
|
66147
66671
|
},
|
|
66148
66672
|
session_id: sessionId,
|
|
@@ -66164,6 +66688,54 @@ async function runBidirectionalMode(agent, conversationId, _client, _outputForma
|
|
|
66164
66688
|
uuid: crypto.randomUUID()
|
|
66165
66689
|
};
|
|
66166
66690
|
console.log(JSON.stringify(interruptResponse));
|
|
66691
|
+
} else if (subtype === "register_external_tools") {
|
|
66692
|
+
const toolsRequest = message.request;
|
|
66693
|
+
const tools = toolsRequest.tools ?? [];
|
|
66694
|
+
registerExternalTools(tools);
|
|
66695
|
+
setExternalToolExecutor(async (toolCallId, toolName, input) => {
|
|
66696
|
+
const execRequest = {
|
|
66697
|
+
type: "control_request",
|
|
66698
|
+
request_id: `ext-${toolCallId}`,
|
|
66699
|
+
request: {
|
|
66700
|
+
subtype: "execute_external_tool",
|
|
66701
|
+
tool_call_id: toolCallId,
|
|
66702
|
+
tool_name: toolName,
|
|
66703
|
+
input
|
|
66704
|
+
}
|
|
66705
|
+
};
|
|
66706
|
+
console.log(JSON.stringify(execRequest));
|
|
66707
|
+
while (true) {
|
|
66708
|
+
const line2 = await getNextLine();
|
|
66709
|
+
if (line2 === null) {
|
|
66710
|
+
return {
|
|
66711
|
+
content: [{ type: "text", text: "stdin closed" }],
|
|
66712
|
+
isError: true
|
|
66713
|
+
};
|
|
66714
|
+
}
|
|
66715
|
+
if (!line2.trim())
|
|
66716
|
+
continue;
|
|
66717
|
+
try {
|
|
66718
|
+
const msg = JSON.parse(line2);
|
|
66719
|
+
if (msg.type === "control_response" && msg.response?.subtype === "external_tool_result" && msg.response?.tool_call_id === toolCallId) {
|
|
66720
|
+
return {
|
|
66721
|
+
content: msg.response.content ?? [{ type: "text", text: "" }],
|
|
66722
|
+
isError: msg.response.is_error ?? false
|
|
66723
|
+
};
|
|
66724
|
+
}
|
|
66725
|
+
} catch {}
|
|
66726
|
+
}
|
|
66727
|
+
});
|
|
66728
|
+
const registerResponse = {
|
|
66729
|
+
type: "control_response",
|
|
66730
|
+
response: {
|
|
66731
|
+
subtype: "success",
|
|
66732
|
+
request_id: requestId ?? "",
|
|
66733
|
+
response: { registered: tools.length }
|
|
66734
|
+
},
|
|
66735
|
+
session_id: sessionId,
|
|
66736
|
+
uuid: crypto.randomUUID()
|
|
66737
|
+
};
|
|
66738
|
+
console.log(JSON.stringify(registerResponse));
|
|
66167
66739
|
} else {
|
|
66168
66740
|
const errorResponse = {
|
|
66169
66741
|
type: "control_response",
|
|
@@ -66232,9 +66804,40 @@ ${enrichedContent}`;
|
|
|
66232
66804
|
];
|
|
66233
66805
|
}
|
|
66234
66806
|
}
|
|
66235
|
-
|
|
66236
|
-
|
|
66237
|
-
|
|
66807
|
+
let stream2;
|
|
66808
|
+
try {
|
|
66809
|
+
stream2 = await sendMessageStream(conversationId, currentInput, {
|
|
66810
|
+
agentId: agent.id
|
|
66811
|
+
});
|
|
66812
|
+
} catch (preStreamError) {
|
|
66813
|
+
let errorDetail = "";
|
|
66814
|
+
if (preStreamError instanceof APIError2 && preStreamError.error && typeof preStreamError.error === "object") {
|
|
66815
|
+
const errObj = preStreamError.error;
|
|
66816
|
+
if (errObj.error && typeof errObj.error === "object" && "detail" in errObj.error) {
|
|
66817
|
+
const nested = errObj.error;
|
|
66818
|
+
errorDetail = typeof nested.detail === "string" ? nested.detail : "";
|
|
66819
|
+
}
|
|
66820
|
+
if (!errorDetail && typeof errObj.detail === "string") {
|
|
66821
|
+
errorDetail = errObj.detail;
|
|
66822
|
+
}
|
|
66823
|
+
}
|
|
66824
|
+
if (!errorDetail && preStreamError instanceof Error) {
|
|
66825
|
+
errorDetail = preStreamError.message;
|
|
66826
|
+
}
|
|
66827
|
+
if (isApprovalPendingError(errorDetail)) {
|
|
66828
|
+
const recoveryMsg = {
|
|
66829
|
+
type: "recovery",
|
|
66830
|
+
recovery_type: "approval_pending",
|
|
66831
|
+
message: "Detected pending approval conflict on send; resolving before retry",
|
|
66832
|
+
session_id: sessionId,
|
|
66833
|
+
uuid: `recovery-bidir-${crypto.randomUUID()}`
|
|
66834
|
+
};
|
|
66835
|
+
console.log(JSON.stringify(recoveryMsg));
|
|
66836
|
+
await resolveAllPendingApprovals();
|
|
66837
|
+
continue;
|
|
66838
|
+
}
|
|
66839
|
+
throw preStreamError;
|
|
66840
|
+
}
|
|
66238
66841
|
const streamJsonHook = ({
|
|
66239
66842
|
chunk,
|
|
66240
66843
|
shouldOutput,
|
|
@@ -66302,6 +66905,7 @@ ${enrichedContent}`;
|
|
|
66302
66905
|
break;
|
|
66303
66906
|
}
|
|
66304
66907
|
const { autoAllowed, autoDenied, needsUserInput } = await classifyApprovals(approvals, {
|
|
66908
|
+
alwaysRequiresUserInput: isInteractiveApprovalTool,
|
|
66305
66909
|
requireArgsForAutoApprove: true,
|
|
66306
66910
|
missingNameReason: "Tool call incomplete - missing name"
|
|
66307
66911
|
});
|
|
@@ -66459,6 +67063,7 @@ var init_headless = __esm(async () => {
|
|
|
66459
67063
|
init_model();
|
|
66460
67064
|
init_errorFormatter();
|
|
66461
67065
|
init_constants();
|
|
67066
|
+
init_interactivePolicy();
|
|
66462
67067
|
init_timing();
|
|
66463
67068
|
await __promiseAll([
|
|
66464
67069
|
init_approval_recovery(),
|
|
@@ -66469,7 +67074,8 @@ var init_headless = __esm(async () => {
|
|
|
66469
67074
|
init_accumulator(),
|
|
66470
67075
|
init_approvalClassification(),
|
|
66471
67076
|
init_stream(),
|
|
66472
|
-
init_settings_manager()
|
|
67077
|
+
init_settings_manager(),
|
|
67078
|
+
init_manager3()
|
|
66473
67079
|
]);
|
|
66474
67080
|
});
|
|
66475
67081
|
|
|
@@ -66720,10 +67326,10 @@ __export(exports_settings, {
|
|
|
66720
67326
|
loadProjectSettings: () => loadProjectSettings,
|
|
66721
67327
|
getSetting: () => getSetting
|
|
66722
67328
|
});
|
|
66723
|
-
import { homedir as
|
|
67329
|
+
import { homedir as homedir13 } from "node:os";
|
|
66724
67330
|
import { join as join20 } from "node:path";
|
|
66725
67331
|
function getSettingsPath() {
|
|
66726
|
-
return join20(
|
|
67332
|
+
return join20(homedir13(), ".letta", "settings.json");
|
|
66727
67333
|
}
|
|
66728
67334
|
async function loadSettings() {
|
|
66729
67335
|
const settingsPath = getSettingsPath();
|
|
@@ -68371,7 +68977,9 @@ function formatArgsDisplay(argsJson, toolName) {
|
|
|
68371
68977
|
return { display, parsed };
|
|
68372
68978
|
}
|
|
68373
68979
|
var isRecord3 = (v) => typeof v === "object" && v !== null;
|
|
68374
|
-
var init_formatArgsDisplay = () => {
|
|
68980
|
+
var init_formatArgsDisplay = __esm(async () => {
|
|
68981
|
+
await init_toolNameMapping();
|
|
68982
|
+
});
|
|
68375
68983
|
|
|
68376
68984
|
// node_modules/diff/libesm/diff/base.js
|
|
68377
68985
|
class Diff {
|
|
@@ -70249,11 +70857,11 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
70249
70857
|
}
|
|
70250
70858
|
var import_react33, jsx_dev_runtime14, SOLID_LINE5 = "─", DOTTED_LINE2 = "╌", ApprovalPreview;
|
|
70251
70859
|
var init_ApprovalPreview = __esm(async () => {
|
|
70252
|
-
init_formatArgsDisplay();
|
|
70253
70860
|
init_useTerminalWidth();
|
|
70254
70861
|
init_colors();
|
|
70255
70862
|
await __promiseAll([
|
|
70256
70863
|
init_build2(),
|
|
70864
|
+
init_formatArgsDisplay(),
|
|
70257
70865
|
init_AdvancedDiffRenderer(),
|
|
70258
70866
|
init_BashPreview(),
|
|
70259
70867
|
init_PlanPreview(),
|
|
@@ -70962,13 +71570,13 @@ function getDiffKind(toolName) {
|
|
|
70962
71570
|
var import_react38, jsx_dev_runtime17, SOLID_LINE8 = "─", DOTTED_LINE3 = "╌", InlineFileEditApproval;
|
|
70963
71571
|
var init_InlineFileEditApproval = __esm(async () => {
|
|
70964
71572
|
init_diff2();
|
|
70965
|
-
init_formatArgsDisplay();
|
|
70966
71573
|
init_useProgressIndicator();
|
|
70967
71574
|
init_useTerminalWidth();
|
|
70968
71575
|
init_useTextInputCursor();
|
|
70969
71576
|
init_colors();
|
|
70970
71577
|
await __promiseAll([
|
|
70971
71578
|
init_build2(),
|
|
71579
|
+
init_formatArgsDisplay(),
|
|
70972
71580
|
init_AdvancedDiffRenderer(),
|
|
70973
71581
|
init_Text2()
|
|
70974
71582
|
]);
|
|
@@ -72543,6 +73151,7 @@ function getQuestions(approval) {
|
|
|
72543
73151
|
var import_react43, jsx_dev_runtime22, ApprovalSwitch;
|
|
72544
73152
|
var init_ApprovalSwitch = __esm(async () => {
|
|
72545
73153
|
await __promiseAll([
|
|
73154
|
+
init_toolNameMapping(),
|
|
72546
73155
|
init_InlineBashApproval(),
|
|
72547
73156
|
init_InlineEnterPlanModeApproval(),
|
|
72548
73157
|
init_InlineFileEditApproval(),
|
|
@@ -72717,8 +73326,9 @@ function AnimationProvider({
|
|
|
72717
73326
|
children,
|
|
72718
73327
|
shouldAnimate
|
|
72719
73328
|
}) {
|
|
73329
|
+
const contextValue = import_react45.useMemo(() => ({ shouldAnimate }), [shouldAnimate]);
|
|
72720
73330
|
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(AnimationContext.Provider, {
|
|
72721
|
-
value:
|
|
73331
|
+
value: contextValue,
|
|
72722
73332
|
children
|
|
72723
73333
|
}, undefined, false, undefined, this);
|
|
72724
73334
|
}
|
|
@@ -72774,11 +73384,18 @@ var init_CollapsedOutputDisplay = __esm(async () => {
|
|
|
72774
73384
|
jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
|
|
72775
73385
|
CollapsedOutputDisplay = import_react47.memo(({
|
|
72776
73386
|
output,
|
|
72777
|
-
maxLines = DEFAULT_COLLAPSED_LINES
|
|
73387
|
+
maxLines = DEFAULT_COLLAPSED_LINES,
|
|
73388
|
+
maxChars
|
|
72778
73389
|
}) => {
|
|
72779
73390
|
const columns = useTerminalWidth();
|
|
72780
73391
|
const contentWidth = Math.max(0, columns - PREFIX_WIDTH);
|
|
72781
|
-
|
|
73392
|
+
let displayOutput = output;
|
|
73393
|
+
let clippedByChars = false;
|
|
73394
|
+
if (typeof maxChars === "number" && maxChars > 0 && output.length > maxChars) {
|
|
73395
|
+
displayOutput = `${output.slice(0, maxChars)}…`;
|
|
73396
|
+
clippedByChars = true;
|
|
73397
|
+
}
|
|
73398
|
+
const lines = displayOutput.split(`
|
|
72782
73399
|
`);
|
|
72783
73400
|
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
72784
73401
|
lines.pop();
|
|
@@ -72853,6 +73470,26 @@ var init_CollapsedOutputDisplay = __esm(async () => {
|
|
|
72853
73470
|
}, undefined, true, undefined, this)
|
|
72854
73471
|
}, undefined, false, undefined, this)
|
|
72855
73472
|
]
|
|
73473
|
+
}, undefined, true, undefined, this),
|
|
73474
|
+
clippedByChars && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
|
|
73475
|
+
flexDirection: "row",
|
|
73476
|
+
children: [
|
|
73477
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
|
|
73478
|
+
width: PREFIX_WIDTH,
|
|
73479
|
+
flexShrink: 0,
|
|
73480
|
+
children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text2, {
|
|
73481
|
+
children: " "
|
|
73482
|
+
}, undefined, false, undefined, this)
|
|
73483
|
+
}, undefined, false, undefined, this),
|
|
73484
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
|
|
73485
|
+
flexGrow: 1,
|
|
73486
|
+
width: contentWidth,
|
|
73487
|
+
children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text2, {
|
|
73488
|
+
dimColor: true,
|
|
73489
|
+
children: "… output clipped"
|
|
73490
|
+
}, undefined, false, undefined, this)
|
|
73491
|
+
}, undefined, false, undefined, this)
|
|
73492
|
+
]
|
|
72856
73493
|
}, undefined, true, undefined, this)
|
|
72857
73494
|
]
|
|
72858
73495
|
}, undefined, true, undefined, this);
|
|
@@ -74896,7 +75533,7 @@ import {
|
|
|
74896
75533
|
readFileSync as readFileSync6,
|
|
74897
75534
|
writeFileSync as writeFileSync5
|
|
74898
75535
|
} from "node:fs";
|
|
74899
|
-
import { homedir as
|
|
75536
|
+
import { homedir as homedir14, platform as platform3 } from "node:os";
|
|
74900
75537
|
import { dirname as dirname12, join as join22 } from "node:path";
|
|
74901
75538
|
function detectTerminalType() {
|
|
74902
75539
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
@@ -74929,7 +75566,7 @@ function getKeybindingsPath(terminal) {
|
|
|
74929
75566
|
}[terminal];
|
|
74930
75567
|
const os5 = platform3();
|
|
74931
75568
|
if (os5 === "darwin") {
|
|
74932
|
-
return join22(
|
|
75569
|
+
return join22(homedir14(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
74933
75570
|
}
|
|
74934
75571
|
if (os5 === "win32") {
|
|
74935
75572
|
const appData = process.env.APPDATA;
|
|
@@ -74938,7 +75575,7 @@ function getKeybindingsPath(terminal) {
|
|
|
74938
75575
|
return join22(appData, appName, "User", "keybindings.json");
|
|
74939
75576
|
}
|
|
74940
75577
|
if (os5 === "linux") {
|
|
74941
|
-
return join22(
|
|
75578
|
+
return join22(homedir14(), ".config", appName, "User", "keybindings.json");
|
|
74942
75579
|
}
|
|
74943
75580
|
return null;
|
|
74944
75581
|
}
|
|
@@ -75095,10 +75732,10 @@ function getWezTermConfigPath() {
|
|
|
75095
75732
|
if (existsSync13(xdgPath))
|
|
75096
75733
|
return xdgPath;
|
|
75097
75734
|
}
|
|
75098
|
-
const configPath = join22(
|
|
75735
|
+
const configPath = join22(homedir14(), ".config", "wezterm", "wezterm.lua");
|
|
75099
75736
|
if (existsSync13(configPath))
|
|
75100
75737
|
return configPath;
|
|
75101
|
-
return join22(
|
|
75738
|
+
return join22(homedir14(), ".wezterm.lua");
|
|
75102
75739
|
}
|
|
75103
75740
|
function wezTermDeleteFixExists(configPath) {
|
|
75104
75741
|
if (!existsSync13(configPath))
|
|
@@ -80501,9 +81138,15 @@ function SlashCommandAutocomplete({
|
|
|
80501
81138
|
manageActiveState: false
|
|
80502
81139
|
});
|
|
80503
81140
|
import_react64.useLayoutEffect(() => {
|
|
80504
|
-
const
|
|
81141
|
+
const queryLength = queryInfo?.query.length ?? 0;
|
|
81142
|
+
const isActive = !hideAutocomplete && (matches.length > 0 || queryLength > 0);
|
|
80505
81143
|
onActiveChange?.(isActive);
|
|
80506
|
-
}, [
|
|
81144
|
+
}, [
|
|
81145
|
+
hideAutocomplete,
|
|
81146
|
+
matches.length,
|
|
81147
|
+
onActiveChange,
|
|
81148
|
+
queryInfo?.query.length
|
|
81149
|
+
]);
|
|
80507
81150
|
if (!currentInput.startsWith("/")) {
|
|
80508
81151
|
return null;
|
|
80509
81152
|
}
|
|
@@ -80725,7 +81368,8 @@ var init_ShimmerText = __esm(async () => {
|
|
|
80725
81368
|
color = colors.status.processing,
|
|
80726
81369
|
boldPrefix,
|
|
80727
81370
|
message,
|
|
80728
|
-
shimmerOffset
|
|
81371
|
+
shimmerOffset,
|
|
81372
|
+
wrap
|
|
80729
81373
|
}) {
|
|
80730
81374
|
const fullText = `${boldPrefix ? `${boldPrefix} ` : ""}${message}…`;
|
|
80731
81375
|
const prefixLength = boldPrefix ? boldPrefix.length + 1 : 0;
|
|
@@ -80740,6 +81384,7 @@ var init_ShimmerText = __esm(async () => {
|
|
|
80740
81384
|
return isInPrefix ? source_default.bold(styledChar) : styledChar;
|
|
80741
81385
|
}).join("");
|
|
80742
81386
|
return /* @__PURE__ */ jsx_dev_runtime44.jsxDEV(Text2, {
|
|
81387
|
+
wrap,
|
|
80743
81388
|
children: shimmerText
|
|
80744
81389
|
}, undefined, false, undefined, this);
|
|
80745
81390
|
});
|
|
@@ -80748,6 +81393,15 @@ var init_ShimmerText = __esm(async () => {
|
|
|
80748
81393
|
// src/cli/components/InputRich.tsx
|
|
80749
81394
|
import { EventEmitter as EventEmitter5 } from "node:events";
|
|
80750
81395
|
import { stdin } from "node:process";
|
|
81396
|
+
function truncateEnd(value, maxChars) {
|
|
81397
|
+
if (maxChars <= 0)
|
|
81398
|
+
return "";
|
|
81399
|
+
if (value.length <= maxChars)
|
|
81400
|
+
return value;
|
|
81401
|
+
if (maxChars <= 3)
|
|
81402
|
+
return value.slice(0, maxChars);
|
|
81403
|
+
return `${value.slice(0, maxChars - 3)}...`;
|
|
81404
|
+
}
|
|
80751
81405
|
function getVisualLines(text, lineWidth) {
|
|
80752
81406
|
const lines = [];
|
|
80753
81407
|
let lineStart = 0;
|
|
@@ -80813,7 +81467,9 @@ function Input({
|
|
|
80813
81467
|
onPasteError,
|
|
80814
81468
|
restoredInput,
|
|
80815
81469
|
onRestoredInputConsumed,
|
|
80816
|
-
networkPhase = null
|
|
81470
|
+
networkPhase = null,
|
|
81471
|
+
terminalWidth,
|
|
81472
|
+
shouldAnimate = true
|
|
80817
81473
|
}) {
|
|
80818
81474
|
const [value, setValue] = import_react68.useState("");
|
|
80819
81475
|
const [escapePressed, setEscapePressed] = import_react68.useState(false);
|
|
@@ -80825,7 +81481,7 @@ function Input({
|
|
|
80825
81481
|
const [isAutocompleteActive, setIsAutocompleteActive] = import_react68.useState(false);
|
|
80826
81482
|
const [cursorPos, setCursorPos] = import_react68.useState(undefined);
|
|
80827
81483
|
const [currentCursorPosition, setCurrentCursorPosition] = import_react68.useState(0);
|
|
80828
|
-
const columns =
|
|
81484
|
+
const columns = terminalWidth;
|
|
80829
81485
|
const contentWidth = Math.max(0, columns - 2);
|
|
80830
81486
|
const interactionEnabled = visible && inputEnabled;
|
|
80831
81487
|
const reserveInputSpace = !collapseInputWhenDisabled;
|
|
@@ -80834,6 +81490,38 @@ function Input({
|
|
|
80834
81490
|
return Math.max(1, getVisualLines(value, contentWidth).length);
|
|
80835
81491
|
}, [value, contentWidth]);
|
|
80836
81492
|
const inputChromeHeight = inputRowLines + 3;
|
|
81493
|
+
const computedFooterRightColumnWidth = import_react68.useMemo(() => Math.max(28, Math.min(72, Math.floor(columns * 0.45))), [columns]);
|
|
81494
|
+
const [footerRightColumnWidth, setFooterRightColumnWidth] = import_react68.useState(computedFooterRightColumnWidth);
|
|
81495
|
+
const debugFlicker = process.env.LETTA_DEBUG_FLICKER === "1";
|
|
81496
|
+
import_react68.useEffect(() => {
|
|
81497
|
+
if (!streaming) {
|
|
81498
|
+
setFooterRightColumnWidth(computedFooterRightColumnWidth);
|
|
81499
|
+
return;
|
|
81500
|
+
}
|
|
81501
|
+
if (computedFooterRightColumnWidth >= footerRightColumnWidth) {
|
|
81502
|
+
const growthDelta = computedFooterRightColumnWidth - footerRightColumnWidth;
|
|
81503
|
+
if (debugFlicker && growthDelta >= FOOTER_WIDTH_STREAMING_DELTA) {
|
|
81504
|
+
console.error(`[debug:flicker:footer-width] defer growth ${footerRightColumnWidth} -> ${computedFooterRightColumnWidth} (delta=${growthDelta})`);
|
|
81505
|
+
}
|
|
81506
|
+
return;
|
|
81507
|
+
}
|
|
81508
|
+
const shrinkDelta = footerRightColumnWidth - computedFooterRightColumnWidth;
|
|
81509
|
+
if (shrinkDelta < FOOTER_WIDTH_STREAMING_DELTA) {
|
|
81510
|
+
if (debugFlicker && shrinkDelta > 0) {
|
|
81511
|
+
console.error(`[debug:flicker:footer-width] ignore minor shrink ${footerRightColumnWidth} -> ${computedFooterRightColumnWidth} (delta=${shrinkDelta})`);
|
|
81512
|
+
}
|
|
81513
|
+
return;
|
|
81514
|
+
}
|
|
81515
|
+
if (debugFlicker) {
|
|
81516
|
+
console.error(`[debug:flicker:footer-width] shrink ${footerRightColumnWidth} -> ${computedFooterRightColumnWidth} (delta=${shrinkDelta})`);
|
|
81517
|
+
}
|
|
81518
|
+
setFooterRightColumnWidth(computedFooterRightColumnWidth);
|
|
81519
|
+
}, [
|
|
81520
|
+
streaming,
|
|
81521
|
+
computedFooterRightColumnWidth,
|
|
81522
|
+
footerRightColumnWidth,
|
|
81523
|
+
debugFlicker
|
|
81524
|
+
]);
|
|
80837
81525
|
const [history, setHistory] = import_react68.useState([]);
|
|
80838
81526
|
const [historyIndex, setHistoryIndex] = import_react68.useState(-1);
|
|
80839
81527
|
const [temporaryInput, setTemporaryInput] = import_react68.useState("");
|
|
@@ -80849,18 +81537,18 @@ function Input({
|
|
|
80849
81537
|
onRestoredInputConsumed?.();
|
|
80850
81538
|
}
|
|
80851
81539
|
}, [restoredInput, value, onRestoredInputConsumed]);
|
|
80852
|
-
const handleBangAtEmpty = () => {
|
|
81540
|
+
const handleBangAtEmpty = import_react68.useCallback(() => {
|
|
80853
81541
|
if (isBashMode)
|
|
80854
81542
|
return false;
|
|
80855
81543
|
setIsBashMode(true);
|
|
80856
81544
|
return true;
|
|
80857
|
-
};
|
|
80858
|
-
const handleBackspaceAtEmpty = () => {
|
|
81545
|
+
}, [isBashMode]);
|
|
81546
|
+
const handleBackspaceAtEmpty = import_react68.useCallback(() => {
|
|
80859
81547
|
if (!isBashMode)
|
|
80860
81548
|
return false;
|
|
80861
81549
|
setIsBashMode(false);
|
|
80862
81550
|
return true;
|
|
80863
|
-
};
|
|
81551
|
+
}, [isBashMode]);
|
|
80864
81552
|
import_react68.useEffect(() => {
|
|
80865
81553
|
if (cursorPos !== undefined) {
|
|
80866
81554
|
const timer = setTimeout(() => setCursorPos(undefined), 0);
|
|
@@ -80881,9 +81569,6 @@ function Input({
|
|
|
80881
81569
|
setCurrentMode(externalMode);
|
|
80882
81570
|
}
|
|
80883
81571
|
}, [externalMode]);
|
|
80884
|
-
const [shimmerOffset, setShimmerOffset] = import_react68.useState(-3);
|
|
80885
|
-
const [elapsedMs, setElapsedMs] = import_react68.useState(0);
|
|
80886
|
-
const streamStartRef = import_react68.useRef(null);
|
|
80887
81572
|
import_react68.useEffect(() => {
|
|
80888
81573
|
if (!interactionEnabled) {
|
|
80889
81574
|
setIsAutocompleteActive(false);
|
|
@@ -81102,35 +81787,7 @@ function Input({
|
|
|
81102
81787
|
clearTimeout(ctrlCTimerRef.current);
|
|
81103
81788
|
};
|
|
81104
81789
|
}, []);
|
|
81105
|
-
import_react68.
|
|
81106
|
-
if (!streaming || !visible)
|
|
81107
|
-
return;
|
|
81108
|
-
const id = setInterval(() => {
|
|
81109
|
-
setShimmerOffset((prev) => {
|
|
81110
|
-
const prefixLen = agentName ? agentName.length + 1 : 0;
|
|
81111
|
-
const len = prefixLen + thinkingMessage.length;
|
|
81112
|
-
const next = prev + 1;
|
|
81113
|
-
return next > len + 3 ? -3 : next;
|
|
81114
|
-
});
|
|
81115
|
-
}, 120);
|
|
81116
|
-
return () => clearInterval(id);
|
|
81117
|
-
}, [streaming, thinkingMessage, visible, agentName]);
|
|
81118
|
-
import_react68.useEffect(() => {
|
|
81119
|
-
if (streaming && visible) {
|
|
81120
|
-
if (streamStartRef.current === null) {
|
|
81121
|
-
streamStartRef.current = performance.now();
|
|
81122
|
-
}
|
|
81123
|
-
const id = setInterval(() => {
|
|
81124
|
-
if (streamStartRef.current !== null) {
|
|
81125
|
-
setElapsedMs(performance.now() - streamStartRef.current);
|
|
81126
|
-
}
|
|
81127
|
-
}, 1000);
|
|
81128
|
-
return () => clearInterval(id);
|
|
81129
|
-
}
|
|
81130
|
-
streamStartRef.current = null;
|
|
81131
|
-
setElapsedMs(0);
|
|
81132
|
-
}, [streaming, visible]);
|
|
81133
|
-
const handleSubmit = async () => {
|
|
81790
|
+
const handleSubmit = import_react68.useCallback(async () => {
|
|
81134
81791
|
if (isAutocompleteActive) {
|
|
81135
81792
|
return;
|
|
81136
81793
|
}
|
|
@@ -81140,9 +81797,11 @@ function Input({
|
|
|
81140
81797
|
return;
|
|
81141
81798
|
if (bashRunning)
|
|
81142
81799
|
return;
|
|
81143
|
-
|
|
81144
|
-
|
|
81145
|
-
|
|
81800
|
+
setHistory((prev) => {
|
|
81801
|
+
if (previousValue.trim() === prev[prev.length - 1])
|
|
81802
|
+
return prev;
|
|
81803
|
+
return [...prev, previousValue];
|
|
81804
|
+
});
|
|
81146
81805
|
setHistoryIndex(-1);
|
|
81147
81806
|
setTemporaryInput("");
|
|
81148
81807
|
setValue("");
|
|
@@ -81151,8 +81810,12 @@ function Input({
|
|
|
81151
81810
|
}
|
|
81152
81811
|
return;
|
|
81153
81812
|
}
|
|
81154
|
-
if (previousValue.trim()
|
|
81155
|
-
setHistory(
|
|
81813
|
+
if (previousValue.trim()) {
|
|
81814
|
+
setHistory((prev) => {
|
|
81815
|
+
if (previousValue === prev[prev.length - 1])
|
|
81816
|
+
return prev;
|
|
81817
|
+
return [...prev, previousValue];
|
|
81818
|
+
});
|
|
81156
81819
|
}
|
|
81157
81820
|
setHistoryIndex(-1);
|
|
81158
81821
|
setTemporaryInput("");
|
|
@@ -81161,8 +81824,15 @@ function Input({
|
|
|
81161
81824
|
if (!result.submitted) {
|
|
81162
81825
|
setValue(previousValue);
|
|
81163
81826
|
}
|
|
81164
|
-
}
|
|
81165
|
-
|
|
81827
|
+
}, [
|
|
81828
|
+
isAutocompleteActive,
|
|
81829
|
+
value,
|
|
81830
|
+
isBashMode,
|
|
81831
|
+
bashRunning,
|
|
81832
|
+
onBashSubmit,
|
|
81833
|
+
onSubmit
|
|
81834
|
+
]);
|
|
81835
|
+
const handleFileSelect = import_react68.useCallback((selectedPath) => {
|
|
81166
81836
|
const atIndex = value.lastIndexOf("@");
|
|
81167
81837
|
if (atIndex === -1)
|
|
81168
81838
|
return;
|
|
@@ -81181,21 +81851,25 @@ function Input({
|
|
|
81181
81851
|
}
|
|
81182
81852
|
setValue(newValue);
|
|
81183
81853
|
setCursorPos(newCursorPos);
|
|
81184
|
-
};
|
|
81185
|
-
const handleCommandSelect = async (selectedCommand) => {
|
|
81854
|
+
}, [value]);
|
|
81855
|
+
const handleCommandSelect = import_react68.useCallback(async (selectedCommand) => {
|
|
81186
81856
|
const commandToSubmit = selectedCommand.trim();
|
|
81187
|
-
if (commandToSubmit
|
|
81188
|
-
setHistory(
|
|
81857
|
+
if (commandToSubmit) {
|
|
81858
|
+
setHistory((prev) => {
|
|
81859
|
+
if (commandToSubmit === prev[prev.length - 1])
|
|
81860
|
+
return prev;
|
|
81861
|
+
return [...prev, commandToSubmit];
|
|
81862
|
+
});
|
|
81189
81863
|
}
|
|
81190
81864
|
setHistoryIndex(-1);
|
|
81191
81865
|
setTemporaryInput("");
|
|
81192
81866
|
setValue("");
|
|
81193
81867
|
await onSubmit(commandToSubmit);
|
|
81194
|
-
};
|
|
81195
|
-
const handleCommandAutocomplete = (selectedCommand) => {
|
|
81868
|
+
}, [onSubmit]);
|
|
81869
|
+
const handleCommandAutocomplete = import_react68.useCallback((selectedCommand) => {
|
|
81196
81870
|
setValue(selectedCommand);
|
|
81197
81871
|
setCursorPos(selectedCommand.length);
|
|
81198
|
-
};
|
|
81872
|
+
}, []);
|
|
81199
81873
|
const modeInfo = import_react68.useMemo(() => {
|
|
81200
81874
|
if (ralphPending) {
|
|
81201
81875
|
if (ralphPendingYolo) {
|
|
@@ -81237,164 +81911,145 @@ function Input({
|
|
|
81237
81911
|
return null;
|
|
81238
81912
|
}
|
|
81239
81913
|
}, [ralphPending, ralphPendingYolo, ralphActive, currentMode]);
|
|
81240
|
-
const
|
|
81241
|
-
const
|
|
81242
|
-
|
|
81243
|
-
|
|
81244
|
-
|
|
81245
|
-
|
|
81246
|
-
|
|
81247
|
-
|
|
81248
|
-
|
|
81249
|
-
|
|
81250
|
-
|
|
81251
|
-
|
|
81252
|
-
|
|
81253
|
-
|
|
81254
|
-
|
|
81255
|
-
|
|
81256
|
-
|
|
81257
|
-
|
|
81258
|
-
|
|
81259
|
-
|
|
81260
|
-
|
|
81261
|
-
|
|
81262
|
-
|
|
81263
|
-
|
|
81264
|
-
|
|
81265
|
-
|
|
81266
|
-
|
|
81267
|
-
|
|
81268
|
-
|
|
81269
|
-
|
|
81270
|
-
|
|
81271
|
-
|
|
81914
|
+
const horizontalLine = import_react68.useMemo(() => "─".repeat(columns), [columns]);
|
|
81915
|
+
const lowerPane = import_react68.useMemo(() => {
|
|
81916
|
+
return /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(jsx_dev_runtime45.Fragment, {
|
|
81917
|
+
children: [
|
|
81918
|
+
messageQueue && messageQueue.length > 0 && /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(QueuedMessages, {
|
|
81919
|
+
messages: messageQueue
|
|
81920
|
+
}, undefined, false, undefined, this),
|
|
81921
|
+
interactionEnabled ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81922
|
+
flexDirection: "column",
|
|
81923
|
+
children: [
|
|
81924
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81925
|
+
dimColor: !isBashMode,
|
|
81926
|
+
color: isBashMode ? colors.bash.border : undefined,
|
|
81927
|
+
children: horizontalLine
|
|
81928
|
+
}, undefined, false, undefined, this),
|
|
81929
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81930
|
+
flexDirection: "row",
|
|
81931
|
+
children: [
|
|
81932
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81933
|
+
width: 2,
|
|
81934
|
+
flexShrink: 0,
|
|
81935
|
+
children: [
|
|
81936
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81937
|
+
color: isBashMode ? colors.bash.prompt : colors.input.prompt,
|
|
81938
|
+
children: isBashMode ? "!" : ">"
|
|
81939
|
+
}, undefined, false, undefined, this),
|
|
81940
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81941
|
+
children: " "
|
|
81942
|
+
}, undefined, false, undefined, this)
|
|
81943
|
+
]
|
|
81944
|
+
}, undefined, true, undefined, this),
|
|
81945
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81946
|
+
flexGrow: 1,
|
|
81947
|
+
width: contentWidth,
|
|
81948
|
+
children: /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(PasteAwareTextInput, {
|
|
81949
|
+
value,
|
|
81950
|
+
onChange: setValue,
|
|
81951
|
+
onSubmit: handleSubmit,
|
|
81952
|
+
cursorPosition: cursorPos,
|
|
81953
|
+
onCursorMove: setCurrentCursorPosition,
|
|
81954
|
+
focus: interactionEnabled && !onEscapeCancel,
|
|
81955
|
+
onBangAtEmpty: handleBangAtEmpty,
|
|
81956
|
+
onBackspaceAtEmpty: handleBackspaceAtEmpty,
|
|
81957
|
+
onPasteError
|
|
81958
|
+
}, undefined, false, undefined, this)
|
|
81959
|
+
}, undefined, false, undefined, this)
|
|
81960
|
+
]
|
|
81961
|
+
}, undefined, true, undefined, this),
|
|
81962
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81963
|
+
dimColor: !isBashMode,
|
|
81964
|
+
color: isBashMode ? colors.bash.border : undefined,
|
|
81965
|
+
children: horizontalLine
|
|
81966
|
+
}, undefined, false, undefined, this),
|
|
81967
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(InputAssist, {
|
|
81968
|
+
currentInput: value,
|
|
81969
|
+
cursorPosition: currentCursorPosition,
|
|
81970
|
+
onFileSelect: handleFileSelect,
|
|
81971
|
+
onCommandSelect: handleCommandSelect,
|
|
81972
|
+
onCommandAutocomplete: handleCommandAutocomplete,
|
|
81973
|
+
onAutocompleteActiveChange: setIsAutocompleteActive,
|
|
81974
|
+
agentId,
|
|
81975
|
+
agentName,
|
|
81976
|
+
serverUrl,
|
|
81977
|
+
workingDirectory: process.cwd(),
|
|
81978
|
+
conversationId
|
|
81979
|
+
}, undefined, false, undefined, this),
|
|
81980
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(InputFooter, {
|
|
81981
|
+
ctrlCPressed,
|
|
81982
|
+
escapePressed,
|
|
81983
|
+
isBashMode,
|
|
81984
|
+
modeName: modeInfo?.name ?? null,
|
|
81985
|
+
modeColor: modeInfo?.color ?? null,
|
|
81986
|
+
showExitHint: ralphActive || ralphPending,
|
|
81987
|
+
agentName,
|
|
81988
|
+
currentModel,
|
|
81989
|
+
isOpenAICodexProvider: currentModelProvider === OPENAI_CODEX_PROVIDER_NAME,
|
|
81990
|
+
isByokProvider: currentModelProvider?.startsWith("lc-") || currentModelProvider === OPENAI_CODEX_PROVIDER_NAME,
|
|
81991
|
+
hideFooter,
|
|
81992
|
+
rightColumnWidth: footerRightColumnWidth
|
|
81993
|
+
}, undefined, false, undefined, this)
|
|
81994
|
+
]
|
|
81995
|
+
}, undefined, true, undefined, this) : reserveInputSpace ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81996
|
+
height: inputChromeHeight
|
|
81997
|
+
}, undefined, false, undefined, this) : null
|
|
81998
|
+
]
|
|
81999
|
+
}, undefined, true, undefined, this);
|
|
81272
82000
|
}, [
|
|
81273
|
-
|
|
81274
|
-
|
|
81275
|
-
|
|
81276
|
-
|
|
81277
|
-
|
|
81278
|
-
|
|
81279
|
-
|
|
82001
|
+
messageQueue,
|
|
82002
|
+
interactionEnabled,
|
|
82003
|
+
isBashMode,
|
|
82004
|
+
horizontalLine,
|
|
82005
|
+
contentWidth,
|
|
82006
|
+
value,
|
|
82007
|
+
handleSubmit,
|
|
82008
|
+
cursorPos,
|
|
82009
|
+
onEscapeCancel,
|
|
82010
|
+
handleBangAtEmpty,
|
|
82011
|
+
handleBackspaceAtEmpty,
|
|
82012
|
+
onPasteError,
|
|
82013
|
+
currentCursorPosition,
|
|
82014
|
+
handleFileSelect,
|
|
82015
|
+
handleCommandSelect,
|
|
82016
|
+
handleCommandAutocomplete,
|
|
82017
|
+
agentId,
|
|
82018
|
+
agentName,
|
|
82019
|
+
serverUrl,
|
|
82020
|
+
conversationId,
|
|
82021
|
+
ctrlCPressed,
|
|
82022
|
+
escapePressed,
|
|
82023
|
+
modeInfo?.name,
|
|
82024
|
+
modeInfo?.color,
|
|
82025
|
+
ralphActive,
|
|
82026
|
+
ralphPending,
|
|
82027
|
+
currentModel,
|
|
82028
|
+
currentModelProvider,
|
|
82029
|
+
hideFooter,
|
|
82030
|
+
footerRightColumnWidth,
|
|
82031
|
+
reserveInputSpace,
|
|
82032
|
+
inputChromeHeight
|
|
81280
82033
|
]);
|
|
81281
|
-
const horizontalLine = import_react68.useMemo(() => "─".repeat(columns), [columns]);
|
|
81282
82034
|
if (!visible) {
|
|
81283
82035
|
return null;
|
|
81284
82036
|
}
|
|
81285
82037
|
return /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81286
82038
|
flexDirection: "column",
|
|
81287
82039
|
children: [
|
|
81288
|
-
|
|
81289
|
-
|
|
81290
|
-
|
|
81291
|
-
|
|
81292
|
-
|
|
81293
|
-
|
|
81294
|
-
|
|
81295
|
-
|
|
81296
|
-
|
|
81297
|
-
|
|
81298
|
-
|
|
81299
|
-
}, undefined, false, undefined, this)
|
|
81300
|
-
}, undefined, false, undefined, this)
|
|
81301
|
-
}, undefined, false, undefined, this),
|
|
81302
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81303
|
-
flexGrow: 1,
|
|
81304
|
-
flexDirection: "row",
|
|
81305
|
-
children: [
|
|
81306
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(ShimmerText, {
|
|
81307
|
-
boldPrefix: agentName || undefined,
|
|
81308
|
-
message: thinkingMessage,
|
|
81309
|
-
shimmerOffset
|
|
81310
|
-
}, undefined, false, undefined, this),
|
|
81311
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81312
|
-
children: statusHintText
|
|
81313
|
-
}, undefined, false, undefined, this)
|
|
81314
|
-
]
|
|
81315
|
-
}, undefined, true, undefined, this)
|
|
81316
|
-
]
|
|
81317
|
-
}, undefined, true, undefined, this),
|
|
81318
|
-
messageQueue && messageQueue.length > 0 && /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(QueuedMessages, {
|
|
81319
|
-
messages: messageQueue
|
|
82040
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(StreamingStatus, {
|
|
82041
|
+
streaming,
|
|
82042
|
+
visible,
|
|
82043
|
+
tokenCount,
|
|
82044
|
+
elapsedBaseMs,
|
|
82045
|
+
thinkingMessage,
|
|
82046
|
+
agentName,
|
|
82047
|
+
interruptRequested,
|
|
82048
|
+
networkPhase,
|
|
82049
|
+
terminalWidth: columns,
|
|
82050
|
+
shouldAnimate
|
|
81320
82051
|
}, undefined, false, undefined, this),
|
|
81321
|
-
|
|
81322
|
-
flexDirection: "column",
|
|
81323
|
-
children: [
|
|
81324
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81325
|
-
dimColor: !isBashMode,
|
|
81326
|
-
color: isBashMode ? colors.bash.border : undefined,
|
|
81327
|
-
children: horizontalLine
|
|
81328
|
-
}, undefined, false, undefined, this),
|
|
81329
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81330
|
-
flexDirection: "row",
|
|
81331
|
-
children: [
|
|
81332
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81333
|
-
width: 2,
|
|
81334
|
-
flexShrink: 0,
|
|
81335
|
-
children: [
|
|
81336
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81337
|
-
color: isBashMode ? colors.bash.prompt : colors.input.prompt,
|
|
81338
|
-
children: isBashMode ? "!" : ">"
|
|
81339
|
-
}, undefined, false, undefined, this),
|
|
81340
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81341
|
-
children: " "
|
|
81342
|
-
}, undefined, false, undefined, this)
|
|
81343
|
-
]
|
|
81344
|
-
}, undefined, true, undefined, this),
|
|
81345
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81346
|
-
flexGrow: 1,
|
|
81347
|
-
width: contentWidth,
|
|
81348
|
-
children: /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(PasteAwareTextInput, {
|
|
81349
|
-
value,
|
|
81350
|
-
onChange: setValue,
|
|
81351
|
-
onSubmit: handleSubmit,
|
|
81352
|
-
cursorPosition: cursorPos,
|
|
81353
|
-
onCursorMove: setCurrentCursorPosition,
|
|
81354
|
-
focus: interactionEnabled && !onEscapeCancel,
|
|
81355
|
-
onBangAtEmpty: handleBangAtEmpty,
|
|
81356
|
-
onBackspaceAtEmpty: handleBackspaceAtEmpty,
|
|
81357
|
-
onPasteError
|
|
81358
|
-
}, undefined, false, undefined, this)
|
|
81359
|
-
}, undefined, false, undefined, this)
|
|
81360
|
-
]
|
|
81361
|
-
}, undefined, true, undefined, this),
|
|
81362
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81363
|
-
dimColor: !isBashMode,
|
|
81364
|
-
color: isBashMode ? colors.bash.border : undefined,
|
|
81365
|
-
children: horizontalLine
|
|
81366
|
-
}, undefined, false, undefined, this),
|
|
81367
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(InputAssist, {
|
|
81368
|
-
currentInput: value,
|
|
81369
|
-
cursorPosition: currentCursorPosition,
|
|
81370
|
-
onFileSelect: handleFileSelect,
|
|
81371
|
-
onCommandSelect: handleCommandSelect,
|
|
81372
|
-
onCommandAutocomplete: handleCommandAutocomplete,
|
|
81373
|
-
onAutocompleteActiveChange: setIsAutocompleteActive,
|
|
81374
|
-
agentId,
|
|
81375
|
-
agentName,
|
|
81376
|
-
serverUrl,
|
|
81377
|
-
workingDirectory: process.cwd(),
|
|
81378
|
-
conversationId
|
|
81379
|
-
}, undefined, false, undefined, this),
|
|
81380
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(InputFooter, {
|
|
81381
|
-
ctrlCPressed,
|
|
81382
|
-
escapePressed,
|
|
81383
|
-
isBashMode,
|
|
81384
|
-
modeName: modeInfo?.name ?? null,
|
|
81385
|
-
modeColor: modeInfo?.color ?? null,
|
|
81386
|
-
showExitHint: ralphActive || ralphPending,
|
|
81387
|
-
agentName,
|
|
81388
|
-
currentModel,
|
|
81389
|
-
isOpenAICodexProvider: currentModelProvider === OPENAI_CODEX_PROVIDER_NAME,
|
|
81390
|
-
isByokProvider: currentModelProvider?.startsWith("lc-") || currentModelProvider === OPENAI_CODEX_PROVIDER_NAME,
|
|
81391
|
-
isAutocompleteActive,
|
|
81392
|
-
hideFooter
|
|
81393
|
-
}, undefined, false, undefined, this)
|
|
81394
|
-
]
|
|
81395
|
-
}, undefined, true, undefined, this) : reserveInputSpace ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81396
|
-
height: inputChromeHeight
|
|
81397
|
-
}, undefined, false, undefined, this) : null
|
|
82052
|
+
lowerPane
|
|
81398
82053
|
]
|
|
81399
82054
|
}, undefined, true, undefined, this);
|
|
81400
82055
|
}
|
|
@@ -81417,14 +82072,13 @@ function formatElapsedLabel(ms) {
|
|
|
81417
82072
|
}
|
|
81418
82073
|
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
81419
82074
|
}
|
|
81420
|
-
var import_react68, jsx_dev_runtime45, Spinner2, ESC_CLEAR_WINDOW_MS = 2500, InputFooter;
|
|
82075
|
+
var import_react68, jsx_dev_runtime45, Spinner2, ESC_CLEAR_WINDOW_MS = 2500, FOOTER_WIDTH_STREAMING_DELTA = 2, InputFooter, StreamingStatus;
|
|
81421
82076
|
var init_InputRich = __esm(async () => {
|
|
81422
82077
|
init_source();
|
|
81423
82078
|
init_oauth();
|
|
81424
82079
|
init_constants();
|
|
81425
82080
|
init_mode();
|
|
81426
82081
|
init_mode2();
|
|
81427
|
-
init_useTerminalWidth();
|
|
81428
82082
|
init_colors();
|
|
81429
82083
|
await __promiseAll([
|
|
81430
82084
|
init_build2(),
|
|
@@ -81451,78 +82105,249 @@ var init_InputRich = __esm(async () => {
|
|
|
81451
82105
|
currentModel,
|
|
81452
82106
|
isOpenAICodexProvider,
|
|
81453
82107
|
isByokProvider,
|
|
81454
|
-
|
|
81455
|
-
|
|
82108
|
+
hideFooter,
|
|
82109
|
+
rightColumnWidth
|
|
82110
|
+
}) {
|
|
82111
|
+
const hideFooterContent = hideFooter;
|
|
82112
|
+
const maxAgentChars = Math.max(10, Math.floor(rightColumnWidth * 0.45));
|
|
82113
|
+
const displayAgentName = truncateEnd(agentName || "Unnamed", maxAgentChars);
|
|
82114
|
+
const byokExtraChars = isByokProvider ? 2 : 0;
|
|
82115
|
+
const reservedChars = displayAgentName.length + byokExtraChars + 4;
|
|
82116
|
+
const maxModelChars = Math.max(8, rightColumnWidth - reservedChars);
|
|
82117
|
+
const displayModel = truncateEnd(currentModel ?? "unknown", maxModelChars);
|
|
82118
|
+
const rightTextLength = displayAgentName.length + displayModel.length + byokExtraChars + 3;
|
|
82119
|
+
const rightPrefixSpaces = Math.max(0, rightColumnWidth - rightTextLength);
|
|
82120
|
+
const rightLabel = import_react68.useMemo(() => {
|
|
82121
|
+
const parts = [];
|
|
82122
|
+
parts.push(" ".repeat(rightPrefixSpaces));
|
|
82123
|
+
parts.push(source_default.hex(colors.footer.agentName)(displayAgentName));
|
|
82124
|
+
parts.push(source_default.dim(" ["));
|
|
82125
|
+
parts.push(source_default.dim(displayModel));
|
|
82126
|
+
if (isByokProvider) {
|
|
82127
|
+
parts.push(source_default.dim(" "));
|
|
82128
|
+
parts.push(isOpenAICodexProvider ? source_default.hex("#74AA9C")("▲") : source_default.yellow("▲"));
|
|
82129
|
+
}
|
|
82130
|
+
parts.push(source_default.dim("]"));
|
|
82131
|
+
return parts.join("");
|
|
82132
|
+
}, [
|
|
82133
|
+
rightPrefixSpaces,
|
|
82134
|
+
displayAgentName,
|
|
82135
|
+
displayModel,
|
|
82136
|
+
isByokProvider,
|
|
82137
|
+
isOpenAICodexProvider
|
|
82138
|
+
]);
|
|
82139
|
+
return /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82140
|
+
flexDirection: "row",
|
|
82141
|
+
marginBottom: 1,
|
|
82142
|
+
children: [
|
|
82143
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82144
|
+
flexGrow: 1,
|
|
82145
|
+
paddingRight: 1,
|
|
82146
|
+
children: hideFooterContent ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82147
|
+
children: " "
|
|
82148
|
+
}, undefined, false, undefined, this) : ctrlCPressed ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82149
|
+
dimColor: true,
|
|
82150
|
+
children: "Press CTRL-C again to exit"
|
|
82151
|
+
}, undefined, false, undefined, this) : escapePressed ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82152
|
+
dimColor: true,
|
|
82153
|
+
children: "Press Esc again to clear"
|
|
82154
|
+
}, undefined, false, undefined, this) : isBashMode ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82155
|
+
children: [
|
|
82156
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82157
|
+
color: colors.bash.prompt,
|
|
82158
|
+
children: "⏵⏵ bash mode"
|
|
82159
|
+
}, undefined, false, undefined, this),
|
|
82160
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82161
|
+
color: colors.bash.prompt,
|
|
82162
|
+
dimColor: true,
|
|
82163
|
+
children: [
|
|
82164
|
+
" ",
|
|
82165
|
+
"(backspace to exit)"
|
|
82166
|
+
]
|
|
82167
|
+
}, undefined, true, undefined, this)
|
|
82168
|
+
]
|
|
82169
|
+
}, undefined, true, undefined, this) : modeName && modeColor ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82170
|
+
children: [
|
|
82171
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82172
|
+
color: modeColor,
|
|
82173
|
+
children: [
|
|
82174
|
+
"⏵⏵ ",
|
|
82175
|
+
modeName
|
|
82176
|
+
]
|
|
82177
|
+
}, undefined, true, undefined, this),
|
|
82178
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82179
|
+
color: modeColor,
|
|
82180
|
+
dimColor: true,
|
|
82181
|
+
children: [
|
|
82182
|
+
" ",
|
|
82183
|
+
"(shift+tab to ",
|
|
82184
|
+
showExitHint ? "exit" : "cycle",
|
|
82185
|
+
")"
|
|
82186
|
+
]
|
|
82187
|
+
}, undefined, true, undefined, this)
|
|
82188
|
+
]
|
|
82189
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82190
|
+
dimColor: true,
|
|
82191
|
+
children: "Press / for commands"
|
|
82192
|
+
}, undefined, false, undefined, this)
|
|
82193
|
+
}, undefined, false, undefined, this),
|
|
82194
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82195
|
+
width: rightColumnWidth,
|
|
82196
|
+
flexShrink: 0,
|
|
82197
|
+
children: hideFooterContent ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82198
|
+
children: " ".repeat(rightColumnWidth)
|
|
82199
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82200
|
+
children: rightLabel
|
|
82201
|
+
}, undefined, false, undefined, this)
|
|
82202
|
+
}, undefined, false, undefined, this)
|
|
82203
|
+
]
|
|
82204
|
+
}, undefined, true, undefined, this);
|
|
82205
|
+
});
|
|
82206
|
+
StreamingStatus = import_react68.memo(function StreamingStatus2({
|
|
82207
|
+
streaming,
|
|
82208
|
+
visible,
|
|
82209
|
+
tokenCount,
|
|
82210
|
+
elapsedBaseMs,
|
|
82211
|
+
thinkingMessage,
|
|
82212
|
+
agentName,
|
|
82213
|
+
interruptRequested,
|
|
82214
|
+
networkPhase,
|
|
82215
|
+
terminalWidth,
|
|
82216
|
+
shouldAnimate
|
|
81456
82217
|
}) {
|
|
81457
|
-
|
|
82218
|
+
const [shimmerOffset, setShimmerOffset] = import_react68.useState(-3);
|
|
82219
|
+
const [elapsedMs, setElapsedMs] = import_react68.useState(0);
|
|
82220
|
+
const streamStartRef = import_react68.useRef(null);
|
|
82221
|
+
import_react68.useEffect(() => {
|
|
82222
|
+
if (!streaming || !visible || !shouldAnimate)
|
|
82223
|
+
return;
|
|
82224
|
+
const id = setInterval(() => {
|
|
82225
|
+
setShimmerOffset((prev) => {
|
|
82226
|
+
const prefixLen = agentName ? agentName.length + 1 : 0;
|
|
82227
|
+
const len = prefixLen + thinkingMessage.length;
|
|
82228
|
+
const next = prev + 1;
|
|
82229
|
+
return next > len + 3 ? -3 : next;
|
|
82230
|
+
});
|
|
82231
|
+
}, 120);
|
|
82232
|
+
return () => clearInterval(id);
|
|
82233
|
+
}, [streaming, thinkingMessage, visible, agentName, shouldAnimate]);
|
|
82234
|
+
import_react68.useEffect(() => {
|
|
82235
|
+
if (!shouldAnimate) {
|
|
82236
|
+
setShimmerOffset(-3);
|
|
82237
|
+
}
|
|
82238
|
+
}, [shouldAnimate]);
|
|
82239
|
+
import_react68.useEffect(() => {
|
|
82240
|
+
if (streaming && visible) {
|
|
82241
|
+
if (streamStartRef.current === null) {
|
|
82242
|
+
streamStartRef.current = performance.now();
|
|
82243
|
+
}
|
|
82244
|
+
const id = setInterval(() => {
|
|
82245
|
+
if (streamStartRef.current !== null) {
|
|
82246
|
+
setElapsedMs(performance.now() - streamStartRef.current);
|
|
82247
|
+
}
|
|
82248
|
+
}, 1000);
|
|
82249
|
+
return () => clearInterval(id);
|
|
82250
|
+
}
|
|
82251
|
+
streamStartRef.current = null;
|
|
82252
|
+
setElapsedMs(0);
|
|
82253
|
+
}, [streaming, visible]);
|
|
82254
|
+
const estimatedTokens = charsToTokens(tokenCount);
|
|
82255
|
+
const totalElapsedMs = elapsedBaseMs + elapsedMs;
|
|
82256
|
+
const shouldShowTokenCount = streaming && estimatedTokens > TOKEN_DISPLAY_THRESHOLD;
|
|
82257
|
+
const shouldShowElapsed = streaming && totalElapsedMs > ELAPSED_DISPLAY_THRESHOLD_MS;
|
|
82258
|
+
const elapsedLabel = formatElapsedLabel(totalElapsedMs);
|
|
82259
|
+
const networkArrow = import_react68.useMemo(() => {
|
|
82260
|
+
if (!networkPhase)
|
|
82261
|
+
return "";
|
|
82262
|
+
if (networkPhase === "upload")
|
|
82263
|
+
return "↑";
|
|
82264
|
+
if (networkPhase === "download")
|
|
82265
|
+
return "↑";
|
|
82266
|
+
return "↑̸";
|
|
82267
|
+
}, [networkPhase]);
|
|
82268
|
+
const showErrorArrow = networkArrow === "↑̸";
|
|
82269
|
+
const statusContentWidth = Math.max(0, terminalWidth - 2);
|
|
82270
|
+
const minMessageWidth = 12;
|
|
82271
|
+
const statusHintParts = import_react68.useMemo(() => {
|
|
82272
|
+
const parts = [];
|
|
82273
|
+
if (shouldShowElapsed) {
|
|
82274
|
+
parts.push(elapsedLabel);
|
|
82275
|
+
}
|
|
82276
|
+
if (shouldShowTokenCount) {
|
|
82277
|
+
parts.push(`${formatCompact(estimatedTokens)}${networkArrow ? ` ${networkArrow}` : ""}`);
|
|
82278
|
+
} else if (showErrorArrow) {
|
|
82279
|
+
parts.push(networkArrow);
|
|
82280
|
+
}
|
|
82281
|
+
return parts;
|
|
82282
|
+
}, [
|
|
82283
|
+
shouldShowElapsed,
|
|
82284
|
+
elapsedLabel,
|
|
82285
|
+
shouldShowTokenCount,
|
|
82286
|
+
estimatedTokens,
|
|
82287
|
+
networkArrow,
|
|
82288
|
+
showErrorArrow
|
|
82289
|
+
]);
|
|
82290
|
+
const statusHintSuffix = statusHintParts.length ? ` · ${statusHintParts.join(" · ")}` : "";
|
|
82291
|
+
const statusHintPlain = interruptRequested ? ` (interrupting${statusHintSuffix})` : ` (esc to interrupt${statusHintSuffix})`;
|
|
82292
|
+
const statusHintWidth = Array.from(statusHintPlain).length;
|
|
82293
|
+
const maxHintWidth = Math.max(0, statusContentWidth - minMessageWidth);
|
|
82294
|
+
const hintColumnWidth = Math.max(0, Math.min(statusHintWidth, maxHintWidth));
|
|
82295
|
+
const maxMessageWidth = Math.max(0, statusContentWidth - hintColumnWidth);
|
|
82296
|
+
const statusLabel = `${agentName ? `${agentName} ` : ""}${thinkingMessage}…`;
|
|
82297
|
+
const statusLabelWidth = Array.from(statusLabel).length;
|
|
82298
|
+
const messageColumnWidth = Math.max(0, Math.min(maxMessageWidth, Math.max(minMessageWidth, statusLabelWidth)));
|
|
82299
|
+
const statusHintText = import_react68.useMemo(() => {
|
|
82300
|
+
const hintColor = source_default.hex(colors.subagent.hint);
|
|
82301
|
+
const hintBold = hintColor.bold;
|
|
82302
|
+
const suffix = `${statusHintSuffix})`;
|
|
82303
|
+
if (interruptRequested) {
|
|
82304
|
+
return hintColor(` (interrupting${suffix}`);
|
|
82305
|
+
}
|
|
82306
|
+
return hintColor(" (") + hintBold("esc") + hintColor(` to interrupt${suffix}`);
|
|
82307
|
+
}, [interruptRequested, statusHintSuffix]);
|
|
82308
|
+
if (!streaming || !visible) {
|
|
81458
82309
|
return null;
|
|
81459
82310
|
}
|
|
81460
82311
|
return /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
81461
|
-
|
|
82312
|
+
flexDirection: "row",
|
|
81462
82313
|
marginBottom: 1,
|
|
81463
82314
|
children: [
|
|
81464
|
-
|
|
81465
|
-
|
|
81466
|
-
|
|
81467
|
-
|
|
81468
|
-
|
|
81469
|
-
|
|
81470
|
-
|
|
81471
|
-
|
|
81472
|
-
|
|
81473
|
-
color: colors.bash.prompt,
|
|
81474
|
-
children: "⏵⏵ bash mode"
|
|
81475
|
-
}, undefined, false, undefined, this),
|
|
81476
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81477
|
-
color: colors.bash.prompt,
|
|
81478
|
-
dimColor: true,
|
|
81479
|
-
children: [
|
|
81480
|
-
" ",
|
|
81481
|
-
"(backspace to exit)"
|
|
81482
|
-
]
|
|
81483
|
-
}, undefined, true, undefined, this)
|
|
81484
|
-
]
|
|
81485
|
-
}, undefined, true, undefined, this) : modeName && modeColor ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81486
|
-
children: [
|
|
81487
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81488
|
-
color: modeColor,
|
|
81489
|
-
children: [
|
|
81490
|
-
"⏵⏵ ",
|
|
81491
|
-
modeName
|
|
81492
|
-
]
|
|
81493
|
-
}, undefined, true, undefined, this),
|
|
81494
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81495
|
-
color: modeColor,
|
|
81496
|
-
dimColor: true,
|
|
81497
|
-
children: [
|
|
81498
|
-
" ",
|
|
81499
|
-
"(shift+tab to ",
|
|
81500
|
-
showExitHint ? "exit" : "cycle",
|
|
81501
|
-
")"
|
|
81502
|
-
]
|
|
81503
|
-
}, undefined, true, undefined, this)
|
|
81504
|
-
]
|
|
81505
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
81506
|
-
dimColor: true,
|
|
81507
|
-
children: "Press / for commands"
|
|
82315
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82316
|
+
width: 2,
|
|
82317
|
+
flexShrink: 0,
|
|
82318
|
+
children: /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82319
|
+
color: colors.status.processing,
|
|
82320
|
+
children: shouldAnimate ? /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Spinner2, {
|
|
82321
|
+
type: "layer"
|
|
82322
|
+
}, undefined, false, undefined, this) : "●"
|
|
82323
|
+
}, undefined, false, undefined, this)
|
|
81508
82324
|
}, undefined, false, undefined, this),
|
|
81509
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(
|
|
82325
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82326
|
+
width: statusContentWidth,
|
|
82327
|
+
flexShrink: 0,
|
|
82328
|
+
flexDirection: "row",
|
|
81510
82329
|
children: [
|
|
81511
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(
|
|
81512
|
-
|
|
81513
|
-
|
|
82330
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82331
|
+
width: messageColumnWidth,
|
|
82332
|
+
flexShrink: 0,
|
|
82333
|
+
children: /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(ShimmerText, {
|
|
82334
|
+
boldPrefix: agentName || undefined,
|
|
82335
|
+
message: thinkingMessage,
|
|
82336
|
+
shimmerOffset: shouldAnimate ? shimmerOffset : -3,
|
|
82337
|
+
wrap: "truncate-end"
|
|
82338
|
+
}, undefined, false, undefined, this)
|
|
81514
82339
|
}, undefined, false, undefined, this),
|
|
81515
|
-
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(
|
|
81516
|
-
|
|
81517
|
-
|
|
81518
|
-
|
|
81519
|
-
|
|
81520
|
-
|
|
81521
|
-
|
|
81522
|
-
|
|
81523
|
-
|
|
81524
|
-
|
|
81525
|
-
}, undefined,
|
|
82340
|
+
hintColumnWidth > 0 && /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82341
|
+
width: hintColumnWidth,
|
|
82342
|
+
flexShrink: 0,
|
|
82343
|
+
children: /* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82344
|
+
wrap: "truncate-end",
|
|
82345
|
+
children: statusHintText
|
|
82346
|
+
}, undefined, false, undefined, this)
|
|
82347
|
+
}, undefined, false, undefined, this),
|
|
82348
|
+
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82349
|
+
flexGrow: 1
|
|
82350
|
+
}, undefined, false, undefined, this)
|
|
81526
82351
|
]
|
|
81527
82352
|
}, undefined, true, undefined, this)
|
|
81528
82353
|
]
|
|
@@ -84640,22 +85465,22 @@ function ModelSelector({
|
|
|
84640
85465
|
};
|
|
84641
85466
|
const getCategoryDescription = (cat) => {
|
|
84642
85467
|
if (cat === "server-recommended") {
|
|
84643
|
-
return "Recommended models
|
|
85468
|
+
return "Recommended models currently available for this account";
|
|
84644
85469
|
}
|
|
84645
85470
|
if (cat === "server-all") {
|
|
84646
|
-
return "All models
|
|
85471
|
+
return "All models currently available for this account";
|
|
84647
85472
|
}
|
|
84648
85473
|
if (cat === "supported") {
|
|
84649
|
-
return isFreeTier ? "Upgrade your account to access more models" : "Recommended models
|
|
85474
|
+
return isFreeTier ? "Upgrade your account to access more models" : "Recommended Letta API models currently available for this account";
|
|
84650
85475
|
}
|
|
84651
85476
|
if (cat === "byok")
|
|
84652
|
-
return "Recommended models via your API keys (use /connect to add more)";
|
|
85477
|
+
return "Recommended models via your connected API keys (use /connect to add more)";
|
|
84653
85478
|
if (cat === "byok-all")
|
|
84654
|
-
return "All models via your API keys (use /connect to add more)";
|
|
85479
|
+
return "All models via your connected API keys (use /connect to add more)";
|
|
84655
85480
|
if (cat === "all") {
|
|
84656
|
-
return isFreeTier ? "Upgrade your account to access more models" : "All models
|
|
85481
|
+
return isFreeTier ? "Upgrade your account to access more models" : "All Letta API models currently available for this account";
|
|
84657
85482
|
}
|
|
84658
|
-
return "All models
|
|
85483
|
+
return "All Letta API models currently available for this account";
|
|
84659
85484
|
};
|
|
84660
85485
|
const renderTabBar = () => /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
|
|
84661
85486
|
flexDirection: "row",
|
|
@@ -84815,7 +85640,7 @@ function ModelSelector({
|
|
|
84815
85640
|
currentList.length,
|
|
84816
85641
|
" models",
|
|
84817
85642
|
isCached ? " · cached" : "",
|
|
84818
|
-
" · R to refresh"
|
|
85643
|
+
" · R to refresh availability"
|
|
84819
85644
|
]
|
|
84820
85645
|
}, undefined, true, undefined, this),
|
|
84821
85646
|
/* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Text2, {
|
|
@@ -85431,11 +86256,11 @@ var init_byok_providers = __esm(async () => {
|
|
|
85431
86256
|
|
|
85432
86257
|
// src/utils/aws-credentials.ts
|
|
85433
86258
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
85434
|
-
import { homedir as
|
|
86259
|
+
import { homedir as homedir15 } from "node:os";
|
|
85435
86260
|
import { join as join26 } from "node:path";
|
|
85436
86261
|
async function parseAwsCredentials() {
|
|
85437
|
-
const credentialsPath = join26(
|
|
85438
|
-
const configPath = join26(
|
|
86262
|
+
const credentialsPath = join26(homedir15(), ".aws", "credentials");
|
|
86263
|
+
const configPath = join26(homedir15(), ".aws", "config");
|
|
85439
86264
|
const profiles = new Map;
|
|
85440
86265
|
try {
|
|
85441
86266
|
const content = await readFile12(credentialsPath, "utf-8");
|
|
@@ -88406,13 +89231,14 @@ function isShellTool2(name) {
|
|
|
88406
89231
|
var import_react85, jsx_dev_runtime65, ToolCallMessage;
|
|
88407
89232
|
var init_ToolCallMessageRich = __esm(async () => {
|
|
88408
89233
|
init_constants();
|
|
88409
|
-
init_formatArgsDisplay();
|
|
88410
89234
|
init_subagentState();
|
|
88411
89235
|
init_useTerminalWidth();
|
|
88412
89236
|
init_colors();
|
|
88413
89237
|
await __promiseAll([
|
|
88414
89238
|
init_build2(),
|
|
88415
89239
|
init_manager3(),
|
|
89240
|
+
init_formatArgsDisplay(),
|
|
89241
|
+
init_toolNameMapping(),
|
|
88416
89242
|
init_Text2(),
|
|
88417
89243
|
init_AdvancedDiffRenderer(),
|
|
88418
89244
|
init_BlinkDot(),
|
|
@@ -89153,7 +89979,8 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
89153
89979
|
streaming: line.streaming
|
|
89154
89980
|
}, undefined, false, undefined, this),
|
|
89155
89981
|
isShellTool2(rawName) && line.phase === "finished" && line.resultText && line.resultOk !== false && /* @__PURE__ */ jsx_dev_runtime65.jsxDEV(CollapsedOutputDisplay, {
|
|
89156
|
-
output: line.resultText
|
|
89982
|
+
output: line.resultText,
|
|
89983
|
+
maxChars: 300
|
|
89157
89984
|
}, undefined, false, undefined, this),
|
|
89158
89985
|
(() => {
|
|
89159
89986
|
const showDefaultResult = !isShellTool2(rawName) || line.phase === "finished" && line.resultOk === false || line.phase !== "running" && line.phase !== "finished";
|
|
@@ -90240,8 +91067,9 @@ function createSubagentGroupItem(taskToolCalls) {
|
|
|
90240
91067
|
agents
|
|
90241
91068
|
};
|
|
90242
91069
|
}
|
|
90243
|
-
var init_subagentAggregation = __esm(() => {
|
|
91070
|
+
var init_subagentAggregation = __esm(async () => {
|
|
90244
91071
|
init_subagentState();
|
|
91072
|
+
await init_toolNameMapping();
|
|
90245
91073
|
});
|
|
90246
91074
|
|
|
90247
91075
|
// src/cli/helpers/subagentTurnStart.ts
|
|
@@ -90414,7 +91242,7 @@ __export(exports_shellAliases, {
|
|
|
90414
91242
|
clearAliasCache: () => clearAliasCache
|
|
90415
91243
|
});
|
|
90416
91244
|
import { existsSync as existsSync16, readFileSync as readFileSync8 } from "node:fs";
|
|
90417
|
-
import { homedir as
|
|
91245
|
+
import { homedir as homedir16 } from "node:os";
|
|
90418
91246
|
import { join as join27 } from "node:path";
|
|
90419
91247
|
function parseAliasesFromFile(filePath) {
|
|
90420
91248
|
const aliases = new Map;
|
|
@@ -90484,7 +91312,7 @@ function loadAliases(forceReload = false) {
|
|
|
90484
91312
|
if (aliasCache && !forceReload) {
|
|
90485
91313
|
return aliasCache;
|
|
90486
91314
|
}
|
|
90487
|
-
const home =
|
|
91315
|
+
const home = homedir16();
|
|
90488
91316
|
const allAliases = new Map;
|
|
90489
91317
|
for (const file of ALIAS_FILES) {
|
|
90490
91318
|
const filePath = join27(home, file);
|
|
@@ -91105,21 +91933,6 @@ Use /disconnect codex to remove the current connection first.`, false);
|
|
|
91105
91933
|
ctx.setCommandRunning(true);
|
|
91106
91934
|
const cmdId = addCommandResult3(ctx.buffersRef, ctx.refreshDerived, msg, "Checking account eligibility...", true, "running");
|
|
91107
91935
|
try {
|
|
91108
|
-
const eligibility = await checkOpenAICodexEligibility();
|
|
91109
|
-
if (!eligibility.eligible) {
|
|
91110
|
-
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `✗ ChatGPT OAuth requires a Pro or Enterprise plan
|
|
91111
|
-
|
|
91112
|
-
` + `This feature is only available for Letta Pro or Enterprise customers.
|
|
91113
|
-
` + `Current plan: ${eligibility.billing_tier}
|
|
91114
|
-
|
|
91115
|
-
` + `To upgrade your plan, visit:
|
|
91116
|
-
|
|
91117
|
-
` + ` https://app.letta.com/settings/organization/usage
|
|
91118
|
-
|
|
91119
|
-
` + `If you have an OpenAI API key, you can use it directly by setting:
|
|
91120
|
-
` + ` export OPENAI_API_KEY=your-key`, false, "finished");
|
|
91121
|
-
return;
|
|
91122
|
-
}
|
|
91123
91936
|
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, `Starting OAuth flow...
|
|
91124
91937
|
A browser window will open for authorization.`, true, "running");
|
|
91125
91938
|
const { authorizationUrl, state, codeVerifier, redirectUri } = await startOpenAIOAuth(OPENAI_OAUTH_CONFIG.defaultPort);
|
|
@@ -91173,20 +91986,7 @@ Your ChatGPT Plus/Pro subscription is now linked.`, true, "finished");
|
|
|
91173
91986
|
} catch (error) {
|
|
91174
91987
|
settingsManager.clearOAuthState();
|
|
91175
91988
|
const errorMessage = getErrorMessage2(error);
|
|
91176
|
-
|
|
91177
|
-
if (errorMessage === "PLAN_UPGRADE_REQUIRED") {
|
|
91178
|
-
displayMessage = `✗ ChatGPT OAuth requires a Pro or Enterprise plan
|
|
91179
|
-
|
|
91180
|
-
` + `This feature is only available for Letta Pro or Enterprise customers.
|
|
91181
|
-
To upgrade your plan, visit:
|
|
91182
|
-
|
|
91183
|
-
https://app.letta.com/settings/organization/usage
|
|
91184
|
-
|
|
91185
|
-
If you have an OpenAI API key, you can use it directly by setting:
|
|
91186
|
-
export OPENAI_API_KEY=your-key`;
|
|
91187
|
-
} else {
|
|
91188
|
-
displayMessage = `✗ Failed to connect: ${errorMessage}`;
|
|
91189
|
-
}
|
|
91989
|
+
const displayMessage = `✗ Failed to connect: ${errorMessage}`;
|
|
91190
91990
|
updateCommandResult3(ctx.buffersRef, ctx.refreshDerived, cmdId, msg, displayMessage, false, "finished");
|
|
91191
91991
|
} finally {
|
|
91192
91992
|
ctx.setCommandRunning(false);
|
|
@@ -91495,7 +92295,7 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
91495
92295
|
console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
|
|
91496
92296
|
continue;
|
|
91497
92297
|
}
|
|
91498
|
-
const sourceUrl = await findSkillSourceUrl(entry.name);
|
|
92298
|
+
const sourceUrl = skillsDir ? null : await findSkillSourceUrl(entry.name);
|
|
91499
92299
|
const skill2 = { name: entry.name };
|
|
91500
92300
|
if (sourceUrl) {
|
|
91501
92301
|
skill2.source_url = sourceUrl;
|
|
@@ -91571,7 +92371,7 @@ __export(exports_App, {
|
|
|
91571
92371
|
default: () => App2
|
|
91572
92372
|
});
|
|
91573
92373
|
import { existsSync as existsSync17, readFileSync as readFileSync9, renameSync, writeFileSync as writeFileSync6 } from "node:fs";
|
|
91574
|
-
import { homedir as
|
|
92374
|
+
import { homedir as homedir17, tmpdir as tmpdir3 } from "node:os";
|
|
91575
92375
|
import { join as join28 } from "node:path";
|
|
91576
92376
|
function getErrorHintForStopReason(stopReason, currentModelId) {
|
|
91577
92377
|
if (currentModelId === "opus" && stopReason === "llm_api_error" && getModelInfo("bedrock-opus")) {
|
|
@@ -92228,18 +93028,93 @@ function App2({
|
|
|
92228
93028
|
setCommandRunning(false);
|
|
92229
93029
|
}
|
|
92230
93030
|
}, [setCommandRunning]);
|
|
92231
|
-
const
|
|
93031
|
+
const rawColumns = useTerminalWidth();
|
|
92232
93032
|
const terminalRows = useTerminalRows();
|
|
92233
|
-
const
|
|
92234
|
-
const
|
|
93033
|
+
const [stableColumns, setStableColumns] = import_react91.useState(rawColumns);
|
|
93034
|
+
const stableColumnsTimeoutRef = import_react91.useRef(null);
|
|
93035
|
+
const prevColumnsRef = import_react91.useRef(rawColumns);
|
|
93036
|
+
const lastClearedColumnsRef = import_react91.useRef(rawColumns);
|
|
92235
93037
|
const pendingResizeRef = import_react91.useRef(false);
|
|
92236
93038
|
const pendingResizeColumnsRef = import_react91.useRef(null);
|
|
92237
93039
|
const [staticRenderEpoch, setStaticRenderEpoch] = import_react91.useState(0);
|
|
92238
93040
|
const resizeClearTimeout = import_react91.useRef(null);
|
|
93041
|
+
const lastClearAtRef = import_react91.useRef(0);
|
|
92239
93042
|
const isInitialResizeRef = import_react91.useRef(true);
|
|
93043
|
+
const columns = stableColumns;
|
|
93044
|
+
const debugFlicker = process.env.LETTA_DEBUG_FLICKER === "1";
|
|
93045
|
+
import_react91.useEffect(() => {
|
|
93046
|
+
if (rawColumns === stableColumns) {
|
|
93047
|
+
if (stableColumnsTimeoutRef.current) {
|
|
93048
|
+
clearTimeout(stableColumnsTimeoutRef.current);
|
|
93049
|
+
stableColumnsTimeoutRef.current = null;
|
|
93050
|
+
}
|
|
93051
|
+
return;
|
|
93052
|
+
}
|
|
93053
|
+
const delta = Math.abs(rawColumns - stableColumns);
|
|
93054
|
+
if (delta >= MIN_RESIZE_DELTA) {
|
|
93055
|
+
if (stableColumnsTimeoutRef.current) {
|
|
93056
|
+
clearTimeout(stableColumnsTimeoutRef.current);
|
|
93057
|
+
stableColumnsTimeoutRef.current = null;
|
|
93058
|
+
}
|
|
93059
|
+
setStableColumns(rawColumns);
|
|
93060
|
+
return;
|
|
93061
|
+
}
|
|
93062
|
+
if (stableColumnsTimeoutRef.current) {
|
|
93063
|
+
clearTimeout(stableColumnsTimeoutRef.current);
|
|
93064
|
+
}
|
|
93065
|
+
stableColumnsTimeoutRef.current = setTimeout(() => {
|
|
93066
|
+
stableColumnsTimeoutRef.current = null;
|
|
93067
|
+
setStableColumns(rawColumns);
|
|
93068
|
+
}, STABLE_WIDTH_SETTLE_MS);
|
|
93069
|
+
}, [rawColumns, stableColumns]);
|
|
93070
|
+
const clearAndRemount = import_react91.useCallback((targetColumns) => {
|
|
93071
|
+
if (debugFlicker) {
|
|
93072
|
+
console.error(`[debug:flicker:clear-remount] target=${targetColumns} previousCleared=${lastClearedColumnsRef.current} raw=${prevColumnsRef.current}`);
|
|
93073
|
+
}
|
|
93074
|
+
if (typeof process !== "undefined" && process.stdout && "write" in process.stdout && process.stdout.isTTY) {
|
|
93075
|
+
process.stdout.write(CLEAR_SCREEN_AND_HOME);
|
|
93076
|
+
}
|
|
93077
|
+
setStaticRenderEpoch((epoch) => epoch + 1);
|
|
93078
|
+
lastClearedColumnsRef.current = targetColumns;
|
|
93079
|
+
lastClearAtRef.current = Date.now();
|
|
93080
|
+
}, [debugFlicker]);
|
|
93081
|
+
const scheduleResizeClear = import_react91.useCallback((targetColumns) => {
|
|
93082
|
+
if (targetColumns === lastClearedColumnsRef.current) {
|
|
93083
|
+
return;
|
|
93084
|
+
}
|
|
93085
|
+
if (resizeClearTimeout.current) {
|
|
93086
|
+
clearTimeout(resizeClearTimeout.current);
|
|
93087
|
+
resizeClearTimeout.current = null;
|
|
93088
|
+
}
|
|
93089
|
+
const elapsedSinceClear = Date.now() - lastClearAtRef.current;
|
|
93090
|
+
const rateLimitDelay = elapsedSinceClear >= MIN_CLEAR_INTERVAL_MS ? 0 : MIN_CLEAR_INTERVAL_MS - elapsedSinceClear;
|
|
93091
|
+
const delay = Math.max(RESIZE_SETTLE_MS, rateLimitDelay);
|
|
93092
|
+
if (debugFlicker) {
|
|
93093
|
+
console.error(`[debug:flicker:resize-schedule] target=${targetColumns} delay=${delay}ms elapsedSinceClear=${elapsedSinceClear}ms`);
|
|
93094
|
+
}
|
|
93095
|
+
resizeClearTimeout.current = setTimeout(() => {
|
|
93096
|
+
resizeClearTimeout.current = null;
|
|
93097
|
+
if (prevColumnsRef.current !== targetColumns) {
|
|
93098
|
+
if (debugFlicker) {
|
|
93099
|
+
console.error(`[debug:flicker:resize-skip] stale target=${targetColumns} currentRaw=${prevColumnsRef.current}`);
|
|
93100
|
+
}
|
|
93101
|
+
return;
|
|
93102
|
+
}
|
|
93103
|
+
if (targetColumns === lastClearedColumnsRef.current) {
|
|
93104
|
+
if (debugFlicker) {
|
|
93105
|
+
console.error(`[debug:flicker:resize-skip] already-cleared target=${targetColumns}`);
|
|
93106
|
+
}
|
|
93107
|
+
return;
|
|
93108
|
+
}
|
|
93109
|
+
if (debugFlicker) {
|
|
93110
|
+
console.error(`[debug:flicker:resize-fire] clear target=${targetColumns}`);
|
|
93111
|
+
}
|
|
93112
|
+
clearAndRemount(targetColumns);
|
|
93113
|
+
}, delay);
|
|
93114
|
+
}, [clearAndRemount, debugFlicker]);
|
|
92240
93115
|
import_react91.useEffect(() => {
|
|
92241
93116
|
const prev = prevColumnsRef.current;
|
|
92242
|
-
if (
|
|
93117
|
+
if (rawColumns === prev)
|
|
92243
93118
|
return;
|
|
92244
93119
|
if (resizeClearTimeout.current) {
|
|
92245
93120
|
clearTimeout(resizeClearTimeout.current);
|
|
@@ -92247,52 +93122,38 @@ function App2({
|
|
|
92247
93122
|
}
|
|
92248
93123
|
if (isInitialResizeRef.current) {
|
|
92249
93124
|
isInitialResizeRef.current = false;
|
|
92250
|
-
prevColumnsRef.current =
|
|
92251
|
-
lastClearedColumnsRef.current =
|
|
93125
|
+
prevColumnsRef.current = rawColumns;
|
|
93126
|
+
lastClearedColumnsRef.current = rawColumns;
|
|
92252
93127
|
return;
|
|
92253
93128
|
}
|
|
92254
|
-
const delta = Math.abs(
|
|
93129
|
+
const delta = Math.abs(rawColumns - prev);
|
|
92255
93130
|
const isMinorJitter = delta > 0 && delta < MIN_RESIZE_DELTA;
|
|
93131
|
+
if (isMinorJitter) {
|
|
93132
|
+
prevColumnsRef.current = rawColumns;
|
|
93133
|
+
return;
|
|
93134
|
+
}
|
|
92256
93135
|
if (streaming) {
|
|
92257
|
-
if (isMinorJitter) {
|
|
92258
|
-
prevColumnsRef.current = columns;
|
|
92259
|
-
return;
|
|
92260
|
-
}
|
|
92261
93136
|
pendingResizeRef.current = true;
|
|
92262
|
-
pendingResizeColumnsRef.current =
|
|
92263
|
-
prevColumnsRef.current =
|
|
93137
|
+
pendingResizeColumnsRef.current = rawColumns;
|
|
93138
|
+
prevColumnsRef.current = rawColumns;
|
|
92264
93139
|
return;
|
|
92265
93140
|
}
|
|
92266
|
-
if (
|
|
93141
|
+
if (rawColumns === lastClearedColumnsRef.current) {
|
|
92267
93142
|
pendingResizeRef.current = false;
|
|
92268
93143
|
pendingResizeColumnsRef.current = null;
|
|
92269
|
-
prevColumnsRef.current =
|
|
93144
|
+
prevColumnsRef.current = rawColumns;
|
|
92270
93145
|
return;
|
|
92271
93146
|
}
|
|
92272
|
-
|
|
92273
|
-
|
|
92274
|
-
|
|
92275
|
-
if (typeof process !== "undefined" && process.stdout && "write" in process.stdout && process.stdout.isTTY) {
|
|
92276
|
-
process.stdout.write(CLEAR_SCREEN_AND_HOME);
|
|
92277
|
-
}
|
|
92278
|
-
setStaticRenderEpoch((epoch) => epoch + 1);
|
|
92279
|
-
lastClearedColumnsRef.current = scheduledColumns;
|
|
92280
|
-
}, 150);
|
|
92281
|
-
prevColumnsRef.current = columns;
|
|
92282
|
-
return () => {
|
|
92283
|
-
if (resizeClearTimeout.current) {
|
|
92284
|
-
clearTimeout(resizeClearTimeout.current);
|
|
92285
|
-
resizeClearTimeout.current = null;
|
|
92286
|
-
}
|
|
92287
|
-
};
|
|
92288
|
-
}, [columns, streaming]);
|
|
93147
|
+
scheduleResizeClear(rawColumns);
|
|
93148
|
+
prevColumnsRef.current = rawColumns;
|
|
93149
|
+
}, [rawColumns, streaming, scheduleResizeClear]);
|
|
92289
93150
|
import_react91.useEffect(() => {
|
|
92290
93151
|
if (streaming) {
|
|
92291
93152
|
if (resizeClearTimeout.current) {
|
|
92292
93153
|
clearTimeout(resizeClearTimeout.current);
|
|
92293
93154
|
resizeClearTimeout.current = null;
|
|
92294
93155
|
pendingResizeRef.current = true;
|
|
92295
|
-
pendingResizeColumnsRef.current =
|
|
93156
|
+
pendingResizeColumnsRef.current = rawColumns;
|
|
92296
93157
|
}
|
|
92297
93158
|
return;
|
|
92298
93159
|
}
|
|
@@ -92305,12 +93166,20 @@ function App2({
|
|
|
92305
93166
|
return;
|
|
92306
93167
|
if (pendingColumns === lastClearedColumnsRef.current)
|
|
92307
93168
|
return;
|
|
92308
|
-
|
|
92309
|
-
|
|
92310
|
-
|
|
92311
|
-
|
|
92312
|
-
|
|
92313
|
-
|
|
93169
|
+
scheduleResizeClear(pendingColumns);
|
|
93170
|
+
}, [rawColumns, streaming, scheduleResizeClear]);
|
|
93171
|
+
import_react91.useEffect(() => {
|
|
93172
|
+
return () => {
|
|
93173
|
+
if (resizeClearTimeout.current) {
|
|
93174
|
+
clearTimeout(resizeClearTimeout.current);
|
|
93175
|
+
resizeClearTimeout.current = null;
|
|
93176
|
+
}
|
|
93177
|
+
if (stableColumnsTimeoutRef.current) {
|
|
93178
|
+
clearTimeout(stableColumnsTimeoutRef.current);
|
|
93179
|
+
stableColumnsTimeoutRef.current = null;
|
|
93180
|
+
}
|
|
93181
|
+
};
|
|
93182
|
+
}, []);
|
|
92314
93183
|
const deferredToolCallCommitsRef = import_react91.useRef(new Map);
|
|
92315
93184
|
const [deferredCommitAt, setDeferredCommitAt] = import_react91.useState(null);
|
|
92316
93185
|
const resetDeferredToolCallCommits = import_react91.useCallback(() => {
|
|
@@ -92909,7 +93778,7 @@ function App2({
|
|
|
92909
93778
|
continue;
|
|
92910
93779
|
if (!line.toolCallId || !line.name)
|
|
92911
93780
|
continue;
|
|
92912
|
-
if (line.name
|
|
93781
|
+
if (!isMemoryTool(line.name))
|
|
92913
93782
|
continue;
|
|
92914
93783
|
if (memorySyncProcessedToolCallsRef.current.has(line.toolCallId))
|
|
92915
93784
|
continue;
|
|
@@ -93980,7 +94849,9 @@ ${feedback}
|
|
|
93980
94849
|
};
|
|
93981
94850
|
const errorDetails = formatErrorDetails(errorObject, agentIdRef.current);
|
|
93982
94851
|
appendError(errorDetails, true);
|
|
93983
|
-
|
|
94852
|
+
if (!isEncryptedContentError(errorObject)) {
|
|
94853
|
+
appendError(getErrorHintForStopReason(stopReasonToHandle, currentModelId), true);
|
|
94854
|
+
}
|
|
93984
94855
|
} else {
|
|
93985
94856
|
appendError(`An error occurred during agent execution
|
|
93986
94857
|
(run_id: ${lastRunId}, stop_reason: ${stopReason})`, true);
|
|
@@ -96852,8 +97723,9 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
96852
97723
|
};
|
|
96853
97724
|
}
|
|
96854
97725
|
if (!selectedModel) {
|
|
96855
|
-
const
|
|
96856
|
-
cmd.
|
|
97726
|
+
const output = `Model not found: ${modelId}. Run /model and press R to refresh available models.`;
|
|
97727
|
+
const cmd = overlayCommand ?? commandRunner.start("/model", output);
|
|
97728
|
+
cmd.fail(output);
|
|
96857
97729
|
return;
|
|
96858
97730
|
}
|
|
96859
97731
|
const model = selectedModel;
|
|
@@ -96902,8 +97774,11 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
96902
97774
|
});
|
|
96903
97775
|
} catch (error) {
|
|
96904
97776
|
const errorDetails = formatErrorDetails(error, agentId);
|
|
96905
|
-
const
|
|
96906
|
-
|
|
97777
|
+
const modelLabel = selectedModel?.label ?? modelId;
|
|
97778
|
+
const guidance = "Run /model and press R to refresh available models. If the model is still unavailable, choose another model or connect a provider with /connect.";
|
|
97779
|
+
const cmd = overlayCommand ?? commandRunner.start("/model", `Failed to switch model to ${modelLabel}.`);
|
|
97780
|
+
cmd.fail(`Failed to switch model to ${modelLabel}: ${errorDetails}
|
|
97781
|
+
${guidance}`);
|
|
96907
97782
|
}
|
|
96908
97783
|
}, [
|
|
96909
97784
|
agentId,
|
|
@@ -97070,9 +97945,9 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
97070
97945
|
commandRunner.start
|
|
97071
97946
|
]);
|
|
97072
97947
|
const handleFeedbackSubmit = import_react91.useCallback(async (message) => {
|
|
97948
|
+
const overlayCommand = consumeOverlayCommand("feedback");
|
|
97073
97949
|
closeOverlay();
|
|
97074
97950
|
await withCommandLock(async () => {
|
|
97075
|
-
const overlayCommand = consumeOverlayCommand("feedback");
|
|
97076
97951
|
const cmd = overlayCommand ?? commandRunner.start("/feedback", "Sending feedback...");
|
|
97077
97952
|
try {
|
|
97078
97953
|
const resolvedMessage = resolvePlaceholders(message);
|
|
@@ -97279,7 +98154,7 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
97279
98154
|
}
|
|
97280
98155
|
if (!planFileExists()) {
|
|
97281
98156
|
const planFilePath = permissionMode2.getPlanFilePath();
|
|
97282
|
-
const plansDir = join28(
|
|
98157
|
+
const plansDir = join28(homedir17(), ".letta", "plans");
|
|
97283
98158
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
97284
98159
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
97285
98160
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -97435,7 +98310,7 @@ Plan file path: ${planFilePath}`;
|
|
|
97435
98310
|
deferredCommitAt
|
|
97436
98311
|
]);
|
|
97437
98312
|
const { agents: subagents } = import_react91.useSyncExternalStore(subscribe2, getSnapshot2);
|
|
97438
|
-
const
|
|
98313
|
+
const estimatedLiveHeight = import_react91.useMemo(() => {
|
|
97439
98314
|
const countLines4 = (text) => {
|
|
97440
98315
|
if (!text)
|
|
97441
98316
|
return 0;
|
|
@@ -97459,8 +98334,23 @@ Plan file path: ${planFilePath}`;
|
|
|
97459
98334
|
const subagentsHeight = subagents.length * LINES_PER_SUBAGENT;
|
|
97460
98335
|
const FIXED_BUFFER = 20;
|
|
97461
98336
|
const estimatedHeight = liveItemsHeight + subagentsHeight + FIXED_BUFFER;
|
|
97462
|
-
return estimatedHeight
|
|
97463
|
-
}, [liveItems,
|
|
98337
|
+
return estimatedHeight;
|
|
98338
|
+
}, [liveItems, subagents.length]);
|
|
98339
|
+
const [shouldAnimate, setShouldAnimate] = import_react91.useState(() => estimatedLiveHeight < terminalRows);
|
|
98340
|
+
import_react91.useEffect(() => {
|
|
98341
|
+
if (terminalRows <= 0) {
|
|
98342
|
+
setShouldAnimate(false);
|
|
98343
|
+
return;
|
|
98344
|
+
}
|
|
98345
|
+
const disableThreshold = terminalRows;
|
|
98346
|
+
const resumeThreshold = Math.max(0, terminalRows - ANIMATION_RESUME_HYSTERESIS_ROWS);
|
|
98347
|
+
setShouldAnimate((prev) => {
|
|
98348
|
+
if (prev) {
|
|
98349
|
+
return estimatedLiveHeight < disableThreshold;
|
|
98350
|
+
}
|
|
98351
|
+
return estimatedLiveHeight < resumeThreshold;
|
|
98352
|
+
});
|
|
98353
|
+
}, [estimatedLiveHeight, terminalRows]);
|
|
97464
98354
|
import_react91.useEffect(() => {
|
|
97465
98355
|
if (loadingState === "ready" && !welcomeCommittedRef.current && messageHistory.length === 0) {
|
|
97466
98356
|
if (!continueSession && !agentProvenance) {
|
|
@@ -97813,7 +98703,9 @@ Plan file path: ${planFilePath}`;
|
|
|
97813
98703
|
onPasteError: handlePasteError,
|
|
97814
98704
|
restoredInput,
|
|
97815
98705
|
onRestoredInputConsumed: () => setRestoredInput(null),
|
|
97816
|
-
networkPhase
|
|
98706
|
+
networkPhase,
|
|
98707
|
+
terminalWidth: columns,
|
|
98708
|
+
shouldAnimate
|
|
97817
98709
|
}, undefined, false, undefined, this)
|
|
97818
98710
|
}, undefined, false, undefined, this),
|
|
97819
98711
|
activeOverlay === "model" && /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(ModelSelector, {
|
|
@@ -98319,7 +99211,7 @@ Open /mcp to attach or detach tools for this server.`, true);
|
|
|
98319
99211
|
]
|
|
98320
99212
|
}, resumeKey, true, undefined, this);
|
|
98321
99213
|
}
|
|
98322
|
-
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;
|
|
99214
|
+
var import_react91, jsx_dev_runtime69, CLEAR_SCREEN_AND_HOME = "\x1B[2J\x1B[H", MIN_RESIZE_DELTA = 2, RESIZE_SETTLE_MS = 250, MIN_CLEAR_INTERVAL_MS = 750, STABLE_WIDTH_SETTLE_MS = 180, TOOL_CALL_COMMIT_DEFER_MS = 50, ANIMATION_RESUME_HYSTERESIS_ROWS = 2, 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;
|
|
98323
99215
|
var init_App2 = __esm(async () => {
|
|
98324
99216
|
init_error();
|
|
98325
99217
|
init_check_approval();
|
|
@@ -98341,12 +99233,10 @@ var init_App2 = __esm(async () => {
|
|
|
98341
99233
|
init_diff2();
|
|
98342
99234
|
init_errorContext();
|
|
98343
99235
|
init_errorFormatter();
|
|
98344
|
-
init_formatArgsDisplay();
|
|
98345
99236
|
init_messageQueueBridge();
|
|
98346
99237
|
init_pasteRegistry();
|
|
98347
99238
|
init_planName();
|
|
98348
99239
|
init_queuedMessageParts();
|
|
98349
|
-
init_subagentAggregation();
|
|
98350
99240
|
init_subagentState();
|
|
98351
99241
|
init_thinkingMessages();
|
|
98352
99242
|
init_useSyncedState();
|
|
@@ -98404,9 +99294,13 @@ var init_App2 = __esm(async () => {
|
|
|
98404
99294
|
init_WelcomeScreen(),
|
|
98405
99295
|
init_accumulator(),
|
|
98406
99296
|
init_approvalClassification(),
|
|
99297
|
+
init_formatArgsDisplay(),
|
|
98407
99298
|
init_memoryReminder(),
|
|
98408
99299
|
init_sessionContext(),
|
|
98409
99300
|
init_stream(),
|
|
99301
|
+
init_subagentAggregation(),
|
|
99302
|
+
init_toolNameMapping(),
|
|
99303
|
+
init_toolNameMapping(),
|
|
98410
99304
|
init_useSuspend()
|
|
98411
99305
|
]);
|
|
98412
99306
|
import_react91 = __toESM(require_react(), 1);
|
|
@@ -98466,7 +99360,7 @@ import {
|
|
|
98466
99360
|
readFileSync as readFileSync10,
|
|
98467
99361
|
writeFileSync as writeFileSync7
|
|
98468
99362
|
} from "node:fs";
|
|
98469
|
-
import { homedir as
|
|
99363
|
+
import { homedir as homedir18, platform as platform5 } from "node:os";
|
|
98470
99364
|
import { dirname as dirname14, join as join29 } from "node:path";
|
|
98471
99365
|
function detectTerminalType2() {
|
|
98472
99366
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
@@ -98499,7 +99393,7 @@ function getKeybindingsPath2(terminal) {
|
|
|
98499
99393
|
}[terminal];
|
|
98500
99394
|
const os6 = platform5();
|
|
98501
99395
|
if (os6 === "darwin") {
|
|
98502
|
-
return join29(
|
|
99396
|
+
return join29(homedir18(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
98503
99397
|
}
|
|
98504
99398
|
if (os6 === "win32") {
|
|
98505
99399
|
const appData = process.env.APPDATA;
|
|
@@ -98508,7 +99402,7 @@ function getKeybindingsPath2(terminal) {
|
|
|
98508
99402
|
return join29(appData, appName, "User", "keybindings.json");
|
|
98509
99403
|
}
|
|
98510
99404
|
if (os6 === "linux") {
|
|
98511
|
-
return join29(
|
|
99405
|
+
return join29(homedir18(), ".config", appName, "User", "keybindings.json");
|
|
98512
99406
|
}
|
|
98513
99407
|
return null;
|
|
98514
99408
|
}
|
|
@@ -98665,10 +99559,10 @@ function getWezTermConfigPath2() {
|
|
|
98665
99559
|
if (existsSync18(xdgPath))
|
|
98666
99560
|
return xdgPath;
|
|
98667
99561
|
}
|
|
98668
|
-
const configPath = join29(
|
|
99562
|
+
const configPath = join29(homedir18(), ".config", "wezterm", "wezterm.lua");
|
|
98669
99563
|
if (existsSync18(configPath))
|
|
98670
99564
|
return configPath;
|
|
98671
|
-
return join29(
|
|
99565
|
+
return join29(homedir18(), ".wezterm.lua");
|
|
98672
99566
|
}
|
|
98673
99567
|
function wezTermDeleteFixExists2(configPath) {
|
|
98674
99568
|
if (!existsSync18(configPath))
|
|
@@ -98766,10 +99660,10 @@ __export(exports_settings2, {
|
|
|
98766
99660
|
loadProjectSettings: () => loadProjectSettings2,
|
|
98767
99661
|
getSetting: () => getSetting2
|
|
98768
99662
|
});
|
|
98769
|
-
import { homedir as
|
|
99663
|
+
import { homedir as homedir19 } from "node:os";
|
|
98770
99664
|
import { join as join30 } from "node:path";
|
|
98771
99665
|
function getSettingsPath2() {
|
|
98772
|
-
return join30(
|
|
99666
|
+
return join30(homedir19(), ".letta", "settings.json");
|
|
98773
99667
|
}
|
|
98774
99668
|
async function loadSettings2() {
|
|
98775
99669
|
const settingsPath = getSettingsPath2();
|
|
@@ -99278,6 +100172,7 @@ var init_create3 = __esm(async () => {
|
|
|
99278
100172
|
// src/agent/import.ts
|
|
99279
100173
|
var exports_import2 = {};
|
|
99280
100174
|
__export(exports_import2, {
|
|
100175
|
+
importAgentFromRegistry: () => importAgentFromRegistry2,
|
|
99281
100176
|
importAgentFromFile: () => importAgentFromFile2,
|
|
99282
100177
|
extractSkillsFromAf: () => extractSkillsFromAf2
|
|
99283
100178
|
});
|
|
@@ -99385,6 +100280,45 @@ async function downloadGitHubDirectory2(entries, destDir, owner, repo, branch, b
|
|
|
99385
100280
|
}
|
|
99386
100281
|
}
|
|
99387
100282
|
}
|
|
100283
|
+
function parseRegistryHandle2(handle) {
|
|
100284
|
+
const normalized = handle.startsWith("@") ? handle.slice(1) : handle;
|
|
100285
|
+
const parts = normalized.split("/");
|
|
100286
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
100287
|
+
throw new Error(`Invalid import handle "${handle}". Use format: @author/agentname`);
|
|
100288
|
+
}
|
|
100289
|
+
return { author: parts[0], name: parts[1] };
|
|
100290
|
+
}
|
|
100291
|
+
async function importAgentFromRegistry2(options) {
|
|
100292
|
+
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
100293
|
+
const { join: join31 } = await import("node:path");
|
|
100294
|
+
const { writeFile: writeFile6, unlink: unlink2 } = await import("node:fs/promises");
|
|
100295
|
+
const { author, name } = parseRegistryHandle2(options.handle);
|
|
100296
|
+
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
100297
|
+
const response = await fetch(rawUrl);
|
|
100298
|
+
if (!response.ok) {
|
|
100299
|
+
if (response.status === 404) {
|
|
100300
|
+
throw new Error(`Agent @${author}/${name} not found in registry. Check that the agent exists at https://github.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/tree/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}`);
|
|
100301
|
+
}
|
|
100302
|
+
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
100303
|
+
}
|
|
100304
|
+
const afContent = await response.text();
|
|
100305
|
+
const tempPath = join31(tmpdir4(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
100306
|
+
await writeFile6(tempPath, afContent, "utf-8");
|
|
100307
|
+
try {
|
|
100308
|
+
const result = await importAgentFromFile2({
|
|
100309
|
+
filePath: tempPath,
|
|
100310
|
+
modelOverride: options.modelOverride,
|
|
100311
|
+
stripMessages: options.stripMessages ?? true,
|
|
100312
|
+
stripSkills: options.stripSkills ?? false
|
|
100313
|
+
});
|
|
100314
|
+
return result;
|
|
100315
|
+
} finally {
|
|
100316
|
+
try {
|
|
100317
|
+
await unlink2(tempPath);
|
|
100318
|
+
} catch {}
|
|
100319
|
+
}
|
|
100320
|
+
}
|
|
100321
|
+
var AGENT_REGISTRY_OWNER2 = "letta-ai", AGENT_REGISTRY_REPO2 = "agent-file", AGENT_REGISTRY_BRANCH2 = "main";
|
|
99388
100322
|
var init_import2 = __esm(async () => {
|
|
99389
100323
|
init_model();
|
|
99390
100324
|
await __promiseAll([
|
|
@@ -99485,7 +100419,7 @@ function buildModelSettings2(modelHandle, updateArgs) {
|
|
|
99485
100419
|
} else {
|
|
99486
100420
|
settings = {};
|
|
99487
100421
|
}
|
|
99488
|
-
if (typeof updateArgs?.max_output_tokens === "number") {
|
|
100422
|
+
if (typeof updateArgs?.max_output_tokens === "number" && "provider_type" in settings) {
|
|
99489
100423
|
settings.max_output_tokens = updateArgs.max_output_tokens;
|
|
99490
100424
|
}
|
|
99491
100425
|
return settings;
|
|
@@ -99498,7 +100432,10 @@ async function updateAgentLLMConfig2(agentId, modelHandle, updateArgs) {
|
|
|
99498
100432
|
await client.agents.update(agentId, {
|
|
99499
100433
|
model: modelHandle,
|
|
99500
100434
|
...hasModelSettings && { model_settings: modelSettings },
|
|
99501
|
-
...contextWindow && { context_window_limit: contextWindow }
|
|
100435
|
+
...contextWindow && { context_window_limit: contextWindow },
|
|
100436
|
+
...typeof updateArgs?.max_output_tokens === "number" && {
|
|
100437
|
+
max_tokens: updateArgs.max_output_tokens
|
|
100438
|
+
}
|
|
99502
100439
|
});
|
|
99503
100440
|
const finalAgent = await client.agents.retrieve(agentId);
|
|
99504
100441
|
return finalAgent.llm_config;
|
|
@@ -103326,6 +104263,8 @@ function releaseSwitchLock2() {
|
|
|
103326
104263
|
lock.resolve = null;
|
|
103327
104264
|
}
|
|
103328
104265
|
}
|
|
104266
|
+
var EXTERNAL_TOOLS_KEY2 = Symbol.for("@letta/externalTools");
|
|
104267
|
+
var EXTERNAL_EXECUTOR_KEY2 = Symbol.for("@letta/externalToolExecutor");
|
|
103329
104268
|
function replaceRegistry2(newTools) {
|
|
103330
104269
|
toolRegistry2.clear();
|
|
103331
104270
|
for (const [key, value] of newTools) {
|
|
@@ -103524,6 +104463,7 @@ OPTIONS
|
|
|
103524
104463
|
--skills <path> Custom path to skills directory (default: .skills in current directory)
|
|
103525
104464
|
--sleeptime Enable sleeptime memory management (only for new agents)
|
|
103526
104465
|
--from-af <path> Create agent from an AgentFile (.af) template
|
|
104466
|
+
Use @author/name to import from the agent registry
|
|
103527
104467
|
--memfs Enable memory filesystem for this agent
|
|
103528
104468
|
--no-memfs Disable memory filesystem for this agent
|
|
103529
104469
|
|
|
@@ -103973,6 +104913,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
103973
104913
|
process.exit(1);
|
|
103974
104914
|
}
|
|
103975
104915
|
}
|
|
104916
|
+
let isRegistryImport = false;
|
|
103976
104917
|
if (fromAfFile) {
|
|
103977
104918
|
if (specifiedAgentId) {
|
|
103978
104919
|
console.error("Error: --from-af cannot be used with --agent");
|
|
@@ -103990,12 +104931,22 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
103990
104931
|
console.error("Error: --from-af cannot be used with --new");
|
|
103991
104932
|
process.exit(1);
|
|
103992
104933
|
}
|
|
103993
|
-
|
|
103994
|
-
|
|
103995
|
-
|
|
103996
|
-
|
|
103997
|
-
|
|
103998
|
-
|
|
104934
|
+
if (fromAfFile.startsWith("@")) {
|
|
104935
|
+
isRegistryImport = true;
|
|
104936
|
+
const normalized = fromAfFile.slice(1);
|
|
104937
|
+
const parts = normalized.split("/");
|
|
104938
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
104939
|
+
console.error(`Error: Invalid registry handle "${fromAfFile}". Use format: @author/agentname`);
|
|
104940
|
+
process.exit(1);
|
|
104941
|
+
}
|
|
104942
|
+
} else {
|
|
104943
|
+
const { resolve: resolve23 } = await import("path");
|
|
104944
|
+
const { existsSync: existsSync19 } = await import("fs");
|
|
104945
|
+
const resolvedPath = resolve23(fromAfFile);
|
|
104946
|
+
if (!existsSync19(resolvedPath)) {
|
|
104947
|
+
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
104948
|
+
process.exit(1);
|
|
104949
|
+
}
|
|
103999
104950
|
}
|
|
104000
104951
|
}
|
|
104001
104952
|
if (specifiedAgentName) {
|
|
@@ -104139,7 +105090,8 @@ Error: ${message}`);
|
|
|
104139
105090
|
systemPromptPreset: systemPromptPreset2,
|
|
104140
105091
|
toolset,
|
|
104141
105092
|
skillsDirectory: skillsDirectory2,
|
|
104142
|
-
fromAfFile: fromAfFile2
|
|
105093
|
+
fromAfFile: fromAfFile2,
|
|
105094
|
+
isRegistryImport: isRegistryImport2
|
|
104143
105095
|
}) {
|
|
104144
105096
|
const [showKeybindingSetup, setShowKeybindingSetup] = useState45(null);
|
|
104145
105097
|
const [loadingState, setLoadingState] = useState45("selecting");
|
|
@@ -104436,13 +105388,24 @@ Error: ${message}`);
|
|
|
104436
105388
|
let isNewlyCreatedAgent = false;
|
|
104437
105389
|
if (fromAfFile2) {
|
|
104438
105390
|
setLoadingState("importing");
|
|
104439
|
-
|
|
104440
|
-
|
|
104441
|
-
|
|
104442
|
-
|
|
104443
|
-
|
|
104444
|
-
|
|
104445
|
-
|
|
105391
|
+
let result;
|
|
105392
|
+
if (isRegistryImport2) {
|
|
105393
|
+
const { importAgentFromRegistry: importAgentFromRegistry3 } = await init_import2().then(() => exports_import2);
|
|
105394
|
+
result = await importAgentFromRegistry3({
|
|
105395
|
+
handle: fromAfFile2,
|
|
105396
|
+
modelOverride: model,
|
|
105397
|
+
stripMessages: true,
|
|
105398
|
+
stripSkills: false
|
|
105399
|
+
});
|
|
105400
|
+
} else {
|
|
105401
|
+
const { importAgentFromFile: importAgentFromFile3 } = await init_import2().then(() => exports_import2);
|
|
105402
|
+
result = await importAgentFromFile3({
|
|
105403
|
+
filePath: fromAfFile2,
|
|
105404
|
+
modelOverride: model,
|
|
105405
|
+
stripMessages: true,
|
|
105406
|
+
stripSkills: false
|
|
105407
|
+
});
|
|
105408
|
+
}
|
|
104446
105409
|
agent = result.agent;
|
|
104447
105410
|
isNewlyCreatedAgent = true;
|
|
104448
105411
|
setAgentProvenance({
|
|
@@ -104802,11 +105765,12 @@ Error during initialization: ${message}`);
|
|
|
104802
105765
|
systemPromptPreset,
|
|
104803
105766
|
toolset: specifiedToolset,
|
|
104804
105767
|
skillsDirectory,
|
|
104805
|
-
fromAfFile
|
|
105768
|
+
fromAfFile,
|
|
105769
|
+
isRegistryImport
|
|
104806
105770
|
}), {
|
|
104807
105771
|
exitOnCtrlC: false
|
|
104808
105772
|
});
|
|
104809
105773
|
}
|
|
104810
105774
|
main();
|
|
104811
105775
|
|
|
104812
|
-
//# debugId=
|
|
105776
|
+
//# debugId=333508E0ED33A45564756E2164756E21
|