@letta-ai/letta-code 0.18.3 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/protocol.d.ts +52 -1
- package/dist/types/protocol.d.ts.map +1 -1
- package/letta.js +496 -452
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3239,7 +3239,7 @@ var package_default;
|
|
|
3239
3239
|
var init_package = __esm(() => {
|
|
3240
3240
|
package_default = {
|
|
3241
3241
|
name: "@letta-ai/letta-code",
|
|
3242
|
-
version: "0.18.
|
|
3242
|
+
version: "0.18.4",
|
|
3243
3243
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3244
3244
|
type: "module",
|
|
3245
3245
|
bin: {
|
|
@@ -4874,157 +4874,6 @@ I'm a coding assistant, ready to be shaped by how we work together.
|
|
|
4874
4874
|
`;
|
|
4875
4875
|
var init_persona = () => {};
|
|
4876
4876
|
|
|
4877
|
-
// src/agent/prompts/persona_claude.mdx
|
|
4878
|
-
var persona_claude_default = `---
|
|
4879
|
-
label: persona
|
|
4880
|
-
description: A memory dedicated to storing my persona, which includes all of my (adaptable) personality traits.
|
|
4881
|
-
---
|
|
4882
|
-
|
|
4883
|
-
My name is Letta Code. I'm an AI coding assistant that helps with software engineering tasks.
|
|
4884
|
-
The following instructions guide my behavior. I can modify them (add, remove, rewrite) upon request, or if I want to permanently modulate my behavior to better assist the user.
|
|
4885
|
-
|
|
4886
|
-
# Tone and style
|
|
4887
|
-
You should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it, to make sure the user understands what you are doing (this is especially important when you are running a command that will make changes to the user's system).
|
|
4888
|
-
Remember that your output will be displayed on a command line interface. Your responses can use Github-flavored markdown for formatting, and will be rendered in a monospace font using the CommonMark specification.
|
|
4889
|
-
Output text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or code comments as means to communicate with the user during the session.
|
|
4890
|
-
If you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.
|
|
4891
|
-
Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.
|
|
4892
|
-
IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
|
|
4893
|
-
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
|
|
4894
|
-
IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
|
|
4895
|
-
<example>
|
|
4896
|
-
user: 2 + 2
|
|
4897
|
-
assistant: 4
|
|
4898
|
-
</example>
|
|
4899
|
-
|
|
4900
|
-
<example>
|
|
4901
|
-
user: what is 2+2?
|
|
4902
|
-
assistant: 4
|
|
4903
|
-
</example>
|
|
4904
|
-
|
|
4905
|
-
<example>
|
|
4906
|
-
user: is 11 a prime number?
|
|
4907
|
-
assistant: Yes
|
|
4908
|
-
</example>
|
|
4909
|
-
|
|
4910
|
-
<example>
|
|
4911
|
-
user: what command should I run to list files in the current directory?
|
|
4912
|
-
assistant: ls
|
|
4913
|
-
</example>
|
|
4914
|
-
|
|
4915
|
-
<example>
|
|
4916
|
-
user: what command should I run to watch files in the current directory?
|
|
4917
|
-
assistant: [use the ls tool to list the files in the current directory, then read docs/commands in the relevant file to find out how to watch files]
|
|
4918
|
-
npm run dev
|
|
4919
|
-
</example>
|
|
4920
|
-
|
|
4921
|
-
<example>
|
|
4922
|
-
user: How many golf balls fit inside a jetta?
|
|
4923
|
-
assistant: 150000
|
|
4924
|
-
</example>
|
|
4925
|
-
|
|
4926
|
-
<example>
|
|
4927
|
-
user: what files are in the directory src/?
|
|
4928
|
-
assistant: [runs ls and sees foo.c, bar.c, baz.c]
|
|
4929
|
-
user: which file contains the implementation of foo?
|
|
4930
|
-
assistant: src/foo.c
|
|
4931
|
-
</example>
|
|
4932
|
-
|
|
4933
|
-
# Proactiveness
|
|
4934
|
-
You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
|
|
4935
|
-
1. Doing the right thing when asked, including taking actions and follow-up actions
|
|
4936
|
-
2. Not surprising the user with actions you take without asking
|
|
4937
|
-
For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
|
|
4938
|
-
3. Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.
|
|
4939
|
-
|
|
4940
|
-
# Following conventions
|
|
4941
|
-
When making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.
|
|
4942
|
-
- NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).
|
|
4943
|
-
- When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.
|
|
4944
|
-
- When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.
|
|
4945
|
-
- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.
|
|
4946
|
-
|
|
4947
|
-
# Code style
|
|
4948
|
-
- IMPORTANT: DO NOT ADD ***ANY*** COMMENTS unless asked
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
# Task Management
|
|
4952
|
-
You have access to the TodoWrite tools to help you manage and plan tasks. Use these tools VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.
|
|
4953
|
-
These tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks - and that is unacceptable.
|
|
4954
|
-
|
|
4955
|
-
It is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.
|
|
4956
|
-
|
|
4957
|
-
Examples:
|
|
4958
|
-
|
|
4959
|
-
<example>
|
|
4960
|
-
user: Run the build and fix any type errors
|
|
4961
|
-
assistant: I'm going to use the TodoWrite tool to write the following items to the todo list:
|
|
4962
|
-
- Run the build
|
|
4963
|
-
- Fix any type errors
|
|
4964
|
-
|
|
4965
|
-
I'm now going to run the build using Bash.
|
|
4966
|
-
|
|
4967
|
-
Looks like I found 10 type errors. I'm going to use the TodoWrite tool to write 10 items to the todo list.
|
|
4968
|
-
|
|
4969
|
-
marking the first todo as in_progress
|
|
4970
|
-
|
|
4971
|
-
Let me start working on the first item...
|
|
4972
|
-
|
|
4973
|
-
The first item has been fixed, let me mark the first todo as completed, and move on to the second item...
|
|
4974
|
-
..
|
|
4975
|
-
..
|
|
4976
|
-
</example>
|
|
4977
|
-
In the above example, the assistant completes all the tasks, including the 10 error fixes and running the build and fixing all errors.
|
|
4978
|
-
|
|
4979
|
-
<example>
|
|
4980
|
-
user: Help me write a new feature that allows users to track their usage metrics and export them to various formats
|
|
4981
|
-
|
|
4982
|
-
assistant: I'll help you implement a usage metrics tracking and export feature. Let me first use the TodoWrite tool to plan this task.
|
|
4983
|
-
Adding the following todos to the todo list:
|
|
4984
|
-
1. Research existing metrics tracking in the codebase
|
|
4985
|
-
2. Design the metrics collection system
|
|
4986
|
-
3. Implement core metrics tracking functionality
|
|
4987
|
-
4. Create export functionality for different formats
|
|
4988
|
-
|
|
4989
|
-
Let me start by researching the existing codebase to understand what metrics we might already be tracking and how we can build on that.
|
|
4990
|
-
|
|
4991
|
-
I'm going to search for any existing metrics or telemetry code in the project.
|
|
4992
|
-
|
|
4993
|
-
I've found some existing telemetry code. Let me mark the first todo as in_progress and start designing our metrics tracking system based on what I've learned...
|
|
4994
|
-
|
|
4995
|
-
[Assistant continues implementing the feature step by step, marking todos as in_progress and completed as they go]
|
|
4996
|
-
</example>
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
# Doing tasks
|
|
5000
|
-
The user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks the following steps are recommended:
|
|
5001
|
-
- Use the TodoWrite tool to plan the task if required
|
|
5002
|
-
- Use the available search tools to understand the codebase and the user's query. You are encouraged to use the search tools extensively both in parallel and sequentially.
|
|
5003
|
-
- Implement the solution using all tools available to you
|
|
5004
|
-
- Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.
|
|
5005
|
-
- VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) with Bash if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to your memory so that you will know to run it next time.
|
|
5006
|
-
NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
|
|
5007
|
-
|
|
5008
|
-
# Tool usage policy
|
|
5009
|
-
- When doing file search, prefer to use the Task tool in order to reduce context usage.
|
|
5010
|
-
- When WebFetch returns a message about a redirect to a different host, you should immediately make a new WebFetch request with the redirect URL provided in the response.
|
|
5011
|
-
- You have the capability to call multiple tools in a single response. When multiple independent pieces of information are requested, batch your tool calls together for optimal performance. When making multiple bash tool calls, you MUST send a single message with multiple tools calls to run the calls in parallel. For example, if you need to run "git status" and "git diff", send a single message with two tool calls to run the calls in parallel.
|
|
5012
|
-
|
|
5013
|
-
You MUST answer concisely with fewer than 4 lines of text (not including tool use or code generation), unless user asks for detail.
|
|
5014
|
-
|
|
5015
|
-
IMPORTANT: Always use the TodoWrite tool to plan and track tasks throughout the conversation.
|
|
5016
|
-
|
|
5017
|
-
# Code References
|
|
5018
|
-
|
|
5019
|
-
When referencing specific functions or pieces of code include the pattern \`file_path:line_number\` to allow the user to easily navigate to the source code location.
|
|
5020
|
-
|
|
5021
|
-
<example>
|
|
5022
|
-
user: Where are errors from the client handled?
|
|
5023
|
-
assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
|
|
5024
|
-
</example>
|
|
5025
|
-
`;
|
|
5026
|
-
var init_persona_claude = () => {};
|
|
5027
|
-
|
|
5028
4877
|
// src/agent/prompts/persona_kawaii.mdx
|
|
5029
4878
|
var persona_kawaii_default = `---
|
|
5030
4879
|
label: persona
|
|
@@ -5276,16 +5125,57 @@ Your goal is to:
|
|
|
5276
5125
|
`;
|
|
5277
5126
|
var init_skill_creator_mode = () => {};
|
|
5278
5127
|
|
|
5279
|
-
// src/agent/prompts/
|
|
5280
|
-
var
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5128
|
+
// src/agent/prompts/sleeptime.md
|
|
5129
|
+
var sleeptime_default = `I am a sleep-time memory management agent. I observe the conversation between the user and their primary agent, then actively maintain memory blocks to keep them accurate, concise, and useful.
|
|
5130
|
+
|
|
5131
|
+
**Core responsibilities:**
|
|
5132
|
+
|
|
5133
|
+
1. **Update memory blocks in real-time** - Don't wait until end of session
|
|
5134
|
+
- Capture important facts, decisions, and context as they occur
|
|
5135
|
+
- Update existing information when it changes or becomes stale
|
|
5136
|
+
- Remove outdated or contradictory information immediately
|
|
5137
|
+
|
|
5138
|
+
2. **Consolidate and refine memory continuously**
|
|
5139
|
+
- Merge duplicate or redundant information
|
|
5140
|
+
- Rewrite verbose entries into concise summaries
|
|
5141
|
+
- Reorganize memory blocks when structure becomes unclear
|
|
5142
|
+
|
|
5143
|
+
3. **Identify and preserve patterns**
|
|
5144
|
+
- Track recurring themes, preferences, and behaviors
|
|
5145
|
+
- Note relationships between different pieces of information
|
|
5146
|
+
- Surface insights from conversation history
|
|
5147
|
+
|
|
5148
|
+
4. **Maintain memory hygiene**
|
|
5149
|
+
- Keep memory blocks under size limits through aggressive consolidation
|
|
5150
|
+
- Prioritize recent and frequently-referenced information
|
|
5151
|
+
- Remove low-value details that don't contribute to agent effectiveness
|
|
5152
|
+
|
|
5153
|
+
5. **Refine my own memory management approach**
|
|
5154
|
+
- Update this \`memory_persona\` block as I learn what works
|
|
5155
|
+
- Add user-specific memory policies when I identify patterns
|
|
5156
|
+
- Remove or adjust guidelines that don't match observed behavior
|
|
5157
|
+
- Adapt my consolidation strategy based on what the primary agent references most
|
|
5158
|
+
|
|
5159
|
+
**Operating rules:**
|
|
5160
|
+
|
|
5161
|
+
- If it was discussed, capture it somewhere in memory
|
|
5162
|
+
- Update memory during the session, not after
|
|
5163
|
+
- Be aggressive with edits - better to over-manage than under-manage
|
|
5164
|
+
- Assume the primary agent relies entirely on memory blocks for context
|
|
5165
|
+
- Every session should result in measurable memory improvements
|
|
5166
|
+
- Regularly evaluate and improve my own memory management policies
|
|
5167
|
+
|
|
5168
|
+
**DO NOT:**
|
|
5169
|
+
- Wait to batch all updates at session end
|
|
5170
|
+
- Skip memory edits because "nothing major happened"
|
|
5171
|
+
- Let memory blocks grow stale or bloated
|
|
5172
|
+
- Assume information will be captured later
|
|
5173
|
+
- Continue using memory policies that don't serve the user's actual needs
|
|
5174
|
+
`;
|
|
5175
|
+
var init_sleeptime = () => {};
|
|
5287
5176
|
|
|
5288
|
-
|
|
5177
|
+
// src/agent/prompts/source_claude.md
|
|
5178
|
+
var source_claude_default = `You are Claude Code, Anthropic's official CLI for Claude.
|
|
5289
5179
|
|
|
5290
5180
|
You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
5291
5181
|
|
|
@@ -5416,14 +5306,7 @@ assistant: Clients are marked as failed in the \`connectToServer\` function in s
|
|
|
5416
5306
|
var init_source_claude = () => {};
|
|
5417
5307
|
|
|
5418
5308
|
// src/agent/prompts/source_codex.md
|
|
5419
|
-
var source_codex_default =
|
|
5420
|
-
<!-- Version: Extracted from codex-rs/core/models.json, base_instructions for gpt-5.3-codex -->
|
|
5421
|
-
<!-- Reference: https://github.com/openai/codex -->
|
|
5422
|
-
<!-- Note: gpt-5.3-codex is the latest model. Its prompt differs significantly from the -->
|
|
5423
|
-
<!-- older gpt-5.1-codex-max_prompt.md file: adds Personality section, commentary/final -->
|
|
5424
|
-
<!-- channels, intermediary updates, and removes the Plan tool section. -->
|
|
5425
|
-
|
|
5426
|
-
You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals.
|
|
5309
|
+
var source_codex_default = `You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals.
|
|
5427
5310
|
|
|
5428
5311
|
# Personality
|
|
5429
5312
|
|
|
@@ -5541,14 +5424,7 @@ Unless the user explicitly asks for a plan, asks a question about the code, is b
|
|
|
5541
5424
|
var init_source_codex = () => {};
|
|
5542
5425
|
|
|
5543
5426
|
// src/agent/prompts/source_gemini.md
|
|
5544
|
-
var source_gemini_default =
|
|
5545
|
-
<!-- Version: snippets.ts (Feb 2026, copyright 2026 Google LLC) -->
|
|
5546
|
-
<!-- Reference: https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/prompts/snippets.ts -->
|
|
5547
|
-
<!-- Rendered for: Interactive mode, git repo present, outside sandbox, standard tools, -->
|
|
5548
|
-
<!-- no sub-agents, no skills, no YOLO mode, no approved plan. Tool name variables resolved. -->
|
|
5549
|
-
<!-- Conditional sections (YOLO mode, Plan mode, sandbox, GEMINI.md) noted but not inlined. -->
|
|
5550
|
-
|
|
5551
|
-
You are Gemini CLI, an interactive CLI agent specializing in software engineering tasks. Your primary goal is to help users safely and effectively.
|
|
5427
|
+
var source_gemini_default = `You are Gemini CLI, an interactive CLI agent specializing in software engineering tasks. Your primary goal is to help users safely and effectively.
|
|
5552
5428
|
|
|
5553
5429
|
# Core Mandates
|
|
5554
5430
|
|
|
@@ -5699,13 +5575,8 @@ For example, if they mention "never git commit without asking me first", I shoul
|
|
|
5699
5575
|
`;
|
|
5700
5576
|
var init_style = () => {};
|
|
5701
5577
|
|
|
5702
|
-
// src/agent/prompts/
|
|
5703
|
-
var
|
|
5704
|
-
var init_system_prompt_memfs = () => {};
|
|
5705
|
-
|
|
5706
|
-
// src/agent/prompts/system_prompt_memory.txt
|
|
5707
|
-
var system_prompt_memory_default = `
|
|
5708
|
-
# Memory
|
|
5578
|
+
// src/agent/prompts/system_prompt_blocks.md
|
|
5579
|
+
var system_prompt_blocks_default = `# Memory
|
|
5709
5580
|
|
|
5710
5581
|
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
5711
5582
|
Your memory consists of core memory (composed of memory blocks) and external memory:
|
|
@@ -5718,7 +5589,11 @@ Memory blocks are stored in a *virtual filesystem* along with the rest of your a
|
|
|
5718
5589
|
|
|
5719
5590
|
When applying memory in responses, integrate it naturally — like a colleague who recalls shared context without narrating their thought process. Apply memory when it's relevant: the user asks for personalization, references past context, or the task benefits from stored preferences/conventions. Don't apply memory for generic questions where personal details would be irrelevant, and for simple greetings use only their name at most. Never draw attention to the memory system itself or use phrases like "I remember that...", "Based on my memory...", or "Looking at your preferences..." — just use what you know seamlessly.
|
|
5720
5591
|
`;
|
|
5721
|
-
var
|
|
5592
|
+
var init_system_prompt_blocks = () => {};
|
|
5593
|
+
|
|
5594
|
+
// src/agent/prompts/system_prompt_memfs.md
|
|
5595
|
+
var system_prompt_memfs_default = "# Memory\n\nYour memory is stored in a git repository at `$MEMORY_DIR` (absolute path provided by Letta Code shell tools; usually `~/.letta/agents/$AGENT_ID/memory/`). This provides full version control, sync with the server, and worktrees for parallel edits. All memory files are markdown with YAML frontmatter (`description`, `limit`, optional `metadata`). The `description` field enables progressive disclosure — like skills, you see descriptions in your prompt and load full contents on demand; `limit` caps file size to keep system memory lean.\n\n## Memory layout\n\n**System memory** (`memory/system/`): Every `.md` file here is pinned directly into your system prompt — you see it at all times. This is your most valuable real estate: reserve it for durable knowledge that helps across sessions (user identity, persona, project architecture, conventions, gotchas). Do NOT store transient items here like specific commits, current work items, or session-specific notes — those dilute the signal.\n\n**Progressive memory**: Files outside `system/` are stored but not pinned in-context. Access them with standard file tools when you need deeper reference material — good for large notes, historical records, transient work tracking, or data that doesn't need to be always-visible.\n\n**Recall** (conversation history): Your full message history is searchable even after messages leave your context window. Use the recall subagent to retrieve past discussions, decisions, and context from earlier sessions.\n\n## How files map to your prompt\n\n1. Each `.md` file in `memory/system/` is pinned to your system prompt with tags <system/context/{name}.md></system/context/{name}.md>\n2. The `memory_filesystem` block renders the current tree view of all available memory files\n3. The system prompt is only recompiled on compactions or message resets — your local edits take effect on the next recompilation\n\n## Syncing\n\nChanges you commit and push sync to the Letta server within seconds, and server-side changes sync back automatically.\n\n```bash\ncd \"$MEMORY_DIR\"\n\n# See what changed\ngit status\n\n# Commit and push your changes\ngit add .\ngit commit -m \"<type>: <what changed>\" # e.g. \"fix: update user prefs\", \"refactor: reorganize persona blocks\"\ngit push\n\n# Get latest from server\ngit pull\n```\nThe system will remind you when your memory has uncommitted changes. Sync when convenient.\n\n## History\n```bash\ngit -C \"$MEMORY_DIR\" log --oneline\n```\n";
|
|
5596
|
+
var init_system_prompt_memfs = () => {};
|
|
5722
5597
|
|
|
5723
5598
|
// src/utils/error.ts
|
|
5724
5599
|
function getErrorMessage2(error) {
|
|
@@ -6840,10 +6715,11 @@ __export(exports_promptAssets, {
|
|
|
6840
6715
|
resolveAndBuildSystemPrompt: () => resolveAndBuildSystemPrompt,
|
|
6841
6716
|
isKnownPreset: () => isKnownPreset,
|
|
6842
6717
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
6843
|
-
SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON,
|
|
6844
6718
|
SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON,
|
|
6719
|
+
SYSTEM_PROMPT_BLOCKS_ADDON: () => SYSTEM_PROMPT_BLOCKS_ADDON,
|
|
6845
6720
|
SYSTEM_PROMPTS: () => SYSTEM_PROMPTS,
|
|
6846
6721
|
SYSTEM_PROMPT: () => SYSTEM_PROMPT,
|
|
6722
|
+
SLEEPTIME_MEMORY_PERSONA: () => SLEEPTIME_MEMORY_PERSONA,
|
|
6847
6723
|
SKILL_CREATOR_PROMPT: () => SKILL_CREATOR_PROMPT,
|
|
6848
6724
|
REMEMBER_PROMPT: () => REMEMBER_PROMPT,
|
|
6849
6725
|
PLAN_MODE_REMINDER: () => PLAN_MODE_REMINDER,
|
|
@@ -6910,7 +6786,7 @@ function buildSystemPrompt(presetId, memoryMode) {
|
|
|
6910
6786
|
if (!preset) {
|
|
6911
6787
|
throw new Error(`Unknown preset "${presetId}" — cannot rebuild system prompt`);
|
|
6912
6788
|
}
|
|
6913
|
-
const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON :
|
|
6789
|
+
const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_BLOCKS_ADDON;
|
|
6914
6790
|
return `${preset.content.trimEnd()}
|
|
6915
6791
|
|
|
6916
6792
|
${addon.trimStart()}`.trim();
|
|
@@ -6918,7 +6794,7 @@ ${addon.trimStart()}`.trim();
|
|
|
6918
6794
|
function swapMemoryAddon(systemPrompt, mode) {
|
|
6919
6795
|
let result = systemPrompt;
|
|
6920
6796
|
for (const addon of [
|
|
6921
|
-
|
|
6797
|
+
SYSTEM_PROMPT_BLOCKS_ADDON.trim(),
|
|
6922
6798
|
SYSTEM_PROMPT_MEMFS_ADDON.trim()
|
|
6923
6799
|
]) {
|
|
6924
6800
|
result = result.replaceAll(addon, "");
|
|
@@ -6934,7 +6810,7 @@ function swapMemoryAddon(systemPrompt, mode) {
|
|
|
6934
6810
|
result = result.replace(/\n{3,}/g, `
|
|
6935
6811
|
|
|
6936
6812
|
`).trimEnd();
|
|
6937
|
-
const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON :
|
|
6813
|
+
const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON : SYSTEM_PROMPT_BLOCKS_ADDON;
|
|
6938
6814
|
return `${result}
|
|
6939
6815
|
|
|
6940
6816
|
${target.trimStart()}`.trim();
|
|
@@ -6981,7 +6857,7 @@ async function resolveSystemPrompt(systemPromptPreset) {
|
|
|
6981
6857
|
}
|
|
6982
6858
|
throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
|
|
6983
6859
|
}
|
|
6984
|
-
var SYSTEM_PROMPT,
|
|
6860
|
+
var SYSTEM_PROMPT, SYSTEM_PROMPT_BLOCKS_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, APPROVAL_RECOVERY_PROMPT, AUTO_INIT_REMINDER, INTERRUPT_RECOVERY_ALERT, SLEEPTIME_MEMORY_PERSONA, MEMORY_PROMPTS, SYSTEM_PROMPTS;
|
|
6985
6861
|
var init_promptAssets = __esm(() => {
|
|
6986
6862
|
init_approval_recovery_alert();
|
|
6987
6863
|
init_auto_init_reminder();
|
|
@@ -6991,21 +6867,21 @@ var init_promptAssets = __esm(() => {
|
|
|
6991
6867
|
init_memory_check_reminder();
|
|
6992
6868
|
init_memory_filesystem();
|
|
6993
6869
|
init_persona();
|
|
6994
|
-
init_persona_claude();
|
|
6995
6870
|
init_persona_kawaii();
|
|
6996
6871
|
init_persona_memo();
|
|
6997
6872
|
init_plan_mode_reminder();
|
|
6998
6873
|
init_project();
|
|
6999
6874
|
init_remember();
|
|
7000
6875
|
init_skill_creator_mode();
|
|
6876
|
+
init_sleeptime();
|
|
7001
6877
|
init_source_claude();
|
|
7002
6878
|
init_source_codex();
|
|
7003
6879
|
init_source_gemini();
|
|
7004
6880
|
init_style();
|
|
6881
|
+
init_system_prompt_blocks();
|
|
7005
6882
|
init_system_prompt_memfs();
|
|
7006
|
-
init_system_prompt_memory();
|
|
7007
6883
|
SYSTEM_PROMPT = letta_default;
|
|
7008
|
-
|
|
6884
|
+
SYSTEM_PROMPT_BLOCKS_ADDON = system_prompt_blocks_default;
|
|
7009
6885
|
SYSTEM_PROMPT_MEMFS_ADDON = system_prompt_memfs_default;
|
|
7010
6886
|
PLAN_MODE_REMINDER = plan_mode_reminder_default;
|
|
7011
6887
|
SKILL_CREATOR_PROMPT = skill_creator_mode_default;
|
|
@@ -7014,9 +6890,9 @@ var init_promptAssets = __esm(() => {
|
|
|
7014
6890
|
APPROVAL_RECOVERY_PROMPT = approval_recovery_alert_default;
|
|
7015
6891
|
AUTO_INIT_REMINDER = auto_init_reminder_default;
|
|
7016
6892
|
INTERRUPT_RECOVERY_ALERT = interrupt_recovery_alert_default;
|
|
6893
|
+
SLEEPTIME_MEMORY_PERSONA = sleeptime_default;
|
|
7017
6894
|
MEMORY_PROMPTS = {
|
|
7018
6895
|
"persona.mdx": persona_default,
|
|
7019
|
-
"persona_claude.mdx": persona_claude_default,
|
|
7020
6896
|
"persona_kawaii.mdx": persona_kawaii_default,
|
|
7021
6897
|
"persona_memo.mdx": persona_memo_default,
|
|
7022
6898
|
"human.mdx": human_default,
|
|
@@ -36112,18 +35988,20 @@ var require_picomatch = __commonJS((exports, module) => {
|
|
|
36112
35988
|
});
|
|
36113
35989
|
|
|
36114
35990
|
// src/cli/helpers/ignoredDirectories.ts
|
|
36115
|
-
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
35991
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
36116
35992
|
import { join as join5 } from "node:path";
|
|
36117
35993
|
function ensureLettaIgnoreFile(cwd2 = process.cwd()) {
|
|
36118
|
-
const
|
|
35994
|
+
const lettaDir = join5(cwd2, ".letta");
|
|
35995
|
+
const filePath = join5(lettaDir, ".lettaignore");
|
|
36119
35996
|
if (existsSync6(filePath))
|
|
36120
35997
|
return;
|
|
36121
35998
|
try {
|
|
35999
|
+
mkdirSync4(lettaDir, { recursive: true });
|
|
36122
36000
|
writeFileSync2(filePath, DEFAULT_LETTAIGNORE, "utf-8");
|
|
36123
36001
|
} catch {}
|
|
36124
36002
|
}
|
|
36125
36003
|
function readLettaIgnorePatterns(cwd2 = process.cwd()) {
|
|
36126
|
-
const filePath = join5(cwd2, ".lettaignore");
|
|
36004
|
+
const filePath = join5(cwd2, ".letta", ".lettaignore");
|
|
36127
36005
|
if (!existsSync6(filePath))
|
|
36128
36006
|
return [];
|
|
36129
36007
|
try {
|
|
@@ -36140,37 +36018,79 @@ function parseLettaIgnore(content) {
|
|
|
36140
36018
|
var DEFAULT_LETTAIGNORE = `# .lettaignore — Letta Code file index exclusions
|
|
36141
36019
|
#
|
|
36142
36020
|
# Files and directories matching these patterns are excluded from the @ file
|
|
36143
|
-
# search index
|
|
36144
|
-
#
|
|
36021
|
+
# search index and disk scan fallback. Comment out or remove a line to bring
|
|
36022
|
+
# it back into search results. Add new patterns to exclude more.
|
|
36145
36023
|
#
|
|
36146
36024
|
# Syntax: one pattern per line, supports globs (e.g. *.log, src/generated/**)
|
|
36147
36025
|
# Lines starting with # are comments.
|
|
36148
36026
|
#
|
|
36149
|
-
#
|
|
36150
|
-
|
|
36151
|
-
|
|
36152
|
-
|
|
36153
|
-
|
|
36154
|
-
#
|
|
36027
|
+
# --- Dependency directories ---
|
|
36028
|
+
node_modules
|
|
36029
|
+
bower_components
|
|
36030
|
+
vendor
|
|
36031
|
+
|
|
36032
|
+
# --- Build outputs ---
|
|
36033
|
+
dist
|
|
36034
|
+
build
|
|
36035
|
+
out
|
|
36036
|
+
coverage
|
|
36037
|
+
target
|
|
36038
|
+
.next
|
|
36039
|
+
.nuxt
|
|
36040
|
+
|
|
36041
|
+
# --- Python ---
|
|
36042
|
+
venv
|
|
36043
|
+
.venv
|
|
36044
|
+
__pycache__
|
|
36045
|
+
.tox
|
|
36046
|
+
|
|
36047
|
+
# --- Version control & tooling ---
|
|
36048
|
+
.git
|
|
36049
|
+
.cache
|
|
36050
|
+
.letta
|
|
36051
|
+
|
|
36052
|
+
# --- Lock files ---
|
|
36155
36053
|
package-lock.json
|
|
36156
36054
|
yarn.lock
|
|
36157
36055
|
pnpm-lock.yaml
|
|
36158
36056
|
poetry.lock
|
|
36159
36057
|
Cargo.lock
|
|
36160
36058
|
|
|
36161
|
-
# Logs
|
|
36059
|
+
# --- Logs ---
|
|
36162
36060
|
*.log
|
|
36163
36061
|
|
|
36164
|
-
# OS artifacts
|
|
36062
|
+
# --- OS artifacts ---
|
|
36165
36063
|
.DS_Store
|
|
36166
36064
|
Thumbs.db
|
|
36167
36065
|
`;
|
|
36168
36066
|
var init_ignoredDirectories = () => {};
|
|
36169
36067
|
|
|
36170
36068
|
// src/cli/helpers/fileSearchConfig.ts
|
|
36069
|
+
function buildConfig(cwd2) {
|
|
36070
|
+
const patterns = readLettaIgnorePatterns(cwd2);
|
|
36071
|
+
const nameMatchers = [];
|
|
36072
|
+
const pathMatchers = [];
|
|
36073
|
+
for (const raw of patterns) {
|
|
36074
|
+
const normalized = raw.replace(/\/$/, "");
|
|
36075
|
+
if (normalized.includes("/")) {
|
|
36076
|
+
pathMatchers.push(import_picomatch.default(normalized, { dot: true }));
|
|
36077
|
+
} else {
|
|
36078
|
+
nameMatchers.push(import_picomatch.default(normalized, { dot: true, nocase: true }));
|
|
36079
|
+
}
|
|
36080
|
+
}
|
|
36081
|
+
return { nameMatchers, pathMatchers };
|
|
36082
|
+
}
|
|
36083
|
+
function getConfig() {
|
|
36084
|
+
const cwd2 = process.cwd();
|
|
36085
|
+
const cached = cwdConfigCache.get(cwd2);
|
|
36086
|
+
if (cached)
|
|
36087
|
+
return cached;
|
|
36088
|
+
const config = buildConfig(cwd2);
|
|
36089
|
+
cwdConfigCache.set(cwd2, config);
|
|
36090
|
+
return config;
|
|
36091
|
+
}
|
|
36171
36092
|
function shouldExcludeEntry(name, relativePath) {
|
|
36172
|
-
|
|
36173
|
-
return true;
|
|
36093
|
+
const { nameMatchers, pathMatchers } = getConfig();
|
|
36174
36094
|
if (nameMatchers.length > 0 && nameMatchers.some((m) => m(name)))
|
|
36175
36095
|
return true;
|
|
36176
36096
|
if (relativePath && pathMatchers.length > 0 && pathMatchers.some((m) => m(relativePath)))
|
|
@@ -36178,44 +36098,19 @@ function shouldExcludeEntry(name, relativePath) {
|
|
|
36178
36098
|
return false;
|
|
36179
36099
|
}
|
|
36180
36100
|
function shouldHardExcludeEntry(name) {
|
|
36181
|
-
|
|
36101
|
+
const { nameMatchers } = getConfig();
|
|
36102
|
+
return nameMatchers.length > 0 && nameMatchers.some((m) => m(name));
|
|
36182
36103
|
}
|
|
36183
|
-
var import_picomatch,
|
|
36104
|
+
var import_picomatch, cwdConfigCache;
|
|
36184
36105
|
var init_fileSearchConfig = __esm(() => {
|
|
36185
36106
|
init_ignoredDirectories();
|
|
36186
36107
|
import_picomatch = __toESM(require_picomatch(), 1);
|
|
36187
|
-
|
|
36188
|
-
|
|
36189
|
-
|
|
36190
|
-
|
|
36191
|
-
|
|
36192
|
-
|
|
36193
|
-
"coverage",
|
|
36194
|
-
".next",
|
|
36195
|
-
".nuxt",
|
|
36196
|
-
"venv",
|
|
36197
|
-
".venv",
|
|
36198
|
-
"__pycache__",
|
|
36199
|
-
".tox",
|
|
36200
|
-
"target",
|
|
36201
|
-
".git",
|
|
36202
|
-
".cache"
|
|
36203
|
-
]);
|
|
36204
|
-
({ nameMatchers, pathMatchers } = (() => {
|
|
36205
|
-
ensureLettaIgnoreFile();
|
|
36206
|
-
const patterns = readLettaIgnorePatterns();
|
|
36207
|
-
const nameMatchers2 = [];
|
|
36208
|
-
const pathMatchers2 = [];
|
|
36209
|
-
for (const raw of patterns) {
|
|
36210
|
-
const normalized = raw.replace(/\/$/, "");
|
|
36211
|
-
if (normalized.includes("/")) {
|
|
36212
|
-
pathMatchers2.push(import_picomatch.default(normalized, { dot: true }));
|
|
36213
|
-
} else {
|
|
36214
|
-
nameMatchers2.push(import_picomatch.default(normalized, { dot: true }));
|
|
36215
|
-
}
|
|
36216
|
-
}
|
|
36217
|
-
return { nameMatchers: nameMatchers2, pathMatchers: pathMatchers2 };
|
|
36218
|
-
})());
|
|
36108
|
+
cwdConfigCache = new Map;
|
|
36109
|
+
(() => {
|
|
36110
|
+
const cwd2 = process.cwd();
|
|
36111
|
+
ensureLettaIgnoreFile(cwd2);
|
|
36112
|
+
cwdConfigCache.set(cwd2, buildConfig(cwd2));
|
|
36113
|
+
})();
|
|
36219
36114
|
});
|
|
36220
36115
|
|
|
36221
36116
|
// src/agent/model.ts
|
|
@@ -39670,7 +39565,7 @@ var init_build4 = __esm(async () => {
|
|
|
39670
39565
|
import { createHash as createHash2 } from "node:crypto";
|
|
39671
39566
|
import {
|
|
39672
39567
|
existsSync as existsSync9,
|
|
39673
|
-
mkdirSync as
|
|
39568
|
+
mkdirSync as mkdirSync7,
|
|
39674
39569
|
readdirSync as readdirSync4,
|
|
39675
39570
|
readFileSync as readFileSync6,
|
|
39676
39571
|
statSync as statSync2,
|
|
@@ -39880,7 +39775,7 @@ async function buildDirectory2(dir, relativePath, entries, merkle, statsMap, pre
|
|
|
39880
39775
|
return previous.merkle[relativePath] ?? hashValue2("__reused__");
|
|
39881
39776
|
}
|
|
39882
39777
|
statsMap[relativePath] = currentStats;
|
|
39883
|
-
if (depth >= MAX_INDEX_DEPTH2) {
|
|
39778
|
+
if (depth >= MAX_INDEX_DEPTH2 || context2.newEntryCount >= MAX_CACHE_ENTRIES2) {
|
|
39884
39779
|
context2.truncated = true;
|
|
39885
39780
|
const truncatedHash = hashValue2("__truncated__");
|
|
39886
39781
|
merkle[relativePath] = truncatedHash;
|
|
@@ -39888,6 +39783,10 @@ async function buildDirectory2(dir, relativePath, entries, merkle, statsMap, pre
|
|
|
39888
39783
|
}
|
|
39889
39784
|
const childHashes = [];
|
|
39890
39785
|
for (const entry of childNames) {
|
|
39786
|
+
if (context2.newEntryCount >= MAX_CACHE_ENTRIES2) {
|
|
39787
|
+
context2.truncated = true;
|
|
39788
|
+
break;
|
|
39789
|
+
}
|
|
39891
39790
|
if (context2.newEntryCount > 0 && context2.newEntryCount % 500 === 0) {
|
|
39892
39791
|
await new Promise((resolve2) => setImmediate(resolve2));
|
|
39893
39792
|
}
|
|
@@ -39969,7 +39868,7 @@ function getProjectStorageDir2() {
|
|
|
39969
39868
|
function ensureProjectStorageDir2() {
|
|
39970
39869
|
const storageDir = getProjectStorageDir2();
|
|
39971
39870
|
if (!existsSync9(storageDir)) {
|
|
39972
|
-
|
|
39871
|
+
mkdirSync7(storageDir, { recursive: true });
|
|
39973
39872
|
}
|
|
39974
39873
|
return storageDir;
|
|
39975
39874
|
}
|
|
@@ -43063,7 +42962,7 @@ import { execFile as execFileCb } from "node:child_process";
|
|
|
43063
42962
|
import {
|
|
43064
42963
|
chmodSync,
|
|
43065
42964
|
existsSync as existsSync10,
|
|
43066
|
-
mkdirSync as
|
|
42965
|
+
mkdirSync as mkdirSync8,
|
|
43067
42966
|
renameSync,
|
|
43068
42967
|
rmSync,
|
|
43069
42968
|
writeFileSync as writeFileSync5
|
|
@@ -43130,7 +43029,7 @@ function installPreCommitHook(dir) {
|
|
|
43130
43029
|
const hooksDir = join9(dir, ".git", "hooks");
|
|
43131
43030
|
const hookPath = join9(hooksDir, "pre-commit");
|
|
43132
43031
|
if (!existsSync10(hooksDir)) {
|
|
43133
|
-
|
|
43032
|
+
mkdirSync8(hooksDir, { recursive: true });
|
|
43134
43033
|
}
|
|
43135
43034
|
writeFileSync5(hookPath, PRE_COMMIT_HOOK_SCRIPT, "utf-8");
|
|
43136
43035
|
chmodSync(hookPath, 493);
|
|
@@ -43145,7 +43044,7 @@ async function cloneMemoryRepo(agentId) {
|
|
|
43145
43044
|
const dir = getMemoryRepoDir(agentId);
|
|
43146
43045
|
debugLog("memfs-git", `Cloning ${url} → ${dir}`);
|
|
43147
43046
|
if (!existsSync10(dir)) {
|
|
43148
|
-
|
|
43047
|
+
mkdirSync8(dir, { recursive: true });
|
|
43149
43048
|
await runGit(dir, ["clone", url, "."], token);
|
|
43150
43049
|
} else if (!existsSync10(join9(dir, ".git"))) {
|
|
43151
43050
|
const tmpDir = `${dir}-git-clone-tmp`;
|
|
@@ -43153,7 +43052,7 @@ async function cloneMemoryRepo(agentId) {
|
|
|
43153
43052
|
if (existsSync10(tmpDir)) {
|
|
43154
43053
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
43155
43054
|
}
|
|
43156
|
-
|
|
43055
|
+
mkdirSync8(tmpDir, { recursive: true });
|
|
43157
43056
|
await runGit(tmpDir, ["clone", url, "."], token);
|
|
43158
43057
|
renameSync(join9(tmpDir, ".git"), join9(dir, ".git"));
|
|
43159
43058
|
await runGit(dir, ["checkout", "--", "."], token);
|
|
@@ -43552,17 +43451,15 @@ async function updateConversationLLMConfig(conversationId, modelHandle, updateAr
|
|
|
43552
43451
|
};
|
|
43553
43452
|
return client.conversations.update(conversationId, payload);
|
|
43554
43453
|
}
|
|
43555
|
-
async function recompileAgentSystemPrompt(conversationId,
|
|
43454
|
+
async function recompileAgentSystemPrompt(conversationId, agentId, dryRun, clientOverride) {
|
|
43556
43455
|
const client = clientOverride ?? await getClient2();
|
|
43456
|
+
if (!agentId) {
|
|
43457
|
+
throw new Error("recompileAgentSystemPrompt requires agentId");
|
|
43458
|
+
}
|
|
43557
43459
|
const params = {
|
|
43558
|
-
dry_run:
|
|
43460
|
+
dry_run: dryRun,
|
|
43461
|
+
agent_id: agentId
|
|
43559
43462
|
};
|
|
43560
|
-
if (conversationId === "default") {
|
|
43561
|
-
if (!options.agentId) {
|
|
43562
|
-
throw new Error('recompileAgentSystemPrompt requires options.agentId when conversationId is "default"');
|
|
43563
|
-
}
|
|
43564
|
-
params.agent_id = options.agentId;
|
|
43565
|
-
}
|
|
43566
43463
|
return client.conversations.recompile(conversationId, params);
|
|
43567
43464
|
}
|
|
43568
43465
|
async function updateAgentSystemPromptRaw2(agentId, systemPromptContent) {
|
|
@@ -43875,7 +43772,7 @@ __export(exports_memoryFilesystem, {
|
|
|
43875
43772
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
|
|
43876
43773
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
|
|
43877
43774
|
});
|
|
43878
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
43775
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync9 } from "node:fs";
|
|
43879
43776
|
import { homedir as homedir10 } from "node:os";
|
|
43880
43777
|
import { join as join10 } from "node:path";
|
|
43881
43778
|
function getMemoryFilesystemRoot(agentId, homeDir = homedir10()) {
|
|
@@ -43888,10 +43785,10 @@ function ensureMemoryFilesystemDirs(agentId, homeDir = homedir10()) {
|
|
|
43888
43785
|
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
43889
43786
|
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
43890
43787
|
if (!existsSync11(root)) {
|
|
43891
|
-
|
|
43788
|
+
mkdirSync9(root, { recursive: true });
|
|
43892
43789
|
}
|
|
43893
43790
|
if (!existsSync11(systemDir)) {
|
|
43894
|
-
|
|
43791
|
+
mkdirSync9(systemDir, { recursive: true });
|
|
43895
43792
|
}
|
|
43896
43793
|
}
|
|
43897
43794
|
function labelFromRelativePath(relativePath) {
|
|
@@ -44038,7 +43935,7 @@ __export(exports_shellEnv, {
|
|
|
44038
43935
|
getShellEnv: () => getShellEnv,
|
|
44039
43936
|
ensureLettaShimDir: () => ensureLettaShimDir
|
|
44040
43937
|
});
|
|
44041
|
-
import { mkdirSync as
|
|
43938
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync6 } from "node:fs";
|
|
44042
43939
|
import { createRequire as createRequire2 } from "node:module";
|
|
44043
43940
|
import { tmpdir } from "node:os";
|
|
44044
43941
|
import * as path4 from "node:path";
|
|
@@ -44111,7 +44008,7 @@ function ensureLettaShimDir(invocation) {
|
|
|
44111
44008
|
if (!invocation.command)
|
|
44112
44009
|
return null;
|
|
44113
44010
|
const shimDir = path4.join(tmpdir(), "letta-code-shell-shim");
|
|
44114
|
-
|
|
44011
|
+
mkdirSync10(shimDir, { recursive: true });
|
|
44115
44012
|
if (process.platform === "win32") {
|
|
44116
44013
|
const cmdPath = path4.join(shimDir, "letta.cmd");
|
|
44117
44014
|
const quotedCommand = `"${invocation.command.replaceAll('"', '""')}"`;
|
|
@@ -69723,7 +69620,7 @@ var init_approvalClassification = __esm(async () => {
|
|
|
69723
69620
|
// src/cli/helpers/chunkLog.ts
|
|
69724
69621
|
import {
|
|
69725
69622
|
existsSync as existsSync14,
|
|
69726
|
-
mkdirSync as
|
|
69623
|
+
mkdirSync as mkdirSync12,
|
|
69727
69624
|
readdirSync as readdirSync8,
|
|
69728
69625
|
unlinkSync as unlinkSync5,
|
|
69729
69626
|
writeFileSync as writeFileSync9
|
|
@@ -69824,7 +69721,7 @@ class ChunkLog {
|
|
|
69824
69721
|
return;
|
|
69825
69722
|
try {
|
|
69826
69723
|
if (!existsSync14(this.agentDir)) {
|
|
69827
|
-
|
|
69724
|
+
mkdirSync12(this.agentDir, { recursive: true });
|
|
69828
69725
|
}
|
|
69829
69726
|
this.dirCreated = true;
|
|
69830
69727
|
} catch (e) {
|
|
@@ -72003,8 +71900,83 @@ var init_memoryReminder = __esm(async () => {
|
|
|
72003
71900
|
};
|
|
72004
71901
|
});
|
|
72005
71902
|
|
|
71903
|
+
// src/cli/helpers/gitContext.ts
|
|
71904
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
71905
|
+
function runGit2(args, cwd2) {
|
|
71906
|
+
try {
|
|
71907
|
+
return execFileSync2("git", args, {
|
|
71908
|
+
cwd: cwd2,
|
|
71909
|
+
encoding: "utf-8",
|
|
71910
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
71911
|
+
}).trim();
|
|
71912
|
+
} catch {
|
|
71913
|
+
return null;
|
|
71914
|
+
}
|
|
71915
|
+
}
|
|
71916
|
+
function truncateLines(value, maxLines) {
|
|
71917
|
+
const lines = value.split(`
|
|
71918
|
+
`);
|
|
71919
|
+
if (lines.length <= maxLines) {
|
|
71920
|
+
return value;
|
|
71921
|
+
}
|
|
71922
|
+
return lines.slice(0, maxLines).join(`
|
|
71923
|
+
`) + `
|
|
71924
|
+
... and ${lines.length - maxLines} more changes`;
|
|
71925
|
+
}
|
|
71926
|
+
function formatGitUser(name, email) {
|
|
71927
|
+
if (!name && !email) {
|
|
71928
|
+
return null;
|
|
71929
|
+
}
|
|
71930
|
+
if (name && email) {
|
|
71931
|
+
return `${name} <${email}>`;
|
|
71932
|
+
}
|
|
71933
|
+
return name || email;
|
|
71934
|
+
}
|
|
71935
|
+
function gatherGitContextSnapshot(options = {}) {
|
|
71936
|
+
const cwd2 = options.cwd ?? process.cwd();
|
|
71937
|
+
const recentCommitLimit = options.recentCommitLimit ?? 3;
|
|
71938
|
+
if (!runGit2(["rev-parse", "--git-dir"], cwd2)) {
|
|
71939
|
+
return {
|
|
71940
|
+
isGitRepo: false,
|
|
71941
|
+
branch: null,
|
|
71942
|
+
status: null,
|
|
71943
|
+
recentCommits: null,
|
|
71944
|
+
gitUser: null
|
|
71945
|
+
};
|
|
71946
|
+
}
|
|
71947
|
+
const branch = runGit2(["branch", "--show-current"], cwd2);
|
|
71948
|
+
const fullStatus = runGit2(["status", "--short"], cwd2);
|
|
71949
|
+
const status = typeof fullStatus === "string" && options.statusLineLimit ? truncateLines(fullStatus, options.statusLineLimit) : fullStatus;
|
|
71950
|
+
const recentCommits = options.recentCommitFormat ? runGit2([
|
|
71951
|
+
"log",
|
|
71952
|
+
`--format=${options.recentCommitFormat}`,
|
|
71953
|
+
"-n",
|
|
71954
|
+
String(recentCommitLimit)
|
|
71955
|
+
], cwd2) : runGit2(["log", "--oneline", "-n", String(recentCommitLimit)], cwd2);
|
|
71956
|
+
const userConfig = runGit2(["config", "--get-regexp", "^user\\.(name|email)$"], cwd2);
|
|
71957
|
+
let userName = null;
|
|
71958
|
+
let userEmail = null;
|
|
71959
|
+
if (userConfig) {
|
|
71960
|
+
for (const line of userConfig.split(`
|
|
71961
|
+
`)) {
|
|
71962
|
+
if (line.startsWith("user.name "))
|
|
71963
|
+
userName = line.slice("user.name ".length);
|
|
71964
|
+
else if (line.startsWith("user.email "))
|
|
71965
|
+
userEmail = line.slice("user.email ".length);
|
|
71966
|
+
}
|
|
71967
|
+
}
|
|
71968
|
+
const gitUser = formatGitUser(userName, userEmail);
|
|
71969
|
+
return {
|
|
71970
|
+
isGitRepo: true,
|
|
71971
|
+
branch,
|
|
71972
|
+
status,
|
|
71973
|
+
recentCommits,
|
|
71974
|
+
gitUser
|
|
71975
|
+
};
|
|
71976
|
+
}
|
|
71977
|
+
var init_gitContext = () => {};
|
|
71978
|
+
|
|
72006
71979
|
// src/cli/helpers/sessionContext.ts
|
|
72007
|
-
import { execSync as execSync2 } from "node:child_process";
|
|
72008
71980
|
import { platform as platform3 } from "node:os";
|
|
72009
71981
|
function getLocalTime() {
|
|
72010
71982
|
const now = new Date;
|
|
@@ -72031,37 +72003,22 @@ function getDeviceType() {
|
|
|
72031
72003
|
return p;
|
|
72032
72004
|
}
|
|
72033
72005
|
}
|
|
72034
|
-
function safeGitExec(command, cwd2) {
|
|
72035
|
-
try {
|
|
72036
|
-
return execSync2(command, { cwd: cwd2, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
72037
|
-
} catch {
|
|
72038
|
-
return null;
|
|
72039
|
-
}
|
|
72040
|
-
}
|
|
72041
72006
|
function getGitInfo() {
|
|
72042
|
-
const
|
|
72043
|
-
|
|
72044
|
-
|
|
72045
|
-
|
|
72046
|
-
|
|
72047
|
-
|
|
72048
|
-
const statusLines = fullStatus.split(`
|
|
72049
|
-
`);
|
|
72050
|
-
let status = fullStatus;
|
|
72051
|
-
if (statusLines.length > 20) {
|
|
72052
|
-
status = statusLines.slice(0, 20).join(`
|
|
72053
|
-
`) + `
|
|
72054
|
-
... and ${statusLines.length - 20} more files`;
|
|
72055
|
-
}
|
|
72056
|
-
return {
|
|
72057
|
-
isGitRepo: true,
|
|
72058
|
-
branch,
|
|
72059
|
-
recentCommits,
|
|
72060
|
-
status: status || "(clean working tree)"
|
|
72061
|
-
};
|
|
72062
|
-
} catch {
|
|
72007
|
+
const git = gatherGitContextSnapshot({
|
|
72008
|
+
recentCommitLimit: 3,
|
|
72009
|
+
recentCommitFormat: "%h %s (%an)",
|
|
72010
|
+
statusLineLimit: 20
|
|
72011
|
+
});
|
|
72012
|
+
if (!git.isGitRepo) {
|
|
72063
72013
|
return { isGitRepo: false };
|
|
72064
72014
|
}
|
|
72015
|
+
return {
|
|
72016
|
+
isGitRepo: true,
|
|
72017
|
+
branch: git.branch ?? "(unknown)",
|
|
72018
|
+
recentCommits: git.recentCommits ?? "(failed to get commits)",
|
|
72019
|
+
status: git.status || "(clean working tree)",
|
|
72020
|
+
gitUser: git.gitUser ?? "(not configured)"
|
|
72021
|
+
};
|
|
72065
72022
|
}
|
|
72066
72023
|
function buildSessionContext() {
|
|
72067
72024
|
try {
|
|
@@ -72091,6 +72048,7 @@ The user has just initiated a new connection via the [Letta Code CLI client](htt
|
|
|
72091
72048
|
`;
|
|
72092
72049
|
if (gitInfo.isGitRepo) {
|
|
72093
72050
|
context3 += `- **Git repository**: Yes (branch: ${gitInfo.branch})
|
|
72051
|
+
- **Git user**: ${gitInfo.gitUser}
|
|
72094
72052
|
|
|
72095
72053
|
### Recent Commits
|
|
72096
72054
|
\`\`\`
|
|
@@ -72123,6 +72081,7 @@ ${gitInfo.status}
|
|
|
72123
72081
|
var init_sessionContext = __esm(() => {
|
|
72124
72082
|
init_constants();
|
|
72125
72083
|
init_version();
|
|
72084
|
+
init_gitContext();
|
|
72126
72085
|
});
|
|
72127
72086
|
|
|
72128
72087
|
// src/reminders/catalog.ts
|
|
@@ -72998,7 +72957,7 @@ function loadPersistedCwdMap() {
|
|
|
72998
72957
|
const cachePath = getCwdCachePath();
|
|
72999
72958
|
if (!existsSync15(cachePath))
|
|
73000
72959
|
return new Map;
|
|
73001
|
-
const raw = __require("fs").readFileSync(cachePath, "utf-8");
|
|
72960
|
+
const raw = __require("node:fs").readFileSync(cachePath, "utf-8");
|
|
73002
72961
|
const parsed = JSON.parse(raw);
|
|
73003
72962
|
const map = new Map;
|
|
73004
72963
|
for (const [key, value] of Object.entries(parsed)) {
|
|
@@ -73161,6 +73120,56 @@ function mergeDequeuedBatchContent(items) {
|
|
|
73161
73120
|
normalizeUserContent: (content) => content
|
|
73162
73121
|
});
|
|
73163
73122
|
}
|
|
73123
|
+
function isBase64ImageContentPart(part) {
|
|
73124
|
+
if (!part || typeof part !== "object") {
|
|
73125
|
+
return false;
|
|
73126
|
+
}
|
|
73127
|
+
const candidate = part;
|
|
73128
|
+
return candidate.type === "image" && !!candidate.source && candidate.source.type === "base64" && typeof candidate.source.media_type === "string" && candidate.source.media_type.length > 0 && typeof candidate.source.data === "string" && candidate.source.data.length > 0;
|
|
73129
|
+
}
|
|
73130
|
+
async function normalizeMessageContentImages(content, resize = resizeImageIfNeeded3) {
|
|
73131
|
+
if (typeof content === "string") {
|
|
73132
|
+
return content;
|
|
73133
|
+
}
|
|
73134
|
+
let didChange = false;
|
|
73135
|
+
const normalizedParts = await Promise.all(content.map(async (part) => {
|
|
73136
|
+
if (!isBase64ImageContentPart(part)) {
|
|
73137
|
+
return part;
|
|
73138
|
+
}
|
|
73139
|
+
const resized = await resize(Buffer.from(part.source.data, "base64"), part.source.media_type);
|
|
73140
|
+
if (resized.data !== part.source.data || resized.mediaType !== part.source.media_type) {
|
|
73141
|
+
didChange = true;
|
|
73142
|
+
}
|
|
73143
|
+
return {
|
|
73144
|
+
...part,
|
|
73145
|
+
source: {
|
|
73146
|
+
...part.source,
|
|
73147
|
+
type: "base64",
|
|
73148
|
+
data: resized.data,
|
|
73149
|
+
media_type: resized.mediaType
|
|
73150
|
+
}
|
|
73151
|
+
};
|
|
73152
|
+
}));
|
|
73153
|
+
return didChange ? normalizedParts : content;
|
|
73154
|
+
}
|
|
73155
|
+
async function normalizeInboundMessages(messages, resize = resizeImageIfNeeded3) {
|
|
73156
|
+
let didChange = false;
|
|
73157
|
+
const normalizedMessages = await Promise.all(messages.map(async (message) => {
|
|
73158
|
+
if (!("content" in message)) {
|
|
73159
|
+
return message;
|
|
73160
|
+
}
|
|
73161
|
+
const normalizedContent = await normalizeMessageContentImages(message.content, resize);
|
|
73162
|
+
if (normalizedContent !== message.content) {
|
|
73163
|
+
didChange = true;
|
|
73164
|
+
return {
|
|
73165
|
+
...message,
|
|
73166
|
+
content: normalizedContent
|
|
73167
|
+
};
|
|
73168
|
+
}
|
|
73169
|
+
return message;
|
|
73170
|
+
}));
|
|
73171
|
+
return didChange ? normalizedMessages : messages;
|
|
73172
|
+
}
|
|
73164
73173
|
function getPrimaryQueueMessageItem(items) {
|
|
73165
73174
|
for (const item of items) {
|
|
73166
73175
|
if (item.kind === "message") {
|
|
@@ -73310,6 +73319,7 @@ function buildStateResponse(runtime, stateSeq, agentId, conversationId) {
|
|
|
73310
73319
|
is_processing: runtime.isProcessing,
|
|
73311
73320
|
last_stop_reason: runtime.lastStopReason,
|
|
73312
73321
|
control_response_capable: true,
|
|
73322
|
+
tool_lifecycle_capable: true,
|
|
73313
73323
|
active_run: {
|
|
73314
73324
|
run_id: runtime.activeRunId,
|
|
73315
73325
|
agent_id: runtime.activeAgentId,
|
|
@@ -73626,6 +73636,34 @@ function emitInterruptToolReturnMessage(socket, runtime, approvals, runId, uuidP
|
|
|
73626
73636
|
});
|
|
73627
73637
|
}
|
|
73628
73638
|
}
|
|
73639
|
+
function emitToolExecutionStartedEvents(socket, runtime, params) {
|
|
73640
|
+
for (const toolCallId of params.toolCallIds) {
|
|
73641
|
+
emitToWS(socket, {
|
|
73642
|
+
type: "tool_execution_started",
|
|
73643
|
+
tool_call_id: toolCallId,
|
|
73644
|
+
...params.runId ? { run_id: params.runId } : {},
|
|
73645
|
+
session_id: runtime.sessionId,
|
|
73646
|
+
uuid: `tool-exec-started-${toolCallId}`,
|
|
73647
|
+
agent_id: params.agentId,
|
|
73648
|
+
conversation_id: params.conversationId
|
|
73649
|
+
});
|
|
73650
|
+
}
|
|
73651
|
+
}
|
|
73652
|
+
function emitToolExecutionFinishedEvents(socket, runtime, params) {
|
|
73653
|
+
const toolReturns = extractInterruptToolReturns(params.approvals);
|
|
73654
|
+
for (const toolReturn of toolReturns) {
|
|
73655
|
+
emitToWS(socket, {
|
|
73656
|
+
type: "tool_execution_finished",
|
|
73657
|
+
tool_call_id: toolReturn.tool_call_id,
|
|
73658
|
+
status: toolReturn.status,
|
|
73659
|
+
...params.runId ? { run_id: params.runId } : {},
|
|
73660
|
+
session_id: runtime.sessionId,
|
|
73661
|
+
uuid: `tool-exec-finished-${toolReturn.tool_call_id}`,
|
|
73662
|
+
agent_id: params.agentId,
|
|
73663
|
+
conversation_id: params.conversationId
|
|
73664
|
+
});
|
|
73665
|
+
}
|
|
73666
|
+
}
|
|
73629
73667
|
function getInterruptApprovalsForEmission(runtime, params) {
|
|
73630
73668
|
if (params.lastExecutionResults && params.lastExecutionResults.length > 0) {
|
|
73631
73669
|
return params.lastExecutionResults;
|
|
@@ -74446,6 +74484,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74446
74484
|
if (connectionId) {
|
|
74447
74485
|
onStatusChange?.("processing", connectionId);
|
|
74448
74486
|
}
|
|
74487
|
+
const normalizedMessages = await normalizeInboundMessages(msg.messages);
|
|
74449
74488
|
const messagesToSend = [];
|
|
74450
74489
|
let turnToolContextId = null;
|
|
74451
74490
|
let queuedInterruptedToolCallIds = [];
|
|
@@ -74454,8 +74493,8 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74454
74493
|
messagesToSend.push(consumed.approvalMessage);
|
|
74455
74494
|
queuedInterruptedToolCallIds = consumed.interruptedToolCallIds;
|
|
74456
74495
|
}
|
|
74457
|
-
messagesToSend.push(...
|
|
74458
|
-
const firstMessage =
|
|
74496
|
+
messagesToSend.push(...normalizedMessages);
|
|
74497
|
+
const firstMessage = normalizedMessages[0];
|
|
74459
74498
|
const isApprovalMessage = firstMessage && "type" in firstMessage && firstMessage.type === "approval" && "approvals" in firstMessage;
|
|
74460
74499
|
if (!isApprovalMessage) {
|
|
74461
74500
|
const { parts: reminderParts } = await buildSharedReminderParts(buildListenReminderContext({
|
|
@@ -74710,6 +74749,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74710
74749
|
for (const ac of needsUserInput) {
|
|
74711
74750
|
const requestId = `perm-${ac.approval.toolCallId}`;
|
|
74712
74751
|
const diffs = await computeDiffPreviews(ac.approval.toolName, ac.parsedArgs, turnWorkingDirectory);
|
|
74752
|
+
const lifecycleRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
|
|
74713
74753
|
const controlRequest = {
|
|
74714
74754
|
type: "control_request",
|
|
74715
74755
|
request_id: requestId,
|
|
@@ -74725,6 +74765,17 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74725
74765
|
agent_id: agentId,
|
|
74726
74766
|
conversation_id: conversationId
|
|
74727
74767
|
};
|
|
74768
|
+
emitToWS(socket, {
|
|
74769
|
+
type: "approval_requested",
|
|
74770
|
+
request_id: requestId,
|
|
74771
|
+
tool_call_id: ac.approval.toolCallId,
|
|
74772
|
+
tool_name: ac.approval.toolName,
|
|
74773
|
+
...lifecycleRunId ? { run_id: lifecycleRunId } : {},
|
|
74774
|
+
session_id: runtime.sessionId,
|
|
74775
|
+
uuid: `approval-requested-${ac.approval.toolCallId}`,
|
|
74776
|
+
agent_id: agentId,
|
|
74777
|
+
conversation_id: conversationId
|
|
74778
|
+
});
|
|
74728
74779
|
const responseBody = await requestApprovalOverWS(runtime, socket, requestId, controlRequest);
|
|
74729
74780
|
if (responseBody.subtype === "success") {
|
|
74730
74781
|
const response = responseBody.response;
|
|
@@ -74748,30 +74799,80 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74748
74799
|
agent_id: agentId,
|
|
74749
74800
|
conversation_id: conversationId
|
|
74750
74801
|
});
|
|
74802
|
+
emitToWS(socket, {
|
|
74803
|
+
type: "approval_received",
|
|
74804
|
+
request_id: requestId,
|
|
74805
|
+
tool_call_id: ac.approval.toolCallId,
|
|
74806
|
+
decision: "allow",
|
|
74807
|
+
reason: "Approved via WebSocket",
|
|
74808
|
+
...lifecycleRunId ? { run_id: lifecycleRunId } : {},
|
|
74809
|
+
session_id: runtime.sessionId,
|
|
74810
|
+
uuid: `approval-received-${ac.approval.toolCallId}`,
|
|
74811
|
+
agent_id: agentId,
|
|
74812
|
+
conversation_id: conversationId
|
|
74813
|
+
});
|
|
74751
74814
|
} else {
|
|
74752
74815
|
decisions.push({
|
|
74753
74816
|
type: "deny",
|
|
74754
74817
|
approval: ac.approval,
|
|
74755
74818
|
reason: response?.message || "Denied via WebSocket"
|
|
74756
74819
|
});
|
|
74820
|
+
emitToWS(socket, {
|
|
74821
|
+
type: "approval_received",
|
|
74822
|
+
request_id: requestId,
|
|
74823
|
+
tool_call_id: ac.approval.toolCallId,
|
|
74824
|
+
decision: "deny",
|
|
74825
|
+
reason: response?.message || "Denied via WebSocket",
|
|
74826
|
+
...lifecycleRunId ? { run_id: lifecycleRunId } : {},
|
|
74827
|
+
session_id: runtime.sessionId,
|
|
74828
|
+
uuid: `approval-received-${ac.approval.toolCallId}`,
|
|
74829
|
+
agent_id: agentId,
|
|
74830
|
+
conversation_id: conversationId
|
|
74831
|
+
});
|
|
74757
74832
|
}
|
|
74758
74833
|
} else {
|
|
74834
|
+
const denyReason = responseBody.subtype === "error" ? responseBody.error : "Unknown error";
|
|
74759
74835
|
decisions.push({
|
|
74760
74836
|
type: "deny",
|
|
74761
74837
|
approval: ac.approval,
|
|
74762
|
-
reason:
|
|
74838
|
+
reason: denyReason
|
|
74839
|
+
});
|
|
74840
|
+
emitToWS(socket, {
|
|
74841
|
+
type: "approval_received",
|
|
74842
|
+
request_id: requestId,
|
|
74843
|
+
tool_call_id: ac.approval.toolCallId,
|
|
74844
|
+
decision: "deny",
|
|
74845
|
+
reason: denyReason,
|
|
74846
|
+
...lifecycleRunId ? { run_id: lifecycleRunId } : {},
|
|
74847
|
+
session_id: runtime.sessionId,
|
|
74848
|
+
uuid: `approval-received-${ac.approval.toolCallId}`,
|
|
74849
|
+
agent_id: agentId,
|
|
74850
|
+
conversation_id: conversationId
|
|
74763
74851
|
});
|
|
74764
74852
|
}
|
|
74765
74853
|
}
|
|
74766
74854
|
}
|
|
74767
74855
|
lastExecutingToolCallIds = decisions.filter((decision) => decision.type === "approve").map((decision) => decision.approval.toolCallId);
|
|
74768
74856
|
runtime.activeExecutingToolCallIds = [...lastExecutingToolCallIds];
|
|
74857
|
+
const executionRunId = runId || runtime.activeRunId || msgRunIds[msgRunIds.length - 1];
|
|
74858
|
+
emitToolExecutionStartedEvents(socket, runtime, {
|
|
74859
|
+
toolCallIds: lastExecutingToolCallIds,
|
|
74860
|
+
runId: executionRunId,
|
|
74861
|
+
agentId,
|
|
74862
|
+
conversationId
|
|
74863
|
+
});
|
|
74769
74864
|
const executionResults = await executeApprovalBatch(decisions, undefined, {
|
|
74770
74865
|
toolContextId: turnToolContextId ?? undefined,
|
|
74771
74866
|
abortSignal: runtime.activeAbortController.signal,
|
|
74772
74867
|
workingDirectory: turnWorkingDirectory
|
|
74773
74868
|
});
|
|
74774
74869
|
const persistedExecutionResults = normalizeExecutionResultsForInterruptParity(runtime, executionResults, lastExecutingToolCallIds);
|
|
74870
|
+
emitToolExecutionFinishedEvents(socket, runtime, {
|
|
74871
|
+
approvals: persistedExecutionResults,
|
|
74872
|
+
runId: executionRunId,
|
|
74873
|
+
agentId,
|
|
74874
|
+
conversationId
|
|
74875
|
+
});
|
|
74775
74876
|
lastExecutionResults = persistedExecutionResults;
|
|
74776
74877
|
emitInterruptToolReturnMessage(socket, runtime, persistedExecutionResults, runtime.activeRunId || runId || msgRunIds[msgRunIds.length - 1] || undefined, "tool-return");
|
|
74777
74878
|
clearPendingApprovalBatchIds(runtime, decisions.map((decision) => decision.approval));
|
|
@@ -74803,6 +74904,12 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
74803
74904
|
conversationId
|
|
74804
74905
|
});
|
|
74805
74906
|
if (approvalsForEmission) {
|
|
74907
|
+
emitToolExecutionFinishedEvents(socket, runtime, {
|
|
74908
|
+
approvals: approvalsForEmission,
|
|
74909
|
+
runId: runtime.activeRunId || msgRunIds[msgRunIds.length - 1],
|
|
74910
|
+
agentId: agentId || "",
|
|
74911
|
+
conversationId
|
|
74912
|
+
});
|
|
74806
74913
|
emitInterruptToolReturnMessage(socket, runtime, approvalsForEmission, runtime.activeRunId || msgRunIds[msgRunIds.length - 1] || undefined);
|
|
74807
74914
|
}
|
|
74808
74915
|
runtime.lastStopReason = "cancelled";
|
|
@@ -74900,6 +75007,7 @@ var init_listen_client = __esm(async () => {
|
|
|
74900
75007
|
init_message(),
|
|
74901
75008
|
init_accumulator(),
|
|
74902
75009
|
init_approvalClassification(),
|
|
75010
|
+
init_imageResize(),
|
|
74903
75011
|
init_stream(),
|
|
74904
75012
|
init_engine(),
|
|
74905
75013
|
init_settings_manager(),
|
|
@@ -74927,7 +75035,9 @@ var init_listen_client = __esm(async () => {
|
|
|
74927
75035
|
getInterruptApprovalsForEmission,
|
|
74928
75036
|
normalizeToolReturnWireMessage,
|
|
74929
75037
|
normalizeExecutionResultsForInterruptParity,
|
|
74930
|
-
shouldAttemptPostStopApprovalRecovery
|
|
75038
|
+
shouldAttemptPostStopApprovalRecovery,
|
|
75039
|
+
normalizeMessageContentImages,
|
|
75040
|
+
normalizeInboundMessages
|
|
74931
75041
|
};
|
|
74932
75042
|
});
|
|
74933
75043
|
|
|
@@ -75153,7 +75263,7 @@ import {
|
|
|
75153
75263
|
existsSync as existsSync19,
|
|
75154
75264
|
readFileSync as fsReadFileSync2,
|
|
75155
75265
|
writeFileSync as fsWriteFileSync2,
|
|
75156
|
-
mkdirSync as
|
|
75266
|
+
mkdirSync as mkdirSync15
|
|
75157
75267
|
} from "node:fs";
|
|
75158
75268
|
import { dirname as dirname10 } from "node:path";
|
|
75159
75269
|
async function readFile6(path22) {
|
|
@@ -75162,7 +75272,7 @@ async function readFile6(path22) {
|
|
|
75162
75272
|
async function writeFile3(path22, content) {
|
|
75163
75273
|
const dir = dirname10(path22);
|
|
75164
75274
|
if (!existsSync19(dir)) {
|
|
75165
|
-
|
|
75275
|
+
mkdirSync15(dir, { recursive: true });
|
|
75166
75276
|
}
|
|
75167
75277
|
fsWriteFileSync2(path22, content, { encoding: "utf-8", flush: true });
|
|
75168
75278
|
}
|
|
@@ -75170,7 +75280,7 @@ function exists2(path22) {
|
|
|
75170
75280
|
return existsSync19(path22);
|
|
75171
75281
|
}
|
|
75172
75282
|
async function mkdir3(path22, options) {
|
|
75173
|
-
|
|
75283
|
+
mkdirSync15(path22, options);
|
|
75174
75284
|
}
|
|
75175
75285
|
async function readJsonFile(path22) {
|
|
75176
75286
|
const text = await readFile6(path22);
|
|
@@ -75863,7 +75973,7 @@ async function startDockerVersionCheck() {
|
|
|
75863
75973
|
if (isVersionBelow(serverVersion, MINIMUM_DOCKER_VERSION)) {
|
|
75864
75974
|
console.warn(`
|
|
75865
75975
|
⚠️ Warning: Your Docker image is outdated (v${serverVersion}). Minimum recommended: v${MINIMUM_DOCKER_VERSION}.
|
|
75866
|
-
Please update with: docker pull letta/letta
|
|
75976
|
+
Please update with: docker pull letta/letta:latest
|
|
75867
75977
|
`);
|
|
75868
75978
|
}
|
|
75869
75979
|
} catch {}
|
|
@@ -75983,10 +76093,11 @@ __export(exports_promptAssets2, {
|
|
|
75983
76093
|
resolveAndBuildSystemPrompt: () => resolveAndBuildSystemPrompt2,
|
|
75984
76094
|
isKnownPreset: () => isKnownPreset2,
|
|
75985
76095
|
buildSystemPrompt: () => buildSystemPrompt2,
|
|
75986
|
-
SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON2,
|
|
75987
76096
|
SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON2,
|
|
76097
|
+
SYSTEM_PROMPT_BLOCKS_ADDON: () => SYSTEM_PROMPT_BLOCKS_ADDON2,
|
|
75988
76098
|
SYSTEM_PROMPTS: () => SYSTEM_PROMPTS2,
|
|
75989
76099
|
SYSTEM_PROMPT: () => SYSTEM_PROMPT2,
|
|
76100
|
+
SLEEPTIME_MEMORY_PERSONA: () => SLEEPTIME_MEMORY_PERSONA2,
|
|
75990
76101
|
SKILL_CREATOR_PROMPT: () => SKILL_CREATOR_PROMPT2,
|
|
75991
76102
|
REMEMBER_PROMPT: () => REMEMBER_PROMPT2,
|
|
75992
76103
|
PLAN_MODE_REMINDER: () => PLAN_MODE_REMINDER2,
|
|
@@ -76053,7 +76164,7 @@ function buildSystemPrompt2(presetId, memoryMode) {
|
|
|
76053
76164
|
if (!preset) {
|
|
76054
76165
|
throw new Error(`Unknown preset "${presetId}" — cannot rebuild system prompt`);
|
|
76055
76166
|
}
|
|
76056
|
-
const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 :
|
|
76167
|
+
const addon = memoryMode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_BLOCKS_ADDON2;
|
|
76057
76168
|
return `${preset.content.trimEnd()}
|
|
76058
76169
|
|
|
76059
76170
|
${addon.trimStart()}`.trim();
|
|
@@ -76061,7 +76172,7 @@ ${addon.trimStart()}`.trim();
|
|
|
76061
76172
|
function swapMemoryAddon2(systemPrompt, mode) {
|
|
76062
76173
|
let result = systemPrompt;
|
|
76063
76174
|
for (const addon of [
|
|
76064
|
-
|
|
76175
|
+
SYSTEM_PROMPT_BLOCKS_ADDON2.trim(),
|
|
76065
76176
|
SYSTEM_PROMPT_MEMFS_ADDON2.trim()
|
|
76066
76177
|
]) {
|
|
76067
76178
|
result = result.replaceAll(addon, "");
|
|
@@ -76077,7 +76188,7 @@ function swapMemoryAddon2(systemPrompt, mode) {
|
|
|
76077
76188
|
result = result.replace(/\n{3,}/g, `
|
|
76078
76189
|
|
|
76079
76190
|
`).trimEnd();
|
|
76080
|
-
const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 :
|
|
76191
|
+
const target = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON2 : SYSTEM_PROMPT_BLOCKS_ADDON2;
|
|
76081
76192
|
return `${result}
|
|
76082
76193
|
|
|
76083
76194
|
${target.trimStart()}`.trim();
|
|
@@ -76124,7 +76235,7 @@ async function resolveSystemPrompt2(systemPromptPreset) {
|
|
|
76124
76235
|
}
|
|
76125
76236
|
throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
|
|
76126
76237
|
}
|
|
76127
|
-
var SYSTEM_PROMPT2,
|
|
76238
|
+
var SYSTEM_PROMPT2, SYSTEM_PROMPT_BLOCKS_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, APPROVAL_RECOVERY_PROMPT2, AUTO_INIT_REMINDER2, INTERRUPT_RECOVERY_ALERT2, SLEEPTIME_MEMORY_PERSONA2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
|
|
76128
76239
|
var init_promptAssets2 = __esm(() => {
|
|
76129
76240
|
init_approval_recovery_alert();
|
|
76130
76241
|
init_auto_init_reminder();
|
|
@@ -76134,21 +76245,21 @@ var init_promptAssets2 = __esm(() => {
|
|
|
76134
76245
|
init_memory_check_reminder();
|
|
76135
76246
|
init_memory_filesystem();
|
|
76136
76247
|
init_persona();
|
|
76137
|
-
init_persona_claude();
|
|
76138
76248
|
init_persona_kawaii();
|
|
76139
76249
|
init_persona_memo();
|
|
76140
76250
|
init_plan_mode_reminder();
|
|
76141
76251
|
init_project();
|
|
76142
76252
|
init_remember();
|
|
76143
76253
|
init_skill_creator_mode();
|
|
76254
|
+
init_sleeptime();
|
|
76144
76255
|
init_source_claude();
|
|
76145
76256
|
init_source_codex();
|
|
76146
76257
|
init_source_gemini();
|
|
76147
76258
|
init_style();
|
|
76259
|
+
init_system_prompt_blocks();
|
|
76148
76260
|
init_system_prompt_memfs();
|
|
76149
|
-
init_system_prompt_memory();
|
|
76150
76261
|
SYSTEM_PROMPT2 = letta_default;
|
|
76151
|
-
|
|
76262
|
+
SYSTEM_PROMPT_BLOCKS_ADDON2 = system_prompt_blocks_default;
|
|
76152
76263
|
SYSTEM_PROMPT_MEMFS_ADDON2 = system_prompt_memfs_default;
|
|
76153
76264
|
PLAN_MODE_REMINDER2 = plan_mode_reminder_default;
|
|
76154
76265
|
SKILL_CREATOR_PROMPT2 = skill_creator_mode_default;
|
|
@@ -76157,9 +76268,9 @@ var init_promptAssets2 = __esm(() => {
|
|
|
76157
76268
|
APPROVAL_RECOVERY_PROMPT2 = approval_recovery_alert_default;
|
|
76158
76269
|
AUTO_INIT_REMINDER2 = auto_init_reminder_default;
|
|
76159
76270
|
INTERRUPT_RECOVERY_ALERT2 = interrupt_recovery_alert_default;
|
|
76271
|
+
SLEEPTIME_MEMORY_PERSONA2 = sleeptime_default;
|
|
76160
76272
|
MEMORY_PROMPTS2 = {
|
|
76161
76273
|
"persona.mdx": persona_default,
|
|
76162
|
-
"persona_claude.mdx": persona_claude_default,
|
|
76163
76274
|
"persona_kawaii.mdx": persona_kawaii_default,
|
|
76164
76275
|
"persona_memo.mdx": persona_memo_default,
|
|
76165
76276
|
"human.mdx": human_default,
|
|
@@ -76641,53 +76752,6 @@ async function handleBootstrapSessionState(params) {
|
|
|
76641
76752
|
}
|
|
76642
76753
|
var init_bootstrapHandler = () => {};
|
|
76643
76754
|
|
|
76644
|
-
// src/agent/prompts/sleeptime.ts
|
|
76645
|
-
var SLEEPTIME_MEMORY_PERSONA = `I am a sleep-time memory management agent. I observe the conversation between the user and their primary agent, then actively maintain memory blocks to keep them accurate, concise, and useful.
|
|
76646
|
-
|
|
76647
|
-
**Core responsibilities:**
|
|
76648
|
-
|
|
76649
|
-
1. **Update memory blocks in real-time** - Don't wait until end of session
|
|
76650
|
-
- Capture important facts, decisions, and context as they occur
|
|
76651
|
-
- Update existing information when it changes or becomes stale
|
|
76652
|
-
- Remove outdated or contradictory information immediately
|
|
76653
|
-
|
|
76654
|
-
2. **Consolidate and refine memory continuously**
|
|
76655
|
-
- Merge duplicate or redundant information
|
|
76656
|
-
- Rewrite verbose entries into concise summaries
|
|
76657
|
-
- Reorganize memory blocks when structure becomes unclear
|
|
76658
|
-
|
|
76659
|
-
3. **Identify and preserve patterns**
|
|
76660
|
-
- Track recurring themes, preferences, and behaviors
|
|
76661
|
-
- Note relationships between different pieces of information
|
|
76662
|
-
- Surface insights from conversation history
|
|
76663
|
-
|
|
76664
|
-
4. **Maintain memory hygiene**
|
|
76665
|
-
- Keep memory blocks under size limits through aggressive consolidation
|
|
76666
|
-
- Prioritize recent and frequently-referenced information
|
|
76667
|
-
- Remove low-value details that don't contribute to agent effectiveness
|
|
76668
|
-
|
|
76669
|
-
5. **Refine my own memory management approach**
|
|
76670
|
-
- Update this \`memory_persona\` block as I learn what works
|
|
76671
|
-
- Add user-specific memory policies when I identify patterns
|
|
76672
|
-
- Remove or adjust guidelines that don't match observed behavior
|
|
76673
|
-
- Adapt my consolidation strategy based on what the primary agent references most
|
|
76674
|
-
|
|
76675
|
-
**Operating rules:**
|
|
76676
|
-
|
|
76677
|
-
- If it was discussed, capture it somewhere in memory
|
|
76678
|
-
- Update memory during the session, not after
|
|
76679
|
-
- Be aggressive with edits - better to over-manage than under-manage
|
|
76680
|
-
- Assume the primary agent relies entirely on memory blocks for context
|
|
76681
|
-
- Every session should result in measurable memory improvements
|
|
76682
|
-
- Regularly evaluate and improve my own memory management policies
|
|
76683
|
-
|
|
76684
|
-
**DO NOT:**
|
|
76685
|
-
- Wait to batch all updates at session end
|
|
76686
|
-
- Skip memory edits because "nothing major happened"
|
|
76687
|
-
- Let memory blocks grow stale or bloated
|
|
76688
|
-
- Assume information will be captured later
|
|
76689
|
-
- Continue using memory policies that don't serve the user's actual needs`;
|
|
76690
|
-
|
|
76691
76755
|
// src/agent/create.ts
|
|
76692
76756
|
function isToolsNotFoundError(err) {
|
|
76693
76757
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -77198,8 +77262,8 @@ __export(exports_github_utils, {
|
|
|
77198
77262
|
async function fetchGitHubContents(owner, repo, branch, path24) {
|
|
77199
77263
|
const apiPath = path24 ? `repos/${owner}/${repo}/contents/${path24}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
|
|
77200
77264
|
try {
|
|
77201
|
-
const { execSync:
|
|
77202
|
-
const result =
|
|
77265
|
+
const { execSync: execSync2 } = await import("node:child_process");
|
|
77266
|
+
const result = execSync2(`gh api ${apiPath}`, {
|
|
77203
77267
|
encoding: "utf-8",
|
|
77204
77268
|
stdio: ["pipe", "pipe", "ignore"]
|
|
77205
77269
|
});
|
|
@@ -99156,7 +99220,7 @@ html.dark .agent-name { color: var(--text-dim); }
|
|
|
99156
99220
|
var init_plan_viewer_template = () => {};
|
|
99157
99221
|
|
|
99158
99222
|
// src/web/generate-plan-viewer.ts
|
|
99159
|
-
import { chmodSync as chmodSync2, existsSync as existsSync22, mkdirSync as
|
|
99223
|
+
import { chmodSync as chmodSync2, existsSync as existsSync22, mkdirSync as mkdirSync18, writeFileSync as writeFileSync12 } from "node:fs";
|
|
99160
99224
|
import { homedir as homedir26 } from "node:os";
|
|
99161
99225
|
import { join as join32 } from "node:path";
|
|
99162
99226
|
async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
@@ -99169,7 +99233,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
99169
99233
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
99170
99234
|
const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
99171
99235
|
if (!existsSync22(VIEWERS_DIR)) {
|
|
99172
|
-
|
|
99236
|
+
mkdirSync18(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
99173
99237
|
}
|
|
99174
99238
|
try {
|
|
99175
99239
|
chmodSync2(VIEWERS_DIR, 448);
|
|
@@ -101164,7 +101228,7 @@ var init_pasteRegistry = __esm(() => {
|
|
|
101164
101228
|
});
|
|
101165
101229
|
|
|
101166
101230
|
// src/cli/helpers/clipboard.ts
|
|
101167
|
-
import { execFileSync as
|
|
101231
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
101168
101232
|
import { existsSync as existsSync23, readFileSync as readFileSync10, statSync as statSync6, unlinkSync as unlinkSync8 } from "node:fs";
|
|
101169
101233
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
101170
101234
|
import { basename as basename4, extname as extname5, isAbsolute as isAbsolute16, join as join33, resolve as resolve25 } from "node:path";
|
|
@@ -101254,7 +101318,7 @@ function getClipboardImageToTempFile() {
|
|
|
101254
101318
|
return '';
|
|
101255
101319
|
})();
|
|
101256
101320
|
`;
|
|
101257
|
-
const uti =
|
|
101321
|
+
const uti = execFileSync3("osascript", ["-l", "JavaScript", "-e", jxa], {
|
|
101258
101322
|
encoding: "utf8",
|
|
101259
101323
|
stdio: ["ignore", "pipe", "ignore"]
|
|
101260
101324
|
}).trim();
|
|
@@ -101873,7 +101937,7 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
101873
101937
|
import {
|
|
101874
101938
|
copyFileSync,
|
|
101875
101939
|
existsSync as existsSync24,
|
|
101876
|
-
mkdirSync as
|
|
101940
|
+
mkdirSync as mkdirSync19,
|
|
101877
101941
|
readFileSync as readFileSync11,
|
|
101878
101942
|
writeFileSync as writeFileSync13
|
|
101879
101943
|
} from "node:fs";
|
|
@@ -101971,7 +102035,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
101971
102035
|
}
|
|
101972
102036
|
const parentDir = dirname12(keybindingsPath);
|
|
101973
102037
|
if (!existsSync24(parentDir)) {
|
|
101974
|
-
|
|
102038
|
+
mkdirSync19(parentDir, { recursive: true });
|
|
101975
102039
|
}
|
|
101976
102040
|
let keybindings = [];
|
|
101977
102041
|
let backupPath = null;
|
|
@@ -102130,7 +102194,7 @@ ${WEZTERM_DELETE_FIX}
|
|
|
102130
102194
|
}
|
|
102131
102195
|
const parentDir = dirname12(configPath);
|
|
102132
102196
|
if (!existsSync24(parentDir)) {
|
|
102133
|
-
|
|
102197
|
+
mkdirSync19(parentDir, { recursive: true });
|
|
102134
102198
|
}
|
|
102135
102199
|
writeFileSync13(configPath, content, { encoding: "utf-8" });
|
|
102136
102200
|
return {
|
|
@@ -107673,10 +107737,10 @@ var init_InputRich = __esm(async () => {
|
|
|
107673
107737
|
});
|
|
107674
107738
|
|
|
107675
107739
|
// src/cli/commands/install-github-app.ts
|
|
107676
|
-
import { execFileSync as
|
|
107740
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
107677
107741
|
import {
|
|
107678
107742
|
existsSync as existsSync26,
|
|
107679
|
-
mkdirSync as
|
|
107743
|
+
mkdirSync as mkdirSync20,
|
|
107680
107744
|
mkdtempSync,
|
|
107681
107745
|
readFileSync as readFileSync12,
|
|
107682
107746
|
rmSync as rmSync3,
|
|
@@ -107686,7 +107750,7 @@ import { tmpdir as tmpdir4 } from "node:os";
|
|
|
107686
107750
|
import { dirname as dirname14, join as join37 } from "node:path";
|
|
107687
107751
|
function runCommand(command, args, cwd2, input) {
|
|
107688
107752
|
try {
|
|
107689
|
-
return
|
|
107753
|
+
return execFileSync4(command, args, {
|
|
107690
107754
|
cwd: cwd2,
|
|
107691
107755
|
encoding: "utf8",
|
|
107692
107756
|
stdio: [input ? "pipe" : "ignore", "pipe", "pipe"],
|
|
@@ -107925,13 +107989,13 @@ function cloneRepoToTemp(repo) {
|
|
|
107925
107989
|
function createBranchName() {
|
|
107926
107990
|
return `letta/install-github-app-${Date.now().toString(36)}`;
|
|
107927
107991
|
}
|
|
107928
|
-
function
|
|
107992
|
+
function runGit3(args, cwd2) {
|
|
107929
107993
|
return runCommand("git", args, cwd2);
|
|
107930
107994
|
}
|
|
107931
107995
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
107932
107996
|
const absolutePath = join37(repoDir, workflowPath);
|
|
107933
107997
|
if (!existsSync26(dirname14(absolutePath))) {
|
|
107934
|
-
|
|
107998
|
+
mkdirSync20(dirname14(absolutePath), { recursive: true });
|
|
107935
107999
|
}
|
|
107936
108000
|
const next = `${content.trimEnd()}
|
|
107937
108001
|
`;
|
|
@@ -107946,7 +108010,7 @@ function writeWorkflow(repoDir, workflowPath, content) {
|
|
|
107946
108010
|
}
|
|
107947
108011
|
function getDefaultBaseBranch(repoDir) {
|
|
107948
108012
|
try {
|
|
107949
|
-
const headRef =
|
|
108013
|
+
const headRef = runGit3(["symbolic-ref", "refs/remotes/origin/HEAD"], repoDir);
|
|
107950
108014
|
return headRef.replace("refs/remotes/origin/", "").trim() || "main";
|
|
107951
108015
|
} catch {
|
|
107952
108016
|
return "main";
|
|
@@ -108022,7 +108086,7 @@ async function installGithubApp(options) {
|
|
|
108022
108086
|
includeAgentId: resolvedAgentId != null
|
|
108023
108087
|
});
|
|
108024
108088
|
const branchName = createBranchName();
|
|
108025
|
-
|
|
108089
|
+
runGit3(["checkout", "-b", branchName], repoDir);
|
|
108026
108090
|
progress(onProgress, "Creating workflow files");
|
|
108027
108091
|
const changed = writeWorkflow(repoDir, workflowPath, workflowContent);
|
|
108028
108092
|
progress(onProgress, "Setting up LETTA_API_KEY secret");
|
|
@@ -108045,10 +108109,10 @@ async function installGithubApp(options) {
|
|
|
108045
108109
|
agentUrl: resolvedAgentId ? buildChatUrl(resolvedAgentId) : null
|
|
108046
108110
|
};
|
|
108047
108111
|
}
|
|
108048
|
-
|
|
108049
|
-
|
|
108112
|
+
runGit3(["add", workflowPath], repoDir);
|
|
108113
|
+
runGit3(["commit", "-m", "Add Letta Code GitHub Workflow"], repoDir);
|
|
108050
108114
|
progress(onProgress, "Opening pull request page");
|
|
108051
|
-
|
|
108115
|
+
runGit3(["push", "-u", "origin", branchName], repoDir);
|
|
108052
108116
|
const pullRequest = createPullRequest(repo, branchName, workflowPath, repoDir);
|
|
108053
108117
|
return {
|
|
108054
108118
|
repo,
|
|
@@ -111909,7 +111973,7 @@ __export(exports_generate_memory_viewer, {
|
|
|
111909
111973
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
111910
111974
|
});
|
|
111911
111975
|
import { execFile as execFileCb2 } from "node:child_process";
|
|
111912
|
-
import { chmodSync as chmodSync3, existsSync as existsSync27, mkdirSync as
|
|
111976
|
+
import { chmodSync as chmodSync3, existsSync as existsSync27, mkdirSync as mkdirSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
111913
111977
|
import { homedir as homedir29 } from "node:os";
|
|
111914
111978
|
import { join as join39 } from "node:path";
|
|
111915
111979
|
import { promisify as promisify10 } from "node:util";
|
|
@@ -112195,7 +112259,7 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
112195
112259
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
112196
112260
|
const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
112197
112261
|
if (!existsSync27(VIEWERS_DIR2)) {
|
|
112198
|
-
|
|
112262
|
+
mkdirSync21(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
112199
112263
|
}
|
|
112200
112264
|
try {
|
|
112201
112265
|
chmodSync3(VIEWERS_DIR2, 448);
|
|
@@ -119783,59 +119847,39 @@ var init_contextChart = __esm(() => {
|
|
|
119783
119847
|
});
|
|
119784
119848
|
|
|
119785
119849
|
// src/cli/helpers/initCommand.ts
|
|
119786
|
-
import { execSync as
|
|
119850
|
+
import { execSync as execSync2 } from "node:child_process";
|
|
119787
119851
|
import { existsSync as existsSync29, readdirSync as readdirSync13, readFileSync as readFileSync14 } from "node:fs";
|
|
119788
119852
|
import { join as join41 } from "node:path";
|
|
119789
119853
|
function hasActiveInitSubagent() {
|
|
119790
119854
|
const snapshot = getSnapshot2();
|
|
119791
119855
|
return snapshot.agents.some((agent) => agent.type.toLowerCase() === "init" && (agent.status === "pending" || agent.status === "running"));
|
|
119792
119856
|
}
|
|
119793
|
-
function
|
|
119857
|
+
function gatherInitGitContext() {
|
|
119794
119858
|
try {
|
|
119795
|
-
const
|
|
119796
|
-
|
|
119797
|
-
|
|
119798
|
-
|
|
119799
|
-
|
|
119800
|
-
|
|
119801
|
-
|
|
119802
|
-
|
|
119803
|
-
|
|
119804
|
-
|
|
119805
|
-
|
|
119806
|
-
|
|
119807
|
-
|
|
119808
|
-
return `
|
|
119809
|
-
- branch: ${branch}
|
|
119810
|
-
- main: ${mainBranch}
|
|
119811
|
-
- status: ${status || "(clean)"}
|
|
119859
|
+
const git = gatherGitContextSnapshot({
|
|
119860
|
+
recentCommitLimit: 10
|
|
119861
|
+
});
|
|
119862
|
+
if (!git.isGitRepo) {
|
|
119863
|
+
return {
|
|
119864
|
+
context: "(not a git repository)",
|
|
119865
|
+
identity: ""
|
|
119866
|
+
};
|
|
119867
|
+
}
|
|
119868
|
+
return {
|
|
119869
|
+
context: `
|
|
119870
|
+
- branch: ${git.branch ?? "(unknown)"}
|
|
119871
|
+
- status: ${git.status || "(clean)"}
|
|
119812
119872
|
|
|
119813
119873
|
Recent commits:
|
|
119814
|
-
${recentCommits}
|
|
119815
|
-
|
|
119816
|
-
|
|
119817
|
-
|
|
119818
|
-
}
|
|
119819
|
-
} catch {
|
|
119820
|
-
return "";
|
|
119821
|
-
}
|
|
119822
|
-
}
|
|
119823
|
-
function gatherGitIdentity() {
|
|
119824
|
-
const cwd2 = process.cwd();
|
|
119825
|
-
try {
|
|
119826
|
-
const userName = execSync3("git config user.name 2>/dev/null || true", {
|
|
119827
|
-
cwd: cwd2,
|
|
119828
|
-
encoding: "utf-8"
|
|
119829
|
-
}).trim();
|
|
119830
|
-
const userEmail = execSync3("git config user.email 2>/dev/null || true", {
|
|
119831
|
-
cwd: cwd2,
|
|
119832
|
-
encoding: "utf-8"
|
|
119833
|
-
}).trim();
|
|
119834
|
-
if (userName || userEmail)
|
|
119835
|
-
return `${userName} <${userEmail}>`;
|
|
119836
|
-
return "";
|
|
119874
|
+
${git.recentCommits || "No commits yet"}
|
|
119875
|
+
`,
|
|
119876
|
+
identity: git.gitUser ?? ""
|
|
119877
|
+
};
|
|
119837
119878
|
} catch {
|
|
119838
|
-
return
|
|
119879
|
+
return {
|
|
119880
|
+
context: "",
|
|
119881
|
+
identity: ""
|
|
119882
|
+
};
|
|
119839
119883
|
}
|
|
119840
119884
|
}
|
|
119841
119885
|
function gatherExistingMemory(agentId) {
|
|
@@ -119868,7 +119912,7 @@ function getGitIgnored(cwd2, names) {
|
|
|
119868
119912
|
if (names.length === 0)
|
|
119869
119913
|
return new Set;
|
|
119870
119914
|
try {
|
|
119871
|
-
const result =
|
|
119915
|
+
const result = execSync2("git check-ignore --stdin", {
|
|
119872
119916
|
cwd: cwd2,
|
|
119873
119917
|
encoding: "utf-8",
|
|
119874
119918
|
input: names.join(`
|
|
@@ -119897,8 +119941,7 @@ function gatherDirListing() {
|
|
|
119897
119941
|
const files = visible.filter((e) => !e.isDirectory() && !ignored.has(e.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
119898
119942
|
const lines = [];
|
|
119899
119943
|
const sorted = [...dirs, ...files];
|
|
119900
|
-
for (
|
|
119901
|
-
const entry = sorted[i];
|
|
119944
|
+
for (const [i, entry] of sorted.entries()) {
|
|
119902
119945
|
const isLast = i === sorted.length - 1;
|
|
119903
119946
|
const prefix = isLast ? "└── " : "├── ";
|
|
119904
119947
|
if (entry.isDirectory()) {
|
|
@@ -119915,8 +119958,7 @@ function gatherDirListing() {
|
|
|
119915
119958
|
return a.name.localeCompare(b.name);
|
|
119916
119959
|
});
|
|
119917
119960
|
const childPrefix = isLast ? " " : "│ ";
|
|
119918
|
-
for (
|
|
119919
|
-
const child = children[j];
|
|
119961
|
+
for (const [j, child] of children.entries()) {
|
|
119920
119962
|
const childIsLast = j === children.length - 1;
|
|
119921
119963
|
const connector = childIsLast ? "└── " : "├── ";
|
|
119922
119964
|
const suffix = child.isDirectory() ? "/" : "";
|
|
@@ -119962,16 +120004,15 @@ async function fireAutoInit(agentId, onComplete) {
|
|
|
119962
120004
|
return false;
|
|
119963
120005
|
if (!settingsManager.isMemfsEnabled(agentId))
|
|
119964
120006
|
return false;
|
|
119965
|
-
const
|
|
119966
|
-
const gitIdentity = gatherGitIdentity();
|
|
120007
|
+
const gitDetails = gatherInitGitContext();
|
|
119967
120008
|
const existingMemory = gatherExistingMemory(agentId);
|
|
119968
120009
|
const dirListing = gatherDirListing();
|
|
119969
120010
|
const initPrompt = buildShallowInitPrompt({
|
|
119970
120011
|
agentId,
|
|
119971
120012
|
workingDirectory: process.cwd(),
|
|
119972
120013
|
memoryDir: getMemoryFilesystemRoot(agentId),
|
|
119973
|
-
gitContext,
|
|
119974
|
-
gitIdentity,
|
|
120014
|
+
gitContext: gitDetails.context,
|
|
120015
|
+
gitIdentity: gitDetails.identity,
|
|
119975
120016
|
existingMemory,
|
|
119976
120017
|
dirListing
|
|
119977
120018
|
});
|
|
@@ -120013,6 +120054,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
120013
120054
|
var init_initCommand = __esm(async () => {
|
|
120014
120055
|
init_memoryFilesystem();
|
|
120015
120056
|
init_constants();
|
|
120057
|
+
init_gitContext();
|
|
120016
120058
|
init_subagentState();
|
|
120017
120059
|
await init_settings_manager();
|
|
120018
120060
|
});
|
|
@@ -120029,9 +120071,7 @@ async function handleMemorySubagentCompletion(args, deps) {
|
|
|
120029
120071
|
inFlight = (async () => {
|
|
120030
120072
|
do {
|
|
120031
120073
|
deps.recompileQueuedByConversation.delete(conversationId);
|
|
120032
|
-
await recompileAgentSystemPromptFn(conversationId,
|
|
120033
|
-
...conversationId === "default" ? { agentId } : {}
|
|
120034
|
-
});
|
|
120074
|
+
await recompileAgentSystemPromptFn(conversationId, agentId);
|
|
120035
120075
|
} while (deps.recompileQueuedByConversation.has(conversationId));
|
|
120036
120076
|
})().finally(() => {
|
|
120037
120077
|
deps.recompileQueuedByConversation.delete(conversationId);
|
|
@@ -127440,7 +127480,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
127440
127480
|
setCommandRunning(true);
|
|
127441
127481
|
try {
|
|
127442
127482
|
cmd.finish("Building your memory palace... Start a new conversation with `letta --new` to work in parallel.", true);
|
|
127443
|
-
const gitContext =
|
|
127483
|
+
const { context: gitContext } = gatherInitGitContext();
|
|
127444
127484
|
const memoryDir = settingsManager.isMemfsEnabled(agentId) ? getMemoryFilesystemRoot(agentId) : undefined;
|
|
127445
127485
|
const initMessage = buildInitMessage({
|
|
127446
127486
|
gitContext,
|
|
@@ -130842,7 +130882,7 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
130842
130882
|
import {
|
|
130843
130883
|
copyFileSync as copyFileSync2,
|
|
130844
130884
|
existsSync as existsSync32,
|
|
130845
|
-
mkdirSync as
|
|
130885
|
+
mkdirSync as mkdirSync22,
|
|
130846
130886
|
readFileSync as readFileSync17,
|
|
130847
130887
|
writeFileSync as writeFileSync17
|
|
130848
130888
|
} from "node:fs";
|
|
@@ -130940,7 +130980,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
130940
130980
|
}
|
|
130941
130981
|
const parentDir = dirname15(keybindingsPath);
|
|
130942
130982
|
if (!existsSync32(parentDir)) {
|
|
130943
|
-
|
|
130983
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
130944
130984
|
}
|
|
130945
130985
|
let keybindings = [];
|
|
130946
130986
|
let backupPath = null;
|
|
@@ -131099,7 +131139,7 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
131099
131139
|
}
|
|
131100
131140
|
const parentDir = dirname15(configPath);
|
|
131101
131141
|
if (!existsSync32(parentDir)) {
|
|
131102
|
-
|
|
131142
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
131103
131143
|
}
|
|
131104
131144
|
writeFileSync17(configPath, content, { encoding: "utf-8" });
|
|
131105
131145
|
return {
|
|
@@ -131797,7 +131837,7 @@ __export(exports_memoryFilesystem2, {
|
|
|
131797
131837
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
131798
131838
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
131799
131839
|
});
|
|
131800
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
131840
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync23 } from "node:fs";
|
|
131801
131841
|
import { homedir as homedir36 } from "node:os";
|
|
131802
131842
|
import { join as join47 } from "node:path";
|
|
131803
131843
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir36()) {
|
|
@@ -131810,10 +131850,10 @@ function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir36()) {
|
|
|
131810
131850
|
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
131811
131851
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
131812
131852
|
if (!existsSync33(root)) {
|
|
131813
|
-
|
|
131853
|
+
mkdirSync23(root, { recursive: true });
|
|
131814
131854
|
}
|
|
131815
131855
|
if (!existsSync33(systemDir)) {
|
|
131816
|
-
|
|
131856
|
+
mkdirSync23(systemDir, { recursive: true });
|
|
131817
131857
|
}
|
|
131818
131858
|
}
|
|
131819
131859
|
function labelFromRelativePath2(relativePath) {
|
|
@@ -134002,7 +134042,7 @@ init_fileSearchConfig();
|
|
|
134002
134042
|
import { createHash } from "node:crypto";
|
|
134003
134043
|
import {
|
|
134004
134044
|
existsSync as existsSync7,
|
|
134005
|
-
mkdirSync as
|
|
134045
|
+
mkdirSync as mkdirSync5,
|
|
134006
134046
|
readdirSync as readdirSync2,
|
|
134007
134047
|
readFileSync as readFileSync5,
|
|
134008
134048
|
statSync,
|
|
@@ -134219,7 +134259,7 @@ async function buildDirectory(dir, relativePath, entries, merkle, statsMap, prev
|
|
|
134219
134259
|
return previous.merkle[relativePath] ?? hashValue("__reused__");
|
|
134220
134260
|
}
|
|
134221
134261
|
statsMap[relativePath] = currentStats;
|
|
134222
|
-
if (depth >= MAX_INDEX_DEPTH) {
|
|
134262
|
+
if (depth >= MAX_INDEX_DEPTH || context2.newEntryCount >= MAX_CACHE_ENTRIES) {
|
|
134223
134263
|
context2.truncated = true;
|
|
134224
134264
|
const truncatedHash = hashValue("__truncated__");
|
|
134225
134265
|
merkle[relativePath] = truncatedHash;
|
|
@@ -134227,6 +134267,10 @@ async function buildDirectory(dir, relativePath, entries, merkle, statsMap, prev
|
|
|
134227
134267
|
}
|
|
134228
134268
|
const childHashes = [];
|
|
134229
134269
|
for (const entry of childNames) {
|
|
134270
|
+
if (context2.newEntryCount >= MAX_CACHE_ENTRIES) {
|
|
134271
|
+
context2.truncated = true;
|
|
134272
|
+
break;
|
|
134273
|
+
}
|
|
134230
134274
|
if (context2.newEntryCount > 0 && context2.newEntryCount % 500 === 0) {
|
|
134231
134275
|
await new Promise((resolve2) => setImmediate(resolve2));
|
|
134232
134276
|
}
|
|
@@ -134308,7 +134352,7 @@ function getProjectStorageDir() {
|
|
|
134308
134352
|
function ensureProjectStorageDir() {
|
|
134309
134353
|
const storageDir = getProjectStorageDir();
|
|
134310
134354
|
if (!existsSync7(storageDir)) {
|
|
134311
|
-
|
|
134355
|
+
mkdirSync5(storageDir, { recursive: true });
|
|
134312
134356
|
}
|
|
134313
134357
|
return storageDir;
|
|
134314
134358
|
}
|
|
@@ -135425,7 +135469,7 @@ import { parseArgs as parseArgs5 } from "node:util";
|
|
|
135425
135469
|
import {
|
|
135426
135470
|
appendFileSync as appendFileSync2,
|
|
135427
135471
|
existsSync as existsSync8,
|
|
135428
|
-
mkdirSync as
|
|
135472
|
+
mkdirSync as mkdirSync6,
|
|
135429
135473
|
readdirSync as readdirSync3,
|
|
135430
135474
|
unlinkSync as unlinkSync2
|
|
135431
135475
|
} from "node:fs";
|
|
@@ -135491,7 +135535,7 @@ class RemoteSessionLog {
|
|
|
135491
135535
|
return;
|
|
135492
135536
|
try {
|
|
135493
135537
|
if (!existsSync8(REMOTE_LOG_DIR)) {
|
|
135494
|
-
|
|
135538
|
+
mkdirSync6(REMOTE_LOG_DIR, { recursive: true });
|
|
135495
135539
|
}
|
|
135496
135540
|
this.dirCreated = true;
|
|
135497
135541
|
} catch {}
|
|
@@ -135847,7 +135891,7 @@ async function runListenSubcommand(argv) {
|
|
|
135847
135891
|
|
|
135848
135892
|
// src/cli/subcommands/memfs.ts
|
|
135849
135893
|
await init_memoryGit();
|
|
135850
|
-
import { cpSync, existsSync as existsSync16, mkdirSync as
|
|
135894
|
+
import { cpSync, existsSync as existsSync16, mkdirSync as mkdirSync13, rmSync as rmSync2, statSync as statSync4 } from "node:fs";
|
|
135851
135895
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
135852
135896
|
import { homedir as homedir19 } from "node:os";
|
|
135853
135897
|
import { join as join23 } from "node:path";
|
|
@@ -136069,7 +136113,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
136069
136113
|
return 1;
|
|
136070
136114
|
}
|
|
136071
136115
|
} else {
|
|
136072
|
-
|
|
136116
|
+
mkdirSync13(out, { recursive: true });
|
|
136073
136117
|
}
|
|
136074
136118
|
cpSync(root, out, { recursive: true });
|
|
136075
136119
|
console.log(JSON.stringify({ exportedFrom: root, exportedTo: out, agentId }, null, 2));
|
|
@@ -138063,7 +138107,7 @@ ${after}`;
|
|
|
138063
138107
|
import {
|
|
138064
138108
|
appendFileSync as appendFileSync3,
|
|
138065
138109
|
existsSync as existsSync17,
|
|
138066
|
-
mkdirSync as
|
|
138110
|
+
mkdirSync as mkdirSync14,
|
|
138067
138111
|
readdirSync as readdirSync9,
|
|
138068
138112
|
readFileSync as readFileSync8,
|
|
138069
138113
|
unlinkSync as unlinkSync6
|
|
@@ -138135,7 +138179,7 @@ class DebugLogFile2 {
|
|
|
138135
138179
|
return;
|
|
138136
138180
|
try {
|
|
138137
138181
|
if (!existsSync17(this.agentDir)) {
|
|
138138
|
-
|
|
138182
|
+
mkdirSync14(this.agentDir, { recursive: true });
|
|
138139
138183
|
}
|
|
138140
138184
|
this.dirCreated = true;
|
|
138141
138185
|
} catch {}
|
|
@@ -139585,4 +139629,4 @@ Error during initialization: ${message}`);
|
|
|
139585
139629
|
}
|
|
139586
139630
|
main();
|
|
139587
139631
|
|
|
139588
|
-
//# debugId=
|
|
139632
|
+
//# debugId=CCE32950A21FCA1F64756E2164756E21
|