@letta-ai/letta-code 0.13.1 → 0.13.3
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
|
@@ -3065,7 +3065,7 @@ var package_default;
|
|
|
3065
3065
|
var init_package = __esm(() => {
|
|
3066
3066
|
package_default = {
|
|
3067
3067
|
name: "@letta-ai/letta-code",
|
|
3068
|
-
version: "0.13.
|
|
3068
|
+
version: "0.13.3",
|
|
3069
3069
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3070
3070
|
type: "module",
|
|
3071
3071
|
bin: {
|
|
@@ -5916,32 +5916,30 @@ var init_plan = () => {};
|
|
|
5916
5916
|
var recall_default = `---
|
|
5917
5917
|
name: recall
|
|
5918
5918
|
description: Search conversation history to recall past discussions, decisions, and context
|
|
5919
|
-
tools:
|
|
5920
|
-
model:
|
|
5921
|
-
memoryBlocks:
|
|
5919
|
+
tools: Bash, Read, BashOutput
|
|
5920
|
+
model: opus
|
|
5921
|
+
memoryBlocks: skills, loaded_skills
|
|
5922
|
+
skills: searching-messages
|
|
5922
5923
|
mode: stateless
|
|
5923
5924
|
---
|
|
5924
5925
|
|
|
5925
5926
|
You are a subagent launched via the Task tool to search conversation history. You run autonomously and return a single final report when done. You CANNOT ask questions mid-execution.
|
|
5926
5927
|
|
|
5927
|
-
##
|
|
5928
|
-
|
|
5929
|
-
### Step 1: Load the searching-messages skill
|
|
5930
|
-
\`\`\`
|
|
5931
|
-
Skill({ command: "load", skills: ["searching-messages"] })
|
|
5932
|
-
\`\`\`
|
|
5928
|
+
## CRITICAL WARNINGS
|
|
5933
5929
|
|
|
5934
|
-
|
|
5930
|
+
1. **NEVER use \`conversation_search\`** - It only searches YOUR empty history, not the parent's.
|
|
5931
|
+
2. **NEVER invent commands** - There is NO \`letta messages search\` or \`letta messages list\`. These don't exist.
|
|
5935
5932
|
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
**CRITICAL - Two rules:**
|
|
5933
|
+
## Instructions
|
|
5939
5934
|
|
|
5940
|
-
|
|
5935
|
+
The \`searching-messages\` skill is pre-loaded in your \`<loaded_skills>\` memory block below. Read it carefully - it contains:
|
|
5936
|
+
- \`# Skill Directory:\` - the exact path to use in commands
|
|
5937
|
+
- Multiple search strategies (needle + expand, date-bounded, broad discovery)
|
|
5938
|
+
- Command options and examples
|
|
5941
5939
|
|
|
5942
|
-
|
|
5940
|
+
**Follow the skill's strategies thoroughly.** Use multiple searches if needed to gather comprehensive context. Always add \`--agent-id $LETTA_PARENT_AGENT_ID\` to search the parent agent's history.
|
|
5943
5941
|
|
|
5944
|
-
|
|
5942
|
+
After gathering results, compile a comprehensive report.
|
|
5945
5943
|
|
|
5946
5944
|
## Output Format
|
|
5947
5945
|
|
|
@@ -8621,6 +8619,8 @@ Launch a subagent to perform a task. Parameters:
|
|
|
8621
8619
|
- **prompt**: Detailed, self-contained instructions for the agent (agents cannot ask questions mid-execution)
|
|
8622
8620
|
- **description**: Short 3-5 word summary for tracking
|
|
8623
8621
|
- **model** (optional): Override the model for this agent
|
|
8622
|
+
- **agent_id** (optional): Deploy an existing agent instead of creating a new one
|
|
8623
|
+
- **conversation_id** (optional): Resume from an existing conversation
|
|
8624
8624
|
|
|
8625
8625
|
### Refresh
|
|
8626
8626
|
Re-scan the \`.letta/agents/\` directories to discover new or updated custom subagents:
|
|
@@ -8652,6 +8652,57 @@ Use this after creating or modifying custom subagent definitions.
|
|
|
8652
8652
|
- **Parallel execution**: Launch multiple agents concurrently by calling Task multiple times in a single response
|
|
8653
8653
|
- **Specify return format**: Tell agents exactly what information to include in their report
|
|
8654
8654
|
|
|
8655
|
+
## Deploying an Existing Agent
|
|
8656
|
+
|
|
8657
|
+
Instead of spawning a fresh subagent from a template, you can deploy an existing agent to work in your local codebase.
|
|
8658
|
+
|
|
8659
|
+
### Access Levels (subagent_type)
|
|
8660
|
+
Use subagent_type to control what tools the deployed agent can access:
|
|
8661
|
+
- **explore**: Read-only access (Read, Glob, Grep) - safer for exploration tasks
|
|
8662
|
+
- **general-purpose**: Full read-write access (Bash, Edit, Write, etc.) - for implementation tasks
|
|
8663
|
+
|
|
8664
|
+
If subagent_type is not specified when deploying an existing agent, it defaults to "general-purpose".
|
|
8665
|
+
|
|
8666
|
+
### Parameters
|
|
8667
|
+
|
|
8668
|
+
- **agent_id**: The ID of an existing agent to deploy (e.g., "agent-abc123")
|
|
8669
|
+
- Starts a new conversation with that agent
|
|
8670
|
+
- The agent keeps its own system prompt and memory
|
|
8671
|
+
- Tool access is controlled by subagent_type
|
|
8672
|
+
|
|
8673
|
+
- **conversation_id**: Resume from an existing conversation (e.g., "conv-xyz789")
|
|
8674
|
+
- Does NOT require agent_id (conversation IDs are unique and encode the agent)
|
|
8675
|
+
- Continues from the conversation's existing message history
|
|
8676
|
+
- Use this to continue context from:
|
|
8677
|
+
- A prior Task tool invocation that returned a conversation_id
|
|
8678
|
+
- A message thread started via the messaging-agents skill
|
|
8679
|
+
|
|
8680
|
+
### Examples
|
|
8681
|
+
|
|
8682
|
+
\`\`\`typescript
|
|
8683
|
+
// Deploy agent with read-only access
|
|
8684
|
+
Task({
|
|
8685
|
+
agent_id: "agent-abc123",
|
|
8686
|
+
subagent_type: "explore",
|
|
8687
|
+
description: "Find auth code",
|
|
8688
|
+
prompt: "Find all auth-related code in this codebase"
|
|
8689
|
+
})
|
|
8690
|
+
|
|
8691
|
+
// Deploy agent with full access (default)
|
|
8692
|
+
Task({
|
|
8693
|
+
agent_id: "agent-abc123",
|
|
8694
|
+
description: "Fix auth bug",
|
|
8695
|
+
prompt: "Fix the bug in auth.ts"
|
|
8696
|
+
})
|
|
8697
|
+
|
|
8698
|
+
// Continue an existing conversation
|
|
8699
|
+
Task({
|
|
8700
|
+
conversation_id: "conv-xyz789",
|
|
8701
|
+
description: "Continue implementation",
|
|
8702
|
+
prompt: "Now implement the fix we discussed"
|
|
8703
|
+
})
|
|
8704
|
+
\`\`\`
|
|
8705
|
+
|
|
8655
8706
|
## Examples:
|
|
8656
8707
|
|
|
8657
8708
|
\`\`\`typescript
|
|
@@ -9675,6 +9726,7 @@ var init_truncation = __esm(() => {
|
|
|
9675
9726
|
init_overflow();
|
|
9676
9727
|
LIMITS = {
|
|
9677
9728
|
BASH_OUTPUT_CHARS: 30000,
|
|
9729
|
+
TASK_OUTPUT_CHARS: 30000,
|
|
9678
9730
|
READ_MAX_LINES: 2000,
|
|
9679
9731
|
READ_MAX_CHARS_PER_LINE: 2000,
|
|
9680
9732
|
GREP_OUTPUT_CHARS: 1e4,
|
|
@@ -19528,6 +19580,33 @@ ${pathLine}${processedContent}`;
|
|
|
19528
19580
|
throw new Error(`Failed to ${command} skill(s): ${String(error)}`);
|
|
19529
19581
|
}
|
|
19530
19582
|
}
|
|
19583
|
+
async function preloadSkillsContent(skillIds, skillsDir) {
|
|
19584
|
+
if (skillIds.length === 0) {
|
|
19585
|
+
return "No skills currently loaded.";
|
|
19586
|
+
}
|
|
19587
|
+
let content = "";
|
|
19588
|
+
for (const skillId of skillIds) {
|
|
19589
|
+
try {
|
|
19590
|
+
const { content: skillContent, path: skillPath } = await readSkillContent(skillId, skillsDir);
|
|
19591
|
+
const skillDir = dirname5(skillPath);
|
|
19592
|
+
const hasExtras = hasAdditionalFiles(skillPath);
|
|
19593
|
+
const pathLine = hasExtras ? `# Skill Directory: ${skillDir}
|
|
19594
|
+
|
|
19595
|
+
` : "";
|
|
19596
|
+
const processedContent = hasExtras ? skillContent.replace(/<SKILL_DIR>/g, skillDir) : skillContent;
|
|
19597
|
+
const separator = content ? `
|
|
19598
|
+
|
|
19599
|
+
---
|
|
19600
|
+
|
|
19601
|
+
` : "";
|
|
19602
|
+
content = `${content}${separator}# Skill: ${skillId}
|
|
19603
|
+
${pathLine}${processedContent}`;
|
|
19604
|
+
} catch (error) {
|
|
19605
|
+
console.error(`Warning: Could not pre-load skill "${skillId}": ${error instanceof Error ? error.message : String(error)}`);
|
|
19606
|
+
}
|
|
19607
|
+
}
|
|
19608
|
+
return content || "No skills currently loaded.";
|
|
19609
|
+
}
|
|
19531
19610
|
var init_Skill2 = __esm(async () => {
|
|
19532
19611
|
init_context();
|
|
19533
19612
|
init_skills2();
|
|
@@ -19822,6 +19901,9 @@ function handleInitEvent(event, state, baseURL, subagentId) {
|
|
|
19822
19901
|
const agentURL = `${baseURL}/agents/${event.agent_id}`;
|
|
19823
19902
|
updateSubagent(subagentId, { agentURL });
|
|
19824
19903
|
}
|
|
19904
|
+
if (event.conversation_id) {
|
|
19905
|
+
state.conversationId = event.conversation_id;
|
|
19906
|
+
}
|
|
19825
19907
|
}
|
|
19826
19908
|
function handleApprovalRequestEvent(event, state) {
|
|
19827
19909
|
const toolCalls = Array.isArray(event.tool_calls) ? event.tool_calls : event.tool_call ? [event.tool_call] : [];
|
|
@@ -19921,18 +20003,24 @@ function parseResultFromStdout(stdout, agentId) {
|
|
|
19921
20003
|
};
|
|
19922
20004
|
}
|
|
19923
20005
|
}
|
|
19924
|
-
function buildSubagentArgs(type, config, model, userPrompt) {
|
|
19925
|
-
const args = [
|
|
19926
|
-
|
|
19927
|
-
|
|
19928
|
-
|
|
19929
|
-
|
|
19930
|
-
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
"--
|
|
19934
|
-
|
|
19935
|
-
|
|
20006
|
+
function buildSubagentArgs(type, config, model, userPrompt, existingAgentId, existingConversationId, preloadedSkillsContent) {
|
|
20007
|
+
const args = [];
|
|
20008
|
+
const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
|
|
20009
|
+
if (isDeployingExisting) {
|
|
20010
|
+
if (existingConversationId) {
|
|
20011
|
+
args.push("--conv", existingConversationId);
|
|
20012
|
+
} else if (existingAgentId) {
|
|
20013
|
+
args.push("--agent", existingAgentId);
|
|
20014
|
+
}
|
|
20015
|
+
args.push("--no-skills");
|
|
20016
|
+
} else {
|
|
20017
|
+
args.push("--new-agent", "--system", type);
|
|
20018
|
+
if (model) {
|
|
20019
|
+
args.push("--model", model);
|
|
20020
|
+
}
|
|
20021
|
+
}
|
|
20022
|
+
args.push("-p", userPrompt);
|
|
20023
|
+
args.push("--output-format", "stream-json");
|
|
19936
20024
|
const subagentMode = config.permissionMode;
|
|
19937
20025
|
const parentMode = permissionMode.getMode();
|
|
19938
20026
|
const modeToUse = subagentMode || parentMode;
|
|
@@ -19941,8 +20029,9 @@ function buildSubagentArgs(type, config, model, userPrompt) {
|
|
|
19941
20029
|
}
|
|
19942
20030
|
const parentAllowedTools = cliPermissions.getAllowedTools();
|
|
19943
20031
|
const sessionAllowRules = sessionPermissions.getRules().allow || [];
|
|
20032
|
+
const subagentTools = config.allowedTools !== "all" && Array.isArray(config.allowedTools) ? config.allowedTools : [];
|
|
19944
20033
|
const combinedAllowedTools = [
|
|
19945
|
-
...new Set([...parentAllowedTools, ...sessionAllowRules])
|
|
20034
|
+
...new Set([...parentAllowedTools, ...sessionAllowRules, ...subagentTools])
|
|
19946
20035
|
];
|
|
19947
20036
|
if (combinedAllowedTools.length > 0) {
|
|
19948
20037
|
args.push("--allowedTools", combinedAllowedTools.join(","));
|
|
@@ -19951,17 +20040,22 @@ function buildSubagentArgs(type, config, model, userPrompt) {
|
|
|
19951
20040
|
if (parentDisallowedTools.length > 0) {
|
|
19952
20041
|
args.push("--disallowedTools", parentDisallowedTools.join(","));
|
|
19953
20042
|
}
|
|
19954
|
-
if (
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
20043
|
+
if (!isDeployingExisting) {
|
|
20044
|
+
if (config.memoryBlocks === "none") {
|
|
20045
|
+
args.push("--init-blocks", "none");
|
|
20046
|
+
} else if (Array.isArray(config.memoryBlocks) && config.memoryBlocks.length > 0) {
|
|
20047
|
+
args.push("--init-blocks", config.memoryBlocks.join(","));
|
|
20048
|
+
}
|
|
19958
20049
|
}
|
|
19959
20050
|
if (config.allowedTools !== "all" && Array.isArray(config.allowedTools) && config.allowedTools.length > 0) {
|
|
19960
20051
|
args.push("--tools", config.allowedTools.join(","));
|
|
19961
20052
|
}
|
|
20053
|
+
if (!isDeployingExisting && preloadedSkillsContent) {
|
|
20054
|
+
args.push("--block-value", `loaded_skills=${preloadedSkillsContent}`);
|
|
20055
|
+
}
|
|
19962
20056
|
return args;
|
|
19963
20057
|
}
|
|
19964
|
-
async function executeSubagent(type, config, model, userPrompt, baseURL, subagentId, isRetry = false, signal) {
|
|
20058
|
+
async function executeSubagent(type, config, model, userPrompt, baseURL, subagentId, isRetry = false, signal, existingAgentId, existingConversationId) {
|
|
19965
20059
|
if (signal?.aborted) {
|
|
19966
20060
|
return {
|
|
19967
20061
|
agentId: "",
|
|
@@ -19970,10 +20064,17 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
19970
20064
|
error: INTERRUPTED_BY_USER
|
|
19971
20065
|
};
|
|
19972
20066
|
}
|
|
19973
|
-
|
|
20067
|
+
if (model) {
|
|
20068
|
+
updateSubagent(subagentId, { model });
|
|
20069
|
+
}
|
|
19974
20070
|
try {
|
|
19975
|
-
|
|
19976
|
-
|
|
20071
|
+
let preloadedSkillsContent;
|
|
20072
|
+
if (config.skills && config.skills.length > 0) {
|
|
20073
|
+
preloadedSkillsContent = await preloadSkillsContent(config.skills, SKILLS_DIR);
|
|
20074
|
+
}
|
|
20075
|
+
const cliArgs = buildSubagentArgs(type, config, model, userPrompt, existingAgentId, existingConversationId, preloadedSkillsContent);
|
|
20076
|
+
const currentScript = process.argv[1] || "";
|
|
20077
|
+
const lettaCmd = process.env.LETTA_CODE_BIN || (currentScript.endsWith(".js") ? currentScript : null) || (currentScript.includes("src/index.ts") ? "./letta.js" : null) || "letta";
|
|
19977
20078
|
let parentAgentId;
|
|
19978
20079
|
try {
|
|
19979
20080
|
parentAgentId = getCurrentAgentId();
|
|
@@ -19995,7 +20096,8 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
19995
20096
|
const stdoutChunks = [];
|
|
19996
20097
|
const stderrChunks = [];
|
|
19997
20098
|
const state = {
|
|
19998
|
-
agentId: null,
|
|
20099
|
+
agentId: existingAgentId || null,
|
|
20100
|
+
conversationId: existingConversationId || null,
|
|
19999
20101
|
finalResult: null,
|
|
20000
20102
|
finalError: null,
|
|
20001
20103
|
resultStats: null,
|
|
@@ -20022,6 +20124,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
20022
20124
|
if (wasAborted) {
|
|
20023
20125
|
return {
|
|
20024
20126
|
agentId: state.agentId || "",
|
|
20127
|
+
conversationId: state.conversationId || undefined,
|
|
20025
20128
|
report: "",
|
|
20026
20129
|
success: false,
|
|
20027
20130
|
error: INTERRUPTED_BY_USER
|
|
@@ -20037,6 +20140,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
20037
20140
|
}
|
|
20038
20141
|
return {
|
|
20039
20142
|
agentId: state.agentId || "",
|
|
20143
|
+
conversationId: state.conversationId || undefined,
|
|
20040
20144
|
report: "",
|
|
20041
20145
|
success: false,
|
|
20042
20146
|
error: stderr || `Subagent exited with code ${exitCode}`
|
|
@@ -20045,6 +20149,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
20045
20149
|
if (state.finalResult !== null) {
|
|
20046
20150
|
return {
|
|
20047
20151
|
agentId: state.agentId || "",
|
|
20152
|
+
conversationId: state.conversationId || undefined,
|
|
20048
20153
|
report: state.finalResult,
|
|
20049
20154
|
success: !state.finalError,
|
|
20050
20155
|
error: state.finalError || undefined,
|
|
@@ -20054,6 +20159,7 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
20054
20159
|
if (state.finalError) {
|
|
20055
20160
|
return {
|
|
20056
20161
|
agentId: state.agentId || "",
|
|
20162
|
+
conversationId: state.conversationId || undefined,
|
|
20057
20163
|
report: "",
|
|
20058
20164
|
success: false,
|
|
20059
20165
|
error: state.finalError,
|
|
@@ -20079,7 +20185,17 @@ function getBaseURL() {
|
|
|
20079
20185
|
}
|
|
20080
20186
|
return baseURL;
|
|
20081
20187
|
}
|
|
20082
|
-
|
|
20188
|
+
function buildDeploySystemReminder(senderAgentName, senderAgentId, subagentType) {
|
|
20189
|
+
const toolDescription = subagentType === "explore" ? "read-only tools (Read, Glob, Grep)" : "local tools (Bash, Read, Write, Edit, etc.)";
|
|
20190
|
+
return `<system-reminder>
|
|
20191
|
+
This task is from "${senderAgentName}" (agent ID: ${senderAgentId}), which deployed you as a subagent inside the Letta Code CLI (docs.letta.com/letta-code).
|
|
20192
|
+
You have access to ${toolDescription} in their codebase.
|
|
20193
|
+
Your final message will be returned to the caller.
|
|
20194
|
+
</system-reminder>
|
|
20195
|
+
|
|
20196
|
+
`;
|
|
20197
|
+
}
|
|
20198
|
+
async function spawnSubagent(type, prompt, userModel, subagentId, signal, existingAgentId, existingConversationId) {
|
|
20083
20199
|
const allConfigs = await getAllSubagentConfigs();
|
|
20084
20200
|
const config = allConfigs[type];
|
|
20085
20201
|
if (!config) {
|
|
@@ -20090,9 +20206,20 @@ async function spawnSubagent(type, prompt, userModel, subagentId, signal) {
|
|
|
20090
20206
|
error: `Unknown subagent type: ${type}`
|
|
20091
20207
|
};
|
|
20092
20208
|
}
|
|
20093
|
-
const
|
|
20209
|
+
const isDeployingExisting = Boolean(existingAgentId || existingConversationId);
|
|
20210
|
+
const model = isDeployingExisting ? null : userModel || config.recommendedModel;
|
|
20094
20211
|
const baseURL = getBaseURL();
|
|
20095
|
-
|
|
20212
|
+
let finalPrompt = prompt;
|
|
20213
|
+
if (isDeployingExisting) {
|
|
20214
|
+
try {
|
|
20215
|
+
const parentAgentId = getCurrentAgentId();
|
|
20216
|
+
const client = await getClient2();
|
|
20217
|
+
const parentAgent = await client.agents.retrieve(parentAgentId);
|
|
20218
|
+
const systemReminder = buildDeploySystemReminder(parentAgent.name, parentAgentId, type);
|
|
20219
|
+
finalPrompt = systemReminder + prompt;
|
|
20220
|
+
} catch {}
|
|
20221
|
+
}
|
|
20222
|
+
const result = await executeSubagent(type, config, model, finalPrompt, baseURL, subagentId, false, signal, existingAgentId, existingConversationId);
|
|
20096
20223
|
return result;
|
|
20097
20224
|
}
|
|
20098
20225
|
var init_manager2 = __esm(async () => {
|
|
@@ -20103,9 +20230,11 @@ var init_manager2 = __esm(async () => {
|
|
|
20103
20230
|
init_session();
|
|
20104
20231
|
init_context();
|
|
20105
20232
|
init_model();
|
|
20233
|
+
init_skills2();
|
|
20106
20234
|
init_subagents();
|
|
20107
20235
|
await __promiseAll([
|
|
20108
20236
|
init_settings_manager(),
|
|
20237
|
+
init_Skill2(),
|
|
20109
20238
|
init_client2()
|
|
20110
20239
|
]);
|
|
20111
20240
|
});
|
|
@@ -20127,19 +20256,27 @@ async function task(args) {
|
|
|
20127
20256
|
const errorSuffix = errors.length > 0 ? `, ${errors.length} error(s)` : "";
|
|
20128
20257
|
return `Refreshed subagents list: found ${totalCount} total (${customCount} custom)${errorSuffix}`;
|
|
20129
20258
|
}
|
|
20130
|
-
|
|
20131
|
-
|
|
20259
|
+
const isDeployingExisting = Boolean(args.agent_id || args.conversation_id);
|
|
20260
|
+
if (isDeployingExisting) {
|
|
20261
|
+
validateRequiredParams(args, ["prompt", "description"], "Task");
|
|
20262
|
+
} else {
|
|
20263
|
+
validateRequiredParams(args, ["subagent_type", "prompt", "description"], "Task");
|
|
20264
|
+
}
|
|
20132
20265
|
const prompt = args.prompt;
|
|
20133
20266
|
const description = args.description;
|
|
20267
|
+
const subagent_type = isDeployingExisting ? args.subagent_type || "general-purpose" : args.subagent_type;
|
|
20134
20268
|
const allConfigs = await getAllSubagentConfigs();
|
|
20135
20269
|
if (!(subagent_type in allConfigs)) {
|
|
20136
20270
|
const available = Object.keys(allConfigs).join(", ");
|
|
20137
20271
|
return `Error: Invalid subagent type "${subagent_type}". Available types: ${available}`;
|
|
20138
20272
|
}
|
|
20273
|
+
if (isDeployingExisting && !VALID_DEPLOY_TYPES.has(subagent_type)) {
|
|
20274
|
+
return `Error: When deploying an existing agent, subagent_type must be "explore" (read-only) or "general-purpose" (read-write). Got: "${subagent_type}"`;
|
|
20275
|
+
}
|
|
20139
20276
|
const subagentId = generateSubagentId();
|
|
20140
20277
|
registerSubagent(subagentId, subagent_type, description, toolCallId);
|
|
20141
20278
|
try {
|
|
20142
|
-
const result = await spawnSubagent(subagent_type, prompt, model, subagentId, signal);
|
|
20279
|
+
const result = await spawnSubagent(subagent_type, prompt, model, subagentId, signal, args.agent_id, args.conversation_id);
|
|
20143
20280
|
completeSubagent(subagentId, {
|
|
20144
20281
|
success: result.success,
|
|
20145
20282
|
error: result.error,
|
|
@@ -20150,21 +20287,28 @@ async function task(args) {
|
|
|
20150
20287
|
}
|
|
20151
20288
|
const header = [
|
|
20152
20289
|
`subagent_type=${subagent_type}`,
|
|
20153
|
-
result.agentId ? `agent_id=${result.agentId}` : undefined
|
|
20290
|
+
result.agentId ? `agent_id=${result.agentId}` : undefined,
|
|
20291
|
+
result.conversationId ? `conversation_id=${result.conversationId}` : undefined
|
|
20154
20292
|
].filter(Boolean).join(" ");
|
|
20155
|
-
|
|
20293
|
+
const fullOutput = `${header}
|
|
20156
20294
|
|
|
20157
20295
|
${result.report}`;
|
|
20296
|
+
const userCwd = process.env.USER_CWD || process.cwd();
|
|
20297
|
+
const { content: truncatedOutput } = truncateByChars(fullOutput, LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: userCwd, toolName: "Task" });
|
|
20298
|
+
return truncatedOutput;
|
|
20158
20299
|
} catch (error) {
|
|
20159
20300
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
20160
20301
|
completeSubagent(subagentId, { success: false, error: errorMessage });
|
|
20161
20302
|
return `Error: ${errorMessage}`;
|
|
20162
20303
|
}
|
|
20163
20304
|
}
|
|
20305
|
+
var VALID_DEPLOY_TYPES;
|
|
20164
20306
|
var init_Task2 = __esm(async () => {
|
|
20165
20307
|
init_subagents();
|
|
20166
20308
|
init_subagentState();
|
|
20309
|
+
init_truncation();
|
|
20167
20310
|
await init_manager2();
|
|
20311
|
+
VALID_DEPLOY_TYPES = new Set(["explore", "general-purpose"]);
|
|
20168
20312
|
});
|
|
20169
20313
|
|
|
20170
20314
|
// src/tools/impl/TodoWrite.ts
|
|
@@ -24267,7 +24411,7 @@ var init_manager3 = __esm(async () => {
|
|
|
24267
24411
|
|
|
24268
24412
|
// src/agent/create.ts
|
|
24269
24413
|
import { join as join11 } from "node:path";
|
|
24270
|
-
async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel
|
|
24414
|
+
async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel, updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
|
|
24271
24415
|
let options;
|
|
24272
24416
|
if (typeof nameOrOptions === "object") {
|
|
24273
24417
|
options = nameOrOptions;
|
|
@@ -24286,7 +24430,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
24286
24430
|
};
|
|
24287
24431
|
}
|
|
24288
24432
|
const name = options.name ?? DEFAULT_AGENT_NAME;
|
|
24289
|
-
const embeddingModelVal = options.embeddingModel
|
|
24433
|
+
const embeddingModelVal = options.embeddingModel;
|
|
24290
24434
|
const parallelToolCallsVal = options.parallelToolCalls ?? true;
|
|
24291
24435
|
const enableSleeptimeVal = options.enableSleeptime ?? false;
|
|
24292
24436
|
let modelHandle;
|
|
@@ -24408,7 +24552,7 @@ ${options.systemPromptAppend}`;
|
|
|
24408
24552
|
system: systemPromptContent,
|
|
24409
24553
|
name,
|
|
24410
24554
|
description: agentDescription,
|
|
24411
|
-
embedding: embeddingModelVal,
|
|
24555
|
+
embedding: embeddingModelVal || undefined,
|
|
24412
24556
|
model: modelHandle,
|
|
24413
24557
|
context_window_limit: contextWindow,
|
|
24414
24558
|
tools: toolNames,
|
|
@@ -50487,6 +50631,103 @@ var init_auto_update = __esm(() => {
|
|
|
50487
50631
|
DEBUG = process.env.LETTA_DEBUG_AUTOUPDATE === "1";
|
|
50488
50632
|
});
|
|
50489
50633
|
|
|
50634
|
+
// src/tools/impl/overflow.ts
|
|
50635
|
+
var exports_overflow = {};
|
|
50636
|
+
__export(exports_overflow, {
|
|
50637
|
+
writeOverflowFile: () => writeOverflowFile2,
|
|
50638
|
+
getOverflowStats: () => getOverflowStats,
|
|
50639
|
+
getOverflowDirectory: () => getOverflowDirectory2,
|
|
50640
|
+
ensureOverflowDirectory: () => ensureOverflowDirectory2,
|
|
50641
|
+
cleanupOldOverflowFiles: () => cleanupOldOverflowFiles,
|
|
50642
|
+
OVERFLOW_CONFIG: () => OVERFLOW_CONFIG2
|
|
50643
|
+
});
|
|
50644
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
50645
|
+
import * as fs10 from "node:fs";
|
|
50646
|
+
import * as os3 from "node:os";
|
|
50647
|
+
import * as path18 from "node:path";
|
|
50648
|
+
function getOverflowDirectory2(workingDirectory) {
|
|
50649
|
+
const homeDir = os3.homedir();
|
|
50650
|
+
const lettaDir = path18.join(homeDir, ".letta");
|
|
50651
|
+
const normalizedPath = path18.normalize(workingDirectory);
|
|
50652
|
+
const sanitizedPath = normalizedPath.replace(/^[/\\]/, "").replace(/[/\\:]/g, "_").replace(/\s+/g, "_");
|
|
50653
|
+
const overflowDir = path18.join(lettaDir, "projects", sanitizedPath, "agent-tools");
|
|
50654
|
+
return overflowDir;
|
|
50655
|
+
}
|
|
50656
|
+
function ensureOverflowDirectory2(workingDirectory) {
|
|
50657
|
+
const overflowDir = getOverflowDirectory2(workingDirectory);
|
|
50658
|
+
if (!fs10.existsSync(overflowDir)) {
|
|
50659
|
+
fs10.mkdirSync(overflowDir, { recursive: true });
|
|
50660
|
+
}
|
|
50661
|
+
return overflowDir;
|
|
50662
|
+
}
|
|
50663
|
+
function writeOverflowFile2(content, workingDirectory, toolName) {
|
|
50664
|
+
const overflowDir = ensureOverflowDirectory2(workingDirectory);
|
|
50665
|
+
const uuid = randomUUID2();
|
|
50666
|
+
const filename = toolName ? `${toolName.toLowerCase()}-${uuid}.txt` : `${uuid}.txt`;
|
|
50667
|
+
const filePath = path18.join(overflowDir, filename);
|
|
50668
|
+
fs10.writeFileSync(filePath, content, "utf-8");
|
|
50669
|
+
return filePath;
|
|
50670
|
+
}
|
|
50671
|
+
function cleanupOldOverflowFiles(workingDirectory, maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
50672
|
+
const overflowDir = getOverflowDirectory2(workingDirectory);
|
|
50673
|
+
if (!fs10.existsSync(overflowDir)) {
|
|
50674
|
+
return 0;
|
|
50675
|
+
}
|
|
50676
|
+
let files;
|
|
50677
|
+
try {
|
|
50678
|
+
files = fs10.readdirSync(overflowDir);
|
|
50679
|
+
} catch {
|
|
50680
|
+
return 0;
|
|
50681
|
+
}
|
|
50682
|
+
const now = Date.now();
|
|
50683
|
+
let deletedCount = 0;
|
|
50684
|
+
for (const file of files) {
|
|
50685
|
+
const filePath = path18.join(overflowDir, file);
|
|
50686
|
+
try {
|
|
50687
|
+
const stats = fs10.statSync(filePath);
|
|
50688
|
+
if (stats.isDirectory()) {
|
|
50689
|
+
continue;
|
|
50690
|
+
}
|
|
50691
|
+
if (now - stats.mtimeMs > maxAgeMs) {
|
|
50692
|
+
fs10.unlinkSync(filePath);
|
|
50693
|
+
deletedCount++;
|
|
50694
|
+
}
|
|
50695
|
+
} catch {}
|
|
50696
|
+
}
|
|
50697
|
+
return deletedCount;
|
|
50698
|
+
}
|
|
50699
|
+
function getOverflowStats(workingDirectory) {
|
|
50700
|
+
const overflowDir = getOverflowDirectory2(workingDirectory);
|
|
50701
|
+
if (!fs10.existsSync(overflowDir)) {
|
|
50702
|
+
return {
|
|
50703
|
+
directory: overflowDir,
|
|
50704
|
+
exists: false,
|
|
50705
|
+
fileCount: 0,
|
|
50706
|
+
totalSize: 0
|
|
50707
|
+
};
|
|
50708
|
+
}
|
|
50709
|
+
const files = fs10.readdirSync(overflowDir);
|
|
50710
|
+
let totalSize = 0;
|
|
50711
|
+
for (const file of files) {
|
|
50712
|
+
const filePath = path18.join(overflowDir, file);
|
|
50713
|
+
const stats = fs10.statSync(filePath);
|
|
50714
|
+
totalSize += stats.size;
|
|
50715
|
+
}
|
|
50716
|
+
return {
|
|
50717
|
+
directory: overflowDir,
|
|
50718
|
+
exists: true,
|
|
50719
|
+
fileCount: files.length,
|
|
50720
|
+
totalSize
|
|
50721
|
+
};
|
|
50722
|
+
}
|
|
50723
|
+
var OVERFLOW_CONFIG2;
|
|
50724
|
+
var init_overflow2 = __esm(() => {
|
|
50725
|
+
OVERFLOW_CONFIG2 = {
|
|
50726
|
+
ENABLED: process.env.LETTA_TOOL_OVERFLOW_TO_FILE?.toLowerCase() !== "false",
|
|
50727
|
+
MIDDLE_TRUNCATE: process.env.LETTA_TOOL_MIDDLE_TRUNCATE?.toLowerCase() !== "false"
|
|
50728
|
+
};
|
|
50729
|
+
});
|
|
50730
|
+
|
|
50490
50731
|
// src/agent/promptAssets.ts
|
|
50491
50732
|
var exports_promptAssets2 = {};
|
|
50492
50733
|
__export(exports_promptAssets2, {
|
|
@@ -50620,9 +50861,9 @@ __export(exports_subagents2, {
|
|
|
50620
50861
|
GLOBAL_AGENTS_DIR: () => GLOBAL_AGENTS_DIR2,
|
|
50621
50862
|
AGENTS_DIR: () => AGENTS_DIR2
|
|
50622
50863
|
});
|
|
50623
|
-
import { existsSync as
|
|
50864
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
50624
50865
|
import { readdir as readdir6, readFile as readFile7 } from "node:fs/promises";
|
|
50625
|
-
import { join as
|
|
50866
|
+
import { join as join16 } from "node:path";
|
|
50626
50867
|
function isValidName2(name) {
|
|
50627
50868
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
50628
50869
|
}
|
|
@@ -50704,7 +50945,7 @@ function getBuiltinSubagentNames2() {
|
|
|
50704
50945
|
return new Set(Object.keys(getBuiltinSubagents2()));
|
|
50705
50946
|
}
|
|
50706
50947
|
async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors) {
|
|
50707
|
-
if (!
|
|
50948
|
+
if (!existsSync9(agentsDir)) {
|
|
50708
50949
|
return;
|
|
50709
50950
|
}
|
|
50710
50951
|
try {
|
|
@@ -50713,7 +50954,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
|
|
|
50713
50954
|
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
50714
50955
|
continue;
|
|
50715
50956
|
}
|
|
50716
|
-
const filePath =
|
|
50957
|
+
const filePath = join16(agentsDir, entry.name);
|
|
50717
50958
|
try {
|
|
50718
50959
|
const config = await parseSubagentFile2(filePath);
|
|
50719
50960
|
if (config) {
|
|
@@ -50745,7 +50986,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
|
|
|
50745
50986
|
const subagents = [];
|
|
50746
50987
|
const seenNames = new Set;
|
|
50747
50988
|
await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
|
|
50748
|
-
const projectAgentsDir =
|
|
50989
|
+
const projectAgentsDir = join16(workingDirectory, AGENTS_DIR2);
|
|
50749
50990
|
await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
|
|
50750
50991
|
return { subagents, errors };
|
|
50751
50992
|
}
|
|
@@ -50784,7 +51025,7 @@ var init_subagents2 = __esm(() => {
|
|
|
50784
51025
|
plan_default,
|
|
50785
51026
|
recall_default
|
|
50786
51027
|
];
|
|
50787
|
-
GLOBAL_AGENTS_DIR2 =
|
|
51028
|
+
GLOBAL_AGENTS_DIR2 = join16(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
|
|
50788
51029
|
VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
|
|
50789
51030
|
cache4 = {
|
|
50790
51031
|
builtins: null,
|
|
@@ -50794,10 +51035,10 @@ var init_subagents2 = __esm(() => {
|
|
|
50794
51035
|
});
|
|
50795
51036
|
|
|
50796
51037
|
// node_modules/is-docker/index.js
|
|
50797
|
-
import
|
|
51038
|
+
import fs11 from "node:fs";
|
|
50798
51039
|
function hasDockerEnv() {
|
|
50799
51040
|
try {
|
|
50800
|
-
|
|
51041
|
+
fs11.statSync("/.dockerenv");
|
|
50801
51042
|
return true;
|
|
50802
51043
|
} catch {
|
|
50803
51044
|
return false;
|
|
@@ -50805,7 +51046,7 @@ function hasDockerEnv() {
|
|
|
50805
51046
|
}
|
|
50806
51047
|
function hasDockerCGroup() {
|
|
50807
51048
|
try {
|
|
50808
|
-
return
|
|
51049
|
+
return fs11.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
50809
51050
|
} catch {
|
|
50810
51051
|
return false;
|
|
50811
51052
|
}
|
|
@@ -50820,7 +51061,7 @@ var isDockerCached;
|
|
|
50820
51061
|
var init_is_docker = () => {};
|
|
50821
51062
|
|
|
50822
51063
|
// node_modules/is-inside-container/index.js
|
|
50823
|
-
import
|
|
51064
|
+
import fs12 from "node:fs";
|
|
50824
51065
|
function isInsideContainer() {
|
|
50825
51066
|
if (cachedResult === undefined) {
|
|
50826
51067
|
cachedResult = hasContainerEnv() || isDocker();
|
|
@@ -50829,7 +51070,7 @@ function isInsideContainer() {
|
|
|
50829
51070
|
}
|
|
50830
51071
|
var cachedResult, hasContainerEnv = () => {
|
|
50831
51072
|
try {
|
|
50832
|
-
|
|
51073
|
+
fs12.statSync("/run/.containerenv");
|
|
50833
51074
|
return true;
|
|
50834
51075
|
} catch {
|
|
50835
51076
|
return false;
|
|
@@ -50841,20 +51082,20 @@ var init_is_inside_container = __esm(() => {
|
|
|
50841
51082
|
|
|
50842
51083
|
// node_modules/is-wsl/index.js
|
|
50843
51084
|
import process13 from "node:process";
|
|
50844
|
-
import
|
|
50845
|
-
import
|
|
51085
|
+
import os4 from "node:os";
|
|
51086
|
+
import fs13 from "node:fs";
|
|
50846
51087
|
var isWsl = () => {
|
|
50847
51088
|
if (process13.platform !== "linux") {
|
|
50848
51089
|
return false;
|
|
50849
51090
|
}
|
|
50850
|
-
if (
|
|
51091
|
+
if (os4.release().toLowerCase().includes("microsoft")) {
|
|
50851
51092
|
if (isInsideContainer()) {
|
|
50852
51093
|
return false;
|
|
50853
51094
|
}
|
|
50854
51095
|
return true;
|
|
50855
51096
|
}
|
|
50856
51097
|
try {
|
|
50857
|
-
return
|
|
51098
|
+
return fs13.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
50858
51099
|
} catch {
|
|
50859
51100
|
return false;
|
|
50860
51101
|
}
|
|
@@ -50866,7 +51107,7 @@ var init_is_wsl = __esm(() => {
|
|
|
50866
51107
|
|
|
50867
51108
|
// node_modules/wsl-utils/index.js
|
|
50868
51109
|
import process14 from "node:process";
|
|
50869
|
-
import
|
|
51110
|
+
import fs14, { constants as fsConstants } from "node:fs/promises";
|
|
50870
51111
|
var wslDrivesMountPoint, powerShellPathFromWsl = async () => {
|
|
50871
51112
|
const mountPoint = await wslDrivesMountPoint();
|
|
50872
51113
|
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
@@ -50889,13 +51130,13 @@ var init_wsl_utils = __esm(() => {
|
|
|
50889
51130
|
const configFilePath = "/etc/wsl.conf";
|
|
50890
51131
|
let isConfigFileExists = false;
|
|
50891
51132
|
try {
|
|
50892
|
-
await
|
|
51133
|
+
await fs14.access(configFilePath, fsConstants.F_OK);
|
|
50893
51134
|
isConfigFileExists = true;
|
|
50894
51135
|
} catch {}
|
|
50895
51136
|
if (!isConfigFileExists) {
|
|
50896
51137
|
return defaultMountPoint;
|
|
50897
51138
|
}
|
|
50898
|
-
const configContent = await
|
|
51139
|
+
const configContent = await fs14.readFile(configFilePath, { encoding: "utf8" });
|
|
50899
51140
|
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
50900
51141
|
if (!configMountPoint) {
|
|
50901
51142
|
return defaultMountPoint;
|
|
@@ -51049,11 +51290,11 @@ __export(exports_open, {
|
|
|
51049
51290
|
});
|
|
51050
51291
|
import process18 from "node:process";
|
|
51051
51292
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
51052
|
-
import
|
|
51293
|
+
import path19 from "node:path";
|
|
51053
51294
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
51054
51295
|
import { promisify as promisify8 } from "node:util";
|
|
51055
51296
|
import childProcess from "node:child_process";
|
|
51056
|
-
import
|
|
51297
|
+
import fs15, { constants as fsConstants2 } from "node:fs/promises";
|
|
51057
51298
|
async function getWindowsDefaultBrowserFromWsl() {
|
|
51058
51299
|
const powershellPath = await powerShellPath();
|
|
51059
51300
|
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
@@ -51210,7 +51451,7 @@ var execFile7, __dirname2, localXdgOpenPath, platform2, arch, pTryEach = async (
|
|
|
51210
51451
|
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
51211
51452
|
let exeLocalXdgOpen = false;
|
|
51212
51453
|
try {
|
|
51213
|
-
await
|
|
51454
|
+
await fs15.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
51214
51455
|
exeLocalXdgOpen = true;
|
|
51215
51456
|
} catch {}
|
|
51216
51457
|
const useSystemXdgOpen = process18.versions.electron ?? (platform2 === "android" || isBundled || !exeLocalXdgOpen);
|
|
@@ -51274,8 +51515,8 @@ var init_open = __esm(() => {
|
|
|
51274
51515
|
init_default_browser();
|
|
51275
51516
|
init_is_inside_container();
|
|
51276
51517
|
execFile7 = promisify8(childProcess.execFile);
|
|
51277
|
-
__dirname2 =
|
|
51278
|
-
localXdgOpenPath =
|
|
51518
|
+
__dirname2 = path19.dirname(fileURLToPath8(import.meta.url));
|
|
51519
|
+
localXdgOpenPath = path19.join(__dirname2, "xdg-open");
|
|
51279
51520
|
({ platform: platform2, arch } = process18);
|
|
51280
51521
|
apps = {};
|
|
51281
51522
|
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
@@ -52998,7 +53239,7 @@ __export(exports_approval_execution, {
|
|
|
52998
53239
|
executeAutoAllowedTools: () => executeAutoAllowedTools,
|
|
52999
53240
|
executeApprovalBatch: () => executeApprovalBatch
|
|
53000
53241
|
});
|
|
53001
|
-
import * as
|
|
53242
|
+
import * as path20 from "node:path";
|
|
53002
53243
|
function isParallelSafe(toolName) {
|
|
53003
53244
|
return PARALLEL_SAFE_TOOLS.has(toolName);
|
|
53004
53245
|
}
|
|
@@ -53010,7 +53251,7 @@ function getResourceKey(toolName, toolArgs) {
|
|
|
53010
53251
|
const filePath = toolArgs.file_path;
|
|
53011
53252
|
if (typeof filePath === "string") {
|
|
53012
53253
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
53013
|
-
return
|
|
53254
|
+
return path20.isAbsolute(filePath) ? path20.normalize(filePath) : path20.resolve(userCwd, filePath);
|
|
53014
53255
|
}
|
|
53015
53256
|
}
|
|
53016
53257
|
return "__global__";
|
|
@@ -53281,7 +53522,8 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
|
|
|
53281
53522
|
sleeptime: { type: "boolean" },
|
|
53282
53523
|
"init-blocks": { type: "string" },
|
|
53283
53524
|
"base-tools": { type: "string" },
|
|
53284
|
-
"from-af": { type: "string" }
|
|
53525
|
+
"from-af": { type: "string" },
|
|
53526
|
+
"no-skills": { type: "boolean" }
|
|
53285
53527
|
},
|
|
53286
53528
|
strict: false,
|
|
53287
53529
|
allowPositionals: true
|
|
@@ -53596,7 +53838,18 @@ Usage: letta -p "..." --new-agent`);
|
|
|
53596
53838
|
}
|
|
53597
53839
|
}
|
|
53598
53840
|
let conversationId;
|
|
53599
|
-
const
|
|
53841
|
+
const noSkillsFlag = values["no-skills"];
|
|
53842
|
+
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
53843
|
+
if (!noSkillsFlag && !isSubagent) {
|
|
53844
|
+
const createdBlocks = await ensureSkillsBlocks(agent.id);
|
|
53845
|
+
if (createdBlocks.length > 0) {
|
|
53846
|
+
console.log("Created missing skills blocks for agent compatibility");
|
|
53847
|
+
}
|
|
53848
|
+
}
|
|
53849
|
+
let isolatedBlockLabels = [];
|
|
53850
|
+
if (!noSkillsFlag) {
|
|
53851
|
+
isolatedBlockLabels = initBlocks === undefined ? [...ISOLATED_BLOCK_LABELS] : ISOLATED_BLOCK_LABELS.filter((label) => initBlocks.includes(label));
|
|
53852
|
+
}
|
|
53600
53853
|
if (specifiedConversationId) {
|
|
53601
53854
|
if (specifiedConversationId === "default") {
|
|
53602
53855
|
conversationId = "default";
|
|
@@ -53642,7 +53895,6 @@ Usage: letta -p "..." --new-agent`);
|
|
|
53642
53895
|
conversationId = conversation.id;
|
|
53643
53896
|
}
|
|
53644
53897
|
markMilestone("HEADLESS_CONVERSATION_READY");
|
|
53645
|
-
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
53646
53898
|
if (!isSubagent) {
|
|
53647
53899
|
await settingsManager.loadLocalProjectSettings();
|
|
53648
53900
|
settingsManager.setLocalLastSession({ agentId: agent.id, conversationId }, process.cwd());
|
|
@@ -53651,24 +53903,22 @@ Usage: letta -p "..." --new-agent`);
|
|
|
53651
53903
|
conversationId
|
|
53652
53904
|
});
|
|
53653
53905
|
}
|
|
53654
|
-
const createdBlocks = await ensureSkillsBlocks(agent.id);
|
|
53655
|
-
if (createdBlocks.length > 0) {
|
|
53656
|
-
console.log("Created missing skills blocks for agent compatibility");
|
|
53657
|
-
}
|
|
53658
53906
|
setAgentContext2(agent.id, skillsDirectory);
|
|
53659
|
-
|
|
53660
|
-
|
|
53661
|
-
|
|
53662
|
-
|
|
53663
|
-
|
|
53664
|
-
|
|
53665
|
-
|
|
53666
|
-
|
|
53667
|
-
|
|
53668
|
-
|
|
53669
|
-
|
|
53670
|
-
|
|
53671
|
-
|
|
53907
|
+
if (!noSkillsFlag && !isSubagent) {
|
|
53908
|
+
initializeLoadedSkillsFlag2().catch(() => {});
|
|
53909
|
+
(async () => {
|
|
53910
|
+
try {
|
|
53911
|
+
const { syncSkillsToAgent: syncSkillsToAgent3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills));
|
|
53912
|
+
const { join: join17 } = await import("node:path");
|
|
53913
|
+
const resolvedSkillsDirectory = skillsDirectory || join17(process.cwd(), SKILLS_DIR3);
|
|
53914
|
+
await syncSkillsToAgent3(client, agent.id, resolvedSkillsDirectory, {
|
|
53915
|
+
skipIfUnchanged: true
|
|
53916
|
+
});
|
|
53917
|
+
} catch (error) {
|
|
53918
|
+
console.warn(`[skills] Background sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
53919
|
+
}
|
|
53920
|
+
})();
|
|
53921
|
+
}
|
|
53672
53922
|
const outputFormat = values["output-format"] || "text";
|
|
53673
53923
|
const includePartialMessages = Boolean(values["include-partial-messages"]);
|
|
53674
53924
|
if (!["text", "json", "stream-json"].includes(outputFormat)) {
|
|
@@ -54607,7 +54857,7 @@ __export(exports_kittyProtocolDetector, {
|
|
|
54607
54857
|
isKittyProtocolEnabled: () => isKittyProtocolEnabled,
|
|
54608
54858
|
detectAndEnableKittyProtocol: () => detectAndEnableKittyProtocol
|
|
54609
54859
|
});
|
|
54610
|
-
import * as
|
|
54860
|
+
import * as fs16 from "node:fs";
|
|
54611
54861
|
async function detectAndEnableKittyProtocol() {
|
|
54612
54862
|
if (detectionComplete) {
|
|
54613
54863
|
return;
|
|
@@ -54680,7 +54930,7 @@ async function detectAndEnableKittyProtocol() {
|
|
|
54680
54930
|
if (DEBUG2) {
|
|
54681
54931
|
console.error("[kitty] querying support");
|
|
54682
54932
|
}
|
|
54683
|
-
|
|
54933
|
+
fs16.writeSync(process.stdout.fd, "\x1B[?u\x1B[c");
|
|
54684
54934
|
timeoutId = setTimeout(finish, 200);
|
|
54685
54935
|
});
|
|
54686
54936
|
}
|
|
@@ -54689,14 +54939,14 @@ function isKittyProtocolEnabled() {
|
|
|
54689
54939
|
}
|
|
54690
54940
|
function enableKittyKeyboardProtocol() {
|
|
54691
54941
|
try {
|
|
54692
|
-
|
|
54942
|
+
fs16.writeSync(process.stdout.fd, "\x1B[>1u");
|
|
54693
54943
|
kittyEnabled = true;
|
|
54694
54944
|
} catch {}
|
|
54695
54945
|
}
|
|
54696
54946
|
function disableKittyKeyboardProtocol() {
|
|
54697
54947
|
try {
|
|
54698
54948
|
if (kittyEnabled) {
|
|
54699
|
-
|
|
54949
|
+
fs16.writeSync(process.stdout.fd, "\x1B[<u");
|
|
54700
54950
|
kittyEnabled = false;
|
|
54701
54951
|
}
|
|
54702
54952
|
} catch {}
|
|
@@ -54928,10 +55178,10 @@ __export(exports_settings, {
|
|
|
54928
55178
|
loadProjectSettings: () => loadProjectSettings,
|
|
54929
55179
|
getSetting: () => getSetting
|
|
54930
55180
|
});
|
|
54931
|
-
import { homedir as
|
|
54932
|
-
import { join as
|
|
55181
|
+
import { homedir as homedir10 } from "node:os";
|
|
55182
|
+
import { join as join17 } from "node:path";
|
|
54933
55183
|
function getSettingsPath() {
|
|
54934
|
-
return
|
|
55184
|
+
return join17(homedir10(), ".letta", "settings.json");
|
|
54935
55185
|
}
|
|
54936
55186
|
async function loadSettings() {
|
|
54937
55187
|
const settingsPath = getSettingsPath();
|
|
@@ -54968,7 +55218,7 @@ async function getSetting(key) {
|
|
|
54968
55218
|
return settings[key];
|
|
54969
55219
|
}
|
|
54970
55220
|
function getProjectSettingsPath() {
|
|
54971
|
-
return
|
|
55221
|
+
return join17(process.cwd(), ".letta", "settings.local.json");
|
|
54972
55222
|
}
|
|
54973
55223
|
async function loadProjectSettings() {
|
|
54974
55224
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -54986,7 +55236,7 @@ async function loadProjectSettings() {
|
|
|
54986
55236
|
}
|
|
54987
55237
|
async function saveProjectSettings(settings) {
|
|
54988
55238
|
const settingsPath = getProjectSettingsPath();
|
|
54989
|
-
const dirPath =
|
|
55239
|
+
const dirPath = join17(process.cwd(), ".letta");
|
|
54990
55240
|
try {
|
|
54991
55241
|
if (!exists(dirPath)) {
|
|
54992
55242
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -56157,7 +56407,7 @@ function parsePatchOperations(input) {
|
|
|
56157
56407
|
continue;
|
|
56158
56408
|
}
|
|
56159
56409
|
if (line.startsWith("*** Add File:")) {
|
|
56160
|
-
const
|
|
56410
|
+
const path21 = line.replace("*** Add File:", "").trim();
|
|
56161
56411
|
i++;
|
|
56162
56412
|
const contentLines = [];
|
|
56163
56413
|
const patchLines = [];
|
|
@@ -56173,7 +56423,7 @@ function parsePatchOperations(input) {
|
|
|
56173
56423
|
}
|
|
56174
56424
|
operations.push({
|
|
56175
56425
|
kind: "add",
|
|
56176
|
-
path:
|
|
56426
|
+
path: path21,
|
|
56177
56427
|
content: contentLines.join(`
|
|
56178
56428
|
`),
|
|
56179
56429
|
patchLines
|
|
@@ -56181,7 +56431,7 @@ function parsePatchOperations(input) {
|
|
|
56181
56431
|
continue;
|
|
56182
56432
|
}
|
|
56183
56433
|
if (line.startsWith("*** Update File:")) {
|
|
56184
|
-
const
|
|
56434
|
+
const path21 = line.replace("*** Update File:", "").trim();
|
|
56185
56435
|
i++;
|
|
56186
56436
|
if (i < stopIdx && lines[i]?.startsWith("*** Move to:")) {
|
|
56187
56437
|
i++;
|
|
@@ -56217,7 +56467,7 @@ function parsePatchOperations(input) {
|
|
|
56217
56467
|
}
|
|
56218
56468
|
operations.push({
|
|
56219
56469
|
kind: "update",
|
|
56220
|
-
path:
|
|
56470
|
+
path: path21,
|
|
56221
56471
|
oldString: oldParts.join(`
|
|
56222
56472
|
`),
|
|
56223
56473
|
newString: newParts.join(`
|
|
@@ -56227,8 +56477,8 @@ function parsePatchOperations(input) {
|
|
|
56227
56477
|
continue;
|
|
56228
56478
|
}
|
|
56229
56479
|
if (line.startsWith("*** Delete File:")) {
|
|
56230
|
-
const
|
|
56231
|
-
operations.push({ kind: "delete", path:
|
|
56480
|
+
const path21 = line.replace("*** Delete File:", "").trim();
|
|
56481
|
+
operations.push({ kind: "delete", path: path21 });
|
|
56232
56482
|
i++;
|
|
56233
56483
|
continue;
|
|
56234
56484
|
}
|
|
@@ -56460,16 +56710,16 @@ class Diff {
|
|
|
56460
56710
|
}
|
|
56461
56711
|
}
|
|
56462
56712
|
}
|
|
56463
|
-
addToPath(
|
|
56464
|
-
const last =
|
|
56713
|
+
addToPath(path21, added, removed, oldPosInc, options) {
|
|
56714
|
+
const last = path21.lastComponent;
|
|
56465
56715
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
56466
56716
|
return {
|
|
56467
|
-
oldPos:
|
|
56717
|
+
oldPos: path21.oldPos + oldPosInc,
|
|
56468
56718
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
56469
56719
|
};
|
|
56470
56720
|
} else {
|
|
56471
56721
|
return {
|
|
56472
|
-
oldPos:
|
|
56722
|
+
oldPos: path21.oldPos + oldPosInc,
|
|
56473
56723
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
56474
56724
|
};
|
|
56475
56725
|
}
|
|
@@ -58206,9 +58456,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
58206
58456
|
const relPath = relative4(cwd2, filePath);
|
|
58207
58457
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
58208
58458
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
58209
|
-
const { existsSync:
|
|
58459
|
+
const { existsSync: existsSync10 } = __require("node:fs");
|
|
58210
58460
|
try {
|
|
58211
|
-
if (
|
|
58461
|
+
if (existsSync10(filePath)) {
|
|
58212
58462
|
return `Overwrite ${displayPath}?`;
|
|
58213
58463
|
}
|
|
58214
58464
|
} catch {}
|
|
@@ -58891,9 +59141,9 @@ function getHeaderText(fileEdit) {
|
|
|
58891
59141
|
const relPath = relative4(cwd2, fileEdit.filePath);
|
|
58892
59142
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
58893
59143
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
58894
|
-
const { existsSync:
|
|
59144
|
+
const { existsSync: existsSync10 } = __require("node:fs");
|
|
58895
59145
|
try {
|
|
58896
|
-
if (
|
|
59146
|
+
if (existsSync10(fileEdit.filePath)) {
|
|
58897
59147
|
return `Overwrite ${displayPath}?`;
|
|
58898
59148
|
}
|
|
58899
59149
|
} catch {}
|
|
@@ -60568,7 +60818,7 @@ var init_ApprovalSwitch = __esm(async () => {
|
|
|
60568
60818
|
});
|
|
60569
60819
|
|
|
60570
60820
|
// src/cli/components/AssistantMessageRich.tsx
|
|
60571
|
-
var import_react43, jsx_dev_runtime21,
|
|
60821
|
+
var import_react43, jsx_dev_runtime21, normalize5 = (s) => s.replace(/\r\n/g, `
|
|
60572
60822
|
`).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
|
|
60573
60823
|
|
|
60574
60824
|
`).replace(/^\n+|\n+$/g, ""), AssistantMessage;
|
|
@@ -60583,7 +60833,7 @@ var init_AssistantMessageRich = __esm(async () => {
|
|
|
60583
60833
|
AssistantMessage = import_react43.memo(({ line }) => {
|
|
60584
60834
|
const columns = useTerminalWidth();
|
|
60585
60835
|
const contentWidth = Math.max(0, columns - 2);
|
|
60586
|
-
const normalizedText =
|
|
60836
|
+
const normalizedText = normalize5(line.text);
|
|
60587
60837
|
return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
|
|
60588
60838
|
flexDirection: "row",
|
|
60589
60839
|
children: [
|
|
@@ -61802,7 +62052,7 @@ var init_pasteRegistry = __esm(() => {
|
|
|
61802
62052
|
|
|
61803
62053
|
// src/cli/helpers/clipboard.ts
|
|
61804
62054
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
61805
|
-
import { existsSync as
|
|
62055
|
+
import { existsSync as existsSync10, readFileSync as readFileSync2, statSync as statSync3 } from "node:fs";
|
|
61806
62056
|
import { basename as basename2, extname as extname3, isAbsolute as isAbsolute12, resolve as resolve18 } from "node:path";
|
|
61807
62057
|
function countLines2(text) {
|
|
61808
62058
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
@@ -61853,7 +62103,7 @@ function translatePasteForImages(paste) {
|
|
|
61853
62103
|
if (!isAbsolute12(filePath))
|
|
61854
62104
|
filePath = resolve18(process.cwd(), filePath);
|
|
61855
62105
|
const ext3 = extname3(filePath || "").toLowerCase();
|
|
61856
|
-
if (IMAGE_EXTS.has(ext3) &&
|
|
62106
|
+
if (IMAGE_EXTS.has(ext3) && existsSync10(filePath) && statSync3(filePath).isFile()) {
|
|
61857
62107
|
const buf = readFileSync2(filePath);
|
|
61858
62108
|
const b64 = buf.toString("base64");
|
|
61859
62109
|
const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
|
|
@@ -62441,13 +62691,13 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
62441
62691
|
});
|
|
62442
62692
|
import {
|
|
62443
62693
|
copyFileSync,
|
|
62444
|
-
existsSync as
|
|
62445
|
-
mkdirSync as
|
|
62694
|
+
existsSync as existsSync11,
|
|
62695
|
+
mkdirSync as mkdirSync5,
|
|
62446
62696
|
readFileSync as readFileSync3,
|
|
62447
|
-
writeFileSync as
|
|
62697
|
+
writeFileSync as writeFileSync3
|
|
62448
62698
|
} from "node:fs";
|
|
62449
|
-
import { homedir as
|
|
62450
|
-
import { dirname as dirname10, join as
|
|
62699
|
+
import { homedir as homedir11, platform as platform3 } from "node:os";
|
|
62700
|
+
import { dirname as dirname10, join as join18 } from "node:path";
|
|
62451
62701
|
function detectTerminalType() {
|
|
62452
62702
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
62453
62703
|
return "cursor";
|
|
@@ -62477,18 +62727,18 @@ function getKeybindingsPath(terminal) {
|
|
|
62477
62727
|
cursor: "Cursor",
|
|
62478
62728
|
windsurf: "Windsurf"
|
|
62479
62729
|
}[terminal];
|
|
62480
|
-
const
|
|
62481
|
-
if (
|
|
62482
|
-
return
|
|
62730
|
+
const os5 = platform3();
|
|
62731
|
+
if (os5 === "darwin") {
|
|
62732
|
+
return join18(homedir11(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
62483
62733
|
}
|
|
62484
|
-
if (
|
|
62734
|
+
if (os5 === "win32") {
|
|
62485
62735
|
const appData = process.env.APPDATA;
|
|
62486
62736
|
if (!appData)
|
|
62487
62737
|
return null;
|
|
62488
|
-
return
|
|
62738
|
+
return join18(appData, appName, "User", "keybindings.json");
|
|
62489
62739
|
}
|
|
62490
|
-
if (
|
|
62491
|
-
return
|
|
62740
|
+
if (os5 === "linux") {
|
|
62741
|
+
return join18(homedir11(), ".config", appName, "User", "keybindings.json");
|
|
62492
62742
|
}
|
|
62493
62743
|
return null;
|
|
62494
62744
|
}
|
|
@@ -62510,7 +62760,7 @@ function parseKeybindings(content) {
|
|
|
62510
62760
|
}
|
|
62511
62761
|
}
|
|
62512
62762
|
function keybindingExists(keybindingsPath) {
|
|
62513
|
-
if (!
|
|
62763
|
+
if (!existsSync11(keybindingsPath))
|
|
62514
62764
|
return false;
|
|
62515
62765
|
try {
|
|
62516
62766
|
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -62523,7 +62773,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
62523
62773
|
}
|
|
62524
62774
|
}
|
|
62525
62775
|
function createBackup(keybindingsPath) {
|
|
62526
|
-
if (!
|
|
62776
|
+
if (!existsSync11(keybindingsPath))
|
|
62527
62777
|
return null;
|
|
62528
62778
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
62529
62779
|
try {
|
|
@@ -62539,12 +62789,12 @@ function installKeybinding(keybindingsPath) {
|
|
|
62539
62789
|
return { success: true, alreadyExists: true };
|
|
62540
62790
|
}
|
|
62541
62791
|
const parentDir = dirname10(keybindingsPath);
|
|
62542
|
-
if (!
|
|
62543
|
-
|
|
62792
|
+
if (!existsSync11(parentDir)) {
|
|
62793
|
+
mkdirSync5(parentDir, { recursive: true });
|
|
62544
62794
|
}
|
|
62545
62795
|
let keybindings = [];
|
|
62546
62796
|
let backupPath = null;
|
|
62547
|
-
if (
|
|
62797
|
+
if (existsSync11(keybindingsPath)) {
|
|
62548
62798
|
backupPath = createBackup(keybindingsPath);
|
|
62549
62799
|
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
62550
62800
|
const parsed = parseKeybindings(content);
|
|
@@ -62559,7 +62809,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
62559
62809
|
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
62560
62810
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
62561
62811
|
`;
|
|
62562
|
-
|
|
62812
|
+
writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
62563
62813
|
return {
|
|
62564
62814
|
success: true,
|
|
62565
62815
|
backupPath: backupPath ?? undefined
|
|
@@ -62574,7 +62824,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
62574
62824
|
}
|
|
62575
62825
|
function removeKeybinding(keybindingsPath) {
|
|
62576
62826
|
try {
|
|
62577
|
-
if (!
|
|
62827
|
+
if (!existsSync11(keybindingsPath)) {
|
|
62578
62828
|
return { success: true };
|
|
62579
62829
|
}
|
|
62580
62830
|
const content = readFileSync3(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -62588,7 +62838,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
62588
62838
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
62589
62839
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
62590
62840
|
`;
|
|
62591
|
-
|
|
62841
|
+
writeFileSync3(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
62592
62842
|
return { success: true };
|
|
62593
62843
|
} catch (error) {
|
|
62594
62844
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -62606,14 +62856,14 @@ function installKeybindingForCurrentTerminal() {
|
|
|
62606
62856
|
error: "Not running in a VS Code-like terminal"
|
|
62607
62857
|
};
|
|
62608
62858
|
}
|
|
62609
|
-
const
|
|
62610
|
-
if (!
|
|
62859
|
+
const path21 = getKeybindingsPath(terminal);
|
|
62860
|
+
if (!path21) {
|
|
62611
62861
|
return {
|
|
62612
62862
|
success: false,
|
|
62613
62863
|
error: `Could not determine keybindings.json path for ${terminal}`
|
|
62614
62864
|
};
|
|
62615
62865
|
}
|
|
62616
|
-
return installKeybinding(
|
|
62866
|
+
return installKeybinding(path21);
|
|
62617
62867
|
}
|
|
62618
62868
|
function removeKeybindingForCurrentTerminal() {
|
|
62619
62869
|
const terminal = detectTerminalType();
|
|
@@ -62623,14 +62873,14 @@ function removeKeybindingForCurrentTerminal() {
|
|
|
62623
62873
|
error: "Not running in a VS Code-like terminal"
|
|
62624
62874
|
};
|
|
62625
62875
|
}
|
|
62626
|
-
const
|
|
62627
|
-
if (!
|
|
62876
|
+
const path21 = getKeybindingsPath(terminal);
|
|
62877
|
+
if (!path21) {
|
|
62628
62878
|
return {
|
|
62629
62879
|
success: false,
|
|
62630
62880
|
error: `Could not determine keybindings.json path for ${terminal}`
|
|
62631
62881
|
};
|
|
62632
62882
|
}
|
|
62633
|
-
return removeKeybinding(
|
|
62883
|
+
return removeKeybinding(path21);
|
|
62634
62884
|
}
|
|
62635
62885
|
function isWezTerm() {
|
|
62636
62886
|
return process.env.TERM_PROGRAM === "WezTerm";
|
|
@@ -62641,17 +62891,17 @@ function getWezTermConfigPath() {
|
|
|
62641
62891
|
}
|
|
62642
62892
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
62643
62893
|
if (xdgConfig) {
|
|
62644
|
-
const xdgPath =
|
|
62645
|
-
if (
|
|
62894
|
+
const xdgPath = join18(xdgConfig, "wezterm", "wezterm.lua");
|
|
62895
|
+
if (existsSync11(xdgPath))
|
|
62646
62896
|
return xdgPath;
|
|
62647
62897
|
}
|
|
62648
|
-
const configPath =
|
|
62649
|
-
if (
|
|
62898
|
+
const configPath = join18(homedir11(), ".config", "wezterm", "wezterm.lua");
|
|
62899
|
+
if (existsSync11(configPath))
|
|
62650
62900
|
return configPath;
|
|
62651
|
-
return
|
|
62901
|
+
return join18(homedir11(), ".wezterm.lua");
|
|
62652
62902
|
}
|
|
62653
62903
|
function wezTermDeleteFixExists(configPath) {
|
|
62654
|
-
if (!
|
|
62904
|
+
if (!existsSync11(configPath))
|
|
62655
62905
|
return false;
|
|
62656
62906
|
try {
|
|
62657
62907
|
const content = readFileSync3(configPath, { encoding: "utf-8" });
|
|
@@ -62668,7 +62918,7 @@ function installWezTermDeleteFix() {
|
|
|
62668
62918
|
}
|
|
62669
62919
|
let content = "";
|
|
62670
62920
|
let backupPath = null;
|
|
62671
|
-
if (
|
|
62921
|
+
if (existsSync11(configPath)) {
|
|
62672
62922
|
backupPath = `${configPath}.letta-backup`;
|
|
62673
62923
|
copyFileSync(configPath, backupPath);
|
|
62674
62924
|
content = readFileSync3(configPath, { encoding: "utf-8" });
|
|
@@ -62698,10 +62948,10 @@ ${WEZTERM_DELETE_FIX}
|
|
|
62698
62948
|
`;
|
|
62699
62949
|
}
|
|
62700
62950
|
const parentDir = dirname10(configPath);
|
|
62701
|
-
if (!
|
|
62702
|
-
|
|
62951
|
+
if (!existsSync11(parentDir)) {
|
|
62952
|
+
mkdirSync5(parentDir, { recursive: true });
|
|
62703
62953
|
}
|
|
62704
|
-
|
|
62954
|
+
writeFileSync3(configPath, content, { encoding: "utf-8" });
|
|
62705
62955
|
return {
|
|
62706
62956
|
success: true,
|
|
62707
62957
|
backupPath: backupPath ?? undefined
|
|
@@ -63098,9 +63348,9 @@ __export(exports_custom, {
|
|
|
63098
63348
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
63099
63349
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
63100
63350
|
});
|
|
63101
|
-
import { existsSync as
|
|
63351
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
63102
63352
|
import { readdir as readdir7, readFile as readFile8 } from "node:fs/promises";
|
|
63103
|
-
import { basename as basename3, dirname as dirname11, join as
|
|
63353
|
+
import { basename as basename3, dirname as dirname11, join as join19 } from "node:path";
|
|
63104
63354
|
async function getCustomCommands() {
|
|
63105
63355
|
if (cachedCommands !== null) {
|
|
63106
63356
|
return cachedCommands;
|
|
@@ -63111,7 +63361,7 @@ async function getCustomCommands() {
|
|
|
63111
63361
|
function refreshCustomCommands() {
|
|
63112
63362
|
cachedCommands = null;
|
|
63113
63363
|
}
|
|
63114
|
-
async function discoverCustomCommands(projectPath =
|
|
63364
|
+
async function discoverCustomCommands(projectPath = join19(process.cwd(), COMMANDS_DIR)) {
|
|
63115
63365
|
const commandsById = new Map;
|
|
63116
63366
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
63117
63367
|
for (const cmd of userCommands) {
|
|
@@ -63132,7 +63382,7 @@ async function discoverCustomCommands(projectPath = join18(process.cwd(), COMMAN
|
|
|
63132
63382
|
return result;
|
|
63133
63383
|
}
|
|
63134
63384
|
async function discoverFromDirectory(dirPath, source) {
|
|
63135
|
-
if (!
|
|
63385
|
+
if (!existsSync12(dirPath)) {
|
|
63136
63386
|
return [];
|
|
63137
63387
|
}
|
|
63138
63388
|
const commands2 = [];
|
|
@@ -63143,7 +63393,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
|
|
|
63143
63393
|
try {
|
|
63144
63394
|
const entries = await readdir7(currentPath, { withFileTypes: true });
|
|
63145
63395
|
for (const entry of entries) {
|
|
63146
|
-
const fullPath =
|
|
63396
|
+
const fullPath = join19(currentPath, entry.name);
|
|
63147
63397
|
if (entry.isDirectory()) {
|
|
63148
63398
|
await findCommandFiles(fullPath, rootPath, commands2, source);
|
|
63149
63399
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -63228,7 +63478,7 @@ async function findCustomCommand(commandName) {
|
|
|
63228
63478
|
}
|
|
63229
63479
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
63230
63480
|
var init_custom = __esm(() => {
|
|
63231
|
-
GLOBAL_COMMANDS_DIR =
|
|
63481
|
+
GLOBAL_COMMANDS_DIR = join19(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
63232
63482
|
});
|
|
63233
63483
|
|
|
63234
63484
|
// src/cli/components/HelpDialog.tsx
|
|
@@ -66077,7 +66327,7 @@ var require_jsx_runtime = __commonJS((exports, module) => {
|
|
|
66077
66327
|
|
|
66078
66328
|
// node_modules/supports-color/index.js
|
|
66079
66329
|
import process19 from "node:process";
|
|
66080
|
-
import
|
|
66330
|
+
import os5 from "node:os";
|
|
66081
66331
|
import tty2 from "node:tty";
|
|
66082
66332
|
function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process19.argv) {
|
|
66083
66333
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
@@ -66143,7 +66393,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
66143
66393
|
return min;
|
|
66144
66394
|
}
|
|
66145
66395
|
if (process19.platform === "win32") {
|
|
66146
|
-
const osRelease =
|
|
66396
|
+
const osRelease = os5.release().split(".");
|
|
66147
66397
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
66148
66398
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
66149
66399
|
}
|
|
@@ -66498,21 +66748,21 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
66498
66748
|
});
|
|
66499
66749
|
|
|
66500
66750
|
// src/cli/helpers/fileSearch.ts
|
|
66501
|
-
import { readdirSync as
|
|
66502
|
-
import { join as
|
|
66751
|
+
import { readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
|
|
66752
|
+
import { join as join20, resolve as resolve19 } from "node:path";
|
|
66503
66753
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = []) {
|
|
66504
66754
|
if (results.length >= maxResults) {
|
|
66505
66755
|
return results;
|
|
66506
66756
|
}
|
|
66507
66757
|
try {
|
|
66508
|
-
const entries =
|
|
66758
|
+
const entries = readdirSync5(dir);
|
|
66509
66759
|
for (const entry of entries) {
|
|
66510
66760
|
if (entry.startsWith(".") || entry === "node_modules" || entry === "dist" || entry === "build") {
|
|
66511
66761
|
continue;
|
|
66512
66762
|
}
|
|
66513
66763
|
try {
|
|
66514
|
-
const fullPath =
|
|
66515
|
-
const stats =
|
|
66764
|
+
const fullPath = join20(dir, entry);
|
|
66765
|
+
const stats = statSync4(fullPath);
|
|
66516
66766
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
66517
66767
|
const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
|
|
66518
66768
|
if (matches) {
|
|
@@ -66544,7 +66794,7 @@ async function searchFiles(query, deep = false) {
|
|
|
66544
66794
|
try {
|
|
66545
66795
|
const resolvedDir = resolve19(process.cwd(), dirPart);
|
|
66546
66796
|
try {
|
|
66547
|
-
|
|
66797
|
+
statSync4(resolvedDir);
|
|
66548
66798
|
searchDir = resolvedDir;
|
|
66549
66799
|
searchPattern = pattern;
|
|
66550
66800
|
} catch {}
|
|
@@ -66556,15 +66806,15 @@ async function searchFiles(query, deep = false) {
|
|
|
66556
66806
|
} else {
|
|
66557
66807
|
let entries = [];
|
|
66558
66808
|
try {
|
|
66559
|
-
entries =
|
|
66809
|
+
entries = readdirSync5(searchDir);
|
|
66560
66810
|
} catch {
|
|
66561
66811
|
return [];
|
|
66562
66812
|
}
|
|
66563
66813
|
const matchingEntries = searchPattern.length === 0 ? entries : entries.filter((entry) => entry.toLowerCase().includes(searchPattern.toLowerCase()));
|
|
66564
66814
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
66565
66815
|
try {
|
|
66566
|
-
const fullPath =
|
|
66567
|
-
const stats =
|
|
66816
|
+
const fullPath = join20(searchDir, entry);
|
|
66817
|
+
const stats = statSync4(fullPath);
|
|
66568
66818
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
66569
66819
|
results.push({
|
|
66570
66820
|
path: relativePath,
|
|
@@ -70679,7 +70929,7 @@ var init_PendingApprovalStub = __esm(async () => {
|
|
|
70679
70929
|
});
|
|
70680
70930
|
|
|
70681
70931
|
// src/cli/components/ReasoningMessageRich.tsx
|
|
70682
|
-
var import_react73, jsx_dev_runtime49,
|
|
70932
|
+
var import_react73, jsx_dev_runtime49, normalize6 = (s) => s.replace(/\r\n/g, `
|
|
70683
70933
|
`).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
|
|
70684
70934
|
|
|
70685
70935
|
`).replace(/^\n+|\n+$/g, ""), ReasoningMessage;
|
|
@@ -70694,7 +70944,7 @@ var init_ReasoningMessageRich = __esm(async () => {
|
|
|
70694
70944
|
ReasoningMessage = import_react73.memo(({ line }) => {
|
|
70695
70945
|
const columns = useTerminalWidth();
|
|
70696
70946
|
const contentWidth = Math.max(0, columns - 2);
|
|
70697
|
-
const normalizedText =
|
|
70947
|
+
const normalizedText = normalize6(line.text);
|
|
70698
70948
|
return /* @__PURE__ */ jsx_dev_runtime49.jsxDEV(Box_default, {
|
|
70699
70949
|
flexDirection: "column",
|
|
70700
70950
|
children: [
|
|
@@ -71654,8 +71904,8 @@ function MemoryDiffRenderer({
|
|
|
71654
71904
|
}, undefined, false, undefined, this);
|
|
71655
71905
|
}
|
|
71656
71906
|
const command = args.command;
|
|
71657
|
-
const
|
|
71658
|
-
const blockName =
|
|
71907
|
+
const path21 = args.path || args.old_path || "unknown";
|
|
71908
|
+
const blockName = path21.split("/").pop() || path21;
|
|
71659
71909
|
switch (command) {
|
|
71660
71910
|
case "str_replace": {
|
|
71661
71911
|
const oldStr = args.old_string || args.old_str || "";
|
|
@@ -74198,9 +74448,9 @@ async function getLettaConfig2() {
|
|
|
74198
74448
|
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
|
|
74199
74449
|
return { baseUrl, apiKey };
|
|
74200
74450
|
}
|
|
74201
|
-
async function providersRequest2(method,
|
|
74451
|
+
async function providersRequest2(method, path21, body) {
|
|
74202
74452
|
const { baseUrl, apiKey } = await getLettaConfig2();
|
|
74203
|
-
const url = `${baseUrl}${
|
|
74453
|
+
const url = `${baseUrl}${path21}`;
|
|
74204
74454
|
const response = await fetch(url, {
|
|
74205
74455
|
method,
|
|
74206
74456
|
headers: {
|
|
@@ -74731,9 +74981,9 @@ var exports_App = {};
|
|
|
74731
74981
|
__export(exports_App, {
|
|
74732
74982
|
default: () => App2
|
|
74733
74983
|
});
|
|
74734
|
-
import { existsSync as
|
|
74735
|
-
import { homedir as
|
|
74736
|
-
import { join as
|
|
74984
|
+
import { existsSync as existsSync13, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
74985
|
+
import { homedir as homedir12 } from "node:os";
|
|
74986
|
+
import { join as join21 } from "node:path";
|
|
74737
74987
|
function uid4(prefix) {
|
|
74738
74988
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
74739
74989
|
}
|
|
@@ -74845,7 +75095,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|
|
74845
75095
|
}
|
|
74846
75096
|
function planFileExists() {
|
|
74847
75097
|
const planFilePath = permissionMode.getPlanFilePath();
|
|
74848
|
-
return !!planFilePath &&
|
|
75098
|
+
return !!planFilePath && existsSync13(planFilePath);
|
|
74849
75099
|
}
|
|
74850
75100
|
function getQuestionsFromApproval(approval) {
|
|
74851
75101
|
const parsed = safeJsonParseOr(approval.toolArgs, {});
|
|
@@ -75003,6 +75253,20 @@ function App2({
|
|
|
75003
75253
|
const [autoDeniedApprovals, setAutoDeniedApprovals] = import_react84.useState([]);
|
|
75004
75254
|
const executingToolCallIdsRef = import_react84.useRef([]);
|
|
75005
75255
|
const interruptQueuedRef = import_react84.useRef(false);
|
|
75256
|
+
const toolResultsInFlightRef = import_react84.useRef(false);
|
|
75257
|
+
const autoAllowedExecutionRef = import_react84.useRef(null);
|
|
75258
|
+
const queuedApprovalMetadataRef = import_react84.useRef(null);
|
|
75259
|
+
const queueApprovalResults = import_react84.useCallback((results, metadata) => {
|
|
75260
|
+
setQueuedApprovalResults(results);
|
|
75261
|
+
if (results) {
|
|
75262
|
+
queuedApprovalMetadataRef.current = metadata ?? {
|
|
75263
|
+
conversationId: conversationIdRef.current,
|
|
75264
|
+
generation: conversationGenerationRef.current
|
|
75265
|
+
};
|
|
75266
|
+
} else {
|
|
75267
|
+
queuedApprovalMetadataRef.current = null;
|
|
75268
|
+
}
|
|
75269
|
+
}, []);
|
|
75006
75270
|
const bashCommandCacheRef = import_react84.useRef([]);
|
|
75007
75271
|
const [pendingRalphConfig, setPendingRalphConfig] = import_react84.useState(null);
|
|
75008
75272
|
const [uiRalphActive, setUiRalphActive] = import_react84.useState(ralphMode.getState().isActive);
|
|
@@ -75363,8 +75627,8 @@ function App2({
|
|
|
75363
75627
|
if (!planFilePath)
|
|
75364
75628
|
return;
|
|
75365
75629
|
try {
|
|
75366
|
-
const { readFileSync: readFileSync5, existsSync:
|
|
75367
|
-
if (!
|
|
75630
|
+
const { readFileSync: readFileSync5, existsSync: existsSync14 } = __require("node:fs");
|
|
75631
|
+
if (!existsSync14(planFilePath))
|
|
75368
75632
|
return;
|
|
75369
75633
|
const planContent = readFileSync5(planFilePath, "utf-8");
|
|
75370
75634
|
const previewItem = {
|
|
@@ -75794,7 +76058,7 @@ ${newState.originalPrompt}`
|
|
|
75794
76058
|
});
|
|
75795
76059
|
}
|
|
75796
76060
|
refreshDerived();
|
|
75797
|
-
|
|
76061
|
+
queueApprovalResults(denialResults);
|
|
75798
76062
|
const concatenatedMessage = queueSnapshotRef.current.join(`
|
|
75799
76063
|
`);
|
|
75800
76064
|
setMessageQueue([]);
|
|
@@ -75902,36 +76166,48 @@ ${newState.originalPrompt}`
|
|
|
75902
76166
|
}
|
|
75903
76167
|
} catch {}
|
|
75904
76168
|
}
|
|
75905
|
-
|
|
75906
|
-
|
|
75907
|
-
const
|
|
75908
|
-
|
|
75909
|
-
|
|
75910
|
-
|
|
75911
|
-
|
|
75912
|
-
|
|
75913
|
-
|
|
75914
|
-
|
|
75915
|
-
|
|
75916
|
-
|
|
75917
|
-
|
|
75918
|
-
|
|
75919
|
-
status: "error",
|
|
75920
|
-
stdout: null,
|
|
75921
|
-
stderr: null
|
|
75922
|
-
});
|
|
75923
|
-
return {
|
|
75924
|
-
approval: ac.approval,
|
|
75925
|
-
reason
|
|
76169
|
+
const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
|
|
76170
|
+
const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
|
|
76171
|
+
const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
|
|
76172
|
+
let autoAllowedResults = [];
|
|
76173
|
+
let autoDeniedResults = [];
|
|
76174
|
+
if (shouldTrackAutoAllowed) {
|
|
76175
|
+
setIsExecutingTool(true);
|
|
76176
|
+
executingToolCallIdsRef.current = autoAllowedToolCallIds;
|
|
76177
|
+
toolAbortControllerRef.current = autoAllowedAbortController;
|
|
76178
|
+
autoAllowedExecutionRef.current = {
|
|
76179
|
+
toolCallIds: autoAllowedToolCallIds,
|
|
76180
|
+
results: null,
|
|
76181
|
+
conversationId: conversationIdRef.current,
|
|
76182
|
+
generation: conversationGenerationRef.current
|
|
75926
76183
|
};
|
|
75927
|
-
}
|
|
75928
|
-
|
|
75929
|
-
if (
|
|
75930
|
-
|
|
75931
|
-
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
76184
|
+
}
|
|
76185
|
+
try {
|
|
76186
|
+
if (autoAllowedToolCallIds.length > 0) {
|
|
76187
|
+
setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
|
|
75932
76188
|
refreshDerived();
|
|
75933
|
-
return;
|
|
75934
76189
|
}
|
|
76190
|
+
autoAllowedResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
|
|
76191
|
+
abortSignal: autoAllowedAbortController.signal,
|
|
76192
|
+
onStreamingOutput: updateStreamingOutput
|
|
76193
|
+
}) : [];
|
|
76194
|
+
autoDeniedResults = autoDenied.map((ac) => {
|
|
76195
|
+
const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown reason";
|
|
76196
|
+
onChunk(buffersRef.current, {
|
|
76197
|
+
message_type: "tool_return_message",
|
|
76198
|
+
id: "dummy",
|
|
76199
|
+
date: new Date().toISOString(),
|
|
76200
|
+
tool_call_id: ac.approval.toolCallId,
|
|
76201
|
+
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
76202
|
+
status: "error",
|
|
76203
|
+
stdout: null,
|
|
76204
|
+
stderr: null
|
|
76205
|
+
});
|
|
76206
|
+
return {
|
|
76207
|
+
approval: ac.approval,
|
|
76208
|
+
reason
|
|
76209
|
+
};
|
|
76210
|
+
});
|
|
75935
76211
|
const allResults = [
|
|
75936
76212
|
...autoAllowedResults.map((ar) => ({
|
|
75937
76213
|
type: "tool",
|
|
@@ -75948,11 +76224,79 @@ ${newState.originalPrompt}`
|
|
|
75948
76224
|
reason: ad.reason
|
|
75949
76225
|
}))
|
|
75950
76226
|
];
|
|
76227
|
+
if (autoAllowedExecutionRef.current) {
|
|
76228
|
+
autoAllowedExecutionRef.current.results = allResults;
|
|
76229
|
+
}
|
|
76230
|
+
const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
|
|
76231
|
+
conversationId: autoAllowedExecutionRef.current.conversationId,
|
|
76232
|
+
generation: conversationGenerationRef.current
|
|
76233
|
+
} : undefined;
|
|
76234
|
+
if (needsUserInput.length === 0) {
|
|
76235
|
+
if (userCancelledRef.current || abortControllerRef.current?.signal.aborted || interruptQueuedRef.current) {
|
|
76236
|
+
if (allResults.length > 0) {
|
|
76237
|
+
queueApprovalResults(allResults, autoAllowedMetadata);
|
|
76238
|
+
}
|
|
76239
|
+
setStreaming(false);
|
|
76240
|
+
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
76241
|
+
refreshDerived();
|
|
76242
|
+
return;
|
|
76243
|
+
}
|
|
76244
|
+
if (waitingForQueueCancelRef.current) {
|
|
76245
|
+
if (restoreQueueOnCancelRef.current) {
|
|
76246
|
+
setRestoreQueueOnCancel(false);
|
|
76247
|
+
} else {
|
|
76248
|
+
if (allResults.length > 0) {
|
|
76249
|
+
queueApprovalResults(allResults, autoAllowedMetadata);
|
|
76250
|
+
}
|
|
76251
|
+
const concatenatedMessage = queueSnapshotRef.current.join(`
|
|
76252
|
+
`);
|
|
76253
|
+
setMessageQueue([]);
|
|
76254
|
+
if (concatenatedMessage.trim()) {
|
|
76255
|
+
onSubmitRef.current(concatenatedMessage);
|
|
76256
|
+
}
|
|
76257
|
+
}
|
|
76258
|
+
waitingForQueueCancelRef.current = false;
|
|
76259
|
+
queueSnapshotRef.current = [];
|
|
76260
|
+
setStreaming(false);
|
|
76261
|
+
return;
|
|
76262
|
+
}
|
|
76263
|
+
setThinkingMessage(getRandomThinkingVerb());
|
|
76264
|
+
refreshDerived();
|
|
76265
|
+
toolResultsInFlightRef.current = true;
|
|
76266
|
+
await processConversation([
|
|
76267
|
+
{
|
|
76268
|
+
type: "approval",
|
|
76269
|
+
approvals: allResults
|
|
76270
|
+
}
|
|
76271
|
+
], { allowReentry: true });
|
|
76272
|
+
toolResultsInFlightRef.current = false;
|
|
76273
|
+
return;
|
|
76274
|
+
}
|
|
75951
76275
|
if (waitingForQueueCancelRef.current) {
|
|
75952
76276
|
if (restoreQueueOnCancelRef.current) {
|
|
75953
76277
|
setRestoreQueueOnCancel(false);
|
|
75954
76278
|
} else {
|
|
75955
|
-
|
|
76279
|
+
const denialResults = needsUserInput.map((ac) => ({
|
|
76280
|
+
type: "approval",
|
|
76281
|
+
tool_call_id: ac.approval.toolCallId,
|
|
76282
|
+
approve: false,
|
|
76283
|
+
reason: "User cancelled - new message queued"
|
|
76284
|
+
}));
|
|
76285
|
+
for (const ac of needsUserInput) {
|
|
76286
|
+
onChunk(buffersRef.current, {
|
|
76287
|
+
message_type: "tool_return_message",
|
|
76288
|
+
id: "dummy",
|
|
76289
|
+
date: new Date().toISOString(),
|
|
76290
|
+
tool_call_id: ac.approval.toolCallId,
|
|
76291
|
+
tool_return: "Cancelled - user sent new message",
|
|
76292
|
+
status: "error"
|
|
76293
|
+
});
|
|
76294
|
+
}
|
|
76295
|
+
refreshDerived();
|
|
76296
|
+
const queuedResults = [...allResults, ...denialResults];
|
|
76297
|
+
if (queuedResults.length > 0) {
|
|
76298
|
+
queueApprovalResults(queuedResults, autoAllowedMetadata);
|
|
76299
|
+
}
|
|
75956
76300
|
const concatenatedMessage = queueSnapshotRef.current.join(`
|
|
75957
76301
|
`);
|
|
75958
76302
|
setMessageQueue([]);
|
|
@@ -75965,64 +76309,14 @@ ${newState.originalPrompt}`
|
|
|
75965
76309
|
setStreaming(false);
|
|
75966
76310
|
return;
|
|
75967
76311
|
}
|
|
75968
|
-
|
|
75969
|
-
|
|
75970
|
-
|
|
75971
|
-
|
|
75972
|
-
|
|
75973
|
-
|
|
75974
|
-
|
|
75975
|
-
], { allowReentry: true });
|
|
75976
|
-
return;
|
|
75977
|
-
}
|
|
75978
|
-
if (waitingForQueueCancelRef.current) {
|
|
75979
|
-
if (restoreQueueOnCancelRef.current) {
|
|
75980
|
-
setRestoreQueueOnCancel(false);
|
|
75981
|
-
} else {
|
|
75982
|
-
const denialResults = needsUserInput.map((ac) => ({
|
|
75983
|
-
type: "approval",
|
|
75984
|
-
tool_call_id: ac.approval.toolCallId,
|
|
75985
|
-
approve: false,
|
|
75986
|
-
reason: "User cancelled - new message queued"
|
|
75987
|
-
}));
|
|
75988
|
-
for (const ac of needsUserInput) {
|
|
75989
|
-
onChunk(buffersRef.current, {
|
|
75990
|
-
message_type: "tool_return_message",
|
|
75991
|
-
id: "dummy",
|
|
75992
|
-
date: new Date().toISOString(),
|
|
75993
|
-
tool_call_id: ac.approval.toolCallId,
|
|
75994
|
-
tool_return: "Cancelled - user sent new message",
|
|
75995
|
-
status: "error"
|
|
75996
|
-
});
|
|
75997
|
-
}
|
|
75998
|
-
refreshDerived();
|
|
75999
|
-
const allResults = [
|
|
76000
|
-
...autoAllowedResults.map((ar) => ({
|
|
76001
|
-
type: "tool",
|
|
76002
|
-
tool_call_id: ar.toolCallId,
|
|
76003
|
-
tool_return: ar.result.toolReturn,
|
|
76004
|
-
status: ar.result.status
|
|
76005
|
-
})),
|
|
76006
|
-
...autoDeniedResults.map((ad) => ({
|
|
76007
|
-
type: "approval",
|
|
76008
|
-
tool_call_id: ad.approval.toolCallId,
|
|
76009
|
-
approve: false,
|
|
76010
|
-
reason: ad.reason
|
|
76011
|
-
})),
|
|
76012
|
-
...denialResults
|
|
76013
|
-
];
|
|
76014
|
-
setQueuedApprovalResults(allResults);
|
|
76015
|
-
const concatenatedMessage = queueSnapshotRef.current.join(`
|
|
76016
|
-
`);
|
|
76017
|
-
setMessageQueue([]);
|
|
76018
|
-
if (concatenatedMessage.trim()) {
|
|
76019
|
-
onSubmitRef.current(concatenatedMessage);
|
|
76020
|
-
}
|
|
76312
|
+
} finally {
|
|
76313
|
+
if (shouldTrackAutoAllowed) {
|
|
76314
|
+
setIsExecutingTool(false);
|
|
76315
|
+
toolAbortControllerRef.current = null;
|
|
76316
|
+
executingToolCallIdsRef.current = [];
|
|
76317
|
+
autoAllowedExecutionRef.current = null;
|
|
76318
|
+
toolResultsInFlightRef.current = false;
|
|
76021
76319
|
}
|
|
76022
|
-
waitingForQueueCancelRef.current = false;
|
|
76023
|
-
queueSnapshotRef.current = [];
|
|
76024
|
-
setStreaming(false);
|
|
76025
|
-
return;
|
|
76026
76320
|
}
|
|
76027
76321
|
if (userCancelledRef.current || abortControllerRef.current?.signal.aborted) {
|
|
76028
76322
|
setStreaming(false);
|
|
@@ -76094,33 +76388,11 @@ ${newState.originalPrompt}`
|
|
|
76094
76388
|
const approvalPendingDetected = isApprovalPendingError(detailFromRun) || isApprovalPendingError(latestErrorText);
|
|
76095
76389
|
if (!hasApprovalInPayload && approvalPendingDetected && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES2) {
|
|
76096
76390
|
llmApiErrorRetriesRef.current += 1;
|
|
76097
|
-
const statusId = uid4("status");
|
|
76098
|
-
buffersRef.current.byId.set(statusId, {
|
|
76099
|
-
kind: "status",
|
|
76100
|
-
id: statusId,
|
|
76101
|
-
lines: [
|
|
76102
|
-
"[LAZY RECOVERY] Detected CONFLICT: server has pending approval",
|
|
76103
|
-
"[LAZY RECOVERY] Fetching stale approvals to auto-deny..."
|
|
76104
|
-
]
|
|
76105
|
-
});
|
|
76106
|
-
buffersRef.current.order.push(statusId);
|
|
76107
|
-
refreshDerived();
|
|
76108
76391
|
try {
|
|
76109
76392
|
const client = await getClient2();
|
|
76110
76393
|
const agent = await client.agents.retrieve(agentIdRef.current);
|
|
76111
76394
|
const { pendingApprovals: existingApprovals } = await getResumeData2(client, agent, conversationIdRef.current);
|
|
76112
76395
|
if (existingApprovals && existingApprovals.length > 0) {
|
|
76113
|
-
buffersRef.current.byId.set(statusId, {
|
|
76114
|
-
kind: "status",
|
|
76115
|
-
id: statusId,
|
|
76116
|
-
lines: [
|
|
76117
|
-
"[LAZY RECOVERY] Detected CONFLICT: server has pending approval",
|
|
76118
|
-
`[LAZY RECOVERY] Found ${existingApprovals.length} stale approval(s):`,
|
|
76119
|
-
...existingApprovals.map((a) => ` - ${a.toolName} (${a.toolCallId.slice(0, 8)}...)`),
|
|
76120
|
-
"[LAZY RECOVERY] Auto-denying and batching with user message..."
|
|
76121
|
-
]
|
|
76122
|
-
});
|
|
76123
|
-
refreshDerived();
|
|
76124
76396
|
const denialResults = existingApprovals.map((approval2) => ({
|
|
76125
76397
|
type: "approval",
|
|
76126
76398
|
tool_call_id: approval2.toolCallId,
|
|
@@ -76132,32 +76404,8 @@ ${newState.originalPrompt}`
|
|
|
76132
76404
|
approvals: denialResults
|
|
76133
76405
|
};
|
|
76134
76406
|
currentInput.unshift(approvalPayload);
|
|
76135
|
-
} else {
|
|
76136
|
-
buffersRef.current.byId.set(statusId, {
|
|
76137
|
-
kind: "status",
|
|
76138
|
-
id: statusId,
|
|
76139
|
-
lines: [
|
|
76140
|
-
"[LAZY RECOVERY] Detected CONFLICT but no pending approvals found",
|
|
76141
|
-
"[LAZY RECOVERY] Retrying message..."
|
|
76142
|
-
]
|
|
76143
|
-
});
|
|
76144
|
-
refreshDerived();
|
|
76145
76407
|
}
|
|
76146
|
-
} catch
|
|
76147
|
-
buffersRef.current.byId.set(statusId, {
|
|
76148
|
-
kind: "status",
|
|
76149
|
-
id: statusId,
|
|
76150
|
-
lines: [
|
|
76151
|
-
"[LAZY RECOVERY] Failed to fetch pending approvals",
|
|
76152
|
-
"[LAZY RECOVERY] Retrying message anyway..."
|
|
76153
|
-
]
|
|
76154
|
-
});
|
|
76155
|
-
refreshDerived();
|
|
76156
|
-
}
|
|
76157
|
-
await new Promise((resolve20) => setTimeout(resolve20, 500));
|
|
76158
|
-
buffersRef.current.byId.delete(statusId);
|
|
76159
|
-
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
76160
|
-
refreshDerived();
|
|
76408
|
+
} catch {}
|
|
76161
76409
|
buffersRef.current.interrupted = false;
|
|
76162
76410
|
continue;
|
|
76163
76411
|
}
|
|
@@ -76276,7 +76524,8 @@ ${newState.originalPrompt}`
|
|
|
76276
76524
|
setStreaming,
|
|
76277
76525
|
currentModelId,
|
|
76278
76526
|
updateStreamingOutput,
|
|
76279
|
-
needsEagerApprovalCheck
|
|
76527
|
+
needsEagerApprovalCheck,
|
|
76528
|
+
queueApprovalResults
|
|
76280
76529
|
]);
|
|
76281
76530
|
const handleExit = import_react84.useCallback(async () => {
|
|
76282
76531
|
saveLastAgentBeforeExit();
|
|
@@ -76292,19 +76541,31 @@ ${newState.originalPrompt}`
|
|
|
76292
76541
|
setMessageQueue([]);
|
|
76293
76542
|
}, []);
|
|
76294
76543
|
const handleInterrupt = import_react84.useCallback(async () => {
|
|
76295
|
-
|
|
76544
|
+
const hasTrackedTools = executingToolCallIdsRef.current.length > 0 || autoAllowedExecutionRef.current?.results;
|
|
76545
|
+
if (isExecutingTool && toolAbortControllerRef.current && hasTrackedTools && !toolResultsInFlightRef.current) {
|
|
76296
76546
|
toolAbortControllerRef.current.abort();
|
|
76297
|
-
|
|
76547
|
+
conversationGenerationRef.current += 1;
|
|
76548
|
+
processingConversationRef.current = 0;
|
|
76549
|
+
const autoAllowedResults = autoAllowedExecutionRef.current?.results;
|
|
76550
|
+
const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
|
|
76551
|
+
conversationId: autoAllowedExecutionRef.current.conversationId,
|
|
76552
|
+
generation: conversationGenerationRef.current
|
|
76553
|
+
} : undefined;
|
|
76554
|
+
if (autoAllowedResults && autoAllowedResults.length > 0) {
|
|
76555
|
+
queueApprovalResults(autoAllowedResults, autoAllowedMetadata);
|
|
76556
|
+
interruptQueuedRef.current = true;
|
|
76557
|
+
} else if (executingToolCallIdsRef.current.length > 0) {
|
|
76298
76558
|
const interruptedResults = executingToolCallIdsRef.current.map((toolCallId) => ({
|
|
76299
76559
|
type: "tool",
|
|
76300
76560
|
tool_call_id: toolCallId,
|
|
76301
76561
|
tool_return: INTERRUPTED_BY_USER,
|
|
76302
76562
|
status: "error"
|
|
76303
76563
|
}));
|
|
76304
|
-
|
|
76305
|
-
executingToolCallIdsRef.current = [];
|
|
76564
|
+
queueApprovalResults(interruptedResults);
|
|
76306
76565
|
interruptQueuedRef.current = true;
|
|
76307
76566
|
}
|
|
76567
|
+
executingToolCallIdsRef.current = [];
|
|
76568
|
+
autoAllowedExecutionRef.current = null;
|
|
76308
76569
|
buffersRef.current.abortGeneration = (buffersRef.current.abortGeneration || 0) + 1;
|
|
76309
76570
|
const toolsCancelled = markIncompleteToolsAsCancelled(buffersRef.current);
|
|
76310
76571
|
interruptActiveSubagents(INTERRUPTED_BY_USER);
|
|
@@ -76318,6 +76579,7 @@ ${newState.originalPrompt}`
|
|
|
76318
76579
|
userCancelledRef.current = true;
|
|
76319
76580
|
setStreaming(false);
|
|
76320
76581
|
setIsExecutingTool(false);
|
|
76582
|
+
toolResultsInFlightRef.current = false;
|
|
76321
76583
|
refreshDerived();
|
|
76322
76584
|
setTimeout(() => {
|
|
76323
76585
|
userCancelledRef.current = false;
|
|
@@ -76343,18 +76605,38 @@ ${newState.originalPrompt}`
|
|
|
76343
76605
|
conversationGenerationRef.current += 1;
|
|
76344
76606
|
processingConversationRef.current = 0;
|
|
76345
76607
|
setStreaming(false);
|
|
76608
|
+
toolResultsInFlightRef.current = false;
|
|
76346
76609
|
if (!toolsCancelled) {
|
|
76347
76610
|
appendError(INTERRUPT_MESSAGE, true);
|
|
76348
76611
|
}
|
|
76349
76612
|
refreshDerived();
|
|
76350
|
-
|
|
76351
|
-
|
|
76613
|
+
const denialResults = pendingApprovals.map((approval) => ({
|
|
76614
|
+
type: "approval",
|
|
76615
|
+
tool_call_id: approval.toolCallId,
|
|
76616
|
+
approve: false,
|
|
76617
|
+
reason: "User interrupted the stream"
|
|
76618
|
+
}));
|
|
76619
|
+
const autoHandledSnapshot = [...autoHandledResults];
|
|
76620
|
+
const autoDeniedSnapshot = [...autoDeniedApprovals];
|
|
76621
|
+
const queuedResults = [
|
|
76622
|
+
...autoHandledSnapshot.map((ar) => ({
|
|
76623
|
+
type: "tool",
|
|
76624
|
+
tool_call_id: ar.toolCallId,
|
|
76625
|
+
tool_return: ar.result.toolReturn,
|
|
76626
|
+
status: ar.result.status,
|
|
76627
|
+
stdout: ar.result.stdout,
|
|
76628
|
+
stderr: ar.result.stderr
|
|
76629
|
+
})),
|
|
76630
|
+
...autoDeniedSnapshot.map((ad) => ({
|
|
76352
76631
|
type: "approval",
|
|
76353
|
-
tool_call_id: approval.toolCallId,
|
|
76632
|
+
tool_call_id: ad.approval.toolCallId,
|
|
76354
76633
|
approve: false,
|
|
76355
|
-
reason:
|
|
76356
|
-
}))
|
|
76357
|
-
|
|
76634
|
+
reason: ad.reason
|
|
76635
|
+
})),
|
|
76636
|
+
...denialResults
|
|
76637
|
+
];
|
|
76638
|
+
if (queuedResults.length > 0) {
|
|
76639
|
+
queueApprovalResults(queuedResults);
|
|
76358
76640
|
}
|
|
76359
76641
|
setPendingApprovals([]);
|
|
76360
76642
|
setApprovalContexts([]);
|
|
@@ -76389,7 +76671,10 @@ ${newState.originalPrompt}`
|
|
|
76389
76671
|
isExecutingTool,
|
|
76390
76672
|
refreshDerived,
|
|
76391
76673
|
setStreaming,
|
|
76392
|
-
pendingApprovals
|
|
76674
|
+
pendingApprovals,
|
|
76675
|
+
autoHandledResults,
|
|
76676
|
+
autoDeniedApprovals,
|
|
76677
|
+
queueApprovalResults
|
|
76393
76678
|
]);
|
|
76394
76679
|
const processConversationRef = import_react84.useRef(processConversation);
|
|
76395
76680
|
import_react84.useEffect(() => {
|
|
@@ -76671,42 +76956,85 @@ ${newState.originalPrompt}`
|
|
|
76671
76956
|
return { blocked: true };
|
|
76672
76957
|
}
|
|
76673
76958
|
const allResults = [];
|
|
76674
|
-
|
|
76675
|
-
|
|
76676
|
-
|
|
76677
|
-
|
|
76678
|
-
|
|
76679
|
-
|
|
76680
|
-
|
|
76681
|
-
|
|
76682
|
-
|
|
76683
|
-
|
|
76684
|
-
|
|
76685
|
-
|
|
76686
|
-
|
|
76687
|
-
|
|
76688
|
-
const reason = ac.permission.reason || "Permission denied";
|
|
76689
|
-
onChunk(buffersRef.current, {
|
|
76690
|
-
message_type: "tool_return_message",
|
|
76691
|
-
id: "dummy",
|
|
76692
|
-
date: new Date().toISOString(),
|
|
76693
|
-
tool_call_id: ac.approval.toolCallId,
|
|
76694
|
-
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
76695
|
-
status: "error",
|
|
76696
|
-
stdout: null,
|
|
76697
|
-
stderr: null
|
|
76698
|
-
});
|
|
76699
|
-
allResults.push({
|
|
76700
|
-
type: "approval",
|
|
76701
|
-
tool_call_id: ac.approval.toolCallId,
|
|
76702
|
-
approve: false,
|
|
76703
|
-
reason
|
|
76704
|
-
});
|
|
76959
|
+
const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
|
|
76960
|
+
const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
|
|
76961
|
+
const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
|
|
76962
|
+
let autoAllowedResults = [];
|
|
76963
|
+
if (shouldTrackAutoAllowed) {
|
|
76964
|
+
setIsExecutingTool(true);
|
|
76965
|
+
executingToolCallIdsRef.current = autoAllowedToolCallIds;
|
|
76966
|
+
toolAbortControllerRef.current = autoAllowedAbortController;
|
|
76967
|
+
autoAllowedExecutionRef.current = {
|
|
76968
|
+
toolCallIds: autoAllowedToolCallIds,
|
|
76969
|
+
results: null,
|
|
76970
|
+
conversationId: conversationIdRef.current,
|
|
76971
|
+
generation: conversationGenerationRef.current
|
|
76972
|
+
};
|
|
76705
76973
|
}
|
|
76706
|
-
|
|
76707
|
-
|
|
76708
|
-
|
|
76709
|
-
|
|
76974
|
+
try {
|
|
76975
|
+
if (autoAllowed.length > 0) {
|
|
76976
|
+
setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
|
|
76977
|
+
refreshDerived();
|
|
76978
|
+
autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
|
|
76979
|
+
abortSignal: autoAllowedAbortController.signal,
|
|
76980
|
+
onStreamingOutput: updateStreamingOutput
|
|
76981
|
+
});
|
|
76982
|
+
allResults.push(...autoAllowedResults.map((ar) => ({
|
|
76983
|
+
type: "tool",
|
|
76984
|
+
tool_call_id: ar.toolCallId,
|
|
76985
|
+
tool_return: ar.result.toolReturn,
|
|
76986
|
+
status: ar.result.status,
|
|
76987
|
+
stdout: ar.result.stdout,
|
|
76988
|
+
stderr: ar.result.stderr
|
|
76989
|
+
})));
|
|
76990
|
+
}
|
|
76991
|
+
for (const ac of autoDenied) {
|
|
76992
|
+
const reason = ac.permission.reason || "Permission denied";
|
|
76993
|
+
onChunk(buffersRef.current, {
|
|
76994
|
+
message_type: "tool_return_message",
|
|
76995
|
+
id: "dummy",
|
|
76996
|
+
date: new Date().toISOString(),
|
|
76997
|
+
tool_call_id: ac.approval.toolCallId,
|
|
76998
|
+
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
76999
|
+
status: "error",
|
|
77000
|
+
stdout: null,
|
|
77001
|
+
stderr: null
|
|
77002
|
+
});
|
|
77003
|
+
allResults.push({
|
|
77004
|
+
type: "approval",
|
|
77005
|
+
tool_call_id: ac.approval.toolCallId,
|
|
77006
|
+
approve: false,
|
|
77007
|
+
reason
|
|
77008
|
+
});
|
|
77009
|
+
}
|
|
77010
|
+
if (autoAllowedExecutionRef.current) {
|
|
77011
|
+
autoAllowedExecutionRef.current.results = allResults;
|
|
77012
|
+
}
|
|
77013
|
+
const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
|
|
77014
|
+
conversationId: autoAllowedExecutionRef.current.conversationId,
|
|
77015
|
+
generation: conversationGenerationRef.current
|
|
77016
|
+
} : undefined;
|
|
77017
|
+
if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
|
|
77018
|
+
if (allResults.length > 0) {
|
|
77019
|
+
queueApprovalResults(allResults, autoAllowedMetadata);
|
|
77020
|
+
}
|
|
77021
|
+
return { blocked: false };
|
|
77022
|
+
}
|
|
77023
|
+
if (allResults.length > 0) {
|
|
77024
|
+
toolResultsInFlightRef.current = true;
|
|
77025
|
+
await processConversation([
|
|
77026
|
+
{ type: "approval", approvals: allResults }
|
|
77027
|
+
]);
|
|
77028
|
+
toolResultsInFlightRef.current = false;
|
|
77029
|
+
}
|
|
77030
|
+
} finally {
|
|
77031
|
+
if (shouldTrackAutoAllowed) {
|
|
77032
|
+
setIsExecutingTool(false);
|
|
77033
|
+
toolAbortControllerRef.current = null;
|
|
77034
|
+
executingToolCallIdsRef.current = [];
|
|
77035
|
+
autoAllowedExecutionRef.current = null;
|
|
77036
|
+
toolResultsInFlightRef.current = false;
|
|
77037
|
+
}
|
|
76710
77038
|
}
|
|
76711
77039
|
return { blocked: false };
|
|
76712
77040
|
} catch {
|
|
@@ -76717,7 +77045,8 @@ ${newState.originalPrompt}`
|
|
|
76717
77045
|
processConversation,
|
|
76718
77046
|
refreshDerived,
|
|
76719
77047
|
updateStreamingOutput,
|
|
76720
|
-
needsEagerApprovalCheck
|
|
77048
|
+
needsEagerApprovalCheck,
|
|
77049
|
+
queueApprovalResults
|
|
76721
77050
|
]);
|
|
76722
77051
|
const onSubmit = import_react84.useCallback(async (message) => {
|
|
76723
77052
|
const msg = message?.trim() ?? "";
|
|
@@ -77687,7 +78016,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
77687
78016
|
const client = await getClient2();
|
|
77688
78017
|
const fileContent = await client.agents.exportFile(agentId);
|
|
77689
78018
|
const fileName = `${agentId}.af`;
|
|
77690
|
-
|
|
78019
|
+
writeFileSync4(fileName, JSON.stringify(fileContent, null, 2));
|
|
77691
78020
|
buffersRef.current.byId.set(cmdId2, {
|
|
77692
78021
|
kind: "command",
|
|
77693
78022
|
id: cmdId2,
|
|
@@ -78267,52 +78596,112 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78267
78596
|
}
|
|
78268
78597
|
} catch {}
|
|
78269
78598
|
}
|
|
78270
|
-
|
|
78271
|
-
|
|
78272
|
-
const
|
|
78273
|
-
|
|
78274
|
-
|
|
78275
|
-
|
|
78276
|
-
|
|
78277
|
-
|
|
78278
|
-
|
|
78279
|
-
|
|
78280
|
-
|
|
78281
|
-
|
|
78282
|
-
|
|
78283
|
-
|
|
78284
|
-
});
|
|
78285
|
-
return {
|
|
78286
|
-
type: "approval",
|
|
78287
|
-
tool_call_id: ac.approval.toolCallId,
|
|
78288
|
-
approve: false,
|
|
78289
|
-
reason
|
|
78599
|
+
const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
|
|
78600
|
+
const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
|
|
78601
|
+
const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
|
|
78602
|
+
let autoAllowedResults = [];
|
|
78603
|
+
let autoDeniedResults = [];
|
|
78604
|
+
if (shouldTrackAutoAllowed) {
|
|
78605
|
+
setIsExecutingTool(true);
|
|
78606
|
+
executingToolCallIdsRef.current = autoAllowedToolCallIds;
|
|
78607
|
+
toolAbortControllerRef.current = autoAllowedAbortController;
|
|
78608
|
+
autoAllowedExecutionRef.current = {
|
|
78609
|
+
toolCallIds: autoAllowedToolCallIds,
|
|
78610
|
+
results: null,
|
|
78611
|
+
conversationId: conversationIdRef.current,
|
|
78612
|
+
generation: conversationGenerationRef.current
|
|
78290
78613
|
};
|
|
78291
|
-
}
|
|
78292
|
-
|
|
78293
|
-
|
|
78294
|
-
|
|
78295
|
-
|
|
78296
|
-
tool_call_id: ar.toolCallId,
|
|
78297
|
-
approve: true,
|
|
78298
|
-
tool_return: ar.result.toolReturn
|
|
78299
|
-
})),
|
|
78300
|
-
...autoDeniedResults
|
|
78301
|
-
];
|
|
78302
|
-
const initialInput2 = [
|
|
78303
|
-
{
|
|
78304
|
-
type: "approval",
|
|
78305
|
-
approvals: recoveryApprovalResults
|
|
78306
|
-
},
|
|
78307
|
-
{
|
|
78308
|
-
type: "message",
|
|
78309
|
-
role: "user",
|
|
78310
|
-
content: messageContent
|
|
78614
|
+
}
|
|
78615
|
+
try {
|
|
78616
|
+
if (autoAllowedToolCallIds.length > 0) {
|
|
78617
|
+
setToolCallsRunning(buffersRef.current, autoAllowedToolCallIds);
|
|
78618
|
+
refreshDerived();
|
|
78311
78619
|
}
|
|
78312
|
-
|
|
78313
|
-
|
|
78314
|
-
|
|
78315
|
-
|
|
78620
|
+
autoAllowedResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
|
|
78621
|
+
abortSignal: autoAllowedAbortController.signal,
|
|
78622
|
+
onStreamingOutput: updateStreamingOutput
|
|
78623
|
+
}) : [];
|
|
78624
|
+
autoDeniedResults = autoDenied.map((ac) => {
|
|
78625
|
+
const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
|
|
78626
|
+
onChunk(buffersRef.current, {
|
|
78627
|
+
message_type: "tool_return_message",
|
|
78628
|
+
id: "dummy",
|
|
78629
|
+
date: new Date().toISOString(),
|
|
78630
|
+
tool_call_id: ac.approval.toolCallId,
|
|
78631
|
+
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
78632
|
+
status: "error",
|
|
78633
|
+
stdout: null,
|
|
78634
|
+
stderr: null
|
|
78635
|
+
});
|
|
78636
|
+
return {
|
|
78637
|
+
type: "approval",
|
|
78638
|
+
tool_call_id: ac.approval.toolCallId,
|
|
78639
|
+
approve: false,
|
|
78640
|
+
reason
|
|
78641
|
+
};
|
|
78642
|
+
});
|
|
78643
|
+
const queuedResults = [
|
|
78644
|
+
...autoAllowedResults.map((ar) => ({
|
|
78645
|
+
type: "tool",
|
|
78646
|
+
tool_call_id: ar.toolCallId,
|
|
78647
|
+
tool_return: ar.result.toolReturn,
|
|
78648
|
+
status: ar.result.status,
|
|
78649
|
+
stdout: ar.result.stdout,
|
|
78650
|
+
stderr: ar.result.stderr
|
|
78651
|
+
})),
|
|
78652
|
+
...autoDeniedResults
|
|
78653
|
+
];
|
|
78654
|
+
if (autoAllowedExecutionRef.current) {
|
|
78655
|
+
autoAllowedExecutionRef.current.results = queuedResults;
|
|
78656
|
+
}
|
|
78657
|
+
const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
|
|
78658
|
+
conversationId: autoAllowedExecutionRef.current.conversationId,
|
|
78659
|
+
generation: conversationGenerationRef.current
|
|
78660
|
+
} : undefined;
|
|
78661
|
+
if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
|
|
78662
|
+
if (queuedResults.length > 0) {
|
|
78663
|
+
queueApprovalResults(queuedResults, autoAllowedMetadata);
|
|
78664
|
+
}
|
|
78665
|
+
setStreaming(false);
|
|
78666
|
+
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
78667
|
+
refreshDerived();
|
|
78668
|
+
return { submitted: false };
|
|
78669
|
+
}
|
|
78670
|
+
refreshDerived();
|
|
78671
|
+
const recoveryApprovalResults = [
|
|
78672
|
+
...autoAllowedResults.map((ar) => ({
|
|
78673
|
+
type: "approval",
|
|
78674
|
+
tool_call_id: ar.toolCallId,
|
|
78675
|
+
approve: true,
|
|
78676
|
+
tool_return: ar.result.toolReturn
|
|
78677
|
+
})),
|
|
78678
|
+
...autoDeniedResults
|
|
78679
|
+
];
|
|
78680
|
+
const initialInput2 = [
|
|
78681
|
+
{
|
|
78682
|
+
type: "approval",
|
|
78683
|
+
approvals: recoveryApprovalResults
|
|
78684
|
+
},
|
|
78685
|
+
{
|
|
78686
|
+
type: "message",
|
|
78687
|
+
role: "user",
|
|
78688
|
+
content: messageContent
|
|
78689
|
+
}
|
|
78690
|
+
];
|
|
78691
|
+
toolResultsInFlightRef.current = true;
|
|
78692
|
+
await processConversation(initialInput2);
|
|
78693
|
+
toolResultsInFlightRef.current = false;
|
|
78694
|
+
clearPlaceholdersInText(msg);
|
|
78695
|
+
return { submitted: true };
|
|
78696
|
+
} finally {
|
|
78697
|
+
if (shouldTrackAutoAllowed) {
|
|
78698
|
+
setIsExecutingTool(false);
|
|
78699
|
+
toolAbortControllerRef.current = null;
|
|
78700
|
+
executingToolCallIdsRef.current = [];
|
|
78701
|
+
autoAllowedExecutionRef.current = null;
|
|
78702
|
+
toolResultsInFlightRef.current = false;
|
|
78703
|
+
}
|
|
78704
|
+
}
|
|
78316
78705
|
} else {
|
|
78317
78706
|
buffersRef.current.byId.delete(userId);
|
|
78318
78707
|
const orderIndex = buffersRef.current.order.indexOf(userId);
|
|
@@ -78378,39 +78767,105 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78378
78767
|
}
|
|
78379
78768
|
} catch {}
|
|
78380
78769
|
}
|
|
78381
|
-
const
|
|
78382
|
-
const
|
|
78383
|
-
|
|
78384
|
-
|
|
78385
|
-
|
|
78386
|
-
|
|
78387
|
-
|
|
78388
|
-
|
|
78389
|
-
|
|
78390
|
-
|
|
78391
|
-
|
|
78392
|
-
|
|
78393
|
-
|
|
78394
|
-
|
|
78395
|
-
approval: ac.approval,
|
|
78396
|
-
reason
|
|
78770
|
+
const autoAllowedToolCallIds = autoAllowed.map((ac) => ac.approval.toolCallId);
|
|
78771
|
+
const autoAllowedAbortController = abortControllerRef.current ?? new AbortController;
|
|
78772
|
+
const shouldTrackAutoAllowed = autoAllowedToolCallIds.length > 0;
|
|
78773
|
+
let autoAllowedWithResults = [];
|
|
78774
|
+
let autoDeniedWithReasons = [];
|
|
78775
|
+
if (shouldTrackAutoAllowed) {
|
|
78776
|
+
setIsExecutingTool(true);
|
|
78777
|
+
executingToolCallIdsRef.current = autoAllowedToolCallIds;
|
|
78778
|
+
toolAbortControllerRef.current = autoAllowedAbortController;
|
|
78779
|
+
autoAllowedExecutionRef.current = {
|
|
78780
|
+
toolCallIds: autoAllowedToolCallIds,
|
|
78781
|
+
results: null,
|
|
78782
|
+
conversationId: conversationIdRef.current,
|
|
78783
|
+
generation: conversationGenerationRef.current
|
|
78397
78784
|
};
|
|
78398
|
-
}
|
|
78399
|
-
|
|
78400
|
-
|
|
78401
|
-
|
|
78402
|
-
|
|
78785
|
+
}
|
|
78786
|
+
try {
|
|
78787
|
+
autoAllowedWithResults = autoAllowed.length > 0 ? await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk), {
|
|
78788
|
+
abortSignal: autoAllowedAbortController.signal,
|
|
78789
|
+
onStreamingOutput: updateStreamingOutput
|
|
78790
|
+
}) : [];
|
|
78791
|
+
autoDeniedWithReasons = autoDenied.map((ac) => {
|
|
78792
|
+
const reason = ac.permission.reason ? `Permission denied: ${ac.permission.reason}` : ("matchedRule" in ac.permission) && ac.permission.matchedRule ? `Permission denied by rule: ${ac.permission.matchedRule}` : "Permission denied: Unknown";
|
|
78793
|
+
onChunk(buffersRef.current, {
|
|
78794
|
+
message_type: "tool_return_message",
|
|
78795
|
+
id: "dummy",
|
|
78796
|
+
date: new Date().toISOString(),
|
|
78797
|
+
tool_call_id: ac.approval.toolCallId,
|
|
78798
|
+
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
78799
|
+
status: "error",
|
|
78800
|
+
stdout: null,
|
|
78801
|
+
stderr: null
|
|
78802
|
+
});
|
|
78803
|
+
return {
|
|
78804
|
+
approval: ac.approval,
|
|
78805
|
+
reason
|
|
78806
|
+
};
|
|
78807
|
+
});
|
|
78808
|
+
const queuedResults = [
|
|
78809
|
+
...autoAllowedWithResults.map((ar) => ({
|
|
78810
|
+
type: "tool",
|
|
78811
|
+
tool_call_id: ar.toolCallId,
|
|
78812
|
+
tool_return: ar.result.toolReturn,
|
|
78813
|
+
status: ar.result.status,
|
|
78814
|
+
stdout: ar.result.stdout,
|
|
78815
|
+
stderr: ar.result.stderr
|
|
78816
|
+
})),
|
|
78817
|
+
...autoDeniedWithReasons.map((ad) => ({
|
|
78818
|
+
type: "approval",
|
|
78819
|
+
tool_call_id: ad.approval.toolCallId,
|
|
78820
|
+
approve: false,
|
|
78821
|
+
reason: ad.reason
|
|
78822
|
+
}))
|
|
78823
|
+
];
|
|
78824
|
+
if (autoAllowedExecutionRef.current) {
|
|
78825
|
+
autoAllowedExecutionRef.current.results = queuedResults;
|
|
78826
|
+
}
|
|
78827
|
+
const autoAllowedMetadata = autoAllowedExecutionRef.current ? {
|
|
78828
|
+
conversationId: autoAllowedExecutionRef.current.conversationId,
|
|
78829
|
+
generation: conversationGenerationRef.current
|
|
78830
|
+
} : undefined;
|
|
78831
|
+
if (userCancelledRef.current || autoAllowedAbortController.signal.aborted || interruptQueuedRef.current) {
|
|
78832
|
+
if (queuedResults.length > 0) {
|
|
78833
|
+
queueApprovalResults(queuedResults, autoAllowedMetadata);
|
|
78834
|
+
}
|
|
78835
|
+
setStreaming(false);
|
|
78836
|
+
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
78837
|
+
refreshDerived();
|
|
78838
|
+
return { submitted: false };
|
|
78839
|
+
}
|
|
78840
|
+
setAutoHandledResults(autoAllowedWithResults);
|
|
78841
|
+
setAutoDeniedApprovals(autoDeniedWithReasons);
|
|
78842
|
+
refreshDerived();
|
|
78843
|
+
return { submitted: false };
|
|
78844
|
+
} finally {
|
|
78845
|
+
if (shouldTrackAutoAllowed) {
|
|
78846
|
+
setIsExecutingTool(false);
|
|
78847
|
+
toolAbortControllerRef.current = null;
|
|
78848
|
+
executingToolCallIdsRef.current = [];
|
|
78849
|
+
autoAllowedExecutionRef.current = null;
|
|
78850
|
+
}
|
|
78851
|
+
}
|
|
78403
78852
|
}
|
|
78404
78853
|
}
|
|
78405
78854
|
} catch (_error) {}
|
|
78406
78855
|
}
|
|
78407
78856
|
const initialInput = [];
|
|
78408
78857
|
if (queuedApprovalResults) {
|
|
78409
|
-
|
|
78410
|
-
|
|
78411
|
-
|
|
78412
|
-
|
|
78413
|
-
|
|
78858
|
+
const queuedMetadata = queuedApprovalMetadataRef.current;
|
|
78859
|
+
const isQueuedValid = queuedMetadata && queuedMetadata.conversationId === conversationIdRef.current && queuedMetadata.generation === conversationGenerationRef.current;
|
|
78860
|
+
if (isQueuedValid) {
|
|
78861
|
+
initialInput.push({
|
|
78862
|
+
type: "approval",
|
|
78863
|
+
approvals: queuedApprovalResults
|
|
78864
|
+
});
|
|
78865
|
+
} else {
|
|
78866
|
+
console.warn("[WARN] Dropping stale queued approval results for mismatched conversation or generation");
|
|
78867
|
+
}
|
|
78868
|
+
queueApprovalResults(null);
|
|
78414
78869
|
interruptQueuedRef.current = false;
|
|
78415
78870
|
}
|
|
78416
78871
|
initialInput.push({
|
|
@@ -78433,6 +78888,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78433
78888
|
handleExit,
|
|
78434
78889
|
isExecutingTool,
|
|
78435
78890
|
queuedApprovalResults,
|
|
78891
|
+
queueApprovalResults,
|
|
78436
78892
|
pendingApprovals,
|
|
78437
78893
|
profileConfirmPending,
|
|
78438
78894
|
handleAgentSelect,
|
|
@@ -78544,24 +79000,27 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78544
79000
|
const userCancelled = userCancelledRef.current;
|
|
78545
79001
|
if (wasAborted || userCancelled) {
|
|
78546
79002
|
if (!interruptQueuedRef.current) {
|
|
78547
|
-
|
|
79003
|
+
queueApprovalResults(allResults);
|
|
78548
79004
|
}
|
|
78549
79005
|
setStreaming(false);
|
|
78550
79006
|
waitingForQueueCancelRef.current = false;
|
|
78551
79007
|
queueSnapshotRef.current = [];
|
|
78552
79008
|
} else {
|
|
79009
|
+
toolResultsInFlightRef.current = true;
|
|
78553
79010
|
await processConversation([
|
|
78554
79011
|
{
|
|
78555
79012
|
type: "approval",
|
|
78556
79013
|
approvals: allResults
|
|
78557
79014
|
}
|
|
78558
79015
|
]);
|
|
79016
|
+
toolResultsInFlightRef.current = false;
|
|
78559
79017
|
}
|
|
78560
79018
|
} finally {
|
|
78561
79019
|
setIsExecutingTool(false);
|
|
78562
79020
|
toolAbortControllerRef.current = null;
|
|
78563
79021
|
executingToolCallIdsRef.current = [];
|
|
78564
79022
|
interruptQueuedRef.current = false;
|
|
79023
|
+
toolResultsInFlightRef.current = false;
|
|
78565
79024
|
}
|
|
78566
79025
|
}, [
|
|
78567
79026
|
approvalResults,
|
|
@@ -78572,7 +79031,8 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78572
79031
|
refreshDerived,
|
|
78573
79032
|
appendError,
|
|
78574
79033
|
setStreaming,
|
|
78575
|
-
updateStreamingOutput
|
|
79034
|
+
updateStreamingOutput,
|
|
79035
|
+
queueApprovalResults
|
|
78576
79036
|
]);
|
|
78577
79037
|
const handleApproveCurrent = import_react84.useCallback(async (diffs) => {
|
|
78578
79038
|
if (isExecutingTool)
|
|
@@ -78770,7 +79230,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78770
79230
|
approve: false,
|
|
78771
79231
|
reason: "User cancelled the approval"
|
|
78772
79232
|
}));
|
|
78773
|
-
|
|
79233
|
+
queueApprovalResults(denialResults);
|
|
78774
79234
|
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
78775
79235
|
refreshDerived();
|
|
78776
79236
|
setPendingApprovals([]);
|
|
@@ -78778,7 +79238,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
78778
79238
|
setApprovalResults([]);
|
|
78779
79239
|
setAutoHandledResults([]);
|
|
78780
79240
|
setAutoDeniedApprovals([]);
|
|
78781
|
-
}, [pendingApprovals, refreshDerived]);
|
|
79241
|
+
}, [pendingApprovals, refreshDerived, queueApprovalResults]);
|
|
78782
79242
|
const handleModelSelect = import_react84.useCallback(async (modelId) => {
|
|
78783
79243
|
await withCommandLock(async () => {
|
|
78784
79244
|
let cmdId = null;
|
|
@@ -79160,7 +79620,7 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
79160
79620
|
reason: "Plan mode session expired (CLI restarted). Use EnterPlanMode to re-enter plan mode, or request the user to re-enter plan mode."
|
|
79161
79621
|
}
|
|
79162
79622
|
];
|
|
79163
|
-
|
|
79623
|
+
queueApprovalResults(denialResults);
|
|
79164
79624
|
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
79165
79625
|
refreshDerived();
|
|
79166
79626
|
setPendingApprovals([]);
|
|
@@ -79172,7 +79632,7 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
79172
79632
|
}
|
|
79173
79633
|
if (!planFileExists()) {
|
|
79174
79634
|
const planFilePath = permissionMode.getPlanFilePath();
|
|
79175
|
-
const plansDir =
|
|
79635
|
+
const plansDir = join21(homedir12(), ".letta", "plans");
|
|
79176
79636
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
79177
79637
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
79178
79638
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -79182,7 +79642,8 @@ Consider switching to a different system prompt using /system to match.` : null;
|
|
|
79182
79642
|
pendingApprovals,
|
|
79183
79643
|
approvalResults.length,
|
|
79184
79644
|
handlePlanKeepPlanning,
|
|
79185
|
-
refreshDerived
|
|
79645
|
+
refreshDerived,
|
|
79646
|
+
queueApprovalResults
|
|
79186
79647
|
]);
|
|
79187
79648
|
const handleQuestionSubmit = import_react84.useCallback(async (answers) => {
|
|
79188
79649
|
const currentIndex = approvalResults.length;
|
|
@@ -80043,13 +80504,13 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
80043
80504
|
});
|
|
80044
80505
|
import {
|
|
80045
80506
|
copyFileSync as copyFileSync2,
|
|
80046
|
-
existsSync as
|
|
80047
|
-
mkdirSync as
|
|
80507
|
+
existsSync as existsSync14,
|
|
80508
|
+
mkdirSync as mkdirSync6,
|
|
80048
80509
|
readFileSync as readFileSync5,
|
|
80049
|
-
writeFileSync as
|
|
80510
|
+
writeFileSync as writeFileSync5
|
|
80050
80511
|
} from "node:fs";
|
|
80051
|
-
import { homedir as
|
|
80052
|
-
import { dirname as dirname12, join as
|
|
80512
|
+
import { homedir as homedir13, platform as platform5 } from "node:os";
|
|
80513
|
+
import { dirname as dirname12, join as join22 } from "node:path";
|
|
80053
80514
|
function detectTerminalType2() {
|
|
80054
80515
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
80055
80516
|
return "cursor";
|
|
@@ -80079,18 +80540,18 @@ function getKeybindingsPath2(terminal) {
|
|
|
80079
80540
|
cursor: "Cursor",
|
|
80080
80541
|
windsurf: "Windsurf"
|
|
80081
80542
|
}[terminal];
|
|
80082
|
-
const
|
|
80083
|
-
if (
|
|
80084
|
-
return
|
|
80543
|
+
const os6 = platform5();
|
|
80544
|
+
if (os6 === "darwin") {
|
|
80545
|
+
return join22(homedir13(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
80085
80546
|
}
|
|
80086
|
-
if (
|
|
80547
|
+
if (os6 === "win32") {
|
|
80087
80548
|
const appData = process.env.APPDATA;
|
|
80088
80549
|
if (!appData)
|
|
80089
80550
|
return null;
|
|
80090
|
-
return
|
|
80551
|
+
return join22(appData, appName, "User", "keybindings.json");
|
|
80091
80552
|
}
|
|
80092
|
-
if (
|
|
80093
|
-
return
|
|
80553
|
+
if (os6 === "linux") {
|
|
80554
|
+
return join22(homedir13(), ".config", appName, "User", "keybindings.json");
|
|
80094
80555
|
}
|
|
80095
80556
|
return null;
|
|
80096
80557
|
}
|
|
@@ -80112,7 +80573,7 @@ function parseKeybindings2(content) {
|
|
|
80112
80573
|
}
|
|
80113
80574
|
}
|
|
80114
80575
|
function keybindingExists2(keybindingsPath) {
|
|
80115
|
-
if (!
|
|
80576
|
+
if (!existsSync14(keybindingsPath))
|
|
80116
80577
|
return false;
|
|
80117
80578
|
try {
|
|
80118
80579
|
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -80125,7 +80586,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
80125
80586
|
}
|
|
80126
80587
|
}
|
|
80127
80588
|
function createBackup2(keybindingsPath) {
|
|
80128
|
-
if (!
|
|
80589
|
+
if (!existsSync14(keybindingsPath))
|
|
80129
80590
|
return null;
|
|
80130
80591
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
80131
80592
|
try {
|
|
@@ -80141,12 +80602,12 @@ function installKeybinding2(keybindingsPath) {
|
|
|
80141
80602
|
return { success: true, alreadyExists: true };
|
|
80142
80603
|
}
|
|
80143
80604
|
const parentDir = dirname12(keybindingsPath);
|
|
80144
|
-
if (!
|
|
80145
|
-
|
|
80605
|
+
if (!existsSync14(parentDir)) {
|
|
80606
|
+
mkdirSync6(parentDir, { recursive: true });
|
|
80146
80607
|
}
|
|
80147
80608
|
let keybindings = [];
|
|
80148
80609
|
let backupPath = null;
|
|
80149
|
-
if (
|
|
80610
|
+
if (existsSync14(keybindingsPath)) {
|
|
80150
80611
|
backupPath = createBackup2(keybindingsPath);
|
|
80151
80612
|
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
80152
80613
|
const parsed = parseKeybindings2(content);
|
|
@@ -80161,7 +80622,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
80161
80622
|
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
80162
80623
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
80163
80624
|
`;
|
|
80164
|
-
|
|
80625
|
+
writeFileSync5(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
80165
80626
|
return {
|
|
80166
80627
|
success: true,
|
|
80167
80628
|
backupPath: backupPath ?? undefined
|
|
@@ -80176,7 +80637,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
80176
80637
|
}
|
|
80177
80638
|
function removeKeybinding2(keybindingsPath) {
|
|
80178
80639
|
try {
|
|
80179
|
-
if (!
|
|
80640
|
+
if (!existsSync14(keybindingsPath)) {
|
|
80180
80641
|
return { success: true };
|
|
80181
80642
|
}
|
|
80182
80643
|
const content = readFileSync5(keybindingsPath, { encoding: "utf-8" });
|
|
@@ -80190,7 +80651,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
80190
80651
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
80191
80652
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
80192
80653
|
`;
|
|
80193
|
-
|
|
80654
|
+
writeFileSync5(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
80194
80655
|
return { success: true };
|
|
80195
80656
|
} catch (error) {
|
|
80196
80657
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -80208,14 +80669,14 @@ function installKeybindingForCurrentTerminal2() {
|
|
|
80208
80669
|
error: "Not running in a VS Code-like terminal"
|
|
80209
80670
|
};
|
|
80210
80671
|
}
|
|
80211
|
-
const
|
|
80212
|
-
if (!
|
|
80672
|
+
const path21 = getKeybindingsPath2(terminal);
|
|
80673
|
+
if (!path21) {
|
|
80213
80674
|
return {
|
|
80214
80675
|
success: false,
|
|
80215
80676
|
error: `Could not determine keybindings.json path for ${terminal}`
|
|
80216
80677
|
};
|
|
80217
80678
|
}
|
|
80218
|
-
return installKeybinding2(
|
|
80679
|
+
return installKeybinding2(path21);
|
|
80219
80680
|
}
|
|
80220
80681
|
function removeKeybindingForCurrentTerminal2() {
|
|
80221
80682
|
const terminal = detectTerminalType2();
|
|
@@ -80225,14 +80686,14 @@ function removeKeybindingForCurrentTerminal2() {
|
|
|
80225
80686
|
error: "Not running in a VS Code-like terminal"
|
|
80226
80687
|
};
|
|
80227
80688
|
}
|
|
80228
|
-
const
|
|
80229
|
-
if (!
|
|
80689
|
+
const path21 = getKeybindingsPath2(terminal);
|
|
80690
|
+
if (!path21) {
|
|
80230
80691
|
return {
|
|
80231
80692
|
success: false,
|
|
80232
80693
|
error: `Could not determine keybindings.json path for ${terminal}`
|
|
80233
80694
|
};
|
|
80234
80695
|
}
|
|
80235
|
-
return removeKeybinding2(
|
|
80696
|
+
return removeKeybinding2(path21);
|
|
80236
80697
|
}
|
|
80237
80698
|
function isWezTerm2() {
|
|
80238
80699
|
return process.env.TERM_PROGRAM === "WezTerm";
|
|
@@ -80243,17 +80704,17 @@ function getWezTermConfigPath2() {
|
|
|
80243
80704
|
}
|
|
80244
80705
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
80245
80706
|
if (xdgConfig) {
|
|
80246
|
-
const xdgPath =
|
|
80247
|
-
if (
|
|
80707
|
+
const xdgPath = join22(xdgConfig, "wezterm", "wezterm.lua");
|
|
80708
|
+
if (existsSync14(xdgPath))
|
|
80248
80709
|
return xdgPath;
|
|
80249
80710
|
}
|
|
80250
|
-
const configPath =
|
|
80251
|
-
if (
|
|
80711
|
+
const configPath = join22(homedir13(), ".config", "wezterm", "wezterm.lua");
|
|
80712
|
+
if (existsSync14(configPath))
|
|
80252
80713
|
return configPath;
|
|
80253
|
-
return
|
|
80714
|
+
return join22(homedir13(), ".wezterm.lua");
|
|
80254
80715
|
}
|
|
80255
80716
|
function wezTermDeleteFixExists2(configPath) {
|
|
80256
|
-
if (!
|
|
80717
|
+
if (!existsSync14(configPath))
|
|
80257
80718
|
return false;
|
|
80258
80719
|
try {
|
|
80259
80720
|
const content = readFileSync5(configPath, { encoding: "utf-8" });
|
|
@@ -80270,7 +80731,7 @@ function installWezTermDeleteFix2() {
|
|
|
80270
80731
|
}
|
|
80271
80732
|
let content = "";
|
|
80272
80733
|
let backupPath = null;
|
|
80273
|
-
if (
|
|
80734
|
+
if (existsSync14(configPath)) {
|
|
80274
80735
|
backupPath = `${configPath}.letta-backup`;
|
|
80275
80736
|
copyFileSync2(configPath, backupPath);
|
|
80276
80737
|
content = readFileSync5(configPath, { encoding: "utf-8" });
|
|
@@ -80300,10 +80761,10 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
80300
80761
|
`;
|
|
80301
80762
|
}
|
|
80302
80763
|
const parentDir = dirname12(configPath);
|
|
80303
|
-
if (!
|
|
80304
|
-
|
|
80764
|
+
if (!existsSync14(parentDir)) {
|
|
80765
|
+
mkdirSync6(parentDir, { recursive: true });
|
|
80305
80766
|
}
|
|
80306
|
-
|
|
80767
|
+
writeFileSync5(configPath, content, { encoding: "utf-8" });
|
|
80307
80768
|
return {
|
|
80308
80769
|
success: true,
|
|
80309
80770
|
backupPath: backupPath ?? undefined
|
|
@@ -80348,10 +80809,10 @@ __export(exports_settings2, {
|
|
|
80348
80809
|
loadProjectSettings: () => loadProjectSettings2,
|
|
80349
80810
|
getSetting: () => getSetting2
|
|
80350
80811
|
});
|
|
80351
|
-
import { homedir as
|
|
80352
|
-
import { join as
|
|
80812
|
+
import { homedir as homedir14 } from "node:os";
|
|
80813
|
+
import { join as join23 } from "node:path";
|
|
80353
80814
|
function getSettingsPath2() {
|
|
80354
|
-
return
|
|
80815
|
+
return join23(homedir14(), ".letta", "settings.json");
|
|
80355
80816
|
}
|
|
80356
80817
|
async function loadSettings2() {
|
|
80357
80818
|
const settingsPath = getSettingsPath2();
|
|
@@ -80388,7 +80849,7 @@ async function getSetting2(key) {
|
|
|
80388
80849
|
return settings[key];
|
|
80389
80850
|
}
|
|
80390
80851
|
function getProjectSettingsPath2() {
|
|
80391
|
-
return
|
|
80852
|
+
return join23(process.cwd(), ".letta", "settings.local.json");
|
|
80392
80853
|
}
|
|
80393
80854
|
async function loadProjectSettings2() {
|
|
80394
80855
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -80406,7 +80867,7 @@ async function loadProjectSettings2() {
|
|
|
80406
80867
|
}
|
|
80407
80868
|
async function saveProjectSettings2(settings) {
|
|
80408
80869
|
const settingsPath = getProjectSettingsPath2();
|
|
80409
|
-
const dirPath =
|
|
80870
|
+
const dirPath = join23(process.cwd(), ".letta");
|
|
80410
80871
|
try {
|
|
80411
80872
|
if (!exists(dirPath)) {
|
|
80412
80873
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -80485,8 +80946,8 @@ var exports_create = {};
|
|
|
80485
80946
|
__export(exports_create, {
|
|
80486
80947
|
createAgent: () => createAgent2
|
|
80487
80948
|
});
|
|
80488
|
-
import { join as
|
|
80489
|
-
async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel
|
|
80949
|
+
import { join as join24 } from "node:path";
|
|
80950
|
+
async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingModel, updateArgs, skillsDirectory, parallelToolCalls = true, enableSleeptime = false, systemPromptPreset, initBlocks, baseTools) {
|
|
80490
80951
|
let options;
|
|
80491
80952
|
if (typeof nameOrOptions === "object") {
|
|
80492
80953
|
options = nameOrOptions;
|
|
@@ -80505,7 +80966,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
80505
80966
|
};
|
|
80506
80967
|
}
|
|
80507
80968
|
const name = options.name ?? DEFAULT_AGENT_NAME;
|
|
80508
|
-
const embeddingModelVal = options.embeddingModel
|
|
80969
|
+
const embeddingModelVal = options.embeddingModel;
|
|
80509
80970
|
const parallelToolCallsVal = options.parallelToolCalls ?? true;
|
|
80510
80971
|
const enableSleeptimeVal = options.enableSleeptime ?? false;
|
|
80511
80972
|
let modelHandle;
|
|
@@ -80580,7 +81041,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
80580
81041
|
}
|
|
80581
81042
|
}
|
|
80582
81043
|
}
|
|
80583
|
-
const resolvedSkillsDirectory = options.skillsDirectory ||
|
|
81044
|
+
const resolvedSkillsDirectory = options.skillsDirectory || join24(process.cwd(), SKILLS_DIR);
|
|
80584
81045
|
try {
|
|
80585
81046
|
const { skills, errors } = await discoverSkills(resolvedSkillsDirectory);
|
|
80586
81047
|
if (errors.length > 0) {
|
|
@@ -80627,7 +81088,7 @@ ${options.systemPromptAppend}`;
|
|
|
80627
81088
|
system: systemPromptContent,
|
|
80628
81089
|
name,
|
|
80629
81090
|
description: agentDescription,
|
|
80630
|
-
embedding: embeddingModelVal,
|
|
81091
|
+
embedding: embeddingModelVal || undefined,
|
|
80631
81092
|
model: modelHandle,
|
|
80632
81093
|
context_window_limit: contextWindow,
|
|
80633
81094
|
tools: toolNames,
|
|
@@ -83416,12 +83877,12 @@ EXAMPLES
|
|
|
83416
83877
|
console.log(usage);
|
|
83417
83878
|
}
|
|
83418
83879
|
async function printInfo() {
|
|
83419
|
-
const { join:
|
|
83880
|
+
const { join: join25 } = await import("path");
|
|
83420
83881
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
|
|
83421
83882
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
83422
83883
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
83423
83884
|
const cwd2 = process.cwd();
|
|
83424
|
-
const skillsDir =
|
|
83885
|
+
const skillsDir = join25(cwd2, SKILLS_DIR3);
|
|
83425
83886
|
const skillsExist = exists3(skillsDir);
|
|
83426
83887
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
83427
83888
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -83560,6 +84021,12 @@ async function main() {
|
|
|
83560
84021
|
telemetry2.init();
|
|
83561
84022
|
const { checkAndAutoUpdate: checkAndAutoUpdate2 } = await Promise.resolve().then(() => (init_auto_update(), exports_auto_update));
|
|
83562
84023
|
checkAndAutoUpdate2().catch(() => {});
|
|
84024
|
+
const { cleanupOldOverflowFiles: cleanupOldOverflowFiles2 } = await Promise.resolve().then(() => (init_overflow2(), exports_overflow));
|
|
84025
|
+
Promise.resolve().then(() => {
|
|
84026
|
+
try {
|
|
84027
|
+
cleanupOldOverflowFiles2(process.cwd());
|
|
84028
|
+
} catch {}
|
|
84029
|
+
});
|
|
83563
84030
|
const processedArgs = process.argv.map((arg) => arg === "--conv" ? "--conversation" : arg);
|
|
83564
84031
|
let values;
|
|
83565
84032
|
let positionals;
|
|
@@ -83599,7 +84066,8 @@ async function main() {
|
|
|
83599
84066
|
"include-partial-messages": { type: "boolean" },
|
|
83600
84067
|
skills: { type: "string" },
|
|
83601
84068
|
sleeptime: { type: "boolean" },
|
|
83602
|
-
"from-af": { type: "string" }
|
|
84069
|
+
"from-af": { type: "string" },
|
|
84070
|
+
"no-skills": { type: "boolean" }
|
|
83603
84071
|
},
|
|
83604
84072
|
strict: true,
|
|
83605
84073
|
allowPositionals: true
|
|
@@ -83796,9 +84264,9 @@ Usage: letta --new-agent`);
|
|
|
83796
84264
|
process.exit(1);
|
|
83797
84265
|
}
|
|
83798
84266
|
const { resolve: resolve21 } = await import("path");
|
|
83799
|
-
const { existsSync:
|
|
84267
|
+
const { existsSync: existsSync15 } = await import("fs");
|
|
83800
84268
|
const resolvedPath = resolve21(fromAfFile);
|
|
83801
|
-
if (!
|
|
84269
|
+
if (!existsSync15(resolvedPath)) {
|
|
83802
84270
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
83803
84271
|
process.exit(1);
|
|
83804
84272
|
}
|
|
@@ -84300,8 +84768,8 @@ Error: ${message}`);
|
|
|
84300
84768
|
(async () => {
|
|
84301
84769
|
try {
|
|
84302
84770
|
const { syncSkillsToAgent: syncSkillsToAgent3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
84303
|
-
const { join:
|
|
84304
|
-
const resolvedSkillsDirectory = skillsDirectory2 ||
|
|
84771
|
+
const { join: join25 } = await import("path");
|
|
84772
|
+
const resolvedSkillsDirectory = skillsDirectory2 || join25(process.cwd(), SKILLS_DIR3);
|
|
84305
84773
|
await syncSkillsToAgent3(client, agent.id, resolvedSkillsDirectory, {
|
|
84306
84774
|
skipIfUnchanged: true
|
|
84307
84775
|
});
|
|
@@ -84542,4 +85010,4 @@ Error during initialization: ${message}`);
|
|
|
84542
85010
|
}
|
|
84543
85011
|
main();
|
|
84544
85012
|
|
|
84545
|
-
//# debugId=
|
|
85013
|
+
//# debugId=A2D04DEC6336411264756E2164756E21
|