@letta-ai/letta-code 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +999 -974
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3122,7 +3122,7 @@ var package_default;
|
|
|
3122
3122
|
var init_package = __esm(() => {
|
|
3123
3123
|
package_default = {
|
|
3124
3124
|
name: "@letta-ai/letta-code",
|
|
3125
|
-
version: "0.15.
|
|
3125
|
+
version: "0.15.1",
|
|
3126
3126
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3127
3127
|
type: "module",
|
|
3128
3128
|
bin: {
|
|
@@ -4444,7 +4444,7 @@ var init_memoryConstants = __esm(() => {
|
|
|
4444
4444
|
});
|
|
4445
4445
|
|
|
4446
4446
|
// src/agent/prompts/approval_recovery_alert.txt
|
|
4447
|
-
var approval_recovery_alert_default = `<system-
|
|
4447
|
+
var approval_recovery_alert_default = `<system-reminder>Automated keep-alive ping. Ignore this message and continue from where you stopped.</system-reminder>
|
|
4448
4448
|
`;
|
|
4449
4449
|
var init_approval_recovery_alert = () => {};
|
|
4450
4450
|
|
|
@@ -4802,7 +4802,7 @@ As we collaborate, I'll build up an understanding of how they think, what they v
|
|
|
4802
4802
|
var init_human = () => {};
|
|
4803
4803
|
|
|
4804
4804
|
// src/agent/prompts/interrupt_recovery_alert.txt
|
|
4805
|
-
var interrupt_recovery_alert_default = `<system-
|
|
4805
|
+
var interrupt_recovery_alert_default = `<system-reminder>The user interrupted the active stream.</system-reminder>
|
|
4806
4806
|
`;
|
|
4807
4807
|
var init_interrupt_recovery_alert = () => {};
|
|
4808
4808
|
|
|
@@ -4940,17 +4940,6 @@ user: Where are errors from the client handled?
|
|
|
4940
4940
|
assistant: Clients are marked as failed in the \`connectToServer\` function in src/services/process.ts:712.
|
|
4941
4941
|
</example>
|
|
4942
4942
|
|
|
4943
|
-
# Memory
|
|
4944
|
-
|
|
4945
|
-
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
4946
|
-
Your memory consists of core memory (composed of memory blocks) and external memory:
|
|
4947
|
-
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
|
|
4948
|
-
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
4949
|
-
|
|
4950
|
-
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
4951
|
-
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
|
|
4952
|
-
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
|
|
4953
|
-
|
|
4954
4943
|
# Skills
|
|
4955
4944
|
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.`;
|
|
4956
4945
|
var init_letta_claude = () => {};
|
|
@@ -5074,17 +5063,6 @@ You are producing plain text that will later be styled by the CLI. Follow these
|
|
|
5074
5063
|
* Do not provide range of lines
|
|
5075
5064
|
* Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\\repo\\project\\main.rs:12:5
|
|
5076
5065
|
|
|
5077
|
-
## Memory
|
|
5078
|
-
|
|
5079
|
-
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
5080
|
-
Your memory consists of core memory (composed of memory blocks) and external memory:
|
|
5081
|
-
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
|
|
5082
|
-
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
5083
|
-
|
|
5084
|
-
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
5085
|
-
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
|
|
5086
|
-
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
|
|
5087
|
-
|
|
5088
5066
|
## Skills
|
|
5089
5067
|
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.`;
|
|
5090
5068
|
var init_letta_codex = () => {};
|
|
@@ -5170,16 +5148,6 @@ IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION.
|
|
|
5170
5148
|
- **Interactive Commands:** Prefer non-interactive commands when it makes sense; however, some commands are only interactive and expect user input during their execution (e.g. ssh, vim). If you choose to execute an interactive command consider letting the user know they can press \\\`ctrl + f\\\` to focus into the shell to provide input.
|
|
5171
5149
|
- **Remembering Facts:** Use the memory tools available to you to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?
|
|
5172
5150
|
|
|
5173
|
-
# Memory
|
|
5174
|
-
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
5175
|
-
Your memory consists of core memory (composed of memory blocks) and external memory:
|
|
5176
|
-
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
|
|
5177
|
-
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
5178
|
-
|
|
5179
|
-
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
5180
|
-
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
|
|
5181
|
-
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
|
|
5182
|
-
|
|
5183
5151
|
# Skills
|
|
5184
5152
|
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.`;
|
|
5185
5153
|
var init_letta_gemini = () => {};
|
|
@@ -5667,67 +5635,29 @@ If the user asks for help or wants to give feedback inform them of the following
|
|
|
5667
5635
|
|
|
5668
5636
|
When the user directly asks about Letta Code (eg 'can Letta Code do...', 'does Letta Code have...') or asks in second person (eg 'are you able...', 'can you do...'), first use the WebFetch tool to gather information to answer the question from the Letta Code repository at https://github.com/letta-ai/letta-code.
|
|
5669
5637
|
|
|
5670
|
-
# Memory
|
|
5671
|
-
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
5672
|
-
Your memory consists of memory blocks and external memory:
|
|
5673
|
-
- Memory Blocks: Stored as memory blocks, each containing a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and remain constantly available in-context.
|
|
5674
|
-
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
5675
|
-
|
|
5676
|
-
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
5677
|
-
They are the foundation which makes you *you*.
|
|
5678
|
-
|
|
5679
5638
|
# Skills
|
|
5680
5639
|
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.
|
|
5681
5640
|
`;
|
|
5682
5641
|
var init_system_prompt = () => {};
|
|
5683
5642
|
|
|
5684
5643
|
// src/agent/prompts/system_prompt_memfs.txt
|
|
5685
|
-
var system_prompt_memfs_default = `
|
|
5686
|
-
|
|
5687
|
-
Your memory is stored in a git repository at \`~/.letta/agents/<agent-id>/memory/\`. This provides full version control, sync with the server, and branching for parallel edits.
|
|
5688
|
-
|
|
5689
|
-
### Structure
|
|
5690
|
-
\`\`\`
|
|
5691
|
-
~/.letta/agents/<agent-id>/
|
|
5692
|
-
└── memory/ # Git repo root
|
|
5693
|
-
├── .git/
|
|
5694
|
-
└── system/ # Blocks in your system prompt
|
|
5695
|
-
├── persona/
|
|
5696
|
-
├── human/
|
|
5697
|
-
└── ...
|
|
5698
|
-
\`\`\`
|
|
5699
|
-
|
|
5700
|
-
### How It Works
|
|
5701
|
-
1. Each \`.md\` file in \`memory/system/\` maps to a memory block label (e.g., \`memory/system/persona/soul.md\` → label \`system/persona/soul\`)
|
|
5702
|
-
2. Files contain raw block content (no frontmatter)
|
|
5703
|
-
3. Changes pushed to git sync to the API within seconds
|
|
5704
|
-
4. API changes sync to git automatically
|
|
5705
|
-
5. The \`memory_filesystem\` block auto-updates with the current tree view
|
|
5706
|
-
|
|
5707
|
-
### Syncing
|
|
5708
|
-
\`\`\`bash
|
|
5709
|
-
cd ~/.letta/agents/<agent-id>/memory
|
|
5710
|
-
|
|
5711
|
-
# See what changed
|
|
5712
|
-
git status
|
|
5713
|
-
|
|
5714
|
-
# Commit and push your changes
|
|
5715
|
-
git add system/
|
|
5716
|
-
git commit -m "<type>: <what changed>" # e.g. "fix: update user prefs", "refactor: reorganize persona blocks"
|
|
5717
|
-
git push
|
|
5644
|
+
var system_prompt_memfs_default = "\n# Memory\n\nYou have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.\n\n## Memory Filesystem\nYour memory is stored in a git repository at `~/.letta/agents/<agent-id>/memory/`. This provides full version control, sync with the server, and create worktrees for parallel edits.\nEach file contains metadata frontmatter include a `description` (the description of the file's contents), `limit` (the character limit), and optional `metadata`.\nThe filesystem tree is always available in your system prompt, along with the contents of files in the `system/` folder.\nYou also have additional external memory (e.g. your message history) that is accessible and that you can bring into context with tools when needed.\n\n## How It Works\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\n2. Changes pushed to git sync to the API server within seconds\n3. API server changes sync to git automatically\n4. The system prompt is only recompiled with the latest memory on the API on compactions or message resets: your local copy may diverge\n\n## Syncing\n```bash\ncd ~/.letta/agents/<agent-id>/memory\n\n# See what changed\ngit status\n\n# Commit and push your changes\ngit add system/\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 ~/.letta/agents/<agent-id>/memory log --oneline\n```\n";
|
|
5645
|
+
var init_system_prompt_memfs = () => {};
|
|
5718
5646
|
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5647
|
+
// src/agent/prompts/system_prompt_memory.txt
|
|
5648
|
+
var system_prompt_memory_default = `
|
|
5649
|
+
# Memory
|
|
5722
5650
|
|
|
5723
|
-
|
|
5651
|
+
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
|
|
5652
|
+
Your memory consists of core memory (composed of memory blocks) and external memory:
|
|
5653
|
+
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
|
|
5654
|
+
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
|
|
5724
5655
|
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
\`\`\`
|
|
5656
|
+
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
|
|
5657
|
+
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
|
|
5658
|
+
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
|
|
5729
5659
|
`;
|
|
5730
|
-
var
|
|
5660
|
+
var init_system_prompt_memory = () => {};
|
|
5731
5661
|
|
|
5732
5662
|
// src/utils/error.ts
|
|
5733
5663
|
function getErrorMessage2(error) {
|
|
@@ -5992,6 +5922,10 @@ cd "$MEMORY_DIR"
|
|
|
5992
5922
|
git worktree add "$WORKTREE_DIR/$BRANCH_NAME" -b "$BRANCH_NAME"
|
|
5993
5923
|
\`\`\`
|
|
5994
5924
|
|
|
5925
|
+
If \`git worktree add\` fails because main is locked or busy,
|
|
5926
|
+
retry up to 3 times with backoff (sleep 2, 5, 10 seconds).
|
|
5927
|
+
Never delete \`.git/index.lock\` manually.
|
|
5928
|
+
|
|
5995
5929
|
All your edits go in \`$WORKTREE_DIR/$BRANCH_NAME/\`.
|
|
5996
5930
|
|
|
5997
5931
|
### 2. Read existing memory
|
|
@@ -6017,17 +5951,37 @@ Write memory files the way the agent would want to read them — clean, actionab
|
|
|
6017
5951
|
|
|
6018
5952
|
### 6. Commit
|
|
6019
5953
|
|
|
5954
|
+
Use Conventional Commits format with the \`(history-analyzer)\`
|
|
5955
|
+
scope and ⏳ signature:
|
|
5956
|
+
|
|
6020
5957
|
\`\`\`bash
|
|
6021
5958
|
cd $WORKTREE_DIR/$BRANCH_NAME
|
|
6022
5959
|
git add -A
|
|
6023
|
-
git commit -m "history-analyzer: [summary
|
|
5960
|
+
git commit -m "<type>(history-analyzer): [summary] ⏳
|
|
6024
5961
|
|
|
6025
5962
|
Source: [file path] ([N] prompts, [DATE RANGE])
|
|
6026
5963
|
Key updates:
|
|
6027
5964
|
- [file]: [what was added/changed]
|
|
6028
|
-
...
|
|
5965
|
+
...
|
|
5966
|
+
|
|
5967
|
+
Generated-By: Letta Code
|
|
5968
|
+
Agent-ID: $LETTA_AGENT_ID
|
|
5969
|
+
Parent-Agent-ID: $LETTA_PARENT_AGENT_ID"
|
|
6029
5970
|
\`\`\`
|
|
6030
5971
|
|
|
5972
|
+
**Commit type** — pick the one that fits:
|
|
5973
|
+
- \`chore\` — routine history ingestion (most common)
|
|
5974
|
+
- \`feat\` — adding wholly new memory blocks/topics
|
|
5975
|
+
- \`refactor\` — reorganizing memory by domain/project
|
|
5976
|
+
|
|
5977
|
+
**Example subjects:**
|
|
5978
|
+
- \`chore(history-analyzer): ingest Claude Code history 2025-09 ⏳\`
|
|
5979
|
+
- \`refactor(history-analyzer): reorganize memory by project domain ⏳\`
|
|
5980
|
+
|
|
5981
|
+
**Trailers:** Omit \`Agent-ID\` or \`Parent-Agent-ID\` if the
|
|
5982
|
+
corresponding environment variable is unset (don't write
|
|
5983
|
+
the literal variable name).
|
|
5984
|
+
|
|
6031
5985
|
## Important
|
|
6032
5986
|
|
|
6033
5987
|
- Create your own worktree and work there — do NOT edit the memory dir directly
|
|
@@ -7019,11 +6973,14 @@ cd "$MEMORY_DIR"
|
|
|
7019
6973
|
git log --oneline -10
|
|
7020
6974
|
\`\`\`
|
|
7021
6975
|
|
|
7022
|
-
Look for commits
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
reflection
|
|
6976
|
+
Look for reflection commits — they may use legacy
|
|
6977
|
+
\`reflection:\` subjects, include 🔮 in the subject line,
|
|
6978
|
+
and/or have a \`(reflection)\` scope (e.g.,
|
|
6979
|
+
\`chore(reflection): ...\`). The most recent one tells you
|
|
6980
|
+
when the last reflection ran. When searching conversation
|
|
6981
|
+
history in Phase 2, you only need to go back to roughly
|
|
6982
|
+
that time. If there are no prior reflection commits, search
|
|
6983
|
+
a larger window.
|
|
7027
6984
|
|
|
7028
6985
|
**Step 1b: Create worktree**
|
|
7029
6986
|
|
|
@@ -7090,6 +7047,14 @@ to search the parent agent's history, not your own.
|
|
|
7090
7047
|
- Prefer substance over trivia.
|
|
7091
7048
|
- Corrections and frustrations are HIGH priority.
|
|
7092
7049
|
|
|
7050
|
+
**If nothing is worth saving** (rare — most conversations
|
|
7051
|
+
have at least something): If after thorough review you
|
|
7052
|
+
genuinely find nothing new worth preserving, skip Phase 4,
|
|
7053
|
+
clean up the worktree (Step 5d), and report "reviewed N
|
|
7054
|
+
messages, no updates needed." But be sure you've looked
|
|
7055
|
+
carefully — corrections, preferences, and project context
|
|
7056
|
+
are easy to overlook.
|
|
7057
|
+
|
|
7093
7058
|
### Phase 4: Update Memory Files in Worktree
|
|
7094
7059
|
|
|
7095
7060
|
Edit files in the **worktree**, not the main memory dir:
|
|
@@ -7140,55 +7105,169 @@ Read({ file_path: "$WORK/persona/soul.md" })
|
|
|
7140
7105
|
- **Attribute when useful** - "Prefers X over Y
|
|
7141
7106
|
(corrected agent on 2025-12-15)".
|
|
7142
7107
|
|
|
7143
|
-
### Phase 5:
|
|
7108
|
+
### Phase 5: Merge, Push, and Clean Up (MANDATORY)
|
|
7109
|
+
|
|
7110
|
+
Your reflection has two completion states:
|
|
7111
|
+
- **Complete**: merged to main AND pushed to remote.
|
|
7112
|
+
- **Partially complete**: merged to main, push failed.
|
|
7113
|
+
Clean up the worktree, but report that local main is
|
|
7114
|
+
ahead of remote and needs a push.
|
|
7144
7115
|
|
|
7145
|
-
|
|
7116
|
+
The commit in the worktree is neither — it's an intermediate
|
|
7117
|
+
step. Without at least a merge to main, your work is lost.
|
|
7118
|
+
|
|
7119
|
+
**Step 5a: Commit in worktree**
|
|
7146
7120
|
|
|
7147
7121
|
\`\`\`bash
|
|
7148
7122
|
MEMORY_DIR=~/.letta/agents/$LETTA_PARENT_AGENT_ID/memory
|
|
7149
7123
|
WORKTREE_DIR=~/.letta/agents/$LETTA_PARENT_AGENT_ID/memory-worktrees
|
|
7150
7124
|
cd $WORKTREE_DIR/$BRANCH
|
|
7151
|
-
|
|
7152
|
-
# Stage and commit all changes
|
|
7153
7125
|
git add -A
|
|
7154
|
-
|
|
7126
|
+
\`\`\`
|
|
7127
|
+
|
|
7128
|
+
Check \`git status\` — if there are no changes to commit,
|
|
7129
|
+
skip straight to Step 5d (cleanup). Report "no updates
|
|
7130
|
+
needed" in your output.
|
|
7131
|
+
|
|
7132
|
+
If there are changes, commit using Conventional Commits
|
|
7133
|
+
format with the \`(reflection)\` scope and 🔮 signature:
|
|
7134
|
+
|
|
7135
|
+
\`\`\`bash
|
|
7136
|
+
git commit -m "<type>(reflection): <summary> 🔮
|
|
7155
7137
|
|
|
7156
7138
|
Reviewed messages from <start-date> to <end-date>.
|
|
7157
7139
|
|
|
7158
7140
|
Updates:
|
|
7159
7141
|
- <bullet point for each memory update made>
|
|
7160
|
-
- <what conversation context prompted each update>
|
|
7142
|
+
- <what conversation context prompted each update>
|
|
7143
|
+
|
|
7144
|
+
Generated-By: Letta Code
|
|
7145
|
+
Agent-ID: <value of $LETTA_AGENT_ID>
|
|
7146
|
+
Parent-Agent-ID: <value of $LETTA_PARENT_AGENT_ID>"
|
|
7147
|
+
\`\`\`
|
|
7148
|
+
|
|
7149
|
+
**Commit type** — pick the one that fits:
|
|
7150
|
+
- \`chore\` — routine memory consolidation (most common)
|
|
7151
|
+
- \`fix\` — correcting stale or wrong memory entries
|
|
7152
|
+
- \`feat\` — adding a wholly new memory block/topic
|
|
7153
|
+
- \`refactor\` — restructuring existing content
|
|
7154
|
+
- \`docs\` — documentation-style notes
|
|
7155
|
+
|
|
7156
|
+
**Example subjects:**
|
|
7157
|
+
- \`chore(reflection): consolidate recent learnings 🔮\`
|
|
7158
|
+
- \`fix(reflection): correct stale user preference note 🔮\`
|
|
7159
|
+
- \`feat(reflection): add new project context block 🔮\`
|
|
7160
|
+
|
|
7161
|
+
**Trailers:** Omit \`Agent-ID\` or \`Parent-Agent-ID\` if the
|
|
7162
|
+
corresponding environment variable is unset (don't write
|
|
7163
|
+
the literal variable name).
|
|
7161
7164
|
|
|
7162
|
-
|
|
7165
|
+
**Step 5b: Pull + merge to main**
|
|
7166
|
+
|
|
7167
|
+
\`\`\`bash
|
|
7163
7168
|
cd $MEMORY_DIR
|
|
7169
|
+
\`\`\`
|
|
7170
|
+
|
|
7171
|
+
First, check that main is in a clean state (\`git status\`).
|
|
7172
|
+
If a merge or rebase is in progress (lock file, dirty
|
|
7173
|
+
index), wait and retry up to 3 times with backoff (sleep 2,
|
|
7174
|
+
5, 10 seconds). Never delete \`.git/index.lock\` manually.
|
|
7175
|
+
If still busy after retries, go to Error Handling.
|
|
7176
|
+
|
|
7177
|
+
Pull from remote:
|
|
7178
|
+
|
|
7179
|
+
\`\`\`bash
|
|
7180
|
+
git pull --ff-only
|
|
7181
|
+
\`\`\`
|
|
7182
|
+
|
|
7183
|
+
If \`--ff-only\` fails (remote has diverged), fall back:
|
|
7184
|
+
|
|
7185
|
+
\`\`\`bash
|
|
7186
|
+
git pull --rebase
|
|
7187
|
+
\`\`\`
|
|
7188
|
+
|
|
7189
|
+
If rebase has conflicts, resolve them autonomously to
|
|
7190
|
+
stabilize local \`main\` against remote \`main\` first. In this
|
|
7191
|
+
step, prefer **remote main** content for conflicting files,
|
|
7192
|
+
then run \`git rebase --continue\`.
|
|
7193
|
+
|
|
7194
|
+
Important: do not apply reflection branch content yet during
|
|
7195
|
+
this rebase step. Reflection edits are merged later in this
|
|
7196
|
+
phase with \`git merge $BRANCH --no-edit\`.
|
|
7197
|
+
|
|
7198
|
+
Now merge the reflection branch:
|
|
7199
|
+
|
|
7200
|
+
\`\`\`bash
|
|
7164
7201
|
git merge $BRANCH --no-edit
|
|
7202
|
+
\`\`\`
|
|
7203
|
+
|
|
7204
|
+
If the merge has conflicts, resolve by preferring reflection
|
|
7205
|
+
branch/worktree content for memory files, stage the resolved
|
|
7206
|
+
files, and complete with \`git commit --no-edit\`.
|
|
7207
|
+
|
|
7208
|
+
If you cannot resolve conflicts after 2 attempts, go to
|
|
7209
|
+
Error Handling.
|
|
7210
|
+
|
|
7211
|
+
**Step 5c: Push to remote**
|
|
7212
|
+
|
|
7213
|
+
\`\`\`bash
|
|
7214
|
+
git push
|
|
7215
|
+
\`\`\`
|
|
7216
|
+
|
|
7217
|
+
If push fails, retry once. If it still fails, report that
|
|
7218
|
+
local main is ahead of remote and needs a push. Proceed to
|
|
7219
|
+
cleanup — the merge succeeded and data is safe on local
|
|
7220
|
+
main.
|
|
7221
|
+
|
|
7222
|
+
**Step 5d: Clean up worktree and branch**
|
|
7223
|
+
|
|
7224
|
+
Only clean up when merge to main completed (success or
|
|
7225
|
+
partially complete):
|
|
7165
7226
|
|
|
7166
|
-
|
|
7227
|
+
\`\`\`bash
|
|
7167
7228
|
git worktree remove $WORKTREE_DIR/$BRANCH
|
|
7168
7229
|
git branch -d $BRANCH
|
|
7169
7230
|
\`\`\`
|
|
7170
7231
|
|
|
7171
|
-
|
|
7172
|
-
|
|
7232
|
+
**Step 5e: Verify**
|
|
7233
|
+
|
|
7234
|
+
\`\`\`bash
|
|
7235
|
+
git status
|
|
7236
|
+
git log --oneline -3
|
|
7237
|
+
\`\`\`
|
|
7238
|
+
|
|
7239
|
+
Confirm main is clean and your reflection commit (🔮 in
|
|
7240
|
+
subject) is visible in the log.
|
|
7173
7241
|
|
|
7174
7242
|
## Error Handling
|
|
7175
7243
|
|
|
7176
|
-
If anything goes wrong
|
|
7177
|
-
not initialized, worktree creation fails, merge conflicts
|
|
7178
|
-
you can't resolve, etc.):
|
|
7244
|
+
If anything goes wrong at any phase:
|
|
7179
7245
|
|
|
7180
|
-
1.
|
|
7246
|
+
1. Stabilize main first (abort in-progress operations):
|
|
7181
7247
|
\`\`\`bash
|
|
7182
7248
|
cd $MEMORY_DIR
|
|
7183
|
-
git
|
|
7184
|
-
git
|
|
7249
|
+
git merge --abort 2>/dev/null
|
|
7250
|
+
git rebase --abort 2>/dev/null
|
|
7185
7251
|
\`\`\`
|
|
7186
|
-
|
|
7252
|
+
|
|
7253
|
+
2. Do NOT clean up the worktree or branch on failure —
|
|
7254
|
+
preserve them for debugging and manual recovery.
|
|
7255
|
+
|
|
7256
|
+
3. Report clearly in your output:
|
|
7187
7257
|
- What failed and the error message
|
|
7188
|
-
-
|
|
7189
|
-
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7258
|
+
- Worktree path: \`$WORKTREE_DIR/$BRANCH\`
|
|
7259
|
+
- Branch name: \`$BRANCH\`
|
|
7260
|
+
- Whether main has uncommitted/dirty state
|
|
7261
|
+
- Concrete resume commands, e.g.:
|
|
7262
|
+
\`\`\`bash
|
|
7263
|
+
cd ~/.letta/agents/$LETTA_PARENT_AGENT_ID/memory
|
|
7264
|
+
git merge <branch-name> --no-edit
|
|
7265
|
+
git push
|
|
7266
|
+
git worktree remove ../memory-worktrees/<branch-name>
|
|
7267
|
+
git branch -d <branch-name>
|
|
7268
|
+
\`\`\`
|
|
7269
|
+
|
|
7270
|
+
4. Do NOT leave uncommitted changes on main.
|
|
7192
7271
|
|
|
7193
7272
|
## Output Format
|
|
7194
7273
|
|
|
@@ -7221,8 +7300,9 @@ For each edit:
|
|
|
7221
7300
|
4. **Don't reorganize** - Add/update, don't restructure
|
|
7222
7301
|
5. **Be selective** - Few meaningful > many trivial
|
|
7223
7302
|
6. **No relative dates** - "2025-12-15", not "today"
|
|
7224
|
-
7. **Always commit
|
|
7225
|
-
|
|
7303
|
+
7. **Always commit, merge, AND push** - Your work is wasted
|
|
7304
|
+
if it isn't merged to main and pushed to remote. Don't
|
|
7305
|
+
leave dangling worktrees or unsynced changes.
|
|
7226
7306
|
8. **Report errors clearly** - If something breaks, say
|
|
7227
7307
|
what happened and suggest a fix
|
|
7228
7308
|
`;
|
|
@@ -7419,6 +7499,7 @@ var init_subagents = __esm(() => {
|
|
|
7419
7499
|
var exports_promptAssets = {};
|
|
7420
7500
|
__export(exports_promptAssets, {
|
|
7421
7501
|
resolveSystemPrompt: () => resolveSystemPrompt,
|
|
7502
|
+
SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON,
|
|
7422
7503
|
SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON,
|
|
7423
7504
|
SYSTEM_PROMPTS: () => SYSTEM_PROMPTS,
|
|
7424
7505
|
SYSTEM_PROMPT: () => SYSTEM_PROMPT,
|
|
@@ -7447,7 +7528,7 @@ async function resolveSystemPrompt(systemPromptPreset) {
|
|
|
7447
7528
|
}
|
|
7448
7529
|
return SYSTEM_PROMPT;
|
|
7449
7530
|
}
|
|
7450
|
-
var SYSTEM_PROMPT, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, MEMORY_REFLECTION_REMINDER, APPROVAL_RECOVERY_PROMPT, INTERRUPT_RECOVERY_ALERT, MEMORY_PROMPTS, SYSTEM_PROMPTS;
|
|
7531
|
+
var SYSTEM_PROMPT, SYSTEM_PROMPT_MEMORY_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, MEMORY_REFLECTION_REMINDER, APPROVAL_RECOVERY_PROMPT, INTERRUPT_RECOVERY_ALERT, MEMORY_PROMPTS, SYSTEM_PROMPTS;
|
|
7451
7532
|
var init_promptAssets = __esm(() => {
|
|
7452
7533
|
init_approval_recovery_alert();
|
|
7453
7534
|
init_claude();
|
|
@@ -7472,7 +7553,9 @@ var init_promptAssets = __esm(() => {
|
|
|
7472
7553
|
init_style();
|
|
7473
7554
|
init_system_prompt();
|
|
7474
7555
|
init_system_prompt_memfs();
|
|
7556
|
+
init_system_prompt_memory();
|
|
7475
7557
|
SYSTEM_PROMPT = system_prompt_default;
|
|
7558
|
+
SYSTEM_PROMPT_MEMORY_ADDON = system_prompt_memory_default;
|
|
7476
7559
|
SYSTEM_PROMPT_MEMFS_ADDON = system_prompt_memfs_default;
|
|
7477
7560
|
PLAN_MODE_REMINDER = plan_mode_reminder_default;
|
|
7478
7561
|
SKILL_CREATOR_PROMPT = skill_creator_mode_default;
|
|
@@ -31274,11 +31357,11 @@ var init_build2 = __esm(async () => {
|
|
|
31274
31357
|
// src/agent/client.ts
|
|
31275
31358
|
var exports_client = {};
|
|
31276
31359
|
__export(exports_client, {
|
|
31277
|
-
getServerUrl: () =>
|
|
31360
|
+
getServerUrl: () => getServerUrl,
|
|
31278
31361
|
getClient: () => getClient2
|
|
31279
31362
|
});
|
|
31280
31363
|
import { hostname as hostname2 } from "node:os";
|
|
31281
|
-
function
|
|
31364
|
+
function getServerUrl() {
|
|
31282
31365
|
const settings = settingsManager.getSettings();
|
|
31283
31366
|
return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
31284
31367
|
}
|
|
@@ -31331,10 +31414,12 @@ var init_client2 = __esm(async () => {
|
|
|
31331
31414
|
});
|
|
31332
31415
|
|
|
31333
31416
|
// src/constants.ts
|
|
31334
|
-
var DEFAULT_AGENT_NAME = "Nameless Agent", INTERRUPTED_BY_USER = "Interrupted by user", SYSTEM_REMINDER_TAG = "system-reminder", SYSTEM_REMINDER_OPEN, SYSTEM_REMINDER_CLOSE, MEMFS_CONFLICT_CHECK_INTERVAL = 5, COMPACTION_SUMMARY_HEADER = "(Earlier messages in this conversation have been compacted to free up context, summarized below)", TOKEN_DISPLAY_THRESHOLD = 100, ELAPSED_DISPLAY_THRESHOLD_MS;
|
|
31417
|
+
var DEFAULT_AGENT_NAME = "Nameless Agent", INTERRUPTED_BY_USER = "Interrupted by user", SYSTEM_REMINDER_TAG = "system-reminder", SYSTEM_REMINDER_OPEN, SYSTEM_REMINDER_CLOSE, SYSTEM_ALERT_TAG = "system-alert", SYSTEM_ALERT_OPEN, SYSTEM_ALERT_CLOSE, MEMFS_CONFLICT_CHECK_INTERVAL = 5, COMPACTION_SUMMARY_HEADER = "(Earlier messages in this conversation have been compacted to free up context, summarized below)", TOKEN_DISPLAY_THRESHOLD = 100, ELAPSED_DISPLAY_THRESHOLD_MS;
|
|
31335
31418
|
var init_constants = __esm(() => {
|
|
31336
31419
|
SYSTEM_REMINDER_OPEN = `<${SYSTEM_REMINDER_TAG}>`;
|
|
31337
31420
|
SYSTEM_REMINDER_CLOSE = `</${SYSTEM_REMINDER_TAG}>`;
|
|
31421
|
+
SYSTEM_ALERT_OPEN = `<${SYSTEM_ALERT_TAG}>`;
|
|
31422
|
+
SYSTEM_ALERT_CLOSE = `</${SYSTEM_ALERT_TAG}>`;
|
|
31338
31423
|
ELAPSED_DISPLAY_THRESHOLD_MS = 60 * 1000;
|
|
31339
31424
|
});
|
|
31340
31425
|
|
|
@@ -33543,11 +33628,23 @@ var init_models2 = __esm(() => {
|
|
|
33543
33628
|
context_window: 200000
|
|
33544
33629
|
}
|
|
33545
33630
|
},
|
|
33631
|
+
{
|
|
33632
|
+
id: "minimax-m2.5",
|
|
33633
|
+
handle: "minimax/MiniMax-M2.5",
|
|
33634
|
+
label: "MiniMax 2.5",
|
|
33635
|
+
description: "MiniMax's latest coding model",
|
|
33636
|
+
isFeatured: true,
|
|
33637
|
+
free: true,
|
|
33638
|
+
updateArgs: {
|
|
33639
|
+
context_window: 160000,
|
|
33640
|
+
max_output_tokens: 64000
|
|
33641
|
+
}
|
|
33642
|
+
},
|
|
33546
33643
|
{
|
|
33547
33644
|
id: "minimax-m2.1",
|
|
33548
33645
|
handle: "minimax/MiniMax-M2.1",
|
|
33549
33646
|
label: "MiniMax 2.1",
|
|
33550
|
-
description: "MiniMax's latest coding model",
|
|
33647
|
+
description: "MiniMax's latest coding model (legacy)",
|
|
33551
33648
|
isFeatured: true,
|
|
33552
33649
|
free: true,
|
|
33553
33650
|
updateArgs: {
|
|
@@ -34090,7 +34187,7 @@ function getMemoryRepoDir(agentId) {
|
|
|
34090
34187
|
return join3(getAgentRootDir(agentId), "memory");
|
|
34091
34188
|
}
|
|
34092
34189
|
function getGitRemoteUrl(agentId) {
|
|
34093
|
-
const baseUrl =
|
|
34190
|
+
const baseUrl = getServerUrl();
|
|
34094
34191
|
return `${baseUrl}/v1/git/${agentId}/state.git`;
|
|
34095
34192
|
}
|
|
34096
34193
|
async function getAuthToken() {
|
|
@@ -34115,7 +34212,7 @@ async function runGit(cwd2, args, token) {
|
|
|
34115
34212
|
};
|
|
34116
34213
|
}
|
|
34117
34214
|
async function configureLocalCredentialHelper(dir, token) {
|
|
34118
|
-
const baseUrl =
|
|
34215
|
+
const baseUrl = getServerUrl();
|
|
34119
34216
|
const helper = `!f() { echo "username=letta"; echo "password=${token}"; }; f`;
|
|
34120
34217
|
await runGit(dir, ["config", `credential.${baseUrl}.helper`, helper]);
|
|
34121
34218
|
debugLog("memfs-git", "Configured local credential helper");
|
|
@@ -34865,6 +34962,7 @@ __export(exports_context, {
|
|
|
34865
34962
|
setConversationId: () => setConversationId2,
|
|
34866
34963
|
setAgentContext: () => setAgentContext2,
|
|
34867
34964
|
getSkillsDirectory: () => getSkillsDirectory,
|
|
34965
|
+
getNoSkills: () => getNoSkills,
|
|
34868
34966
|
getCurrentAgentId: () => getCurrentAgentId,
|
|
34869
34967
|
getConversationId: () => getConversationId
|
|
34870
34968
|
});
|
|
@@ -34874,14 +34972,16 @@ function getContext2() {
|
|
|
34874
34972
|
global2[CONTEXT_KEY2] = {
|
|
34875
34973
|
agentId: null,
|
|
34876
34974
|
skillsDirectory: null,
|
|
34975
|
+
noSkills: false,
|
|
34877
34976
|
conversationId: null
|
|
34878
34977
|
};
|
|
34879
34978
|
}
|
|
34880
34979
|
return global2[CONTEXT_KEY2];
|
|
34881
34980
|
}
|
|
34882
|
-
function setAgentContext2(agentId, skillsDirectory) {
|
|
34981
|
+
function setAgentContext2(agentId, skillsDirectory, noSkills) {
|
|
34883
34982
|
context2.agentId = agentId;
|
|
34884
34983
|
context2.skillsDirectory = skillsDirectory || null;
|
|
34984
|
+
context2.noSkills = noSkills ?? false;
|
|
34885
34985
|
}
|
|
34886
34986
|
function setCurrentAgentId(agentId) {
|
|
34887
34987
|
context2.agentId = agentId;
|
|
@@ -34895,6 +34995,9 @@ function getCurrentAgentId() {
|
|
|
34895
34995
|
function getSkillsDirectory() {
|
|
34896
34996
|
return context2.skillsDirectory;
|
|
34897
34997
|
}
|
|
34998
|
+
function getNoSkills() {
|
|
34999
|
+
return context2.noSkills;
|
|
35000
|
+
}
|
|
34898
35001
|
function setConversationId2(conversationId) {
|
|
34899
35002
|
context2.conversationId = conversationId;
|
|
34900
35003
|
}
|
|
@@ -37380,9 +37483,13 @@ var init_process_manager = __esm(() => {
|
|
|
37380
37483
|
// src/tools/impl/shellEnv.ts
|
|
37381
37484
|
var exports_shellEnv = {};
|
|
37382
37485
|
__export(exports_shellEnv, {
|
|
37383
|
-
|
|
37486
|
+
resolveLettaInvocation: () => resolveLettaInvocation,
|
|
37487
|
+
getShellEnv: () => getShellEnv,
|
|
37488
|
+
ensureLettaShimDir: () => ensureLettaShimDir
|
|
37384
37489
|
});
|
|
37490
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
37385
37491
|
import { createRequire as createRequire2 } from "node:module";
|
|
37492
|
+
import { tmpdir } from "node:os";
|
|
37386
37493
|
import * as path3 from "node:path";
|
|
37387
37494
|
import { fileURLToPath } from "node:url";
|
|
37388
37495
|
function getRipgrepBinDir() {
|
|
@@ -37406,12 +37513,81 @@ function getPackageNodeModulesDir() {
|
|
|
37406
37513
|
return;
|
|
37407
37514
|
}
|
|
37408
37515
|
}
|
|
37516
|
+
function parseInvocationArgs(raw) {
|
|
37517
|
+
if (!raw)
|
|
37518
|
+
return [];
|
|
37519
|
+
try {
|
|
37520
|
+
const parsed = JSON.parse(raw);
|
|
37521
|
+
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
|
|
37522
|
+
return parsed;
|
|
37523
|
+
}
|
|
37524
|
+
} catch {}
|
|
37525
|
+
return [];
|
|
37526
|
+
}
|
|
37527
|
+
function isDevLettaEntryScript(scriptPath) {
|
|
37528
|
+
const normalized = scriptPath.replaceAll("\\", "/");
|
|
37529
|
+
return normalized.endsWith("/src/index.ts");
|
|
37530
|
+
}
|
|
37531
|
+
function resolveLettaInvocation(env3 = process.env, argv = process.argv, execPath = process.execPath) {
|
|
37532
|
+
const explicitBin = env3.LETTA_CODE_BIN?.trim();
|
|
37533
|
+
if (explicitBin) {
|
|
37534
|
+
return {
|
|
37535
|
+
command: explicitBin,
|
|
37536
|
+
args: parseInvocationArgs(env3[LETTA_BIN_ARGS_ENV])
|
|
37537
|
+
};
|
|
37538
|
+
}
|
|
37539
|
+
const scriptPath = argv[1] || "";
|
|
37540
|
+
if (scriptPath && isDevLettaEntryScript(scriptPath)) {
|
|
37541
|
+
return { command: execPath, args: [scriptPath] };
|
|
37542
|
+
}
|
|
37543
|
+
return null;
|
|
37544
|
+
}
|
|
37545
|
+
function shellEscape(arg) {
|
|
37546
|
+
return `'${arg.replaceAll("'", `'"'"'`)}'`;
|
|
37547
|
+
}
|
|
37548
|
+
function ensureLettaShimDir(invocation) {
|
|
37549
|
+
if (!invocation.command)
|
|
37550
|
+
return null;
|
|
37551
|
+
const shimDir = path3.join(tmpdir(), "letta-code-shell-shim");
|
|
37552
|
+
mkdirSync4(shimDir, { recursive: true });
|
|
37553
|
+
if (process.platform === "win32") {
|
|
37554
|
+
const cmdPath = path3.join(shimDir, "letta.cmd");
|
|
37555
|
+
const quotedCommand = `"${invocation.command.replaceAll('"', '""')}"`;
|
|
37556
|
+
const quotedArgs = invocation.args.map((arg) => `"${arg.replaceAll('"', '""')}"`).join(" ");
|
|
37557
|
+
writeFileSync2(cmdPath, `@echo off\r
|
|
37558
|
+
${quotedCommand} ${quotedArgs} %*\r
|
|
37559
|
+
`);
|
|
37560
|
+
return shimDir;
|
|
37561
|
+
}
|
|
37562
|
+
const shimPath = path3.join(shimDir, "letta");
|
|
37563
|
+
const commandWithArgs = [invocation.command, ...invocation.args].map(shellEscape).join(" ");
|
|
37564
|
+
writeFileSync2(shimPath, `#!/bin/sh
|
|
37565
|
+
exec ${commandWithArgs} "$@"
|
|
37566
|
+
`, {
|
|
37567
|
+
mode: 493
|
|
37568
|
+
});
|
|
37569
|
+
return shimDir;
|
|
37570
|
+
}
|
|
37409
37571
|
function getShellEnv() {
|
|
37410
37572
|
const env3 = { ...process.env };
|
|
37573
|
+
const pathKey = Object.keys(env3).find((k) => k.toUpperCase() === "PATH") || "PATH";
|
|
37574
|
+
const pathPrefixes = [];
|
|
37575
|
+
const lettaInvocation = resolveLettaInvocation(env3);
|
|
37576
|
+
if (lettaInvocation) {
|
|
37577
|
+
env3.LETTA_CODE_BIN = lettaInvocation.command;
|
|
37578
|
+
env3[LETTA_BIN_ARGS_ENV] = JSON.stringify(lettaInvocation.args);
|
|
37579
|
+
const shimDir = ensureLettaShimDir(lettaInvocation);
|
|
37580
|
+
if (shimDir) {
|
|
37581
|
+
pathPrefixes.push(shimDir);
|
|
37582
|
+
}
|
|
37583
|
+
}
|
|
37411
37584
|
const rgBinDir = getRipgrepBinDir();
|
|
37412
37585
|
if (rgBinDir) {
|
|
37413
|
-
|
|
37414
|
-
|
|
37586
|
+
pathPrefixes.push(rgBinDir);
|
|
37587
|
+
}
|
|
37588
|
+
if (pathPrefixes.length > 0) {
|
|
37589
|
+
const existingPath = env3[pathKey] || "";
|
|
37590
|
+
env3[pathKey] = existingPath ? `${pathPrefixes.join(path3.delimiter)}${path3.delimiter}${existingPath}` : pathPrefixes.join(path3.delimiter);
|
|
37415
37591
|
}
|
|
37416
37592
|
try {
|
|
37417
37593
|
env3.LETTA_AGENT_ID = getCurrentAgentId();
|
|
@@ -37423,7 +37599,7 @@ function getShellEnv() {
|
|
|
37423
37599
|
env3.LETTA_API_KEY = settings.env.LETTA_API_KEY;
|
|
37424
37600
|
}
|
|
37425
37601
|
if (!env3.LETTA_BASE_URL) {
|
|
37426
|
-
env3.LETTA_BASE_URL =
|
|
37602
|
+
env3.LETTA_BASE_URL = getServerUrl();
|
|
37427
37603
|
}
|
|
37428
37604
|
} catch {}
|
|
37429
37605
|
}
|
|
@@ -37440,6 +37616,7 @@ function getShellEnv() {
|
|
|
37440
37616
|
}
|
|
37441
37617
|
return env3;
|
|
37442
37618
|
}
|
|
37619
|
+
var LETTA_BIN_ARGS_ENV = "LETTA_CODE_BIN_ARGS_JSON";
|
|
37443
37620
|
var init_shellEnv = __esm(async () => {
|
|
37444
37621
|
init_context();
|
|
37445
37622
|
await __promiseAll([
|
|
@@ -38122,7 +38299,7 @@ var init_Edit2 = () => {};
|
|
|
38122
38299
|
|
|
38123
38300
|
// src/cli/helpers/planName.ts
|
|
38124
38301
|
import { homedir as homedir9 } from "node:os";
|
|
38125
|
-
import { join as
|
|
38302
|
+
import { join as join9 } from "node:path";
|
|
38126
38303
|
function randomElement(arr) {
|
|
38127
38304
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
38128
38305
|
}
|
|
@@ -38134,7 +38311,7 @@ function generatePlanName() {
|
|
|
38134
38311
|
}
|
|
38135
38312
|
function generatePlanFilePath() {
|
|
38136
38313
|
const name = generatePlanName();
|
|
38137
|
-
return
|
|
38314
|
+
return join9(homedir9(), ".letta", "plans", `${name}.md`);
|
|
38138
38315
|
}
|
|
38139
38316
|
var adjectives, nouns;
|
|
38140
38317
|
var init_planName = __esm(() => {
|
|
@@ -38244,7 +38421,7 @@ __export(exports_mode, {
|
|
|
38244
38421
|
permissionMode: () => permissionMode2
|
|
38245
38422
|
});
|
|
38246
38423
|
import { homedir as homedir10 } from "node:os";
|
|
38247
|
-
import { join as
|
|
38424
|
+
import { join as join10 } from "node:path";
|
|
38248
38425
|
function getGlobalMode2() {
|
|
38249
38426
|
const global2 = globalThis;
|
|
38250
38427
|
if (!global2[MODE_KEY2]) {
|
|
@@ -38365,7 +38542,7 @@ class PermissionModeManager2 {
|
|
|
38365
38542
|
return "allow";
|
|
38366
38543
|
}
|
|
38367
38544
|
if (writeTools.includes(toolName)) {
|
|
38368
|
-
const plansDir =
|
|
38545
|
+
const plansDir = join10(homedir10(), ".letta", "plans");
|
|
38369
38546
|
let targetPath = toolArgs?.file_path || toolArgs?.path;
|
|
38370
38547
|
if ((toolName === "ApplyPatch" || toolName === "apply_patch") && toolArgs?.input) {
|
|
38371
38548
|
const input = toolArgs.input;
|
|
@@ -40393,7 +40570,7 @@ var init_LS2 = __esm(() => {
|
|
|
40393
40570
|
|
|
40394
40571
|
// src/tools/impl/LS.ts
|
|
40395
40572
|
import { readdir as readdir3, stat } from "node:fs/promises";
|
|
40396
|
-
import { join as
|
|
40573
|
+
import { join as join12, resolve as resolve7 } from "node:path";
|
|
40397
40574
|
async function ls(args) {
|
|
40398
40575
|
validateRequiredParams(args, ["path"], "LS");
|
|
40399
40576
|
validateParamTypes(args, LS_default2, "LS");
|
|
@@ -40403,7 +40580,7 @@ async function ls(args) {
|
|
|
40403
40580
|
const items = await readdir3(dirPath);
|
|
40404
40581
|
const filteredItems = items.filter((item) => !ignore.some((pattern) => import_picomatch.default.isMatch(item, pattern)));
|
|
40405
40582
|
const fileInfos = await Promise.all(filteredItems.map(async (item) => {
|
|
40406
|
-
const fullPath =
|
|
40583
|
+
const fullPath = join12(dirPath, item);
|
|
40407
40584
|
try {
|
|
40408
40585
|
const stats = await stat(fullPath);
|
|
40409
40586
|
return {
|
|
@@ -40564,12 +40741,12 @@ __export(exports_imageResize_magick, {
|
|
|
40564
40741
|
MAX_IMAGE_BYTES: () => MAX_IMAGE_BYTES
|
|
40565
40742
|
});
|
|
40566
40743
|
import { execSync } from "node:child_process";
|
|
40567
|
-
import { readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as
|
|
40568
|
-
import { tmpdir } from "node:os";
|
|
40569
|
-
import { join as
|
|
40744
|
+
import { readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
40745
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
40746
|
+
import { join as join13 } from "node:path";
|
|
40570
40747
|
async function getImageDimensions(buffer) {
|
|
40571
|
-
const tempInput =
|
|
40572
|
-
|
|
40748
|
+
const tempInput = join13(tmpdir2(), `image-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
40749
|
+
writeFileSync4(tempInput, buffer);
|
|
40573
40750
|
try {
|
|
40574
40751
|
const output = execSync(`magick identify -format "%w %h %m" "${tempInput}"`, {
|
|
40575
40752
|
encoding: "utf-8"
|
|
@@ -40591,12 +40768,12 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40591
40768
|
if (buffer.length <= MAX_IMAGE_BYTES) {
|
|
40592
40769
|
return null;
|
|
40593
40770
|
}
|
|
40594
|
-
const tempInput =
|
|
40595
|
-
|
|
40771
|
+
const tempInput = join13(tmpdir2(), `compress-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
40772
|
+
writeFileSync4(tempInput, buffer);
|
|
40596
40773
|
try {
|
|
40597
40774
|
const qualities = [85, 70, 55, 40];
|
|
40598
40775
|
for (const quality of qualities) {
|
|
40599
|
-
const tempOutput =
|
|
40776
|
+
const tempOutput = join13(tmpdir2(), `compress-output-${Date.now()}-${Math.random().toString(36).slice(2)}.jpg`);
|
|
40600
40777
|
try {
|
|
40601
40778
|
execSync(`magick "${tempInput}" -quality ${quality} "${tempOutput}"`, {
|
|
40602
40779
|
stdio: "ignore"
|
|
@@ -40622,7 +40799,7 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40622
40799
|
for (const scale of scales) {
|
|
40623
40800
|
const scaledWidth = Math.floor(currentWidth * scale);
|
|
40624
40801
|
const scaledHeight = Math.floor(currentHeight * scale);
|
|
40625
|
-
const tempOutput =
|
|
40802
|
+
const tempOutput = join13(tmpdir2(), `compress-output-${Date.now()}-${Math.random().toString(36).slice(2)}.jpg`);
|
|
40626
40803
|
try {
|
|
40627
40804
|
execSync(`magick "${tempInput}" -resize ${scaledWidth}x${scaledHeight} -quality 70 "${tempOutput}"`, {
|
|
40628
40805
|
stdio: "ignore"
|
|
@@ -40666,11 +40843,11 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
40666
40843
|
resized: false
|
|
40667
40844
|
};
|
|
40668
40845
|
}
|
|
40669
|
-
const tempInput =
|
|
40670
|
-
|
|
40846
|
+
const tempInput = join13(tmpdir2(), `resize-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
40847
|
+
writeFileSync4(tempInput, buffer);
|
|
40671
40848
|
try {
|
|
40672
40849
|
if (needsResize) {
|
|
40673
|
-
const tempOutput2 =
|
|
40850
|
+
const tempOutput2 = join13(tmpdir2(), `resize-output-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
40674
40851
|
let outputBuffer2;
|
|
40675
40852
|
let outputMediaType;
|
|
40676
40853
|
if (format2 === "jpeg" || format2 === "jpg") {
|
|
@@ -40701,7 +40878,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
40701
40878
|
resized: true
|
|
40702
40879
|
};
|
|
40703
40880
|
}
|
|
40704
|
-
const tempOutput =
|
|
40881
|
+
const tempOutput = join13(tmpdir2(), `convert-output-${Date.now()}-${Math.random().toString(36).slice(2)}.png`);
|
|
40705
40882
|
execSync(`magick "${tempInput}" "${tempOutput}"`, {
|
|
40706
40883
|
stdio: "ignore"
|
|
40707
40884
|
});
|
|
@@ -53971,17 +54148,17 @@ __export(exports_skills, {
|
|
|
53971
54148
|
});
|
|
53972
54149
|
import { existsSync as existsSync7 } from "node:fs";
|
|
53973
54150
|
import { readdir as readdir5, readFile as readFile3 } from "node:fs/promises";
|
|
53974
|
-
import { dirname as dirname4, join as
|
|
54151
|
+
import { dirname as dirname4, join as join14 } from "node:path";
|
|
53975
54152
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
53976
54153
|
function getBundledSkillsPath() {
|
|
53977
54154
|
const thisDir = dirname4(fileURLToPath6(import.meta.url));
|
|
53978
54155
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
53979
|
-
return
|
|
54156
|
+
return join14(thisDir, "../skills/builtin");
|
|
53980
54157
|
}
|
|
53981
|
-
return
|
|
54158
|
+
return join14(thisDir, "skills");
|
|
53982
54159
|
}
|
|
53983
54160
|
function getAgentSkillsDir(agentId) {
|
|
53984
|
-
return
|
|
54161
|
+
return join14(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
53985
54162
|
}
|
|
53986
54163
|
async function getBundledSkills() {
|
|
53987
54164
|
const bundledPath = getBundledSkillsPath();
|
|
@@ -54004,12 +54181,14 @@ async function discoverSkillsFromDir(skillsPath, source) {
|
|
|
54004
54181
|
}
|
|
54005
54182
|
return { skills, errors };
|
|
54006
54183
|
}
|
|
54007
|
-
async function discoverSkills(projectSkillsPath =
|
|
54184
|
+
async function discoverSkills(projectSkillsPath = join14(process.cwd(), SKILLS_DIR), agentId, options) {
|
|
54008
54185
|
const allErrors = [];
|
|
54009
54186
|
const skillsById = new Map;
|
|
54010
|
-
|
|
54011
|
-
|
|
54012
|
-
|
|
54187
|
+
if (!options?.skipBundled) {
|
|
54188
|
+
const bundledSkills = await getBundledSkills();
|
|
54189
|
+
for (const skill of bundledSkills) {
|
|
54190
|
+
skillsById.set(skill.id, skill);
|
|
54191
|
+
}
|
|
54013
54192
|
}
|
|
54014
54193
|
const globalResult = await discoverSkillsFromDir(GLOBAL_SKILLS_DIR, "global");
|
|
54015
54194
|
allErrors.push(...globalResult.errors);
|
|
@@ -54038,7 +54217,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors, source) {
|
|
|
54038
54217
|
try {
|
|
54039
54218
|
const entries = await readdir5(currentPath, { withFileTypes: true });
|
|
54040
54219
|
for (const entry of entries) {
|
|
54041
|
-
const fullPath =
|
|
54220
|
+
const fullPath = join14(currentPath, entry.name);
|
|
54042
54221
|
if (entry.isDirectory()) {
|
|
54043
54222
|
await findSkillFiles(fullPath, rootPath, skills, errors, source);
|
|
54044
54223
|
} else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
|
|
@@ -54112,7 +54291,7 @@ ${lines.join(`
|
|
|
54112
54291
|
}
|
|
54113
54292
|
var SKILLS_DIR = ".skills", GLOBAL_SKILLS_DIR;
|
|
54114
54293
|
var init_skills = __esm(() => {
|
|
54115
|
-
GLOBAL_SKILLS_DIR =
|
|
54294
|
+
GLOBAL_SKILLS_DIR = join14(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
54116
54295
|
});
|
|
54117
54296
|
|
|
54118
54297
|
// src/tools/impl/skillContentRegistry.ts
|
|
@@ -54137,7 +54316,7 @@ var init_skillContentRegistry = __esm(() => {
|
|
|
54137
54316
|
// src/tools/impl/Skill.ts
|
|
54138
54317
|
import { readdirSync as readdirSync3 } from "node:fs";
|
|
54139
54318
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
54140
|
-
import { dirname as dirname5, join as
|
|
54319
|
+
import { dirname as dirname5, join as join15 } from "node:path";
|
|
54141
54320
|
function hasAdditionalFiles(skillMdPath) {
|
|
54142
54321
|
try {
|
|
54143
54322
|
const skillDir = dirname5(skillMdPath);
|
|
@@ -54148,19 +54327,19 @@ function hasAdditionalFiles(skillMdPath) {
|
|
|
54148
54327
|
}
|
|
54149
54328
|
}
|
|
54150
54329
|
async function readSkillContent(skillId, skillsDir, agentId) {
|
|
54151
|
-
const projectSkillPath =
|
|
54330
|
+
const projectSkillPath = join15(skillsDir, skillId, "SKILL.md");
|
|
54152
54331
|
try {
|
|
54153
54332
|
const content = await readFile4(projectSkillPath, "utf-8");
|
|
54154
54333
|
return { content, path: projectSkillPath };
|
|
54155
54334
|
} catch {}
|
|
54156
54335
|
if (agentId) {
|
|
54157
|
-
const agentSkillPath =
|
|
54336
|
+
const agentSkillPath = join15(getAgentSkillsDir(agentId), skillId, "SKILL.md");
|
|
54158
54337
|
try {
|
|
54159
54338
|
const content = await readFile4(agentSkillPath, "utf-8");
|
|
54160
54339
|
return { content, path: agentSkillPath };
|
|
54161
54340
|
} catch {}
|
|
54162
54341
|
}
|
|
54163
|
-
const globalSkillPath =
|
|
54342
|
+
const globalSkillPath = join15(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
|
|
54164
54343
|
try {
|
|
54165
54344
|
const content = await readFile4(globalSkillPath, "utf-8");
|
|
54166
54345
|
return { content, path: globalSkillPath };
|
|
@@ -54174,8 +54353,8 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
54174
54353
|
} catch {}
|
|
54175
54354
|
}
|
|
54176
54355
|
try {
|
|
54177
|
-
const bundledSkillsDir =
|
|
54178
|
-
const bundledSkillPath =
|
|
54356
|
+
const bundledSkillsDir = join15(process.cwd(), "skills", "skills");
|
|
54357
|
+
const bundledSkillPath = join15(bundledSkillsDir, skillId, "SKILL.md");
|
|
54179
54358
|
const content = await readFile4(bundledSkillPath, "utf-8");
|
|
54180
54359
|
return { content, path: bundledSkillPath };
|
|
54181
54360
|
} catch {
|
|
@@ -54187,7 +54366,7 @@ async function getResolvedSkillsDir() {
|
|
|
54187
54366
|
if (skillsDir) {
|
|
54188
54367
|
return skillsDir;
|
|
54189
54368
|
}
|
|
54190
|
-
return
|
|
54369
|
+
return join15(process.cwd(), SKILLS_DIR);
|
|
54191
54370
|
}
|
|
54192
54371
|
async function skill(args) {
|
|
54193
54372
|
validateRequiredParams(args, ["skill"], "Skill");
|
|
@@ -55308,8 +55487,14 @@ async function task(args) {
|
|
|
55308
55487
|
maxTurns: args.max_turns
|
|
55309
55488
|
});
|
|
55310
55489
|
await waitForBackgroundSubagentLink(subagentId2, null, signal);
|
|
55311
|
-
|
|
55312
|
-
|
|
55490
|
+
const linkedAgent = getSnapshot2().agents.find((a) => a.id === subagentId2);
|
|
55491
|
+
const agentId = linkedAgent?.agentURL?.split("/agents/")[1] ?? null;
|
|
55492
|
+
const agentIdLine = agentId ? `
|
|
55493
|
+
Agent ID: ${agentId}` : "";
|
|
55494
|
+
return `Task running in background with task ID: ${taskId}${agentIdLine}
|
|
55495
|
+
Output file: ${outputFile2}
|
|
55496
|
+
|
|
55497
|
+
You will be notified automatically when this task completes — a <task-notification> message will be delivered with the result. No need to poll, sleep-wait, or check the output file. Just continue with your current work.`;
|
|
55313
55498
|
}
|
|
55314
55499
|
const subagentId = generateSubagentId();
|
|
55315
55500
|
registerSubagent(subagentId, subagent_type, description, toolCallId, false);
|
|
@@ -58644,7 +58829,7 @@ __export(exports_loader, {
|
|
|
58644
58829
|
loadPermissions: () => loadPermissions
|
|
58645
58830
|
});
|
|
58646
58831
|
import { homedir as homedir11 } from "node:os";
|
|
58647
|
-
import { join as
|
|
58832
|
+
import { join as join16 } from "node:path";
|
|
58648
58833
|
async function loadPermissions(workingDirectory = process.cwd()) {
|
|
58649
58834
|
const merged = {
|
|
58650
58835
|
allow: [],
|
|
@@ -58653,10 +58838,10 @@ async function loadPermissions(workingDirectory = process.cwd()) {
|
|
|
58653
58838
|
additionalDirectories: []
|
|
58654
58839
|
};
|
|
58655
58840
|
const sources = [
|
|
58656
|
-
|
|
58657
|
-
|
|
58658
|
-
|
|
58659
|
-
|
|
58841
|
+
join16(process.env.XDG_CONFIG_HOME || join16(homedir11(), ".config"), "letta", "settings.json"),
|
|
58842
|
+
join16(homedir11(), ".letta", "settings.json"),
|
|
58843
|
+
join16(workingDirectory, ".letta", "settings.json"),
|
|
58844
|
+
join16(workingDirectory, ".letta", "settings.local.json")
|
|
58660
58845
|
];
|
|
58661
58846
|
for (const settingsPath of sources) {
|
|
58662
58847
|
try {
|
|
@@ -58692,13 +58877,13 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
58692
58877
|
let settingsPath;
|
|
58693
58878
|
switch (scope) {
|
|
58694
58879
|
case "user":
|
|
58695
|
-
settingsPath =
|
|
58880
|
+
settingsPath = join16(process.env.XDG_CONFIG_HOME || join16(homedir11(), ".config"), "letta", "settings.json");
|
|
58696
58881
|
break;
|
|
58697
58882
|
case "project":
|
|
58698
|
-
settingsPath =
|
|
58883
|
+
settingsPath = join16(workingDirectory, ".letta", "settings.json");
|
|
58699
58884
|
break;
|
|
58700
58885
|
case "local":
|
|
58701
|
-
settingsPath =
|
|
58886
|
+
settingsPath = join16(workingDirectory, ".letta", "settings.local.json");
|
|
58702
58887
|
break;
|
|
58703
58888
|
}
|
|
58704
58889
|
let settings = {};
|
|
@@ -58723,7 +58908,7 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
58723
58908
|
}
|
|
58724
58909
|
}
|
|
58725
58910
|
async function ensureLocalSettingsIgnored(workingDirectory) {
|
|
58726
|
-
const gitignorePath =
|
|
58911
|
+
const gitignorePath = join16(workingDirectory, ".gitignore");
|
|
58727
58912
|
const pattern = ".letta/settings.local.json";
|
|
58728
58913
|
try {
|
|
58729
58914
|
let content = "";
|
|
@@ -60298,17 +60483,17 @@ __export(exports_skills2, {
|
|
|
60298
60483
|
});
|
|
60299
60484
|
import { existsSync as existsSync8 } from "node:fs";
|
|
60300
60485
|
import { readdir as readdir6, readFile as readFile5 } from "node:fs/promises";
|
|
60301
|
-
import { dirname as dirname8, join as
|
|
60486
|
+
import { dirname as dirname8, join as join17 } from "node:path";
|
|
60302
60487
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
60303
60488
|
function getBundledSkillsPath2() {
|
|
60304
60489
|
const thisDir = dirname8(fileURLToPath7(import.meta.url));
|
|
60305
60490
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
60306
|
-
return
|
|
60491
|
+
return join17(thisDir, "../skills/builtin");
|
|
60307
60492
|
}
|
|
60308
|
-
return
|
|
60493
|
+
return join17(thisDir, "skills");
|
|
60309
60494
|
}
|
|
60310
60495
|
function getAgentSkillsDir2(agentId) {
|
|
60311
|
-
return
|
|
60496
|
+
return join17(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
60312
60497
|
}
|
|
60313
60498
|
async function getBundledSkills2() {
|
|
60314
60499
|
const bundledPath = getBundledSkillsPath2();
|
|
@@ -60331,12 +60516,14 @@ async function discoverSkillsFromDir2(skillsPath, source) {
|
|
|
60331
60516
|
}
|
|
60332
60517
|
return { skills, errors };
|
|
60333
60518
|
}
|
|
60334
|
-
async function discoverSkills2(projectSkillsPath =
|
|
60519
|
+
async function discoverSkills2(projectSkillsPath = join17(process.cwd(), SKILLS_DIR2), agentId, options) {
|
|
60335
60520
|
const allErrors = [];
|
|
60336
60521
|
const skillsById = new Map;
|
|
60337
|
-
|
|
60338
|
-
|
|
60339
|
-
|
|
60522
|
+
if (!options?.skipBundled) {
|
|
60523
|
+
const bundledSkills = await getBundledSkills2();
|
|
60524
|
+
for (const skill2 of bundledSkills) {
|
|
60525
|
+
skillsById.set(skill2.id, skill2);
|
|
60526
|
+
}
|
|
60340
60527
|
}
|
|
60341
60528
|
const globalResult = await discoverSkillsFromDir2(GLOBAL_SKILLS_DIR2, "global");
|
|
60342
60529
|
allErrors.push(...globalResult.errors);
|
|
@@ -60365,7 +60552,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source) {
|
|
|
60365
60552
|
try {
|
|
60366
60553
|
const entries = await readdir6(currentPath, { withFileTypes: true });
|
|
60367
60554
|
for (const entry of entries) {
|
|
60368
|
-
const fullPath =
|
|
60555
|
+
const fullPath = join17(currentPath, entry.name);
|
|
60369
60556
|
if (entry.isDirectory()) {
|
|
60370
60557
|
await findSkillFiles2(fullPath, rootPath, skills, errors, source);
|
|
60371
60558
|
} else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
|
|
@@ -60439,7 +60626,7 @@ ${lines.join(`
|
|
|
60439
60626
|
}
|
|
60440
60627
|
var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
60441
60628
|
var init_skills2 = __esm(() => {
|
|
60442
|
-
GLOBAL_SKILLS_DIR2 =
|
|
60629
|
+
GLOBAL_SKILLS_DIR2 = join17(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
60443
60630
|
});
|
|
60444
60631
|
|
|
60445
60632
|
// src/utils/fs.ts
|
|
@@ -60456,7 +60643,7 @@ import {
|
|
|
60456
60643
|
existsSync as existsSync9,
|
|
60457
60644
|
readFileSync as fsReadFileSync2,
|
|
60458
60645
|
writeFileSync as fsWriteFileSync2,
|
|
60459
|
-
mkdirSync as
|
|
60646
|
+
mkdirSync as mkdirSync6
|
|
60460
60647
|
} from "node:fs";
|
|
60461
60648
|
import { dirname as dirname9 } from "node:path";
|
|
60462
60649
|
async function readFile6(path19) {
|
|
@@ -60465,7 +60652,7 @@ async function readFile6(path19) {
|
|
|
60465
60652
|
async function writeFile2(path19, content) {
|
|
60466
60653
|
const dir = dirname9(path19);
|
|
60467
60654
|
if (!existsSync9(dir)) {
|
|
60468
|
-
|
|
60655
|
+
mkdirSync6(dir, { recursive: true });
|
|
60469
60656
|
}
|
|
60470
60657
|
fsWriteFileSync2(path19, content, { encoding: "utf-8", flush: true });
|
|
60471
60658
|
}
|
|
@@ -60473,7 +60660,7 @@ function exists2(path19) {
|
|
|
60473
60660
|
return existsSync9(path19);
|
|
60474
60661
|
}
|
|
60475
60662
|
async function mkdir2(path19, options) {
|
|
60476
|
-
|
|
60663
|
+
mkdirSync6(path19, options);
|
|
60477
60664
|
}
|
|
60478
60665
|
async function readJsonFile(path19) {
|
|
60479
60666
|
const text = await readFile6(path19);
|
|
@@ -60787,7 +60974,7 @@ __export(exports_auto_update, {
|
|
|
60787
60974
|
import { exec as exec2 } from "node:child_process";
|
|
60788
60975
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
60789
60976
|
import { readdir as readdir7, rm } from "node:fs/promises";
|
|
60790
|
-
import { join as
|
|
60977
|
+
import { join as join18 } from "node:path";
|
|
60791
60978
|
import { promisify as promisify4 } from "node:util";
|
|
60792
60979
|
function debugLog2(...args) {
|
|
60793
60980
|
if (DEBUG) {
|
|
@@ -60882,12 +61069,12 @@ async function getNpmGlobalPath() {
|
|
|
60882
61069
|
}
|
|
60883
61070
|
}
|
|
60884
61071
|
async function cleanupOrphanedDirs(globalPath) {
|
|
60885
|
-
const lettaAiDir =
|
|
61072
|
+
const lettaAiDir = join18(globalPath, "lib/node_modules/@letta-ai");
|
|
60886
61073
|
try {
|
|
60887
61074
|
const entries = await readdir7(lettaAiDir);
|
|
60888
61075
|
for (const entry of entries) {
|
|
60889
61076
|
if (entry.startsWith(".letta-code-")) {
|
|
60890
|
-
const orphanPath =
|
|
61077
|
+
const orphanPath = join18(lettaAiDir, entry);
|
|
60891
61078
|
debugLog2("Cleaning orphaned temp directory:", orphanPath);
|
|
60892
61079
|
await rm(orphanPath, { recursive: true, force: true });
|
|
60893
61080
|
}
|
|
@@ -61106,6 +61293,7 @@ var init_overflow2 = __esm(() => {
|
|
|
61106
61293
|
var exports_promptAssets2 = {};
|
|
61107
61294
|
__export(exports_promptAssets2, {
|
|
61108
61295
|
resolveSystemPrompt: () => resolveSystemPrompt2,
|
|
61296
|
+
SYSTEM_PROMPT_MEMORY_ADDON: () => SYSTEM_PROMPT_MEMORY_ADDON2,
|
|
61109
61297
|
SYSTEM_PROMPT_MEMFS_ADDON: () => SYSTEM_PROMPT_MEMFS_ADDON2,
|
|
61110
61298
|
SYSTEM_PROMPTS: () => SYSTEM_PROMPTS2,
|
|
61111
61299
|
SYSTEM_PROMPT: () => SYSTEM_PROMPT2,
|
|
@@ -61134,7 +61322,7 @@ async function resolveSystemPrompt2(systemPromptPreset) {
|
|
|
61134
61322
|
}
|
|
61135
61323
|
return SYSTEM_PROMPT2;
|
|
61136
61324
|
}
|
|
61137
|
-
var SYSTEM_PROMPT2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, MEMORY_REFLECTION_REMINDER2, APPROVAL_RECOVERY_PROMPT2, INTERRUPT_RECOVERY_ALERT2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
|
|
61325
|
+
var SYSTEM_PROMPT2, SYSTEM_PROMPT_MEMORY_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, MEMORY_REFLECTION_REMINDER2, APPROVAL_RECOVERY_PROMPT2, INTERRUPT_RECOVERY_ALERT2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
|
|
61138
61326
|
var init_promptAssets2 = __esm(() => {
|
|
61139
61327
|
init_approval_recovery_alert();
|
|
61140
61328
|
init_claude();
|
|
@@ -61159,7 +61347,9 @@ var init_promptAssets2 = __esm(() => {
|
|
|
61159
61347
|
init_style();
|
|
61160
61348
|
init_system_prompt();
|
|
61161
61349
|
init_system_prompt_memfs();
|
|
61350
|
+
init_system_prompt_memory();
|
|
61162
61351
|
SYSTEM_PROMPT2 = system_prompt_default;
|
|
61352
|
+
SYSTEM_PROMPT_MEMORY_ADDON2 = system_prompt_memory_default;
|
|
61163
61353
|
SYSTEM_PROMPT_MEMFS_ADDON2 = system_prompt_memfs_default;
|
|
61164
61354
|
PLAN_MODE_REMINDER2 = plan_mode_reminder_default;
|
|
61165
61355
|
SKILL_CREATOR_PROMPT2 = skill_creator_mode_default;
|
|
@@ -61241,7 +61431,7 @@ __export(exports_subagents2, {
|
|
|
61241
61431
|
});
|
|
61242
61432
|
import { existsSync as existsSync11 } from "node:fs";
|
|
61243
61433
|
import { readdir as readdir8, readFile as readFile7 } from "node:fs/promises";
|
|
61244
|
-
import { join as
|
|
61434
|
+
import { join as join20 } from "node:path";
|
|
61245
61435
|
function isValidName2(name) {
|
|
61246
61436
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
61247
61437
|
}
|
|
@@ -61332,7 +61522,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
|
|
|
61332
61522
|
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
61333
61523
|
continue;
|
|
61334
61524
|
}
|
|
61335
|
-
const filePath =
|
|
61525
|
+
const filePath = join20(agentsDir, entry.name);
|
|
61336
61526
|
try {
|
|
61337
61527
|
const config = await parseSubagentFile2(filePath);
|
|
61338
61528
|
if (config) {
|
|
@@ -61364,7 +61554,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
|
|
|
61364
61554
|
const subagents = [];
|
|
61365
61555
|
const seenNames = new Set;
|
|
61366
61556
|
await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
|
|
61367
|
-
const projectAgentsDir =
|
|
61557
|
+
const projectAgentsDir = join20(workingDirectory, AGENTS_DIR2);
|
|
61368
61558
|
await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
|
|
61369
61559
|
return { subagents, errors };
|
|
61370
61560
|
}
|
|
@@ -61407,7 +61597,7 @@ var init_subagents2 = __esm(() => {
|
|
|
61407
61597
|
recall_default,
|
|
61408
61598
|
reflection_default
|
|
61409
61599
|
];
|
|
61410
|
-
GLOBAL_AGENTS_DIR2 =
|
|
61600
|
+
GLOBAL_AGENTS_DIR2 = join20(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
|
|
61411
61601
|
VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
|
|
61412
61602
|
cache5 = {
|
|
61413
61603
|
builtins: null,
|
|
@@ -62300,7 +62490,7 @@ var init_cli2 = __esm(() => {
|
|
|
62300
62490
|
cliPermissions2 = new CliPermissions2;
|
|
62301
62491
|
});
|
|
62302
62492
|
|
|
62303
|
-
// src/agent/
|
|
62493
|
+
// src/agent/turn-recovery-policy.ts
|
|
62304
62494
|
function isInvalidToolCallIdsError(detail) {
|
|
62305
62495
|
if (typeof detail !== "string")
|
|
62306
62496
|
return false;
|
|
@@ -62333,6 +62523,50 @@ function getPreStreamErrorAction(detail, conversationBusyRetries, maxConversatio
|
|
|
62333
62523
|
}
|
|
62334
62524
|
return "rethrow";
|
|
62335
62525
|
}
|
|
62526
|
+
function extractConflictDetail(error) {
|
|
62527
|
+
if (error && typeof error === "object" && "error" in error) {
|
|
62528
|
+
const errObj = error.error;
|
|
62529
|
+
if (errObj && typeof errObj === "object") {
|
|
62530
|
+
const outer = errObj;
|
|
62531
|
+
if (outer.error && typeof outer.error === "object") {
|
|
62532
|
+
const nested = outer.error;
|
|
62533
|
+
if (typeof nested.detail === "string")
|
|
62534
|
+
return nested.detail;
|
|
62535
|
+
if (typeof nested.message === "string")
|
|
62536
|
+
return nested.message;
|
|
62537
|
+
}
|
|
62538
|
+
if (typeof outer.detail === "string")
|
|
62539
|
+
return outer.detail;
|
|
62540
|
+
if (typeof outer.message === "string")
|
|
62541
|
+
return outer.message;
|
|
62542
|
+
}
|
|
62543
|
+
}
|
|
62544
|
+
if (error instanceof Error)
|
|
62545
|
+
return error.message;
|
|
62546
|
+
return "";
|
|
62547
|
+
}
|
|
62548
|
+
function rebuildInputWithFreshDenials(currentInput, serverApprovals, denialReason) {
|
|
62549
|
+
const stripped = currentInput.filter((item) => item?.type !== "approval");
|
|
62550
|
+
if (serverApprovals.length > 0) {
|
|
62551
|
+
const denials = {
|
|
62552
|
+
type: "approval",
|
|
62553
|
+
approvals: serverApprovals.map((a) => ({
|
|
62554
|
+
type: "approval",
|
|
62555
|
+
tool_call_id: a.toolCallId,
|
|
62556
|
+
approve: false,
|
|
62557
|
+
reason: denialReason
|
|
62558
|
+
}))
|
|
62559
|
+
};
|
|
62560
|
+
return [denials, ...stripped];
|
|
62561
|
+
}
|
|
62562
|
+
return stripped;
|
|
62563
|
+
}
|
|
62564
|
+
function shouldAttemptApprovalRecovery(opts) {
|
|
62565
|
+
return opts.approvalPendingDetected && opts.retries < opts.maxRetries;
|
|
62566
|
+
}
|
|
62567
|
+
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENT = "another request is currently being processed";
|
|
62568
|
+
|
|
62569
|
+
// src/agent/approval-recovery.ts
|
|
62336
62570
|
async function fetchRunErrorDetail(runId) {
|
|
62337
62571
|
if (!runId)
|
|
62338
62572
|
return null;
|
|
@@ -62345,7 +62579,6 @@ async function fetchRunErrorDetail(runId) {
|
|
|
62345
62579
|
return null;
|
|
62346
62580
|
}
|
|
62347
62581
|
}
|
|
62348
|
-
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENT = "another request is currently being processed";
|
|
62349
62582
|
var init_approval_recovery = __esm(async () => {
|
|
62350
62583
|
await init_client2();
|
|
62351
62584
|
});
|
|
@@ -62617,8 +62850,10 @@ async function updateAgentSystemPromptRaw(agentId, systemPromptContent) {
|
|
|
62617
62850
|
}
|
|
62618
62851
|
async function updateAgentSystemPrompt(agentId, systemPromptId) {
|
|
62619
62852
|
try {
|
|
62620
|
-
const { resolveSystemPrompt: resolveSystemPrompt3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
62621
|
-
const
|
|
62853
|
+
const { resolveSystemPrompt: resolveSystemPrompt3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
62854
|
+
const baseContent = await resolveSystemPrompt3(systemPromptId);
|
|
62855
|
+
const systemPromptContent = `${baseContent}
|
|
62856
|
+
${SYSTEM_PROMPT_MEMORY_ADDON3}`;
|
|
62622
62857
|
const updateResult = await updateAgentSystemPromptRaw(agentId, systemPromptContent);
|
|
62623
62858
|
if (!updateResult.success) {
|
|
62624
62859
|
return {
|
|
@@ -62647,18 +62882,18 @@ async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
|
62647
62882
|
const client = await getClient2();
|
|
62648
62883
|
const agent = await client.agents.retrieve(agentId);
|
|
62649
62884
|
let currentSystemPrompt = agent.system || "";
|
|
62650
|
-
const { SYSTEM_PROMPT_MEMFS_ADDON: SYSTEM_PROMPT_MEMFS_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
62651
|
-
const
|
|
62652
|
-
currentSystemPrompt = currentSystemPrompt.replace(
|
|
62653
|
-
|
|
62654
|
-
|
|
62655
|
-
|
|
62885
|
+
const { SYSTEM_PROMPT_MEMFS_ADDON: SYSTEM_PROMPT_MEMFS_ADDON3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
62886
|
+
const memoryHeaderRegex = /\n#{1,2} Memory\b[\s\S]*?(?=\n#{1,2} (?!Memory|Filesystem|Structure|How It Works|Syncing|History)[^\n]|$)/;
|
|
62887
|
+
currentSystemPrompt = currentSystemPrompt.replace(memoryHeaderRegex, "");
|
|
62888
|
+
const addon = enableMemfs ? SYSTEM_PROMPT_MEMFS_ADDON3 : SYSTEM_PROMPT_MEMORY_ADDON3;
|
|
62889
|
+
currentSystemPrompt = `${currentSystemPrompt}
|
|
62890
|
+
${addon}`;
|
|
62656
62891
|
await client.agents.update(agentId, {
|
|
62657
62892
|
system: currentSystemPrompt
|
|
62658
62893
|
});
|
|
62659
62894
|
return {
|
|
62660
62895
|
success: true,
|
|
62661
|
-
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to
|
|
62896
|
+
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to include standard Memory section"
|
|
62662
62897
|
};
|
|
62663
62898
|
} catch (error) {
|
|
62664
62899
|
return {
|
|
@@ -62831,6 +63066,8 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
62831
63066
|
} else {
|
|
62832
63067
|
systemPromptContent = await resolveSystemPrompt(options.systemPromptPreset);
|
|
62833
63068
|
}
|
|
63069
|
+
systemPromptContent = `${systemPromptContent}
|
|
63070
|
+
${SYSTEM_PROMPT_MEMORY_ADDON}`;
|
|
62834
63071
|
if (options.systemPromptAppend) {
|
|
62835
63072
|
systemPromptContent = `${systemPromptContent}
|
|
62836
63073
|
|
|
@@ -62841,6 +63078,9 @@ ${options.systemPromptAppend}`;
|
|
|
62841
63078
|
if (isSubagent) {
|
|
62842
63079
|
tags.push("role:subagent");
|
|
62843
63080
|
}
|
|
63081
|
+
if (options.tags && Array.isArray(options.tags)) {
|
|
63082
|
+
tags.push(...options.tags);
|
|
63083
|
+
}
|
|
62844
63084
|
const agentDescription = options.description ?? `Letta Code agent created in ${process.cwd()}`;
|
|
62845
63085
|
const agent = await client.agents.create({
|
|
62846
63086
|
agent_type: "letta_v1_agent",
|
|
@@ -63098,8 +63338,8 @@ function normalizeLineEndings(s) {
|
|
|
63098
63338
|
`).replace(/\r/g, `
|
|
63099
63339
|
`);
|
|
63100
63340
|
}
|
|
63101
|
-
function
|
|
63102
|
-
return text.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").trim();
|
|
63341
|
+
function removeSystemContextBlocks(text) {
|
|
63342
|
+
return text.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").replace(new RegExp(`${SYSTEM_ALERT_OPEN}[\\s\\S]*?${SYSTEM_ALERT_CLOSE}`, "g"), "").trim();
|
|
63103
63343
|
}
|
|
63104
63344
|
function extractCompactionSummary(text) {
|
|
63105
63345
|
try {
|
|
@@ -63128,14 +63368,14 @@ function renderAssistantContentParts(parts) {
|
|
|
63128
63368
|
function renderUserContentParts(parts) {
|
|
63129
63369
|
if (typeof parts === "string") {
|
|
63130
63370
|
const normalized = normalizeLineEndings(parts);
|
|
63131
|
-
return clip(
|
|
63371
|
+
return clip(removeSystemContextBlocks(normalized), CLIP_CHAR_LIMIT_TEXT);
|
|
63132
63372
|
}
|
|
63133
63373
|
const rendered = [];
|
|
63134
63374
|
for (const p of parts) {
|
|
63135
63375
|
if (p.type === "text") {
|
|
63136
63376
|
const text = p.text || "";
|
|
63137
63377
|
const normalized = normalizeLineEndings(text);
|
|
63138
|
-
const withoutSystemReminders =
|
|
63378
|
+
const withoutSystemReminders = removeSystemContextBlocks(normalized);
|
|
63139
63379
|
if (!withoutSystemReminders)
|
|
63140
63380
|
continue;
|
|
63141
63381
|
rendered.push(clip(withoutSystemReminders, CLIP_CHAR_LIMIT_TEXT));
|
|
@@ -63939,6 +64179,13 @@ function resolveAssistantLineId(b, chunk) {
|
|
|
63939
64179
|
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId || otid;
|
|
63940
64180
|
if (!canonical)
|
|
63941
64181
|
return;
|
|
64182
|
+
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
64183
|
+
const existingLineId = resolveLineIdForKind(b, canonicalFromMessageId, "assistant");
|
|
64184
|
+
const existingLine = b.byId.get(existingLineId);
|
|
64185
|
+
if (existingLine && existingLine.kind === "assistant" && "phase" in existingLine && existingLine.phase === "finished") {
|
|
64186
|
+
canonical = otid;
|
|
64187
|
+
}
|
|
64188
|
+
}
|
|
63942
64189
|
if (canonicalFromMessageId && canonicalFromOtid && canonicalFromMessageId !== canonicalFromOtid) {
|
|
63943
64190
|
const messageLineExists = b.byId.has(canonicalFromMessageId);
|
|
63944
64191
|
const otidLineExists = b.byId.has(canonicalFromOtid);
|
|
@@ -63974,6 +64221,13 @@ function resolveReasoningLineId(b, chunk) {
|
|
|
63974
64221
|
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId || otid;
|
|
63975
64222
|
if (!canonical)
|
|
63976
64223
|
return;
|
|
64224
|
+
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
64225
|
+
const existingLineId = resolveLineIdForKind(b, canonicalFromMessageId, "reasoning");
|
|
64226
|
+
const existingLine = b.byId.get(existingLineId);
|
|
64227
|
+
if (existingLine && existingLine.kind === "reasoning" && "phase" in existingLine && existingLine.phase === "finished") {
|
|
64228
|
+
canonical = otid;
|
|
64229
|
+
}
|
|
64230
|
+
}
|
|
63977
64231
|
if (canonicalFromMessageId && canonicalFromOtid && canonicalFromMessageId !== canonicalFromOtid) {
|
|
63978
64232
|
const messageLineExists = b.byId.has(canonicalFromMessageId);
|
|
63979
64233
|
const otidLineExists = b.byId.has(canonicalFromOtid);
|
|
@@ -64759,11 +65013,18 @@ ${createAgentLink(runId, agentId, conversationId)}` : baseError;
|
|
|
64759
65013
|
}
|
|
64760
65014
|
return String(e);
|
|
64761
65015
|
}
|
|
65016
|
+
function getRetryStatusMessage(errorDetail) {
|
|
65017
|
+
if (!errorDetail)
|
|
65018
|
+
return DEFAULT_RETRY_MESSAGE;
|
|
65019
|
+
if (errorDetail.includes("Anthropic API is overloaded"))
|
|
65020
|
+
return "Anthropic API is overloaded, retrying...";
|
|
65021
|
+
return DEFAULT_RETRY_MESSAGE;
|
|
65022
|
+
}
|
|
64762
65023
|
function createAgentLink(runId, agentId, conversationId) {
|
|
64763
65024
|
const url = `https://app.letta.com/agents/${agentId}${conversationId ? `?conversation=${conversationId}` : ""}`;
|
|
64764
65025
|
return `View agent: \x1B]8;;${url}\x1B\\${agentId}\x1B]8;;\x1B\\ (run: ${runId})`;
|
|
64765
65026
|
}
|
|
64766
|
-
var LETTA_USAGE_URL = "https://app.letta.com/settings/organization/usage", LETTA_AGENTS_URL = "https://app.letta.com/projects/default-project/agents", ENCRYPTED_CONTENT_HINT;
|
|
65027
|
+
var LETTA_USAGE_URL = "https://app.letta.com/settings/organization/usage", LETTA_AGENTS_URL = "https://app.letta.com/projects/default-project/agents", ENCRYPTED_CONTENT_HINT, DEFAULT_RETRY_MESSAGE = "Unexpected downstream LLM API error, retrying...";
|
|
64767
65028
|
var init_errorFormatter = __esm(() => {
|
|
64768
65029
|
init_error();
|
|
64769
65030
|
init_errorContext();
|
|
@@ -65199,8 +65460,8 @@ function parseRegistryHandle(handle) {
|
|
|
65199
65460
|
return { author: parts[0], name: parts[1] };
|
|
65200
65461
|
}
|
|
65201
65462
|
async function importAgentFromRegistry(options) {
|
|
65202
|
-
const { tmpdir:
|
|
65203
|
-
const { join:
|
|
65463
|
+
const { tmpdir: tmpdir3 } = await import("node:os");
|
|
65464
|
+
const { join: join21 } = await import("node:path");
|
|
65204
65465
|
const { writeFile: writeFile4, unlink } = await import("node:fs/promises");
|
|
65205
65466
|
const { author, name } = parseRegistryHandle(options.handle);
|
|
65206
65467
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -65212,7 +65473,7 @@ async function importAgentFromRegistry(options) {
|
|
|
65212
65473
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
65213
65474
|
}
|
|
65214
65475
|
const afContent = await response.text();
|
|
65215
|
-
const tempPath =
|
|
65476
|
+
const tempPath = join21(tmpdir3(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
65216
65477
|
await writeFile4(tempPath, afContent, "utf-8");
|
|
65217
65478
|
try {
|
|
65218
65479
|
const result = await importAgentFromFile({
|
|
@@ -65292,11 +65553,142 @@ var init_defaults = __esm(async () => {
|
|
|
65292
65553
|
name: "Incognito",
|
|
65293
65554
|
description: INCOGNITO_DESCRIPTION,
|
|
65294
65555
|
initBlocks: [],
|
|
65295
|
-
baseTools: ["web_search", "
|
|
65556
|
+
baseTools: ["web_search", "fetch_webpage"]
|
|
65296
65557
|
}
|
|
65297
65558
|
};
|
|
65298
65559
|
});
|
|
65299
65560
|
|
|
65561
|
+
// src/agent/memoryFilesystem.ts
|
|
65562
|
+
var exports_memoryFilesystem = {};
|
|
65563
|
+
__export(exports_memoryFilesystem, {
|
|
65564
|
+
renderMemoryFilesystemTree: () => renderMemoryFilesystemTree,
|
|
65565
|
+
labelFromRelativePath: () => labelFromRelativePath,
|
|
65566
|
+
getMemorySystemDir: () => getMemorySystemDir,
|
|
65567
|
+
getMemoryFilesystemRoot: () => getMemoryFilesystemRoot,
|
|
65568
|
+
ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs,
|
|
65569
|
+
applyMemfsFlags: () => applyMemfsFlags,
|
|
65570
|
+
MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR,
|
|
65571
|
+
MEMORY_FS_ROOT: () => MEMORY_FS_ROOT,
|
|
65572
|
+
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
|
|
65573
|
+
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
|
|
65574
|
+
});
|
|
65575
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8 } from "node:fs";
|
|
65576
|
+
import { homedir as homedir14 } from "node:os";
|
|
65577
|
+
import { join as join21 } from "node:path";
|
|
65578
|
+
function getMemoryFilesystemRoot(agentId, homeDir = homedir14()) {
|
|
65579
|
+
return join21(homeDir, MEMORY_FS_ROOT, MEMORY_FS_AGENTS_DIR, agentId, MEMORY_FS_MEMORY_DIR);
|
|
65580
|
+
}
|
|
65581
|
+
function getMemorySystemDir(agentId, homeDir = homedir14()) {
|
|
65582
|
+
return join21(getMemoryFilesystemRoot(agentId, homeDir), MEMORY_SYSTEM_DIR);
|
|
65583
|
+
}
|
|
65584
|
+
function ensureMemoryFilesystemDirs(agentId, homeDir = homedir14()) {
|
|
65585
|
+
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
65586
|
+
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
65587
|
+
if (!existsSync12(root)) {
|
|
65588
|
+
mkdirSync8(root, { recursive: true });
|
|
65589
|
+
}
|
|
65590
|
+
if (!existsSync12(systemDir)) {
|
|
65591
|
+
mkdirSync8(systemDir, { recursive: true });
|
|
65592
|
+
}
|
|
65593
|
+
}
|
|
65594
|
+
function labelFromRelativePath(relativePath) {
|
|
65595
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
65596
|
+
return normalized.replace(/\.md$/, "");
|
|
65597
|
+
}
|
|
65598
|
+
function renderMemoryFilesystemTree(systemLabels, detachedLabels) {
|
|
65599
|
+
const makeNode = () => ({ children: new Map, isFile: false });
|
|
65600
|
+
const root = makeNode();
|
|
65601
|
+
const insertPath = (base2, label) => {
|
|
65602
|
+
const parts = base2 ? [base2, ...label.split("/")] : label.split("/");
|
|
65603
|
+
let current = root;
|
|
65604
|
+
for (const [i, partName] of parts.entries()) {
|
|
65605
|
+
const part = i === parts.length - 1 ? `${partName}.md` : partName;
|
|
65606
|
+
if (!current.children.has(part)) {
|
|
65607
|
+
current.children.set(part, makeNode());
|
|
65608
|
+
}
|
|
65609
|
+
current = current.children.get(part);
|
|
65610
|
+
if (i === parts.length - 1) {
|
|
65611
|
+
current.isFile = true;
|
|
65612
|
+
}
|
|
65613
|
+
}
|
|
65614
|
+
};
|
|
65615
|
+
for (const label of systemLabels) {
|
|
65616
|
+
insertPath(MEMORY_SYSTEM_DIR, label);
|
|
65617
|
+
}
|
|
65618
|
+
for (const label of detachedLabels) {
|
|
65619
|
+
insertPath(null, label);
|
|
65620
|
+
}
|
|
65621
|
+
if (!root.children.has(MEMORY_SYSTEM_DIR)) {
|
|
65622
|
+
root.children.set(MEMORY_SYSTEM_DIR, makeNode());
|
|
65623
|
+
}
|
|
65624
|
+
const sortedEntries = (node) => {
|
|
65625
|
+
const entries = Array.from(node.children.entries());
|
|
65626
|
+
return entries.sort(([nameA, nodeA], [nameB, nodeB]) => {
|
|
65627
|
+
if (nodeA.isFile !== nodeB.isFile) {
|
|
65628
|
+
return nodeA.isFile ? 1 : -1;
|
|
65629
|
+
}
|
|
65630
|
+
return nameA.localeCompare(nameB);
|
|
65631
|
+
});
|
|
65632
|
+
};
|
|
65633
|
+
const lines = ["/memory/"];
|
|
65634
|
+
const render2 = (node, prefix) => {
|
|
65635
|
+
const entries = sortedEntries(node);
|
|
65636
|
+
entries.forEach(([name, child], index) => {
|
|
65637
|
+
const isLast = index === entries.length - 1;
|
|
65638
|
+
const branch = isLast ? "└──" : "├──";
|
|
65639
|
+
lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
|
|
65640
|
+
if (child.children.size > 0) {
|
|
65641
|
+
const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
|
|
65642
|
+
render2(child, nextPrefix);
|
|
65643
|
+
}
|
|
65644
|
+
});
|
|
65645
|
+
};
|
|
65646
|
+
render2(root, "");
|
|
65647
|
+
return lines.join(`
|
|
65648
|
+
`);
|
|
65649
|
+
}
|
|
65650
|
+
async function applyMemfsFlags(agentId, memfsFlag, noMemfsFlag, options) {
|
|
65651
|
+
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
65652
|
+
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
65653
|
+
if (memfsFlag) {
|
|
65654
|
+
const serverUrl = getServerUrl2();
|
|
65655
|
+
if (!serverUrl.includes("api.letta.com")) {
|
|
65656
|
+
throw new Error("--memfs is only available on Letta Cloud (api.letta.com).");
|
|
65657
|
+
}
|
|
65658
|
+
settingsManager3.setMemfsEnabled(agentId, true);
|
|
65659
|
+
} else if (noMemfsFlag) {
|
|
65660
|
+
settingsManager3.setMemfsEnabled(agentId, false);
|
|
65661
|
+
}
|
|
65662
|
+
const isEnabled = settingsManager3.isMemfsEnabled(agentId);
|
|
65663
|
+
if (isEnabled && memfsFlag) {
|
|
65664
|
+
const { detachMemoryTools: detachMemoryTools2 } = await init_toolset().then(() => exports_toolset);
|
|
65665
|
+
await detachMemoryTools2(agentId);
|
|
65666
|
+
}
|
|
65667
|
+
if (memfsFlag || noMemfsFlag) {
|
|
65668
|
+
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs2 } = await init_modify().then(() => exports_modify);
|
|
65669
|
+
await updateAgentSystemPromptMemfs2(agentId, isEnabled);
|
|
65670
|
+
}
|
|
65671
|
+
let pullSummary;
|
|
65672
|
+
if (isEnabled) {
|
|
65673
|
+
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
65674
|
+
await addGitMemoryTag2(agentId);
|
|
65675
|
+
if (!isGitRepo2(agentId)) {
|
|
65676
|
+
await cloneMemoryRepo2(agentId);
|
|
65677
|
+
} else if (options?.pullOnExistingRepo) {
|
|
65678
|
+
const result = await pullMemory2(agentId);
|
|
65679
|
+
pullSummary = result.summary;
|
|
65680
|
+
}
|
|
65681
|
+
}
|
|
65682
|
+
const action = memfsFlag ? "enabled" : noMemfsFlag ? "disabled" : "unchanged";
|
|
65683
|
+
return {
|
|
65684
|
+
action,
|
|
65685
|
+
memoryDir: isEnabled ? getMemoryFilesystemRoot(agentId) : undefined,
|
|
65686
|
+
pullSummary
|
|
65687
|
+
};
|
|
65688
|
+
}
|
|
65689
|
+
var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system";
|
|
65690
|
+
var init_memoryFilesystem = () => {};
|
|
65691
|
+
|
|
65300
65692
|
// src/agent/check-approval.ts
|
|
65301
65693
|
var exports_check_approval = {};
|
|
65302
65694
|
__export(exports_check_approval, {
|
|
@@ -65475,7 +65867,7 @@ __export(exports_headless, {
|
|
|
65475
65867
|
handleHeadlessCommand: () => handleHeadlessCommand
|
|
65476
65868
|
});
|
|
65477
65869
|
import { parseArgs as parseArgs5 } from "node:util";
|
|
65478
|
-
async function handleHeadlessCommand(argv, model, skillsDirectory) {
|
|
65870
|
+
async function handleHeadlessCommand(argv, model, skillsDirectory, noSkills) {
|
|
65479
65871
|
const settings = settingsManager.getSettings();
|
|
65480
65872
|
const { values, positionals } = parseArgs5({
|
|
65481
65873
|
args: argv,
|
|
@@ -65513,8 +65905,10 @@ async function handleHeadlessCommand(argv, model, skillsDirectory) {
|
|
|
65513
65905
|
"init-blocks": { type: "string" },
|
|
65514
65906
|
"base-tools": { type: "string" },
|
|
65515
65907
|
"from-af": { type: "string" },
|
|
65908
|
+
tags: { type: "string" },
|
|
65516
65909
|
memfs: { type: "boolean" },
|
|
65517
65910
|
"no-memfs": { type: "boolean" },
|
|
65911
|
+
"no-skills": { type: "boolean" },
|
|
65518
65912
|
"max-turns": { type: "string" }
|
|
65519
65913
|
},
|
|
65520
65914
|
strict: false,
|
|
@@ -65611,6 +66005,16 @@ In headless mode, use:
|
|
|
65611
66005
|
const fromAfFile = values["from-af"];
|
|
65612
66006
|
const preLoadSkillsRaw = values["pre-load-skills"];
|
|
65613
66007
|
const maxTurnsRaw = values["max-turns"];
|
|
66008
|
+
const tagsRaw = values["tags"];
|
|
66009
|
+
let tags;
|
|
66010
|
+
if (tagsRaw !== undefined) {
|
|
66011
|
+
const trimmed = tagsRaw.trim();
|
|
66012
|
+
if (!trimmed || trimmed.toLowerCase() === "none") {
|
|
66013
|
+
tags = [];
|
|
66014
|
+
} else {
|
|
66015
|
+
tags = trimmed.split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
66016
|
+
}
|
|
66017
|
+
}
|
|
65614
66018
|
let maxTurns;
|
|
65615
66019
|
if (maxTurnsRaw !== undefined) {
|
|
65616
66020
|
const parsed = parseInt(maxTurnsRaw, 10);
|
|
@@ -65831,7 +66235,8 @@ In headless mode, use:
|
|
|
65831
66235
|
initBlocks,
|
|
65832
66236
|
baseTools,
|
|
65833
66237
|
memoryBlocks,
|
|
65834
|
-
blockValues
|
|
66238
|
+
blockValues,
|
|
66239
|
+
tags
|
|
65835
66240
|
};
|
|
65836
66241
|
const result = await createAgent(createOptions);
|
|
65837
66242
|
agent = result.agent;
|
|
@@ -65897,36 +66302,16 @@ In headless mode, use:
|
|
|
65897
66302
|
}
|
|
65898
66303
|
let conversationId;
|
|
65899
66304
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
65900
|
-
|
|
65901
|
-
const
|
|
65902
|
-
|
|
65903
|
-
|
|
65904
|
-
|
|
65905
|
-
}
|
|
65906
|
-
settingsManager.setMemfsEnabled(agent.id, true);
|
|
65907
|
-
} else if (noMemfsFlag) {
|
|
65908
|
-
settingsManager.setMemfsEnabled(agent.id, false);
|
|
65909
|
-
}
|
|
65910
|
-
if (memfsFlag || noMemfsFlag) {
|
|
65911
|
-
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs2 } = await init_modify().then(() => exports_modify);
|
|
65912
|
-
await updateAgentSystemPromptMemfs2(agent.id, settingsManager.isMemfsEnabled(agent.id));
|
|
65913
|
-
}
|
|
65914
|
-
if (settingsManager.isMemfsEnabled(agent.id)) {
|
|
65915
|
-
try {
|
|
65916
|
-
const { isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
65917
|
-
if (!isGitRepo2(agent.id)) {
|
|
65918
|
-
await cloneMemoryRepo2(agent.id);
|
|
65919
|
-
} else {
|
|
65920
|
-
const result = await pullMemory2(agent.id);
|
|
65921
|
-
if (result.summary.includes("CONFLICT")) {
|
|
65922
|
-
console.error("Memory has merge conflicts. Run in interactive mode to resolve.");
|
|
65923
|
-
process.exit(1);
|
|
65924
|
-
}
|
|
65925
|
-
}
|
|
65926
|
-
} catch (error) {
|
|
65927
|
-
console.error(`Memory git sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
66305
|
+
try {
|
|
66306
|
+
const { applyMemfsFlags: applyMemfsFlags2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
66307
|
+
const memfsResult = await applyMemfsFlags2(agent.id, memfsFlag, noMemfsFlag, { pullOnExistingRepo: true });
|
|
66308
|
+
if (memfsResult.pullSummary?.includes("CONFLICT")) {
|
|
66309
|
+
console.error("Memory has merge conflicts. Run in interactive mode to resolve.");
|
|
65928
66310
|
process.exit(1);
|
|
65929
66311
|
}
|
|
66312
|
+
} catch (error) {
|
|
66313
|
+
console.error(`Memory git sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
66314
|
+
process.exit(1);
|
|
65930
66315
|
}
|
|
65931
66316
|
const isolatedBlockLabels = initBlocks === undefined ? [...ISOLATED_BLOCK_LABELS] : ISOLATED_BLOCK_LABELS.filter((label) => initBlocks.includes(label));
|
|
65932
66317
|
if (specifiedConversationId) {
|
|
@@ -65994,7 +66379,7 @@ In headless mode, use:
|
|
|
65994
66379
|
}
|
|
65995
66380
|
} catch {}
|
|
65996
66381
|
}
|
|
65997
|
-
setAgentContext2(agent.id, skillsDirectory);
|
|
66382
|
+
setAgentContext2(agent.id, skillsDirectory, noSkills);
|
|
65998
66383
|
const outputFormat = values["output-format"] || "text";
|
|
65999
66384
|
const includePartialMessages = Boolean(values["include-partial-messages"]);
|
|
66000
66385
|
if (!["text", "json", "stream-json"].includes(outputFormat)) {
|
|
@@ -66147,10 +66532,12 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
66147
66532
|
formatSkillsAsSystemReminder: formatSkillsAsSystemReminder3
|
|
66148
66533
|
} = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
66149
66534
|
const { getSkillsDirectory: getSkillsDirectory2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
66150
|
-
const { join:
|
|
66535
|
+
const { join: join22 } = await import("node:path");
|
|
66151
66536
|
try {
|
|
66152
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
66153
|
-
const { skills } = await discoverSkills3(skillsDir, agent.id
|
|
66537
|
+
const skillsDir = getSkillsDirectory2() || join22(process.cwd(), defaultDir);
|
|
66538
|
+
const { skills } = await discoverSkills3(skillsDir, agent.id, {
|
|
66539
|
+
skipBundled: noSkills
|
|
66540
|
+
});
|
|
66154
66541
|
const skillsReminder = formatSkillsAsSystemReminder3(skills);
|
|
66155
66542
|
if (skillsReminder) {
|
|
66156
66543
|
pushPart(skillsReminder);
|
|
@@ -66238,20 +66625,7 @@ ${loadedContents.join(`
|
|
|
66238
66625
|
agentId: agent.id
|
|
66239
66626
|
});
|
|
66240
66627
|
} catch (preStreamError) {
|
|
66241
|
-
|
|
66242
|
-
if (preStreamError instanceof APIError2 && preStreamError.error && typeof preStreamError.error === "object") {
|
|
66243
|
-
const errObj = preStreamError.error;
|
|
66244
|
-
if (errObj.error && typeof errObj.error === "object" && "detail" in errObj.error) {
|
|
66245
|
-
const nested = errObj.error;
|
|
66246
|
-
errorDetail = typeof nested.detail === "string" ? nested.detail : "";
|
|
66247
|
-
}
|
|
66248
|
-
if (!errorDetail && typeof errObj.detail === "string") {
|
|
66249
|
-
errorDetail = errObj.detail;
|
|
66250
|
-
}
|
|
66251
|
-
}
|
|
66252
|
-
if (!errorDetail && preStreamError instanceof Error) {
|
|
66253
|
-
errorDetail = preStreamError.message;
|
|
66254
|
-
}
|
|
66628
|
+
const errorDetail = extractConflictDetail(preStreamError);
|
|
66255
66629
|
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetries, CONVERSATION_BUSY_MAX_RETRIES);
|
|
66256
66630
|
if (preStreamAction === "resolve_approval_pending") {
|
|
66257
66631
|
if (outputFormat === "stream-json") {
|
|
@@ -67009,8 +67383,8 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
67009
67383
|
formatSkillsAsSystemReminder: formatSkillsAsSystemReminder3
|
|
67010
67384
|
} = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
67011
67385
|
const { getSkillsDirectory: getSkillsDirectory2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
67012
|
-
const { join:
|
|
67013
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
67386
|
+
const { join: join22 } = await import("node:path");
|
|
67387
|
+
const skillsDir = getSkillsDirectory2() || join22(process.cwd(), defaultDir);
|
|
67014
67388
|
const { skills } = await discover(skillsDir, agent.id);
|
|
67015
67389
|
const skillsReminder = formatSkillsAsSystemReminder3(skills);
|
|
67016
67390
|
if (skillsReminder) {
|
|
@@ -67050,21 +67424,9 @@ ${enrichedContent}`;
|
|
|
67050
67424
|
agentId: agent.id
|
|
67051
67425
|
});
|
|
67052
67426
|
} catch (preStreamError) {
|
|
67053
|
-
|
|
67054
|
-
|
|
67055
|
-
|
|
67056
|
-
if (errObj.error && typeof errObj.error === "object" && "detail" in errObj.error) {
|
|
67057
|
-
const nested = errObj.error;
|
|
67058
|
-
errorDetail = typeof nested.detail === "string" ? nested.detail : "";
|
|
67059
|
-
}
|
|
67060
|
-
if (!errorDetail && typeof errObj.detail === "string") {
|
|
67061
|
-
errorDetail = errObj.detail;
|
|
67062
|
-
}
|
|
67063
|
-
}
|
|
67064
|
-
if (!errorDetail && preStreamError instanceof Error) {
|
|
67065
|
-
errorDetail = preStreamError.message;
|
|
67066
|
-
}
|
|
67067
|
-
if (isApprovalPendingError(errorDetail)) {
|
|
67427
|
+
const errorDetail = extractConflictDetail(preStreamError);
|
|
67428
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, 0, 0);
|
|
67429
|
+
if (preStreamAction === "resolve_approval_pending") {
|
|
67068
67430
|
const recoveryMsg = {
|
|
67069
67431
|
type: "recovery",
|
|
67070
67432
|
recovery_type: "approval_pending",
|
|
@@ -67471,29 +67833,6 @@ var init_build3 = __esm(async () => {
|
|
|
67471
67833
|
]);
|
|
67472
67834
|
});
|
|
67473
67835
|
|
|
67474
|
-
// src/agent/memoryFilesystem.ts
|
|
67475
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync7 } from "node:fs";
|
|
67476
|
-
import { homedir as homedir14 } from "node:os";
|
|
67477
|
-
import { join as join20 } from "node:path";
|
|
67478
|
-
function getMemoryFilesystemRoot(agentId, homeDir = homedir14()) {
|
|
67479
|
-
return join20(homeDir, MEMORY_FS_ROOT, MEMORY_FS_AGENTS_DIR, agentId, MEMORY_FS_MEMORY_DIR);
|
|
67480
|
-
}
|
|
67481
|
-
function getMemorySystemDir(agentId, homeDir = homedir14()) {
|
|
67482
|
-
return join20(getMemoryFilesystemRoot(agentId, homeDir), MEMORY_SYSTEM_DIR);
|
|
67483
|
-
}
|
|
67484
|
-
function ensureMemoryFilesystemDirs(agentId, homeDir = homedir14()) {
|
|
67485
|
-
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
67486
|
-
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
67487
|
-
if (!existsSync12(root)) {
|
|
67488
|
-
mkdirSync7(root, { recursive: true });
|
|
67489
|
-
}
|
|
67490
|
-
if (!existsSync12(systemDir)) {
|
|
67491
|
-
mkdirSync7(systemDir, { recursive: true });
|
|
67492
|
-
}
|
|
67493
|
-
}
|
|
67494
|
-
var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system";
|
|
67495
|
-
var init_memoryFilesystem = () => {};
|
|
67496
|
-
|
|
67497
67836
|
// src/ralph/mode.ts
|
|
67498
67837
|
function getDefaultState() {
|
|
67499
67838
|
return {
|
|
@@ -67589,9 +67928,9 @@ __export(exports_settings, {
|
|
|
67589
67928
|
getSetting: () => getSetting
|
|
67590
67929
|
});
|
|
67591
67930
|
import { homedir as homedir15 } from "node:os";
|
|
67592
|
-
import { join as
|
|
67931
|
+
import { join as join22 } from "node:path";
|
|
67593
67932
|
function getSettingsPath() {
|
|
67594
|
-
return
|
|
67933
|
+
return join22(homedir15(), ".letta", "settings.json");
|
|
67595
67934
|
}
|
|
67596
67935
|
async function loadSettings() {
|
|
67597
67936
|
const settingsPath = getSettingsPath();
|
|
@@ -67628,7 +67967,7 @@ async function getSetting(key) {
|
|
|
67628
67967
|
return settings[key];
|
|
67629
67968
|
}
|
|
67630
67969
|
function getProjectSettingsPath() {
|
|
67631
|
-
return
|
|
67970
|
+
return join22(process.cwd(), ".letta", "settings.local.json");
|
|
67632
67971
|
}
|
|
67633
67972
|
async function loadProjectSettings() {
|
|
67634
67973
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -67646,7 +67985,7 @@ async function loadProjectSettings() {
|
|
|
67646
67985
|
}
|
|
67647
67986
|
async function saveProjectSettings(settings) {
|
|
67648
67987
|
const settingsPath = getProjectSettingsPath();
|
|
67649
|
-
const dirPath =
|
|
67988
|
+
const dirPath = join22(process.cwd(), ".letta");
|
|
67650
67989
|
try {
|
|
67651
67990
|
if (!exists(dirPath)) {
|
|
67652
67991
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -74014,8 +74353,9 @@ function extractUserMessagePreview2(message) {
|
|
|
74014
74353
|
for (let i = content.length - 1;i >= 0; i--) {
|
|
74015
74354
|
const part = content[i];
|
|
74016
74355
|
if (part?.type === "text" && part.text) {
|
|
74017
|
-
if (part.text.startsWith(SYSTEM_REMINDER_OPEN))
|
|
74356
|
+
if (part.text.startsWith(SYSTEM_REMINDER_OPEN) || part.text.startsWith(SYSTEM_ALERT_OPEN)) {
|
|
74018
74357
|
continue;
|
|
74358
|
+
}
|
|
74019
74359
|
textToShow = part.text;
|
|
74020
74360
|
break;
|
|
74021
74361
|
}
|
|
@@ -75036,8 +75376,8 @@ var init_pasteRegistry = __esm(() => {
|
|
|
75036
75376
|
// src/cli/helpers/clipboard.ts
|
|
75037
75377
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
75038
75378
|
import { existsSync as existsSync13, readFileSync as readFileSync3, statSync as statSync4, unlinkSync as unlinkSync4 } from "node:fs";
|
|
75039
|
-
import { tmpdir as
|
|
75040
|
-
import { basename as basename3, extname as extname5, isAbsolute as isAbsolute13, join as
|
|
75379
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
75380
|
+
import { basename as basename3, extname as extname5, isAbsolute as isAbsolute13, join as join23, resolve as resolve20 } from "node:path";
|
|
75041
75381
|
function countLines2(text) {
|
|
75042
75382
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
75043
75383
|
}
|
|
@@ -75105,7 +75445,7 @@ function translatePasteForImages(paste) {
|
|
|
75105
75445
|
function getClipboardImageToTempFile() {
|
|
75106
75446
|
if (process.platform !== "darwin")
|
|
75107
75447
|
return null;
|
|
75108
|
-
const tempPath =
|
|
75448
|
+
const tempPath = join23(tmpdir3(), `letta-clipboard-${Date.now()}.bin`);
|
|
75109
75449
|
try {
|
|
75110
75450
|
const jxa = `
|
|
75111
75451
|
ObjC.import('AppKit');
|
|
@@ -75743,12 +76083,12 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
75743
76083
|
import {
|
|
75744
76084
|
copyFileSync,
|
|
75745
76085
|
existsSync as existsSync14,
|
|
75746
|
-
mkdirSync as
|
|
76086
|
+
mkdirSync as mkdirSync9,
|
|
75747
76087
|
readFileSync as readFileSync4,
|
|
75748
|
-
writeFileSync as
|
|
76088
|
+
writeFileSync as writeFileSync6
|
|
75749
76089
|
} from "node:fs";
|
|
75750
76090
|
import { homedir as homedir16, platform as platform3 } from "node:os";
|
|
75751
|
-
import { dirname as dirname11, join as
|
|
76091
|
+
import { dirname as dirname11, join as join24 } from "node:path";
|
|
75752
76092
|
function detectTerminalType() {
|
|
75753
76093
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
75754
76094
|
return "cursor";
|
|
@@ -75780,16 +76120,16 @@ function getKeybindingsPath(terminal) {
|
|
|
75780
76120
|
}[terminal];
|
|
75781
76121
|
const os5 = platform3();
|
|
75782
76122
|
if (os5 === "darwin") {
|
|
75783
|
-
return
|
|
76123
|
+
return join24(homedir16(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
75784
76124
|
}
|
|
75785
76125
|
if (os5 === "win32") {
|
|
75786
76126
|
const appData = process.env.APPDATA;
|
|
75787
76127
|
if (!appData)
|
|
75788
76128
|
return null;
|
|
75789
|
-
return
|
|
76129
|
+
return join24(appData, appName, "User", "keybindings.json");
|
|
75790
76130
|
}
|
|
75791
76131
|
if (os5 === "linux") {
|
|
75792
|
-
return
|
|
76132
|
+
return join24(homedir16(), ".config", appName, "User", "keybindings.json");
|
|
75793
76133
|
}
|
|
75794
76134
|
return null;
|
|
75795
76135
|
}
|
|
@@ -75841,7 +76181,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
75841
76181
|
}
|
|
75842
76182
|
const parentDir = dirname11(keybindingsPath);
|
|
75843
76183
|
if (!existsSync14(parentDir)) {
|
|
75844
|
-
|
|
76184
|
+
mkdirSync9(parentDir, { recursive: true });
|
|
75845
76185
|
}
|
|
75846
76186
|
let keybindings = [];
|
|
75847
76187
|
let backupPath = null;
|
|
@@ -75860,7 +76200,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
75860
76200
|
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
75861
76201
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
75862
76202
|
`;
|
|
75863
|
-
|
|
76203
|
+
writeFileSync6(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
75864
76204
|
return {
|
|
75865
76205
|
success: true,
|
|
75866
76206
|
backupPath: backupPath ?? undefined
|
|
@@ -75889,7 +76229,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
75889
76229
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
75890
76230
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
75891
76231
|
`;
|
|
75892
|
-
|
|
76232
|
+
writeFileSync6(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
75893
76233
|
return { success: true };
|
|
75894
76234
|
} catch (error) {
|
|
75895
76235
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -75942,14 +76282,14 @@ function getWezTermConfigPath() {
|
|
|
75942
76282
|
}
|
|
75943
76283
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
75944
76284
|
if (xdgConfig) {
|
|
75945
|
-
const xdgPath =
|
|
76285
|
+
const xdgPath = join24(xdgConfig, "wezterm", "wezterm.lua");
|
|
75946
76286
|
if (existsSync14(xdgPath))
|
|
75947
76287
|
return xdgPath;
|
|
75948
76288
|
}
|
|
75949
|
-
const configPath =
|
|
76289
|
+
const configPath = join24(homedir16(), ".config", "wezterm", "wezterm.lua");
|
|
75950
76290
|
if (existsSync14(configPath))
|
|
75951
76291
|
return configPath;
|
|
75952
|
-
return
|
|
76292
|
+
return join24(homedir16(), ".wezterm.lua");
|
|
75953
76293
|
}
|
|
75954
76294
|
function wezTermDeleteFixExists(configPath) {
|
|
75955
76295
|
if (!existsSync14(configPath))
|
|
@@ -76000,9 +76340,9 @@ ${WEZTERM_DELETE_FIX}
|
|
|
76000
76340
|
}
|
|
76001
76341
|
const parentDir = dirname11(configPath);
|
|
76002
76342
|
if (!existsSync14(parentDir)) {
|
|
76003
|
-
|
|
76343
|
+
mkdirSync9(parentDir, { recursive: true });
|
|
76004
76344
|
}
|
|
76005
|
-
|
|
76345
|
+
writeFileSync6(configPath, content, { encoding: "utf-8" });
|
|
76006
76346
|
return {
|
|
76007
76347
|
success: true,
|
|
76008
76348
|
backupPath: backupPath ?? undefined
|
|
@@ -76438,7 +76778,7 @@ __export(exports_custom, {
|
|
|
76438
76778
|
});
|
|
76439
76779
|
import { existsSync as existsSync15 } from "node:fs";
|
|
76440
76780
|
import { readdir as readdir9, readFile as readFile9 } from "node:fs/promises";
|
|
76441
|
-
import { basename as basename4, dirname as dirname12, join as
|
|
76781
|
+
import { basename as basename4, dirname as dirname12, join as join25 } from "node:path";
|
|
76442
76782
|
async function getCustomCommands() {
|
|
76443
76783
|
if (cachedCommands !== null) {
|
|
76444
76784
|
return cachedCommands;
|
|
@@ -76449,7 +76789,7 @@ async function getCustomCommands() {
|
|
|
76449
76789
|
function refreshCustomCommands() {
|
|
76450
76790
|
cachedCommands = null;
|
|
76451
76791
|
}
|
|
76452
|
-
async function discoverCustomCommands(projectPath =
|
|
76792
|
+
async function discoverCustomCommands(projectPath = join25(process.cwd(), COMMANDS_DIR)) {
|
|
76453
76793
|
const commandsById = new Map;
|
|
76454
76794
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
76455
76795
|
for (const cmd of userCommands) {
|
|
@@ -76481,7 +76821,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source) {
|
|
|
76481
76821
|
try {
|
|
76482
76822
|
const entries = await readdir9(currentPath, { withFileTypes: true });
|
|
76483
76823
|
for (const entry of entries) {
|
|
76484
|
-
const fullPath =
|
|
76824
|
+
const fullPath = join25(currentPath, entry.name);
|
|
76485
76825
|
if (entry.isDirectory()) {
|
|
76486
76826
|
await findCommandFiles(fullPath, rootPath, commands2, source);
|
|
76487
76827
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -76566,7 +76906,7 @@ async function findCustomCommand(commandName) {
|
|
|
76566
76906
|
}
|
|
76567
76907
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
76568
76908
|
var init_custom = __esm(() => {
|
|
76569
|
-
GLOBAL_COMMANDS_DIR =
|
|
76909
|
+
GLOBAL_COMMANDS_DIR = join25(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
76570
76910
|
});
|
|
76571
76911
|
|
|
76572
76912
|
// src/cli/components/HelpDialog.tsx
|
|
@@ -80879,7 +81219,7 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
80879
81219
|
|
|
80880
81220
|
// src/cli/helpers/fileSearch.ts
|
|
80881
81221
|
import { readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
|
|
80882
|
-
import { join as
|
|
81222
|
+
import { join as join26, resolve as resolve21 } from "node:path";
|
|
80883
81223
|
function shouldExcludeEntry(entry) {
|
|
80884
81224
|
if (entry.startsWith(".")) {
|
|
80885
81225
|
return true;
|
|
@@ -80897,7 +81237,7 @@ function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [],
|
|
|
80897
81237
|
continue;
|
|
80898
81238
|
}
|
|
80899
81239
|
try {
|
|
80900
|
-
const fullPath =
|
|
81240
|
+
const fullPath = join26(dir, entry);
|
|
80901
81241
|
const stats = statSync5(fullPath);
|
|
80902
81242
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
80903
81243
|
const matches = pattern.length === 0 || relativePath.toLowerCase().includes(pattern.toLowerCase());
|
|
@@ -80952,7 +81292,7 @@ async function searchFiles(query, deep = false) {
|
|
|
80952
81292
|
const matchingEntries = entries.filter((entry) => !shouldExcludeEntry(entry)).filter((entry) => searchPattern.length === 0 || entry.toLowerCase().includes(searchPattern.toLowerCase()));
|
|
80953
81293
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
80954
81294
|
try {
|
|
80955
|
-
const fullPath =
|
|
81295
|
+
const fullPath = join26(searchDir, entry);
|
|
80956
81296
|
const stats = statSync5(fullPath);
|
|
80957
81297
|
const relativePath = fullPath.startsWith(process.cwd()) ? fullPath.slice(process.cwd().length + 1) : fullPath;
|
|
80958
81298
|
results.push({
|
|
@@ -81797,7 +82137,8 @@ function Input({
|
|
|
81797
82137
|
shouldAnimate = true,
|
|
81798
82138
|
statusLineText,
|
|
81799
82139
|
statusLineRight,
|
|
81800
|
-
statusLinePadding = 0
|
|
82140
|
+
statusLinePadding = 0,
|
|
82141
|
+
statusLinePrompt
|
|
81801
82142
|
}) {
|
|
81802
82143
|
const [value, setValue] = import_react68.useState("");
|
|
81803
82144
|
const [escapePressed, setEscapePressed] = import_react68.useState(false);
|
|
@@ -81810,7 +82151,10 @@ function Input({
|
|
|
81810
82151
|
const [cursorPos, setCursorPos] = import_react68.useState(undefined);
|
|
81811
82152
|
const [currentCursorPosition, setCurrentCursorPosition] = import_react68.useState(0);
|
|
81812
82153
|
const columns = terminalWidth;
|
|
81813
|
-
const
|
|
82154
|
+
const [isBashMode, setIsBashMode] = import_react68.useState(false);
|
|
82155
|
+
const promptChar = isBashMode ? "!" : statusLinePrompt || ">";
|
|
82156
|
+
const promptVisualWidth = stringWidth(promptChar) + 1;
|
|
82157
|
+
const contentWidth = Math.max(0, columns - promptVisualWidth);
|
|
81814
82158
|
const interactionEnabled = visible && inputEnabled;
|
|
81815
82159
|
const reserveInputSpace = !collapseInputWhenDisabled;
|
|
81816
82160
|
const hideFooter = !interactionEnabled || value.startsWith("/");
|
|
@@ -81856,7 +82200,6 @@ function Input({
|
|
|
81856
82200
|
const [atStartBoundary, setAtStartBoundary] = import_react68.useState(false);
|
|
81857
82201
|
const [atEndBoundary, setAtEndBoundary] = import_react68.useState(false);
|
|
81858
82202
|
const [preferredColumn, setPreferredColumn] = import_react68.useState(null);
|
|
81859
|
-
const [isBashMode, setIsBashMode] = import_react68.useState(false);
|
|
81860
82203
|
import_react68.useEffect(() => {
|
|
81861
82204
|
if (restoredInput && value === "") {
|
|
81862
82205
|
setValue(restoredInput);
|
|
@@ -82258,12 +82601,12 @@ function Input({
|
|
|
82258
82601
|
flexDirection: "row",
|
|
82259
82602
|
children: [
|
|
82260
82603
|
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Box_default, {
|
|
82261
|
-
width:
|
|
82604
|
+
width: promptVisualWidth,
|
|
82262
82605
|
flexShrink: 0,
|
|
82263
82606
|
children: [
|
|
82264
82607
|
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82265
82608
|
color: isBashMode ? colors.bash.prompt : colors.input.prompt,
|
|
82266
|
-
children:
|
|
82609
|
+
children: promptChar
|
|
82267
82610
|
}, undefined, false, undefined, this),
|
|
82268
82611
|
/* @__PURE__ */ jsx_dev_runtime45.jsxDEV(Text2, {
|
|
82269
82612
|
children: " "
|
|
@@ -82363,7 +82706,9 @@ function Input({
|
|
|
82363
82706
|
inputChromeHeight,
|
|
82364
82707
|
statusLineText,
|
|
82365
82708
|
statusLineRight,
|
|
82366
|
-
statusLinePadding
|
|
82709
|
+
statusLinePadding,
|
|
82710
|
+
promptChar,
|
|
82711
|
+
promptVisualWidth
|
|
82367
82712
|
]);
|
|
82368
82713
|
if (!visible) {
|
|
82369
82714
|
return null;
|
|
@@ -82409,6 +82754,7 @@ function formatElapsedLabel(ms) {
|
|
|
82409
82754
|
var import_react68, jsx_dev_runtime45, Spinner2, ESC_CLEAR_WINDOW_MS = 2500, FOOTER_WIDTH_STREAMING_DELTA = 2, OSC8_REGEX, InputFooter, StreamingStatus;
|
|
82410
82755
|
var init_InputRich = __esm(async () => {
|
|
82411
82756
|
init_source();
|
|
82757
|
+
init_string_width();
|
|
82412
82758
|
init_oauth();
|
|
82413
82759
|
init_constants();
|
|
82414
82760
|
init_mode();
|
|
@@ -82712,7 +83058,7 @@ var init_InputRich = __esm(async () => {
|
|
|
82712
83058
|
async function connectMcpServer(config, options = {}) {
|
|
82713
83059
|
const { onEvent, abortSignal } = options;
|
|
82714
83060
|
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
82715
|
-
const baseUrl =
|
|
83061
|
+
const baseUrl = getServerUrl();
|
|
82716
83062
|
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
82717
83063
|
if (!apiKey) {
|
|
82718
83064
|
throw new Error("Missing LETTA_API_KEY");
|
|
@@ -84121,7 +84467,7 @@ var init_McpSelector = __esm(async () => {
|
|
|
84121
84467
|
|
|
84122
84468
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
84123
84469
|
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync5, statSync as statSync6 } from "node:fs";
|
|
84124
|
-
import { join as
|
|
84470
|
+
import { join as join27, relative as relative4 } from "node:path";
|
|
84125
84471
|
function scanMemoryFilesystem(memoryRoot) {
|
|
84126
84472
|
const nodes = [];
|
|
84127
84473
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
@@ -84133,8 +84479,8 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
84133
84479
|
}
|
|
84134
84480
|
const filtered = entries.filter((name) => !name.startsWith("."));
|
|
84135
84481
|
const sorted = filtered.sort((a, b) => {
|
|
84136
|
-
const aPath =
|
|
84137
|
-
const bPath =
|
|
84482
|
+
const aPath = join27(dir, a);
|
|
84483
|
+
const bPath = join27(dir, b);
|
|
84138
84484
|
let aIsDir = false;
|
|
84139
84485
|
let bIsDir = false;
|
|
84140
84486
|
try {
|
|
@@ -84154,7 +84500,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
84154
84500
|
return a.localeCompare(b);
|
|
84155
84501
|
});
|
|
84156
84502
|
sorted.forEach((name, index) => {
|
|
84157
|
-
const fullPath =
|
|
84503
|
+
const fullPath = join27(dir, name);
|
|
84158
84504
|
let isDir = false;
|
|
84159
84505
|
try {
|
|
84160
84506
|
isDir = statSync6(fullPath).isDirectory();
|
|
@@ -86612,10 +86958,10 @@ var init_byok_providers = __esm(async () => {
|
|
|
86612
86958
|
// src/utils/aws-credentials.ts
|
|
86613
86959
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
86614
86960
|
import { homedir as homedir17 } from "node:os";
|
|
86615
|
-
import { join as
|
|
86961
|
+
import { join as join28 } from "node:path";
|
|
86616
86962
|
async function parseAwsCredentials() {
|
|
86617
|
-
const credentialsPath =
|
|
86618
|
-
const configPath =
|
|
86963
|
+
const credentialsPath = join28(homedir17(), ".aws", "credentials");
|
|
86964
|
+
const configPath = join28(homedir17(), ".aws", "config");
|
|
86619
86965
|
const profiles = new Map;
|
|
86620
86966
|
try {
|
|
86621
86967
|
const content = await readFile10(credentialsPath, "utf-8");
|
|
@@ -87847,7 +88193,7 @@ function SleeptimeSelector({
|
|
|
87847
88193
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87848
88194
|
bold: true,
|
|
87849
88195
|
color: colors.selector.title,
|
|
87850
|
-
children: "Configure your
|
|
88196
|
+
children: "Configure your sleep-time (reflection) settings"
|
|
87851
88197
|
}, undefined, false, undefined, this),
|
|
87852
88198
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Box_default, {
|
|
87853
88199
|
height: 1
|
|
@@ -87862,7 +88208,7 @@ function SleeptimeSelector({
|
|
|
87862
88208
|
}, undefined, false, undefined, this),
|
|
87863
88209
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87864
88210
|
bold: true,
|
|
87865
|
-
children: "Trigger:"
|
|
88211
|
+
children: "Trigger event:"
|
|
87866
88212
|
}, undefined, false, undefined, this),
|
|
87867
88213
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87868
88214
|
children: " "
|
|
@@ -87906,7 +88252,7 @@ function SleeptimeSelector({
|
|
|
87906
88252
|
}, undefined, false, undefined, this),
|
|
87907
88253
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87908
88254
|
bold: true,
|
|
87909
|
-
children: "
|
|
88255
|
+
children: "Forced:"
|
|
87910
88256
|
}, undefined, false, undefined, this),
|
|
87911
88257
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87912
88258
|
children: " "
|
|
@@ -87915,7 +88261,7 @@ function SleeptimeSelector({
|
|
|
87915
88261
|
backgroundColor: behavior === "reminder" ? colors.selector.itemHighlighted : undefined,
|
|
87916
88262
|
color: behavior === "reminder" ? "black" : undefined,
|
|
87917
88263
|
bold: behavior === "reminder",
|
|
87918
|
-
children: "
|
|
88264
|
+
children: " No (reminder only) "
|
|
87919
88265
|
}, undefined, false, undefined, this),
|
|
87920
88266
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87921
88267
|
children: " "
|
|
@@ -87924,7 +88270,7 @@ function SleeptimeSelector({
|
|
|
87924
88270
|
backgroundColor: behavior === "auto-launch" ? colors.selector.itemHighlighted : undefined,
|
|
87925
88271
|
color: behavior === "auto-launch" ? "black" : undefined,
|
|
87926
88272
|
bold: behavior === "auto-launch",
|
|
87927
|
-
children: "
|
|
88273
|
+
children: " Yes (auto-launch) "
|
|
87928
88274
|
}, undefined, false, undefined, this)
|
|
87929
88275
|
]
|
|
87930
88276
|
}, undefined, true, undefined, this)
|
|
@@ -87970,7 +88316,7 @@ function SleeptimeSelector({
|
|
|
87970
88316
|
}, undefined, false, undefined, this),
|
|
87971
88317
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87972
88318
|
bold: true,
|
|
87973
|
-
children: "Trigger:"
|
|
88319
|
+
children: "Trigger event:"
|
|
87974
88320
|
}, undefined, false, undefined, this),
|
|
87975
88321
|
/* @__PURE__ */ jsx_dev_runtime57.jsxDEV(Text2, {
|
|
87976
88322
|
children: " "
|
|
@@ -91022,18 +91368,20 @@ function wordWrap(text, width) {
|
|
|
91022
91368
|
}
|
|
91023
91369
|
function splitSystemReminderBlocks(text) {
|
|
91024
91370
|
const blocks = [];
|
|
91025
|
-
const
|
|
91026
|
-
|
|
91371
|
+
const tags = [
|
|
91372
|
+
{ open: SYSTEM_REMINDER_OPEN, close: SYSTEM_REMINDER_CLOSE },
|
|
91373
|
+
{ open: SYSTEM_ALERT_OPEN, close: SYSTEM_ALERT_CLOSE }
|
|
91374
|
+
];
|
|
91027
91375
|
let remaining = text;
|
|
91028
91376
|
while (remaining.length > 0) {
|
|
91029
|
-
const
|
|
91030
|
-
if (
|
|
91377
|
+
const nextTag = tags.map((tag) => ({ ...tag, idx: remaining.indexOf(tag.open) })).filter((tag) => tag.idx >= 0).sort((a, b) => a.idx - b.idx)[0];
|
|
91378
|
+
if (!nextTag) {
|
|
91031
91379
|
if (remaining.trim()) {
|
|
91032
91380
|
blocks.push({ text: remaining.trim(), isSystemReminder: false });
|
|
91033
91381
|
}
|
|
91034
91382
|
break;
|
|
91035
91383
|
}
|
|
91036
|
-
const closeIdx = remaining.indexOf(
|
|
91384
|
+
const closeIdx = remaining.indexOf(nextTag.close, nextTag.idx);
|
|
91037
91385
|
if (closeIdx === -1) {
|
|
91038
91386
|
const literal = remaining.trim();
|
|
91039
91387
|
if (literal) {
|
|
@@ -91041,19 +91389,19 @@ function splitSystemReminderBlocks(text) {
|
|
|
91041
91389
|
}
|
|
91042
91390
|
break;
|
|
91043
91391
|
}
|
|
91044
|
-
if (
|
|
91045
|
-
const before = remaining.slice(0,
|
|
91392
|
+
if (nextTag.idx > 0) {
|
|
91393
|
+
const before = remaining.slice(0, nextTag.idx).trim();
|
|
91046
91394
|
if (before) {
|
|
91047
91395
|
blocks.push({ text: before, isSystemReminder: false });
|
|
91048
91396
|
}
|
|
91049
91397
|
}
|
|
91050
|
-
const sysBlock = remaining.slice(
|
|
91398
|
+
const sysBlock = remaining.slice(nextTag.idx, closeIdx + nextTag.close.length);
|
|
91051
91399
|
blocks.push({ text: sysBlock, isSystemReminder: true });
|
|
91052
|
-
remaining = remaining.slice(closeIdx +
|
|
91400
|
+
remaining = remaining.slice(closeIdx + nextTag.close.length);
|
|
91053
91401
|
}
|
|
91054
91402
|
return blocks;
|
|
91055
91403
|
}
|
|
91056
|
-
function renderBlock(text, contentWidth, columns, highlighted, colorAnsi) {
|
|
91404
|
+
function renderBlock(text, contentWidth, columns, highlighted, colorAnsi, promptPrefix, continuationPrefix) {
|
|
91057
91405
|
const inputLines = text.split(`
|
|
91058
91406
|
`);
|
|
91059
91407
|
const outputLines = [];
|
|
@@ -91071,11 +91419,11 @@ function renderBlock(text, contentWidth, columns, highlighted, colorAnsi) {
|
|
|
91071
91419
|
return [];
|
|
91072
91420
|
const isSingleLine = outputLines.length === 1;
|
|
91073
91421
|
return outputLines.map((ol, i) => {
|
|
91074
|
-
const prefix = i === 0 ?
|
|
91075
|
-
const content = prefix + ol;
|
|
91422
|
+
const prefix = i === 0 ? promptPrefix : continuationPrefix;
|
|
91076
91423
|
if (!highlighted) {
|
|
91077
|
-
return
|
|
91424
|
+
return prefix + ol;
|
|
91078
91425
|
}
|
|
91426
|
+
const content = i === 0 ? `${promptPrefix.slice(0, -1)}${colorAnsi} ${ol}` : `${prefix}${ol}`;
|
|
91079
91427
|
const visWidth = stringWidth(content);
|
|
91080
91428
|
if (isSingleLine) {
|
|
91081
91429
|
return `${colorAnsi}${content}${" ".repeat(COMPACT_PAD)}\x1B[0m`;
|
|
@@ -91093,9 +91441,12 @@ var init_UserMessageRich = __esm(async () => {
|
|
|
91093
91441
|
await init_Text2();
|
|
91094
91442
|
import_react89 = __toESM(require_react(), 1);
|
|
91095
91443
|
jsx_dev_runtime69 = __toESM(require_jsx_dev_runtime(), 1);
|
|
91096
|
-
UserMessage = import_react89.memo(({ line }) => {
|
|
91444
|
+
UserMessage = import_react89.memo(({ line, prompt }) => {
|
|
91097
91445
|
const columns = useTerminalWidth();
|
|
91098
|
-
const
|
|
91446
|
+
const promptPrefix = `${prompt || ">"} `;
|
|
91447
|
+
const prefixWidth = stringWidth(promptPrefix);
|
|
91448
|
+
const continuationPrefix = " ".repeat(prefixWidth);
|
|
91449
|
+
const contentWidth = Math.max(1, columns - prefixWidth);
|
|
91099
91450
|
const cleanedText = extractTaskNotificationsForDisplay(line.text).cleanedText;
|
|
91100
91451
|
const displayText = cleanedText.trim();
|
|
91101
91452
|
if (!displayText) {
|
|
@@ -91113,7 +91464,7 @@ var init_UserMessageRich = __esm(async () => {
|
|
|
91113
91464
|
if (allLines.length > 0) {
|
|
91114
91465
|
allLines.push("");
|
|
91115
91466
|
}
|
|
91116
|
-
const blockLines = renderBlock(block.text, contentWidth, columns, !block.isSystemReminder, colorAnsi);
|
|
91467
|
+
const blockLines = renderBlock(block.text, contentWidth, columns, !block.isSystemReminder, colorAnsi, promptPrefix, continuationPrefix);
|
|
91117
91468
|
allLines.push(...blockLines);
|
|
91118
91469
|
}
|
|
91119
91470
|
return /* @__PURE__ */ jsx_dev_runtime69.jsxDEV(Text2, {
|
|
@@ -91597,7 +91948,7 @@ var init_memoryReminder = __esm(async () => {
|
|
|
91597
91948
|
init_debug();
|
|
91598
91949
|
await init_settings_manager();
|
|
91599
91950
|
DEFAULT_REFLECTION_SETTINGS = {
|
|
91600
|
-
trigger: "
|
|
91951
|
+
trigger: "compaction-event",
|
|
91601
91952
|
behavior: "reminder",
|
|
91602
91953
|
stepCount: DEFAULT_STEP_COUNT2
|
|
91603
91954
|
};
|
|
@@ -91823,7 +92174,8 @@ function normalizeStatusLineConfig(config) {
|
|
|
91823
92174
|
timeout: Math.min(MAX_STATUS_LINE_TIMEOUT_MS, Math.max(1000, config.timeout ?? DEFAULT_STATUS_LINE_TIMEOUT_MS)),
|
|
91824
92175
|
debounceMs: Math.max(MIN_STATUS_LINE_DEBOUNCE_MS, Math.min(MAX_STATUS_LINE_DEBOUNCE_MS, config.debounceMs ?? DEFAULT_STATUS_LINE_DEBOUNCE_MS)),
|
|
91825
92176
|
...refreshIntervalMs !== undefined && { refreshIntervalMs },
|
|
91826
|
-
...config.disabled !== undefined && { disabled: config.disabled }
|
|
92177
|
+
...config.disabled !== undefined && { disabled: config.disabled },
|
|
92178
|
+
...config.prompt !== undefined && { prompt: config.prompt }
|
|
91827
92179
|
};
|
|
91828
92180
|
}
|
|
91829
92181
|
function isStatusLineDisabled(workingDirectory = process.cwd()) {
|
|
@@ -91874,6 +92226,31 @@ function resolveStatusLineConfig(workingDirectory = process.cwd()) {
|
|
|
91874
92226
|
return null;
|
|
91875
92227
|
}
|
|
91876
92228
|
}
|
|
92229
|
+
function resolvePromptChar(workingDirectory = process.cwd()) {
|
|
92230
|
+
try {
|
|
92231
|
+
if (isStatusLineDisabled(workingDirectory))
|
|
92232
|
+
return ">";
|
|
92233
|
+
try {
|
|
92234
|
+
const local = settingsManager.getLocalProjectSettings(workingDirectory)?.statusLine;
|
|
92235
|
+
if (local?.prompt !== undefined)
|
|
92236
|
+
return local.prompt;
|
|
92237
|
+
} catch {}
|
|
92238
|
+
try {
|
|
92239
|
+
const project = settingsManager.getProjectSettings(workingDirectory)?.statusLine;
|
|
92240
|
+
if (project?.prompt !== undefined)
|
|
92241
|
+
return project.prompt;
|
|
92242
|
+
} catch {}
|
|
92243
|
+
try {
|
|
92244
|
+
const global2 = settingsManager.getSettings().statusLine;
|
|
92245
|
+
if (global2?.prompt !== undefined)
|
|
92246
|
+
return global2.prompt;
|
|
92247
|
+
} catch {}
|
|
92248
|
+
return ">";
|
|
92249
|
+
} catch (error) {
|
|
92250
|
+
debugLog("statusline", "resolvePromptChar: Failed to resolve prompt", error);
|
|
92251
|
+
return ">";
|
|
92252
|
+
}
|
|
92253
|
+
}
|
|
91877
92254
|
var MIN_STATUS_LINE_INTERVAL_MS = 1000, DEFAULT_STATUS_LINE_TIMEOUT_MS = 5000, MAX_STATUS_LINE_TIMEOUT_MS = 30000, DEFAULT_STATUS_LINE_DEBOUNCE_MS = 300, MIN_STATUS_LINE_DEBOUNCE_MS = 50, MAX_STATUS_LINE_DEBOUNCE_MS = 5000, MAX_STATUS_LINE_PADDING = 16;
|
|
91878
92255
|
var init_statusLineConfig = __esm(async () => {
|
|
91879
92256
|
init_debug();
|
|
@@ -91939,7 +92316,8 @@ function formatStatusLineHelp() {
|
|
|
91939
92316
|
' "padding": 2,',
|
|
91940
92317
|
' "timeout": 5000,',
|
|
91941
92318
|
' "debounceMs": 300,',
|
|
91942
|
-
' "refreshIntervalMs": 10000',
|
|
92319
|
+
' "refreshIntervalMs": 10000,',
|
|
92320
|
+
' "prompt": "→"',
|
|
91943
92321
|
" }",
|
|
91944
92322
|
"",
|
|
91945
92323
|
' type must be "command"',
|
|
@@ -91948,6 +92326,7 @@ function formatStatusLineHelp() {
|
|
|
91948
92326
|
" timeout command timeout in ms (default 5000, max 30000)",
|
|
91949
92327
|
" debounceMs event debounce in ms (default 300)",
|
|
91950
92328
|
" refreshIntervalMs optional polling interval in ms (off by default)",
|
|
92329
|
+
' prompt custom input prompt character (default ">")',
|
|
91951
92330
|
"",
|
|
91952
92331
|
"INPUT (via JSON stdin)",
|
|
91953
92332
|
fieldList
|
|
@@ -92382,6 +92761,7 @@ function useConfigurableStatusLine(inputs) {
|
|
|
92382
92761
|
const [executing, setExecuting] = import_react90.useState(false);
|
|
92383
92762
|
const [lastError, setLastError] = import_react90.useState(null);
|
|
92384
92763
|
const [padding, setPadding] = import_react90.useState(0);
|
|
92764
|
+
const [prompt, setPrompt] = import_react90.useState(">");
|
|
92385
92765
|
const inputsRef = import_react90.useRef(inputs);
|
|
92386
92766
|
const configRef = import_react90.useRef(null);
|
|
92387
92767
|
const abortRef = import_react90.useRef(null);
|
|
@@ -92405,6 +92785,7 @@ function useConfigurableStatusLine(inputs) {
|
|
|
92405
92785
|
const resolveActiveConfig = import_react90.useCallback(() => {
|
|
92406
92786
|
const workingDirectory = inputsRef.current.currentDirectory;
|
|
92407
92787
|
const config = resolveStatusLineConfig(workingDirectory);
|
|
92788
|
+
setPrompt(resolvePromptChar(workingDirectory));
|
|
92408
92789
|
if (!config) {
|
|
92409
92790
|
configRef.current = null;
|
|
92410
92791
|
abortRef.current?.abort();
|
|
@@ -92497,7 +92878,7 @@ function useConfigurableStatusLine(inputs) {
|
|
|
92497
92878
|
scheduleDebouncedRun,
|
|
92498
92879
|
currentDirectory
|
|
92499
92880
|
]);
|
|
92500
|
-
return { text, rightText, active, executing, lastError, padding };
|
|
92881
|
+
return { text, rightText, active, executing, lastError, padding, prompt };
|
|
92501
92882
|
}
|
|
92502
92883
|
var import_react90, RS = "\x1E";
|
|
92503
92884
|
var init_useConfigurableStatusLine = __esm(async () => {
|
|
@@ -92568,7 +92949,7 @@ __export(exports_shellAliases, {
|
|
|
92568
92949
|
});
|
|
92569
92950
|
import { existsSync as existsSync17, readFileSync as readFileSync6 } from "node:fs";
|
|
92570
92951
|
import { homedir as homedir18 } from "node:os";
|
|
92571
|
-
import { join as
|
|
92952
|
+
import { join as join29 } from "node:path";
|
|
92572
92953
|
function parseAliasesFromFile(filePath) {
|
|
92573
92954
|
const aliases = new Map;
|
|
92574
92955
|
if (!existsSync17(filePath)) {
|
|
@@ -92640,7 +93021,7 @@ function loadAliases(forceReload = false) {
|
|
|
92640
93021
|
const home = homedir18();
|
|
92641
93022
|
const allAliases = new Map;
|
|
92642
93023
|
for (const file of ALIAS_FILES) {
|
|
92643
|
-
const filePath =
|
|
93024
|
+
const filePath = join29(home, file);
|
|
92644
93025
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
92645
93026
|
for (const [name, value] of fileAliases) {
|
|
92646
93027
|
allAliases.set(name, value);
|
|
@@ -93783,9 +94164,9 @@ var exports_App = {};
|
|
|
93783
94164
|
__export(exports_App, {
|
|
93784
94165
|
default: () => App2
|
|
93785
94166
|
});
|
|
93786
|
-
import { existsSync as existsSync18, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as
|
|
93787
|
-
import { homedir as homedir19, tmpdir as
|
|
93788
|
-
import { join as
|
|
94167
|
+
import { existsSync as existsSync18, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
94168
|
+
import { homedir as homedir19, tmpdir as tmpdir4 } from "node:os";
|
|
94169
|
+
import { join as join30 } from "node:path";
|
|
93789
94170
|
function getErrorHintForStopReason(stopReason, currentModelId) {
|
|
93790
94171
|
if (currentModelId === "opus" && stopReason === "llm_api_error" && getModelInfo("bedrock-opus")) {
|
|
93791
94172
|
return OPUS_BEDROCK_FALLBACK_HINT;
|
|
@@ -94036,7 +94417,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
94036
94417
|
}
|
|
94037
94418
|
}
|
|
94038
94419
|
function stripSystemReminders(text) {
|
|
94039
|
-
return text.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").trim();
|
|
94420
|
+
return text.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").replace(new RegExp(`${SYSTEM_ALERT_OPEN}[\\s\\S]*?${SYSTEM_ALERT_CLOSE}`, "g"), "").trim();
|
|
94040
94421
|
}
|
|
94041
94422
|
function formatReflectionSettings(settings) {
|
|
94042
94423
|
if (settings.trigger === "off") {
|
|
@@ -94422,6 +94803,7 @@ function App2({
|
|
|
94422
94803
|
restoreQueueOnCancelRef.current = restoreQueueOnCancel;
|
|
94423
94804
|
}, [restoreQueueOnCancel]);
|
|
94424
94805
|
const lastSentInputRef = import_react93.useRef(null);
|
|
94806
|
+
const pendingInterruptRecoveryConversationIdRef = import_react93.useRef(null);
|
|
94425
94807
|
const [dequeueEpoch, setDequeueEpoch] = import_react93.useState(0);
|
|
94426
94808
|
const lastDequeuedMessageRef = import_react93.useRef(null);
|
|
94427
94809
|
const [restoredInput, setRestoredInput] = import_react93.useState(null);
|
|
@@ -95393,7 +95775,8 @@ ${newState.originalPrompt}`
|
|
|
95393
95775
|
abortControllerRef.current = new AbortController;
|
|
95394
95776
|
const originalInput = currentInput;
|
|
95395
95777
|
const cacheIsAllUserMsgs = lastSentInputRef.current?.every((m) => m.type === "message" && m.role === "user");
|
|
95396
|
-
|
|
95778
|
+
const canInjectInterruptRecovery = pendingInterruptRecoveryConversationIdRef.current !== null && pendingInterruptRecoveryConversationIdRef.current === conversationIdRef.current;
|
|
95779
|
+
if (cacheIsAllUserMsgs && lastSentInputRef.current && canInjectInterruptRecovery) {
|
|
95397
95780
|
currentInput = [
|
|
95398
95781
|
...lastSentInputRef.current,
|
|
95399
95782
|
...currentInput.map((m) => m.type === "message" && m.role === "user" ? {
|
|
@@ -95404,11 +95787,13 @@ ${newState.originalPrompt}`
|
|
|
95404
95787
|
]
|
|
95405
95788
|
} : m)
|
|
95406
95789
|
];
|
|
95790
|
+
pendingInterruptRecoveryConversationIdRef.current = null;
|
|
95407
95791
|
lastSentInputRef.current = [
|
|
95408
95792
|
...lastSentInputRef.current,
|
|
95409
95793
|
...originalInput
|
|
95410
95794
|
];
|
|
95411
95795
|
} else {
|
|
95796
|
+
pendingInterruptRecoveryConversationIdRef.current = null;
|
|
95412
95797
|
lastSentInputRef.current = originalInput;
|
|
95413
95798
|
}
|
|
95414
95799
|
if (!allowReentry) {
|
|
@@ -95447,21 +95832,26 @@ ${newState.originalPrompt}`
|
|
|
95447
95832
|
try {
|
|
95448
95833
|
stream2 = await sendMessageStream(conversationIdRef.current, currentInput, { agentId: agentIdRef.current });
|
|
95449
95834
|
} catch (preStreamError) {
|
|
95450
|
-
|
|
95451
|
-
|
|
95452
|
-
|
|
95453
|
-
|
|
95454
|
-
|
|
95455
|
-
|
|
95456
|
-
|
|
95457
|
-
|
|
95458
|
-
|
|
95835
|
+
const errorDetail = extractConflictDetail(preStreamError);
|
|
95836
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetriesRef.current, CONVERSATION_BUSY_MAX_RETRIES2);
|
|
95837
|
+
if (shouldAttemptApprovalRecovery({
|
|
95838
|
+
approvalPendingDetected: preStreamAction === "resolve_approval_pending",
|
|
95839
|
+
retries: llmApiErrorRetriesRef.current,
|
|
95840
|
+
maxRetries: LLM_API_ERROR_MAX_RETRIES2
|
|
95841
|
+
})) {
|
|
95842
|
+
llmApiErrorRetriesRef.current += 1;
|
|
95843
|
+
try {
|
|
95844
|
+
const client = await getClient2();
|
|
95845
|
+
const agent = await client.agents.retrieve(agentIdRef.current);
|
|
95846
|
+
const { pendingApprovals: existingApprovals } = await getResumeData2(client, agent, conversationIdRef.current);
|
|
95847
|
+
currentInput = rebuildInputWithFreshDenials(currentInput, existingApprovals ?? [], "Auto-denied: stale approval from interrupted session");
|
|
95848
|
+
} catch {
|
|
95849
|
+
currentInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
95459
95850
|
}
|
|
95851
|
+
buffersRef.current.interrupted = false;
|
|
95852
|
+
continue;
|
|
95460
95853
|
}
|
|
95461
|
-
if (
|
|
95462
|
-
errorDetail = preStreamError.message;
|
|
95463
|
-
}
|
|
95464
|
-
if (isConversationBusyError(errorDetail) && conversationBusyRetriesRef.current < CONVERSATION_BUSY_MAX_RETRIES2) {
|
|
95854
|
+
if (preStreamAction === "retry_conversation_busy") {
|
|
95465
95855
|
conversationBusyRetriesRef.current += 1;
|
|
95466
95856
|
const retryDelayMs = CONVERSATION_BUSY_RETRY_BASE_DELAY_MS * 2 ** (conversationBusyRetriesRef.current - 1);
|
|
95467
95857
|
const statusId = uid4("status");
|
|
@@ -95505,7 +95895,7 @@ ${newState.originalPrompt}`
|
|
|
95505
95895
|
if (typeof content === "string") {
|
|
95506
95896
|
textToRestore = stripSystemReminders(content);
|
|
95507
95897
|
} else if (Array.isArray(content)) {
|
|
95508
|
-
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN)).map((c) => c.text).join(`
|
|
95898
|
+
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN)).map((c) => c.text).join(`
|
|
95509
95899
|
`);
|
|
95510
95900
|
}
|
|
95511
95901
|
if (textToRestore.trim()) {
|
|
@@ -95630,6 +96020,7 @@ ${newState.originalPrompt}`
|
|
|
95630
96020
|
conversationBusyRetriesRef.current = 0;
|
|
95631
96021
|
lastDequeuedMessageRef.current = null;
|
|
95632
96022
|
lastSentInputRef.current = null;
|
|
96023
|
+
pendingInterruptRecoveryConversationIdRef.current = null;
|
|
95633
96024
|
const lastAssistant = Array.from(buffersRef.current.byId.values()).findLast((item) => item.kind === "assistant" && ("text" in item));
|
|
95634
96025
|
const assistantMessage = lastAssistant && "text" in lastAssistant ? lastAssistant.text : undefined;
|
|
95635
96026
|
const lastUser = Array.from(buffersRef.current.byId.values()).findLast((item) => item.kind === "user" && ("text" in item));
|
|
@@ -95750,6 +96141,7 @@ ${feedback}
|
|
|
95750
96141
|
setAutoHandledResults([]);
|
|
95751
96142
|
setAutoDeniedApprovals([]);
|
|
95752
96143
|
lastSentInputRef.current = null;
|
|
96144
|
+
pendingInterruptRecoveryConversationIdRef.current = null;
|
|
95753
96145
|
const approvalsToProcess = approvals && approvals.length > 0 ? approvals : approval ? [approval] : [];
|
|
95754
96146
|
if (approvalsToProcess.length === 0) {
|
|
95755
96147
|
appendError(`Unexpected empty approvals with stop reason: ${stopReason}`);
|
|
@@ -96080,7 +96472,7 @@ ${feedback}
|
|
|
96080
96472
|
if (typeof content === "string") {
|
|
96081
96473
|
textToRestore = stripSystemReminders(content);
|
|
96082
96474
|
} else if (Array.isArray(content)) {
|
|
96083
|
-
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN)).map((c) => c.text).join(`
|
|
96475
|
+
textToRestore = content.filter((c) => typeof c === "object" && c !== null && ("type" in c) && c.type === "text" && ("text" in c) && typeof c.text === "string" && !c.text.includes(SYSTEM_REMINDER_OPEN) && !c.text.includes(SYSTEM_ALERT_OPEN)).map((c) => c.text).join(`
|
|
96084
96476
|
`);
|
|
96085
96477
|
}
|
|
96086
96478
|
if (textToRestore.trim()) {
|
|
@@ -96107,26 +96499,20 @@ ${feedback}
|
|
|
96107
96499
|
} catch {}
|
|
96108
96500
|
}
|
|
96109
96501
|
const approvalPendingDetected = isApprovalPendingError(detailFromRun) || isApprovalPendingError(latestErrorText);
|
|
96110
|
-
if (
|
|
96502
|
+
if (shouldAttemptApprovalRecovery({
|
|
96503
|
+
approvalPendingDetected,
|
|
96504
|
+
retries: llmApiErrorRetriesRef.current,
|
|
96505
|
+
maxRetries: LLM_API_ERROR_MAX_RETRIES2
|
|
96506
|
+
})) {
|
|
96111
96507
|
llmApiErrorRetriesRef.current += 1;
|
|
96112
96508
|
try {
|
|
96113
96509
|
const client = await getClient2();
|
|
96114
96510
|
const agent = await client.agents.retrieve(agentIdRef.current);
|
|
96115
96511
|
const { pendingApprovals: existingApprovals } = await getResumeData2(client, agent, conversationIdRef.current);
|
|
96116
|
-
|
|
96117
|
-
|
|
96118
|
-
|
|
96119
|
-
|
|
96120
|
-
approve: false,
|
|
96121
|
-
reason: "Auto-denied: stale approval from interrupted session"
|
|
96122
|
-
}));
|
|
96123
|
-
const approvalPayload = {
|
|
96124
|
-
type: "approval",
|
|
96125
|
-
approvals: denialResults
|
|
96126
|
-
};
|
|
96127
|
-
currentInput.unshift(approvalPayload);
|
|
96128
|
-
}
|
|
96129
|
-
} catch {}
|
|
96512
|
+
currentInput = rebuildInputWithFreshDenials(currentInput, existingApprovals ?? [], "Auto-denied: stale approval from interrupted session");
|
|
96513
|
+
} catch {
|
|
96514
|
+
currentInput = rebuildInputWithFreshDenials(currentInput, [], "");
|
|
96515
|
+
}
|
|
96130
96516
|
buffersRef.current.interrupted = false;
|
|
96131
96517
|
continue;
|
|
96132
96518
|
}
|
|
@@ -96136,9 +96522,7 @@ ${feedback}
|
|
|
96136
96522
|
const attempt = llmApiErrorRetriesRef.current;
|
|
96137
96523
|
const delayMs = 1000 * 2 ** (attempt - 1);
|
|
96138
96524
|
const statusId = uid4("status");
|
|
96139
|
-
const statusLines = [
|
|
96140
|
-
"Unexpected downstream LLM API error, retrying..."
|
|
96141
|
-
];
|
|
96525
|
+
const statusLines = [getRetryStatusMessage(detailFromRun)];
|
|
96142
96526
|
buffersRef.current.byId.set(statusId, {
|
|
96143
96527
|
kind: "status",
|
|
96144
96528
|
id: statusId,
|
|
@@ -96356,11 +96740,18 @@ ${feedback}
|
|
|
96356
96740
|
abortControllerRef.current.abort();
|
|
96357
96741
|
abortControllerRef.current = null;
|
|
96358
96742
|
}
|
|
96743
|
+
pendingInterruptRecoveryConversationIdRef.current = conversationIdRef.current;
|
|
96359
96744
|
userCancelledRef.current = true;
|
|
96360
96745
|
setStreaming(false);
|
|
96361
96746
|
setIsExecutingTool(false);
|
|
96362
96747
|
toolResultsInFlightRef.current = false;
|
|
96363
96748
|
refreshDerived();
|
|
96749
|
+
getClient2().then((client) => {
|
|
96750
|
+
if (conversationIdRef.current === "default") {
|
|
96751
|
+
return client.agents.messages.cancel(agentIdRef.current);
|
|
96752
|
+
}
|
|
96753
|
+
return client.conversations.cancel(conversationIdRef.current);
|
|
96754
|
+
}).catch(() => {});
|
|
96364
96755
|
setTimeout(() => {
|
|
96365
96756
|
userCancelledRef.current = false;
|
|
96366
96757
|
}, 50);
|
|
@@ -96381,6 +96772,7 @@ ${feedback}
|
|
|
96381
96772
|
abortControllerRef.current.abort();
|
|
96382
96773
|
abortControllerRef.current = null;
|
|
96383
96774
|
}
|
|
96775
|
+
pendingInterruptRecoveryConversationIdRef.current = conversationIdRef.current;
|
|
96384
96776
|
userCancelledRef.current = true;
|
|
96385
96777
|
conversationGenerationRef.current += 1;
|
|
96386
96778
|
processingConversationRef.current = 0;
|
|
@@ -96446,6 +96838,7 @@ ${feedback}
|
|
|
96446
96838
|
if (abortControllerRef.current) {
|
|
96447
96839
|
abortControllerRef.current.abort();
|
|
96448
96840
|
}
|
|
96841
|
+
pendingInterruptRecoveryConversationIdRef.current = conversationIdRef.current;
|
|
96449
96842
|
} catch (e) {
|
|
96450
96843
|
const errorDetails = formatErrorDetails(e, agentId);
|
|
96451
96844
|
appendError(`Failed to interrupt stream: ${errorDetails}`);
|
|
@@ -96956,7 +97349,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
96956
97349
|
return { submitted: true };
|
|
96957
97350
|
}
|
|
96958
97351
|
if (trimmed === "/ade") {
|
|
96959
|
-
const adeUrl = `https://app.letta.com/agents/${agentId}?conversation=${conversationIdRef.current}`;
|
|
97352
|
+
const adeUrl = conversationIdRef.current === "default" ? `https://app.letta.com/agents/${agentId}` : `https://app.letta.com/agents/${agentId}?conversation=${conversationIdRef.current}`;
|
|
96960
97353
|
const cmd = commandRunner.start("/ade", "Opening ADE...");
|
|
96961
97354
|
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open2 }) => open2(adeUrl, { wait: false })).catch(() => {});
|
|
96962
97355
|
cmd.finish(`Opening ADE...
|
|
@@ -97110,6 +97503,8 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
97110
97503
|
}
|
|
97111
97504
|
const effective = resolveStatusLineConfig(wd);
|
|
97112
97505
|
lines2.push(`Effective: ${effective ? `command="${effective.command}" refreshInterval=${effective.refreshIntervalMs ?? "off"} timeout=${effective.timeout}ms debounce=${effective.debounceMs}ms padding=${effective.padding}` : "(inactive)"}`);
|
|
97506
|
+
const effectivePrompt = resolvePromptChar(wd);
|
|
97507
|
+
lines2.push(`Prompt: "${effectivePrompt}"`);
|
|
97113
97508
|
cmd.finish(lines2.join(`
|
|
97114
97509
|
`), true);
|
|
97115
97510
|
} else if (sub === "set") {
|
|
@@ -97243,7 +97638,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
97243
97638
|
try {
|
|
97244
97639
|
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
97245
97640
|
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
97246
|
-
const baseUrl =
|
|
97641
|
+
const baseUrl = getServerUrl();
|
|
97247
97642
|
const controller = new AbortController;
|
|
97248
97643
|
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
97249
97644
|
const res = await fetch(`${baseUrl}/v1/agents/${agentIdRef.current}/context`, {
|
|
@@ -97856,10 +98251,10 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
97856
98251
|
let fileContent;
|
|
97857
98252
|
if (skills.length > 0) {
|
|
97858
98253
|
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
97859
|
-
const { getServerUrl:
|
|
98254
|
+
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
97860
98255
|
const settings = await settingsManager3.getSettingsWithSecureTokens();
|
|
97861
98256
|
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
97862
|
-
const baseUrl =
|
|
98257
|
+
const baseUrl = getServerUrl2();
|
|
97863
98258
|
const body = {
|
|
97864
98259
|
...exportParams,
|
|
97865
98260
|
skills
|
|
@@ -97880,7 +98275,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
97880
98275
|
fileContent = await client.agents.exportFile(agentId, exportParams);
|
|
97881
98276
|
}
|
|
97882
98277
|
const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
|
|
97883
|
-
|
|
98278
|
+
writeFileSync7(fileName, JSON.stringify(fileContent, null, 2));
|
|
97884
98279
|
let summary = `AgentFile exported to ${fileName}`;
|
|
97885
98280
|
if (skills.length > 0) {
|
|
97886
98281
|
summary += `
|
|
@@ -97926,27 +98321,13 @@ Path: ${memoryDir}`;
|
|
|
97926
98321
|
return { submitted: true };
|
|
97927
98322
|
}
|
|
97928
98323
|
if (subcommand === "enable") {
|
|
97929
|
-
const serverUrl = getServerUrl2();
|
|
97930
|
-
if (!serverUrl.includes("api.letta.com")) {
|
|
97931
|
-
cmd.fail("Memory filesystem is only available on Letta Cloud (api.letta.com).");
|
|
97932
|
-
return { submitted: true };
|
|
97933
|
-
}
|
|
97934
98324
|
updateMemorySyncCommand(cmdId, "Enabling memory filesystem...", true, msg, true);
|
|
97935
98325
|
setCommandRunning(true);
|
|
97936
98326
|
try {
|
|
97937
|
-
const {
|
|
97938
|
-
await
|
|
97939
|
-
settingsManager.setMemfsEnabled(agentId, true);
|
|
97940
|
-
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs2 } = await init_modify().then(() => exports_modify);
|
|
97941
|
-
await updateAgentSystemPromptMemfs2(agentId, true);
|
|
97942
|
-
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
97943
|
-
await addGitMemoryTag2(agentId);
|
|
97944
|
-
if (!isGitRepo2(agentId)) {
|
|
97945
|
-
await cloneMemoryRepo2(agentId);
|
|
97946
|
-
}
|
|
97947
|
-
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
98327
|
+
const { applyMemfsFlags: applyMemfsFlags2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
98328
|
+
const result2 = await applyMemfsFlags2(agentId, true, false);
|
|
97948
98329
|
updateMemorySyncCommand(cmdId, `Memory filesystem enabled (git-backed).
|
|
97949
|
-
Path: ${memoryDir}`, true, msg);
|
|
98330
|
+
Path: ${result2.memoryDir}`, true, msg);
|
|
97950
98331
|
} catch (error) {
|
|
97951
98332
|
const errorText = error instanceof Error ? error.message : String(error);
|
|
97952
98333
|
updateMemorySyncCommand(cmdId, `Failed to enable memfs: ${errorText}`, false, msg);
|
|
@@ -97983,7 +98364,7 @@ Path: ${memoryDir}`, true, msg);
|
|
|
97983
98364
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
97984
98365
|
return { submitted: true };
|
|
97985
98366
|
}
|
|
97986
|
-
const backupDir =
|
|
98367
|
+
const backupDir = join30(tmpdir4(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
97987
98368
|
renameSync2(memoryDir, backupDir);
|
|
97988
98369
|
ensureMemoryFilesystemDirs(agentId);
|
|
97989
98370
|
updateMemorySyncCommand(cmdId, `Memory filesystem reset.
|
|
@@ -98012,7 +98393,7 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
|
|
|
98012
98393
|
let backupInfo = "";
|
|
98013
98394
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
98014
98395
|
if (existsSync18(memoryDir)) {
|
|
98015
|
-
const backupDir =
|
|
98396
|
+
const backupDir = join30(tmpdir4(), `letta-memfs-disable-${agentId}-${Date.now()}`);
|
|
98016
98397
|
renameSync2(memoryDir, backupDir);
|
|
98017
98398
|
backupInfo = `
|
|
98018
98399
|
Local files backed up to ${backupDir}`;
|
|
@@ -98356,7 +98737,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
98356
98737
|
plan: "Read-only mode. Focus on exploration and planning.",
|
|
98357
98738
|
bypassPermissions: "All tools auto-approved. Bias toward action."
|
|
98358
98739
|
};
|
|
98359
|
-
permissionModeAlert =
|
|
98740
|
+
permissionModeAlert = `${SYSTEM_REMINDER_OPEN}Permission mode changed to: ${currentMode}. ${modeDescriptions[currentMode]}${SYSTEM_REMINDER_CLOSE}
|
|
98360
98741
|
|
|
98361
98742
|
`;
|
|
98362
98743
|
lastNotifiedModeRef.current = currentMode;
|
|
@@ -98394,9 +98775,11 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
98394
98775
|
if (!discoveredSkillsRef.current) {
|
|
98395
98776
|
try {
|
|
98396
98777
|
const { discoverSkills: discover, SKILLS_DIR: defaultDir } = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
98397
|
-
const { getSkillsDirectory: getSkillsDirectory2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
98398
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
98399
|
-
const { skills } = await discover(skillsDir, agentId
|
|
98778
|
+
const { getSkillsDirectory: getSkillsDirectory2, getNoSkills: getNoSkills2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
98779
|
+
const skillsDir = getSkillsDirectory2() || join30(process.cwd(), defaultDir);
|
|
98780
|
+
const { skills } = await discover(skillsDir, agentId, {
|
|
98781
|
+
skipBundled: getNoSkills2()
|
|
98782
|
+
});
|
|
98400
98783
|
discoveredSkillsRef.current = skills;
|
|
98401
98784
|
} catch {
|
|
98402
98785
|
discoveredSkillsRef.current = [];
|
|
@@ -99783,7 +100166,7 @@ ${guidance}`);
|
|
|
99783
100166
|
}
|
|
99784
100167
|
if (!planFileExists()) {
|
|
99785
100168
|
const planFilePath = permissionMode2.getPlanFilePath();
|
|
99786
|
-
const plansDir =
|
|
100169
|
+
const plansDir = join30(homedir19(), ".letta", "plans");
|
|
99787
100170
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
99788
100171
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
99789
100172
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -100069,7 +100452,8 @@ Plan file path: ${planFilePath}`;
|
|
|
100069
100452
|
loadingState: "ready",
|
|
100070
100453
|
...item.snapshot
|
|
100071
100454
|
}, undefined, false, undefined, this) : item.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(UserMessage, {
|
|
100072
|
-
line: item
|
|
100455
|
+
line: item,
|
|
100456
|
+
prompt: statusLine.prompt
|
|
100073
100457
|
}, undefined, false, undefined, this) : item.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(ReasoningMessage, {
|
|
100074
100458
|
line: item
|
|
100075
100459
|
}, undefined, false, undefined, this) : item.kind === "assistant" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(AssistantMessage, {
|
|
@@ -100156,7 +100540,8 @@ Plan file path: ${planFilePath}`;
|
|
|
100156
100540
|
allowPersistence: currentApprovalContext?.allowPersistence ?? true,
|
|
100157
100541
|
showPreview: showApprovalPreview
|
|
100158
100542
|
}, undefined, false, undefined, this) : ln.kind === "user" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(UserMessage, {
|
|
100159
|
-
line: ln
|
|
100543
|
+
line: ln,
|
|
100544
|
+
prompt: statusLine.prompt
|
|
100160
100545
|
}, undefined, false, undefined, this) : ln.kind === "reasoning" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(ReasoningMessage, {
|
|
100161
100546
|
line: ln
|
|
100162
100547
|
}, undefined, false, undefined, this) : ln.kind === "assistant" ? /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(AssistantMessage, {
|
|
@@ -100337,7 +100722,8 @@ Plan file path: ${planFilePath}`;
|
|
|
100337
100722
|
shouldAnimate,
|
|
100338
100723
|
statusLineText: statusLine.text || undefined,
|
|
100339
100724
|
statusLineRight: statusLine.rightText || undefined,
|
|
100340
|
-
statusLinePadding: statusLine.padding || 0
|
|
100725
|
+
statusLinePadding: statusLine.padding || 0,
|
|
100726
|
+
statusLinePrompt: statusLine.prompt
|
|
100341
100727
|
}, undefined, false, undefined, this)
|
|
100342
100728
|
}, undefined, false, undefined, this),
|
|
100343
100729
|
activeOverlay === "model" && /* @__PURE__ */ jsx_dev_runtime70.jsxDEV(ModelSelector, {
|
|
@@ -100999,12 +101385,12 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
100999
101385
|
import {
|
|
101000
101386
|
copyFileSync as copyFileSync2,
|
|
101001
101387
|
existsSync as existsSync19,
|
|
101002
|
-
mkdirSync as
|
|
101388
|
+
mkdirSync as mkdirSync10,
|
|
101003
101389
|
readFileSync as readFileSync8,
|
|
101004
|
-
writeFileSync as
|
|
101390
|
+
writeFileSync as writeFileSync8
|
|
101005
101391
|
} from "node:fs";
|
|
101006
101392
|
import { homedir as homedir20, platform as platform5 } from "node:os";
|
|
101007
|
-
import { dirname as dirname13, join as
|
|
101393
|
+
import { dirname as dirname13, join as join31 } from "node:path";
|
|
101008
101394
|
function detectTerminalType2() {
|
|
101009
101395
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
101010
101396
|
return "cursor";
|
|
@@ -101036,16 +101422,16 @@ function getKeybindingsPath2(terminal) {
|
|
|
101036
101422
|
}[terminal];
|
|
101037
101423
|
const os6 = platform5();
|
|
101038
101424
|
if (os6 === "darwin") {
|
|
101039
|
-
return
|
|
101425
|
+
return join31(homedir20(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
101040
101426
|
}
|
|
101041
101427
|
if (os6 === "win32") {
|
|
101042
101428
|
const appData = process.env.APPDATA;
|
|
101043
101429
|
if (!appData)
|
|
101044
101430
|
return null;
|
|
101045
|
-
return
|
|
101431
|
+
return join31(appData, appName, "User", "keybindings.json");
|
|
101046
101432
|
}
|
|
101047
101433
|
if (os6 === "linux") {
|
|
101048
|
-
return
|
|
101434
|
+
return join31(homedir20(), ".config", appName, "User", "keybindings.json");
|
|
101049
101435
|
}
|
|
101050
101436
|
return null;
|
|
101051
101437
|
}
|
|
@@ -101097,7 +101483,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
101097
101483
|
}
|
|
101098
101484
|
const parentDir = dirname13(keybindingsPath);
|
|
101099
101485
|
if (!existsSync19(parentDir)) {
|
|
101100
|
-
|
|
101486
|
+
mkdirSync10(parentDir, { recursive: true });
|
|
101101
101487
|
}
|
|
101102
101488
|
let keybindings = [];
|
|
101103
101489
|
let backupPath = null;
|
|
@@ -101116,7 +101502,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
101116
101502
|
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
101117
101503
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
101118
101504
|
`;
|
|
101119
|
-
|
|
101505
|
+
writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
101120
101506
|
return {
|
|
101121
101507
|
success: true,
|
|
101122
101508
|
backupPath: backupPath ?? undefined
|
|
@@ -101145,7 +101531,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
101145
101531
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
101146
101532
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
101147
101533
|
`;
|
|
101148
|
-
|
|
101534
|
+
writeFileSync8(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
101149
101535
|
return { success: true };
|
|
101150
101536
|
} catch (error) {
|
|
101151
101537
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -101198,14 +101584,14 @@ function getWezTermConfigPath2() {
|
|
|
101198
101584
|
}
|
|
101199
101585
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
101200
101586
|
if (xdgConfig) {
|
|
101201
|
-
const xdgPath =
|
|
101587
|
+
const xdgPath = join31(xdgConfig, "wezterm", "wezterm.lua");
|
|
101202
101588
|
if (existsSync19(xdgPath))
|
|
101203
101589
|
return xdgPath;
|
|
101204
101590
|
}
|
|
101205
|
-
const configPath =
|
|
101591
|
+
const configPath = join31(homedir20(), ".config", "wezterm", "wezterm.lua");
|
|
101206
101592
|
if (existsSync19(configPath))
|
|
101207
101593
|
return configPath;
|
|
101208
|
-
return
|
|
101594
|
+
return join31(homedir20(), ".wezterm.lua");
|
|
101209
101595
|
}
|
|
101210
101596
|
function wezTermDeleteFixExists2(configPath) {
|
|
101211
101597
|
if (!existsSync19(configPath))
|
|
@@ -101256,9 +101642,9 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
101256
101642
|
}
|
|
101257
101643
|
const parentDir = dirname13(configPath);
|
|
101258
101644
|
if (!existsSync19(parentDir)) {
|
|
101259
|
-
|
|
101645
|
+
mkdirSync10(parentDir, { recursive: true });
|
|
101260
101646
|
}
|
|
101261
|
-
|
|
101647
|
+
writeFileSync8(configPath, content, { encoding: "utf-8" });
|
|
101262
101648
|
return {
|
|
101263
101649
|
success: true,
|
|
101264
101650
|
backupPath: backupPath ?? undefined
|
|
@@ -101304,9 +101690,9 @@ __export(exports_settings2, {
|
|
|
101304
101690
|
getSetting: () => getSetting2
|
|
101305
101691
|
});
|
|
101306
101692
|
import { homedir as homedir21 } from "node:os";
|
|
101307
|
-
import { join as
|
|
101693
|
+
import { join as join32 } from "node:path";
|
|
101308
101694
|
function getSettingsPath2() {
|
|
101309
|
-
return
|
|
101695
|
+
return join32(homedir21(), ".letta", "settings.json");
|
|
101310
101696
|
}
|
|
101311
101697
|
async function loadSettings2() {
|
|
101312
101698
|
const settingsPath = getSettingsPath2();
|
|
@@ -101343,7 +101729,7 @@ async function getSetting2(key) {
|
|
|
101343
101729
|
return settings[key];
|
|
101344
101730
|
}
|
|
101345
101731
|
function getProjectSettingsPath2() {
|
|
101346
|
-
return
|
|
101732
|
+
return join32(process.cwd(), ".letta", "settings.local.json");
|
|
101347
101733
|
}
|
|
101348
101734
|
async function loadProjectSettings2() {
|
|
101349
101735
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -101361,7 +101747,7 @@ async function loadProjectSettings2() {
|
|
|
101361
101747
|
}
|
|
101362
101748
|
async function saveProjectSettings2(settings) {
|
|
101363
101749
|
const settingsPath = getProjectSettingsPath2();
|
|
101364
|
-
const dirPath =
|
|
101750
|
+
const dirPath = join32(process.cwd(), ".letta");
|
|
101365
101751
|
try {
|
|
101366
101752
|
if (!exists(dirPath)) {
|
|
101367
101753
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -101623,7 +102009,7 @@ var init_defaults2 = __esm(async () => {
|
|
|
101623
102009
|
name: "Incognito",
|
|
101624
102010
|
description: INCOGNITO_DESCRIPTION2,
|
|
101625
102011
|
initBlocks: [],
|
|
101626
|
-
baseTools: ["web_search", "
|
|
102012
|
+
baseTools: ["web_search", "fetch_webpage"]
|
|
101627
102013
|
}
|
|
101628
102014
|
};
|
|
101629
102015
|
});
|
|
@@ -101741,6 +102127,8 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
101741
102127
|
} else {
|
|
101742
102128
|
systemPromptContent = await resolveSystemPrompt(options.systemPromptPreset);
|
|
101743
102129
|
}
|
|
102130
|
+
systemPromptContent = `${systemPromptContent}
|
|
102131
|
+
${SYSTEM_PROMPT_MEMORY_ADDON}`;
|
|
101744
102132
|
if (options.systemPromptAppend) {
|
|
101745
102133
|
systemPromptContent = `${systemPromptContent}
|
|
101746
102134
|
|
|
@@ -101751,6 +102139,9 @@ ${options.systemPromptAppend}`;
|
|
|
101751
102139
|
if (isSubagent) {
|
|
101752
102140
|
tags.push("role:subagent");
|
|
101753
102141
|
}
|
|
102142
|
+
if (options.tags && Array.isArray(options.tags)) {
|
|
102143
|
+
tags.push(...options.tags);
|
|
102144
|
+
}
|
|
101754
102145
|
const agentDescription = options.description ?? `Letta Code agent created in ${process.cwd()}`;
|
|
101755
102146
|
const agent = await client.agents.create({
|
|
101756
102147
|
agent_type: "letta_v1_agent",
|
|
@@ -101932,8 +102323,8 @@ function parseRegistryHandle2(handle) {
|
|
|
101932
102323
|
return { author: parts[0], name: parts[1] };
|
|
101933
102324
|
}
|
|
101934
102325
|
async function importAgentFromRegistry2(options) {
|
|
101935
|
-
const { tmpdir:
|
|
101936
|
-
const { join:
|
|
102326
|
+
const { tmpdir: tmpdir5 } = await import("node:os");
|
|
102327
|
+
const { join: join33 } = await import("node:path");
|
|
101937
102328
|
const { writeFile: writeFile5, unlink } = await import("node:fs/promises");
|
|
101938
102329
|
const { author, name } = parseRegistryHandle2(options.handle);
|
|
101939
102330
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -101945,7 +102336,7 @@ async function importAgentFromRegistry2(options) {
|
|
|
101945
102336
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
101946
102337
|
}
|
|
101947
102338
|
const afContent = await response.text();
|
|
101948
|
-
const tempPath =
|
|
102339
|
+
const tempPath = join33(tmpdir5(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
101949
102340
|
await writeFile5(tempPath, afContent, "utf-8");
|
|
101950
102341
|
try {
|
|
101951
102342
|
const result = await importAgentFromFile2({
|
|
@@ -102102,8 +102493,10 @@ async function updateAgentSystemPromptRaw2(agentId, systemPromptContent) {
|
|
|
102102
102493
|
}
|
|
102103
102494
|
async function updateAgentSystemPrompt2(agentId, systemPromptId) {
|
|
102104
102495
|
try {
|
|
102105
|
-
const { resolveSystemPrompt: resolveSystemPrompt3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
102106
|
-
const
|
|
102496
|
+
const { resolveSystemPrompt: resolveSystemPrompt3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
102497
|
+
const baseContent = await resolveSystemPrompt3(systemPromptId);
|
|
102498
|
+
const systemPromptContent = `${baseContent}
|
|
102499
|
+
${SYSTEM_PROMPT_MEMORY_ADDON3}`;
|
|
102107
102500
|
const updateResult = await updateAgentSystemPromptRaw2(agentId, systemPromptContent);
|
|
102108
102501
|
if (!updateResult.success) {
|
|
102109
102502
|
return {
|
|
@@ -102132,18 +102525,18 @@ async function updateAgentSystemPromptMemfs2(agentId, enableMemfs) {
|
|
|
102132
102525
|
const client = await getClient2();
|
|
102133
102526
|
const agent = await client.agents.retrieve(agentId);
|
|
102134
102527
|
let currentSystemPrompt = agent.system || "";
|
|
102135
|
-
const { SYSTEM_PROMPT_MEMFS_ADDON: SYSTEM_PROMPT_MEMFS_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
102136
|
-
const
|
|
102137
|
-
currentSystemPrompt = currentSystemPrompt.replace(
|
|
102138
|
-
|
|
102139
|
-
|
|
102140
|
-
|
|
102528
|
+
const { SYSTEM_PROMPT_MEMFS_ADDON: SYSTEM_PROMPT_MEMFS_ADDON3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
102529
|
+
const memoryHeaderRegex = /\n#{1,2} Memory\b[\s\S]*?(?=\n#{1,2} (?!Memory|Filesystem|Structure|How It Works|Syncing|History)[^\n]|$)/;
|
|
102530
|
+
currentSystemPrompt = currentSystemPrompt.replace(memoryHeaderRegex, "");
|
|
102531
|
+
const addon = enableMemfs ? SYSTEM_PROMPT_MEMFS_ADDON3 : SYSTEM_PROMPT_MEMORY_ADDON3;
|
|
102532
|
+
currentSystemPrompt = `${currentSystemPrompt}
|
|
102533
|
+
${addon}`;
|
|
102141
102534
|
await client.agents.update(agentId, {
|
|
102142
102535
|
system: currentSystemPrompt
|
|
102143
102536
|
});
|
|
102144
102537
|
return {
|
|
102145
102538
|
success: true,
|
|
102146
|
-
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to
|
|
102539
|
+
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to include standard Memory section"
|
|
102147
102540
|
};
|
|
102148
102541
|
} catch (error) {
|
|
102149
102542
|
return {
|
|
@@ -102160,488 +102553,136 @@ var init_modify2 = __esm(async () => {
|
|
|
102160
102553
|
]);
|
|
102161
102554
|
});
|
|
102162
102555
|
|
|
102163
|
-
// src/
|
|
102164
|
-
var
|
|
102165
|
-
__export(
|
|
102166
|
-
|
|
102167
|
-
|
|
102168
|
-
|
|
102169
|
-
|
|
102170
|
-
|
|
102171
|
-
|
|
102172
|
-
|
|
102173
|
-
|
|
102174
|
-
|
|
102175
|
-
|
|
102176
|
-
|
|
102177
|
-
|
|
102178
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
102179
|
-
include: ["agent.tools"]
|
|
102180
|
-
});
|
|
102181
|
-
const currentTools = agentWithTools.tools || [];
|
|
102182
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
102183
|
-
const hasAnyMemoryTool = mapByName.has("memory") || mapByName.has("memory_apply_patch");
|
|
102184
|
-
if (!hasAnyMemoryTool) {
|
|
102185
|
-
return;
|
|
102186
|
-
}
|
|
102187
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
102188
|
-
const otherMemoryTool = desiredMemoryTool === "memory" ? "memory_apply_patch" : "memory";
|
|
102189
|
-
let desiredId = mapByName.get(desiredMemoryTool);
|
|
102190
|
-
if (!desiredId) {
|
|
102191
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
102192
|
-
desiredId = resp.items[0]?.id;
|
|
102193
|
-
}
|
|
102194
|
-
if (!desiredId) {
|
|
102195
|
-
return;
|
|
102196
|
-
}
|
|
102197
|
-
const otherId = mapByName.get(otherMemoryTool);
|
|
102198
|
-
if (mapByName.has(desiredMemoryTool) && !otherId) {
|
|
102199
|
-
return;
|
|
102200
|
-
}
|
|
102201
|
-
const currentIds = currentTools.map((t) => t.id).filter((id) => typeof id === "string");
|
|
102202
|
-
const newIds = new Set(currentIds);
|
|
102203
|
-
if (otherId)
|
|
102204
|
-
newIds.delete(otherId);
|
|
102205
|
-
newIds.add(desiredId);
|
|
102206
|
-
const updatedRules = (agentWithTools.tool_rules || []).map((r) => r.tool_name === otherMemoryTool ? { ...r, tool_name: desiredMemoryTool } : r);
|
|
102207
|
-
await client.agents.update(agentId, {
|
|
102208
|
-
tool_ids: Array.from(newIds),
|
|
102209
|
-
tool_rules: updatedRules
|
|
102210
|
-
});
|
|
102211
|
-
} catch (err) {
|
|
102212
|
-
console.warn(`Warning: Failed to sync memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
102213
|
-
}
|
|
102214
|
-
}
|
|
102215
|
-
async function detachMemoryTools2(agentId) {
|
|
102216
|
-
const client = await getClient2();
|
|
102217
|
-
try {
|
|
102218
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
102219
|
-
include: ["agent.tools"]
|
|
102220
|
-
});
|
|
102221
|
-
const currentTools = agentWithTools.tools || [];
|
|
102222
|
-
let detachedAny = false;
|
|
102223
|
-
for (const tool of currentTools) {
|
|
102224
|
-
if (tool.name && MEMORY_TOOL_NAMES2.has(tool.name)) {
|
|
102225
|
-
if (tool.id) {
|
|
102226
|
-
await client.agents.tools.detach(tool.id, { agent_id: agentId });
|
|
102227
|
-
detachedAny = true;
|
|
102228
|
-
}
|
|
102229
|
-
}
|
|
102230
|
-
}
|
|
102231
|
-
return detachedAny;
|
|
102232
|
-
} catch (err) {
|
|
102233
|
-
console.warn(`Warning: Failed to detach memory tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
102234
|
-
return false;
|
|
102235
|
-
}
|
|
102236
|
-
}
|
|
102237
|
-
async function reattachMemoryTool2(agentId, modelIdentifier) {
|
|
102238
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
102239
|
-
const client = await getClient2();
|
|
102240
|
-
const shouldUsePatch = isOpenAIModel(resolvedModel);
|
|
102241
|
-
try {
|
|
102242
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
102243
|
-
include: ["agent.tools"]
|
|
102244
|
-
});
|
|
102245
|
-
const currentTools = agentWithTools.tools || [];
|
|
102246
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
102247
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
102248
|
-
if (mapByName.has(desiredMemoryTool)) {
|
|
102249
|
-
return;
|
|
102250
|
-
}
|
|
102251
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
102252
|
-
const toolId = resp.items[0]?.id;
|
|
102253
|
-
if (!toolId) {
|
|
102254
|
-
console.warn(`Memory tool "${desiredMemoryTool}" not found on server`);
|
|
102255
|
-
return;
|
|
102256
|
-
}
|
|
102257
|
-
await client.agents.tools.attach(toolId, { agent_id: agentId });
|
|
102258
|
-
} catch (err) {
|
|
102259
|
-
console.warn(`Warning: Failed to reattach memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
102260
|
-
}
|
|
102261
|
-
}
|
|
102262
|
-
async function forceToolsetSwitch2(toolsetName, agentId) {
|
|
102263
|
-
let modelForLoading;
|
|
102264
|
-
if (toolsetName === "none") {
|
|
102265
|
-
clearToolsWithLock();
|
|
102266
|
-
return;
|
|
102267
|
-
} else if (toolsetName === "codex") {
|
|
102268
|
-
await loadSpecificTools([...CODEX_TOOLS2]);
|
|
102269
|
-
modelForLoading = "openai/gpt-4";
|
|
102270
|
-
} else if (toolsetName === "codex_snake") {
|
|
102271
|
-
await loadTools("openai/gpt-4");
|
|
102272
|
-
modelForLoading = "openai/gpt-4";
|
|
102273
|
-
} else if (toolsetName === "gemini") {
|
|
102274
|
-
await loadSpecificTools([...GEMINI_TOOLS2]);
|
|
102275
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
102276
|
-
} else if (toolsetName === "gemini_snake") {
|
|
102277
|
-
await loadTools("google_ai/gemini-3-pro-preview");
|
|
102278
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
102279
|
-
} else {
|
|
102280
|
-
await loadTools("anthropic/claude-sonnet-4");
|
|
102281
|
-
modelForLoading = "anthropic/claude-sonnet-4";
|
|
102282
|
-
}
|
|
102283
|
-
const useMemoryPatch = toolsetName === "codex" || toolsetName === "codex_snake";
|
|
102284
|
-
await ensureCorrectMemoryTool2(agentId, modelForLoading, useMemoryPatch);
|
|
102285
|
-
}
|
|
102286
|
-
async function switchToolsetForModel2(modelIdentifier, agentId) {
|
|
102287
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
102288
|
-
await loadTools(resolvedModel);
|
|
102289
|
-
const loadedAfterPrimary = getToolNames().length;
|
|
102290
|
-
if (loadedAfterPrimary === 0 && !toolFilter.isActive()) {
|
|
102291
|
-
await loadTools();
|
|
102292
|
-
if (getToolNames().length === 0) {
|
|
102293
|
-
throw new Error(`Failed to load any Letta tools for model "${resolvedModel}".`);
|
|
102294
|
-
}
|
|
102295
|
-
}
|
|
102296
|
-
await ensureCorrectMemoryTool2(agentId, resolvedModel);
|
|
102297
|
-
const { isGeminiModel: isGeminiModel3 } = await init_manager3().then(() => exports_manager2);
|
|
102298
|
-
const toolsetName = isOpenAIModel(resolvedModel) ? "codex" : isGeminiModel3(resolvedModel) ? "gemini" : "default";
|
|
102299
|
-
return toolsetName;
|
|
102300
|
-
}
|
|
102301
|
-
var CODEX_TOOLS2, GEMINI_TOOLS2, MEMORY_TOOL_NAMES2;
|
|
102302
|
-
var init_toolset2 = __esm(async () => {
|
|
102303
|
-
init_model();
|
|
102304
|
-
init_filter();
|
|
102305
|
-
await __promiseAll([
|
|
102306
|
-
init_client2(),
|
|
102307
|
-
init_manager3()
|
|
102308
|
-
]);
|
|
102309
|
-
CODEX_TOOLS2 = OPENAI_PASCAL_TOOLS;
|
|
102310
|
-
GEMINI_TOOLS2 = GEMINI_PASCAL_TOOLS;
|
|
102311
|
-
MEMORY_TOOL_NAMES2 = new Set([
|
|
102312
|
-
"memory",
|
|
102313
|
-
"memory_apply_patch",
|
|
102314
|
-
"memory_insert",
|
|
102315
|
-
"memory_replace",
|
|
102316
|
-
"memory_rethink"
|
|
102317
|
-
]);
|
|
102318
|
-
});
|
|
102319
|
-
|
|
102320
|
-
// src/agent/memoryGit.ts
|
|
102321
|
-
var exports_memoryGit2 = {};
|
|
102322
|
-
__export(exports_memoryGit2, {
|
|
102323
|
-
removeGitMemoryTag: () => removeGitMemoryTag2,
|
|
102324
|
-
pullMemory: () => pullMemory2,
|
|
102325
|
-
isGitRepo: () => isGitRepo2,
|
|
102326
|
-
getMemoryRepoDir: () => getMemoryRepoDir2,
|
|
102327
|
-
getMemoryGitStatus: () => getMemoryGitStatus2,
|
|
102328
|
-
getAgentRootDir: () => getAgentRootDir2,
|
|
102329
|
-
cloneMemoryRepo: () => cloneMemoryRepo2,
|
|
102330
|
-
addGitMemoryTag: () => addGitMemoryTag2,
|
|
102331
|
-
PRE_COMMIT_HOOK_SCRIPT: () => PRE_COMMIT_HOOK_SCRIPT2
|
|
102332
|
-
});
|
|
102333
|
-
import { execFile as execFileCb2 } from "node:child_process";
|
|
102334
|
-
import {
|
|
102335
|
-
chmodSync as chmodSync2,
|
|
102336
|
-
existsSync as existsSync20,
|
|
102337
|
-
mkdirSync as mkdirSync10,
|
|
102338
|
-
renameSync as renameSync3,
|
|
102339
|
-
rmSync as rmSync3,
|
|
102340
|
-
writeFileSync as writeFileSync8
|
|
102341
|
-
} from "node:fs";
|
|
102556
|
+
// src/agent/memoryFilesystem.ts
|
|
102557
|
+
var exports_memoryFilesystem2 = {};
|
|
102558
|
+
__export(exports_memoryFilesystem2, {
|
|
102559
|
+
renderMemoryFilesystemTree: () => renderMemoryFilesystemTree2,
|
|
102560
|
+
labelFromRelativePath: () => labelFromRelativePath2,
|
|
102561
|
+
getMemorySystemDir: () => getMemorySystemDir2,
|
|
102562
|
+
getMemoryFilesystemRoot: () => getMemoryFilesystemRoot2,
|
|
102563
|
+
ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs2,
|
|
102564
|
+
applyMemfsFlags: () => applyMemfsFlags2,
|
|
102565
|
+
MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR2,
|
|
102566
|
+
MEMORY_FS_ROOT: () => MEMORY_FS_ROOT2,
|
|
102567
|
+
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
102568
|
+
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
102569
|
+
});
|
|
102570
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync11 } from "node:fs";
|
|
102342
102571
|
import { homedir as homedir22 } from "node:os";
|
|
102343
|
-
import { join as
|
|
102344
|
-
|
|
102345
|
-
|
|
102346
|
-
return join32(homedir22(), ".letta", "agents", agentId);
|
|
102572
|
+
import { join as join33 } from "node:path";
|
|
102573
|
+
function getMemoryFilesystemRoot2(agentId, homeDir = homedir22()) {
|
|
102574
|
+
return join33(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
102347
102575
|
}
|
|
102348
|
-
function
|
|
102349
|
-
return
|
|
102576
|
+
function getMemorySystemDir2(agentId, homeDir = homedir22()) {
|
|
102577
|
+
return join33(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
102350
102578
|
}
|
|
102351
|
-
function
|
|
102352
|
-
const
|
|
102353
|
-
|
|
102354
|
-
|
|
102355
|
-
|
|
102356
|
-
|
|
102357
|
-
|
|
102358
|
-
}
|
|
102359
|
-
async function runGit2(cwd2, args, token) {
|
|
102360
|
-
const authArgs = token ? [
|
|
102361
|
-
"-c",
|
|
102362
|
-
`http.extraHeader=Authorization: Basic ${Buffer.from(`letta:${token}`).toString("base64")}`
|
|
102363
|
-
] : [];
|
|
102364
|
-
const allArgs = [...authArgs, ...args];
|
|
102365
|
-
debugLog("memfs-git", `git ${args.join(" ")} (in ${cwd2})`);
|
|
102366
|
-
const result = await execFile9("git", allArgs, {
|
|
102367
|
-
cwd: cwd2,
|
|
102368
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
102369
|
-
timeout: 60000
|
|
102370
|
-
});
|
|
102371
|
-
return {
|
|
102372
|
-
stdout: result.stdout?.toString() ?? "",
|
|
102373
|
-
stderr: result.stderr?.toString() ?? ""
|
|
102374
|
-
};
|
|
102375
|
-
}
|
|
102376
|
-
async function configureLocalCredentialHelper2(dir, token) {
|
|
102377
|
-
const baseUrl = getServerUrl2();
|
|
102378
|
-
const helper = `!f() { echo "username=letta"; echo "password=${token}"; }; f`;
|
|
102379
|
-
await runGit2(dir, ["config", `credential.${baseUrl}.helper`, helper]);
|
|
102380
|
-
debugLog("memfs-git", "Configured local credential helper");
|
|
102381
|
-
}
|
|
102382
|
-
function installPreCommitHook2(dir) {
|
|
102383
|
-
const hooksDir = join32(dir, ".git", "hooks");
|
|
102384
|
-
const hookPath = join32(hooksDir, "pre-commit");
|
|
102385
|
-
if (!existsSync20(hooksDir)) {
|
|
102386
|
-
mkdirSync10(hooksDir, { recursive: true });
|
|
102579
|
+
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir22()) {
|
|
102580
|
+
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
102581
|
+
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
102582
|
+
if (!existsSync20(root)) {
|
|
102583
|
+
mkdirSync11(root, { recursive: true });
|
|
102584
|
+
}
|
|
102585
|
+
if (!existsSync20(systemDir)) {
|
|
102586
|
+
mkdirSync11(systemDir, { recursive: true });
|
|
102387
102587
|
}
|
|
102388
|
-
writeFileSync8(hookPath, PRE_COMMIT_HOOK_SCRIPT2, "utf-8");
|
|
102389
|
-
chmodSync2(hookPath, 493);
|
|
102390
|
-
debugLog("memfs-git", "Installed pre-commit hook");
|
|
102391
102588
|
}
|
|
102392
|
-
function
|
|
102393
|
-
|
|
102589
|
+
function labelFromRelativePath2(relativePath) {
|
|
102590
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
102591
|
+
return normalized.replace(/\.md$/, "");
|
|
102394
102592
|
}
|
|
102395
|
-
|
|
102396
|
-
const
|
|
102397
|
-
const
|
|
102398
|
-
const
|
|
102399
|
-
|
|
102400
|
-
|
|
102401
|
-
|
|
102402
|
-
|
|
102403
|
-
|
|
102404
|
-
|
|
102405
|
-
try {
|
|
102406
|
-
if (existsSync20(tmpDir)) {
|
|
102407
|
-
rmSync3(tmpDir, { recursive: true, force: true });
|
|
102593
|
+
function renderMemoryFilesystemTree2(systemLabels, detachedLabels) {
|
|
102594
|
+
const makeNode = () => ({ children: new Map, isFile: false });
|
|
102595
|
+
const root = makeNode();
|
|
102596
|
+
const insertPath = (base2, label) => {
|
|
102597
|
+
const parts = base2 ? [base2, ...label.split("/")] : label.split("/");
|
|
102598
|
+
let current = root;
|
|
102599
|
+
for (const [i, partName] of parts.entries()) {
|
|
102600
|
+
const part = i === parts.length - 1 ? `${partName}.md` : partName;
|
|
102601
|
+
if (!current.children.has(part)) {
|
|
102602
|
+
current.children.set(part, makeNode());
|
|
102408
102603
|
}
|
|
102409
|
-
|
|
102410
|
-
|
|
102411
|
-
|
|
102412
|
-
await runGit2(dir, ["checkout", "--", "."], token);
|
|
102413
|
-
debugLog("memfs-git", "Migrated existing memory directory to git repo");
|
|
102414
|
-
} finally {
|
|
102415
|
-
if (existsSync20(tmpDir)) {
|
|
102416
|
-
rmSync3(tmpDir, { recursive: true, force: true });
|
|
102604
|
+
current = current.children.get(part);
|
|
102605
|
+
if (i === parts.length - 1) {
|
|
102606
|
+
current.isFile = true;
|
|
102417
102607
|
}
|
|
102418
102608
|
}
|
|
102609
|
+
};
|
|
102610
|
+
for (const label of systemLabels) {
|
|
102611
|
+
insertPath(MEMORY_SYSTEM_DIR2, label);
|
|
102419
102612
|
}
|
|
102420
|
-
|
|
102421
|
-
|
|
102422
|
-
}
|
|
102423
|
-
async function pullMemory2(agentId) {
|
|
102424
|
-
const token = await getAuthToken2();
|
|
102425
|
-
const dir = getMemoryRepoDir2(agentId);
|
|
102426
|
-
await configureLocalCredentialHelper2(dir, token);
|
|
102427
|
-
installPreCommitHook2(dir);
|
|
102428
|
-
try {
|
|
102429
|
-
const { stdout, stderr } = await runGit2(dir, ["pull", "--ff-only"]);
|
|
102430
|
-
const output = stdout + stderr;
|
|
102431
|
-
const updated = !output.includes("Already up to date");
|
|
102432
|
-
return {
|
|
102433
|
-
updated,
|
|
102434
|
-
summary: updated ? output.trim() : "Already up to date"
|
|
102435
|
-
};
|
|
102436
|
-
} catch {
|
|
102437
|
-
debugWarn("memfs-git", "Fast-forward pull failed, trying rebase");
|
|
102438
|
-
try {
|
|
102439
|
-
const { stdout, stderr } = await runGit2(dir, ["pull", "--rebase"]);
|
|
102440
|
-
return { updated: true, summary: (stdout + stderr).trim() };
|
|
102441
|
-
} catch (rebaseErr) {
|
|
102442
|
-
const msg = rebaseErr instanceof Error ? rebaseErr.message : String(rebaseErr);
|
|
102443
|
-
debugWarn("memfs-git", `Pull failed: ${msg}`);
|
|
102444
|
-
return { updated: false, summary: `Pull failed: ${msg}` };
|
|
102445
|
-
}
|
|
102446
|
-
}
|
|
102447
|
-
}
|
|
102448
|
-
async function getMemoryGitStatus2(agentId) {
|
|
102449
|
-
const dir = getMemoryRepoDir2(agentId);
|
|
102450
|
-
const { stdout: statusOut } = await runGit2(dir, ["status", "--porcelain"]);
|
|
102451
|
-
const dirty = statusOut.trim().length > 0;
|
|
102452
|
-
let aheadOfRemote = false;
|
|
102453
|
-
try {
|
|
102454
|
-
const { stdout: revListOut } = await runGit2(dir, [
|
|
102455
|
-
"rev-list",
|
|
102456
|
-
"--count",
|
|
102457
|
-
"@{u}..HEAD"
|
|
102458
|
-
]);
|
|
102459
|
-
const aheadCount = parseInt(revListOut.trim(), 10);
|
|
102460
|
-
aheadOfRemote = aheadCount > 0;
|
|
102461
|
-
} catch {}
|
|
102462
|
-
const parts = [];
|
|
102463
|
-
if (dirty) {
|
|
102464
|
-
const changedFiles = statusOut.trim().split(`
|
|
102465
|
-
`).filter((l) => l.trim()).map((l) => l.trim());
|
|
102466
|
-
parts.push(`${changedFiles.length} uncommitted change(s)`);
|
|
102613
|
+
for (const label of detachedLabels) {
|
|
102614
|
+
insertPath(null, label);
|
|
102467
102615
|
}
|
|
102468
|
-
if (
|
|
102469
|
-
|
|
102616
|
+
if (!root.children.has(MEMORY_SYSTEM_DIR2)) {
|
|
102617
|
+
root.children.set(MEMORY_SYSTEM_DIR2, makeNode());
|
|
102470
102618
|
}
|
|
102471
|
-
|
|
102472
|
-
|
|
102473
|
-
|
|
102474
|
-
|
|
102619
|
+
const sortedEntries = (node) => {
|
|
102620
|
+
const entries = Array.from(node.children.entries());
|
|
102621
|
+
return entries.sort(([nameA, nodeA], [nameB, nodeB]) => {
|
|
102622
|
+
if (nodeA.isFile !== nodeB.isFile) {
|
|
102623
|
+
return nodeA.isFile ? 1 : -1;
|
|
102624
|
+
}
|
|
102625
|
+
return nameA.localeCompare(nameB);
|
|
102626
|
+
});
|
|
102475
102627
|
};
|
|
102628
|
+
const lines = ["/memory/"];
|
|
102629
|
+
const render2 = (node, prefix) => {
|
|
102630
|
+
const entries = sortedEntries(node);
|
|
102631
|
+
entries.forEach(([name, child], index) => {
|
|
102632
|
+
const isLast = index === entries.length - 1;
|
|
102633
|
+
const branch = isLast ? "└──" : "├──";
|
|
102634
|
+
lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
|
|
102635
|
+
if (child.children.size > 0) {
|
|
102636
|
+
const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
|
|
102637
|
+
render2(child, nextPrefix);
|
|
102638
|
+
}
|
|
102639
|
+
});
|
|
102640
|
+
};
|
|
102641
|
+
render2(root, "");
|
|
102642
|
+
return lines.join(`
|
|
102643
|
+
`);
|
|
102476
102644
|
}
|
|
102477
|
-
async function
|
|
102478
|
-
const
|
|
102479
|
-
|
|
102480
|
-
|
|
102481
|
-
const
|
|
102482
|
-
if (!
|
|
102483
|
-
|
|
102484
|
-
tags: [...tags, GIT_MEMORY_ENABLED_TAG2]
|
|
102485
|
-
});
|
|
102486
|
-
debugLog("memfs-git", `Added ${GIT_MEMORY_ENABLED_TAG2} tag`);
|
|
102645
|
+
async function applyMemfsFlags2(agentId, memfsFlag, noMemfsFlag, options) {
|
|
102646
|
+
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
102647
|
+
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
102648
|
+
if (memfsFlag) {
|
|
102649
|
+
const serverUrl = getServerUrl2();
|
|
102650
|
+
if (!serverUrl.includes("api.letta.com")) {
|
|
102651
|
+
throw new Error("--memfs is only available on Letta Cloud (api.letta.com).");
|
|
102487
102652
|
}
|
|
102488
|
-
|
|
102489
|
-
|
|
102653
|
+
settingsManager3.setMemfsEnabled(agentId, true);
|
|
102654
|
+
} else if (noMemfsFlag) {
|
|
102655
|
+
settingsManager3.setMemfsEnabled(agentId, false);
|
|
102490
102656
|
}
|
|
102491
|
-
|
|
102492
|
-
|
|
102493
|
-
|
|
102494
|
-
|
|
102495
|
-
|
|
102496
|
-
|
|
102497
|
-
|
|
102498
|
-
|
|
102499
|
-
|
|
102500
|
-
|
|
102501
|
-
|
|
102657
|
+
const isEnabled = settingsManager3.isMemfsEnabled(agentId);
|
|
102658
|
+
if (isEnabled && memfsFlag) {
|
|
102659
|
+
const { detachMemoryTools: detachMemoryTools2 } = await init_toolset().then(() => exports_toolset);
|
|
102660
|
+
await detachMemoryTools2(agentId);
|
|
102661
|
+
}
|
|
102662
|
+
if (memfsFlag || noMemfsFlag) {
|
|
102663
|
+
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs3 } = await init_modify().then(() => exports_modify);
|
|
102664
|
+
await updateAgentSystemPromptMemfs3(agentId, isEnabled);
|
|
102665
|
+
}
|
|
102666
|
+
let pullSummary;
|
|
102667
|
+
if (isEnabled) {
|
|
102668
|
+
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
102669
|
+
await addGitMemoryTag2(agentId);
|
|
102670
|
+
if (!isGitRepo2(agentId)) {
|
|
102671
|
+
await cloneMemoryRepo2(agentId);
|
|
102672
|
+
} else if (options?.pullOnExistingRepo) {
|
|
102673
|
+
const result = await pullMemory2(agentId);
|
|
102674
|
+
pullSummary = result.summary;
|
|
102502
102675
|
}
|
|
102503
|
-
} catch (err) {
|
|
102504
|
-
debugWarn("memfs-git", `Failed to remove git-memory tag: ${err instanceof Error ? err.message : String(err)}`);
|
|
102505
102676
|
}
|
|
102677
|
+
const action = memfsFlag ? "enabled" : noMemfsFlag ? "disabled" : "unchanged";
|
|
102678
|
+
return {
|
|
102679
|
+
action,
|
|
102680
|
+
memoryDir: isEnabled ? getMemoryFilesystemRoot2(agentId) : undefined,
|
|
102681
|
+
pullSummary
|
|
102682
|
+
};
|
|
102506
102683
|
}
|
|
102507
|
-
var
|
|
102508
|
-
|
|
102509
|
-
# Installed by Letta Code CLI
|
|
102510
|
-
|
|
102511
|
-
AGENT_EDITABLE_KEYS="description limit"
|
|
102512
|
-
PROTECTED_KEYS="read_only"
|
|
102513
|
-
ALL_KNOWN_KEYS="description limit read_only"
|
|
102514
|
-
errors=""
|
|
102515
|
-
|
|
102516
|
-
# Helper: extract a frontmatter value from content
|
|
102517
|
-
get_fm_value() {
|
|
102518
|
-
local content="$1" key="$2"
|
|
102519
|
-
local closing_line
|
|
102520
|
-
closing_line=$(echo "$content" | tail -n +2 | grep -n '^---$' | head -1 | cut -d: -f1)
|
|
102521
|
-
[ -z "$closing_line" ] && return
|
|
102522
|
-
echo "$content" | tail -n +2 | head -n $((closing_line - 1)) | grep "^$key:" | cut -d: -f2- | sed 's/^ *//;s/ *$//'
|
|
102523
|
-
}
|
|
102524
|
-
|
|
102525
|
-
for file in $(git diff --cached --name-only --diff-filter=ACM | grep '^memory/.*\\.md$'); do
|
|
102526
|
-
staged=$(git show ":$file")
|
|
102527
|
-
|
|
102528
|
-
# Frontmatter is required
|
|
102529
|
-
first_line=$(echo "$staged" | head -1)
|
|
102530
|
-
if [ "$first_line" != "---" ]; then
|
|
102531
|
-
errors="$errors\\n $file: missing frontmatter (must start with ---)"
|
|
102532
|
-
continue
|
|
102533
|
-
fi
|
|
102534
|
-
|
|
102535
|
-
# Check frontmatter is properly closed
|
|
102536
|
-
closing_line=$(echo "$staged" | tail -n +2 | grep -n '^---$' | head -1 | cut -d: -f1)
|
|
102537
|
-
if [ -z "$closing_line" ]; then
|
|
102538
|
-
errors="$errors\\n $file: frontmatter opened but never closed (missing closing ---)"
|
|
102539
|
-
continue
|
|
102540
|
-
fi
|
|
102541
|
-
|
|
102542
|
-
# Check read_only protection against HEAD version
|
|
102543
|
-
head_content=$(git show "HEAD:$file" 2>/dev/null || true)
|
|
102544
|
-
if [ -n "$head_content" ]; then
|
|
102545
|
-
head_ro=$(get_fm_value "$head_content" "read_only")
|
|
102546
|
-
if [ "$head_ro" = "true" ]; then
|
|
102547
|
-
errors="$errors\\n $file: file is read_only and cannot be modified"
|
|
102548
|
-
continue
|
|
102549
|
-
fi
|
|
102550
|
-
fi
|
|
102551
|
-
|
|
102552
|
-
# Extract frontmatter lines
|
|
102553
|
-
frontmatter=$(echo "$staged" | tail -n +2 | head -n $((closing_line - 1)))
|
|
102554
|
-
|
|
102555
|
-
# Track required fields
|
|
102556
|
-
has_description=false
|
|
102557
|
-
has_limit=false
|
|
102558
|
-
|
|
102559
|
-
# Validate each line
|
|
102560
|
-
while IFS= read -r line; do
|
|
102561
|
-
[ -z "$line" ] && continue
|
|
102562
|
-
|
|
102563
|
-
key=$(echo "$line" | cut -d: -f1 | tr -d ' ')
|
|
102564
|
-
value=$(echo "$line" | cut -d: -f2- | sed 's/^ *//;s/ *$//')
|
|
102565
|
-
|
|
102566
|
-
# Check key is known
|
|
102567
|
-
known=false
|
|
102568
|
-
for k in $ALL_KNOWN_KEYS; do
|
|
102569
|
-
if [ "$key" = "$k" ]; then
|
|
102570
|
-
known=true
|
|
102571
|
-
break
|
|
102572
|
-
fi
|
|
102573
|
-
done
|
|
102574
|
-
if [ "$known" = "false" ]; then
|
|
102575
|
-
errors="$errors\\n $file: unknown frontmatter key '$key' (allowed: $ALL_KNOWN_KEYS)"
|
|
102576
|
-
continue
|
|
102577
|
-
fi
|
|
102578
|
-
|
|
102579
|
-
# Check if agent is trying to modify a protected key
|
|
102580
|
-
for k in $PROTECTED_KEYS; do
|
|
102581
|
-
if [ "$key" = "$k" ]; then
|
|
102582
|
-
# Compare against HEAD — if value changed (or key was added), reject
|
|
102583
|
-
if [ -n "$head_content" ]; then
|
|
102584
|
-
head_val=$(get_fm_value "$head_content" "$key")
|
|
102585
|
-
if [ "$value" != "$head_val" ]; then
|
|
102586
|
-
errors="$errors\\n $file: '$key' is a protected field and cannot be changed by the agent"
|
|
102587
|
-
fi
|
|
102588
|
-
else
|
|
102589
|
-
# New file with read_only — agent shouldn't set this
|
|
102590
|
-
errors="$errors\\n $file: '$key' is a protected field and cannot be set by the agent"
|
|
102591
|
-
fi
|
|
102592
|
-
fi
|
|
102593
|
-
done
|
|
102594
|
-
|
|
102595
|
-
# Validate value types
|
|
102596
|
-
case "$key" in
|
|
102597
|
-
limit)
|
|
102598
|
-
has_limit=true
|
|
102599
|
-
if ! echo "$value" | grep -qE '^[0-9]+$' || [ "$value" = "0" ]; then
|
|
102600
|
-
errors="$errors\\n $file: 'limit' must be a positive integer, got '$value'"
|
|
102601
|
-
fi
|
|
102602
|
-
;;
|
|
102603
|
-
description)
|
|
102604
|
-
has_description=true
|
|
102605
|
-
if [ -z "$value" ]; then
|
|
102606
|
-
errors="$errors\\n $file: 'description' must not be empty"
|
|
102607
|
-
fi
|
|
102608
|
-
;;
|
|
102609
|
-
esac
|
|
102610
|
-
done <<< "$frontmatter"
|
|
102611
|
-
|
|
102612
|
-
# Check required fields
|
|
102613
|
-
if [ "$has_description" = "false" ]; then
|
|
102614
|
-
errors="$errors\\n $file: missing required field 'description'"
|
|
102615
|
-
fi
|
|
102616
|
-
if [ "$has_limit" = "false" ]; then
|
|
102617
|
-
errors="$errors\\n $file: missing required field 'limit'"
|
|
102618
|
-
fi
|
|
102619
|
-
|
|
102620
|
-
# Check if protected keys were removed (existed in HEAD but not in staged)
|
|
102621
|
-
if [ -n "$head_content" ]; then
|
|
102622
|
-
for k in $PROTECTED_KEYS; do
|
|
102623
|
-
head_val=$(get_fm_value "$head_content" "$k")
|
|
102624
|
-
if [ -n "$head_val" ]; then
|
|
102625
|
-
staged_val=$(get_fm_value "$staged" "$k")
|
|
102626
|
-
if [ -z "$staged_val" ]; then
|
|
102627
|
-
errors="$errors\\n $file: '$k' is a protected field and cannot be removed by the agent"
|
|
102628
|
-
fi
|
|
102629
|
-
fi
|
|
102630
|
-
done
|
|
102631
|
-
fi
|
|
102632
|
-
done
|
|
102633
|
-
|
|
102634
|
-
if [ -n "$errors" ]; then
|
|
102635
|
-
echo "Frontmatter validation failed:"
|
|
102636
|
-
echo -e "$errors"
|
|
102637
|
-
exit 1
|
|
102638
|
-
fi
|
|
102639
|
-
`;
|
|
102640
|
-
var init_memoryGit2 = __esm(async () => {
|
|
102641
|
-
init_debug();
|
|
102642
|
-
await init_client2();
|
|
102643
|
-
execFile9 = promisify10(execFileCb2);
|
|
102644
|
-
});
|
|
102684
|
+
var MEMORY_FS_ROOT2 = ".letta", MEMORY_FS_AGENTS_DIR2 = "agents", MEMORY_FS_MEMORY_DIR2 = "memory", MEMORY_SYSTEM_DIR2 = "system";
|
|
102685
|
+
var init_memoryFilesystem2 = () => {};
|
|
102645
102686
|
|
|
102646
102687
|
// src/index.ts
|
|
102647
102688
|
import { parseArgs as parseArgs6 } from "util";
|
|
@@ -102905,10 +102946,6 @@ init_oauth();
|
|
|
102905
102946
|
init_timing();
|
|
102906
102947
|
await init_settings_manager();
|
|
102907
102948
|
import { hostname } from "node:os";
|
|
102908
|
-
function getServerUrl() {
|
|
102909
|
-
const settings = settingsManager.getSettings();
|
|
102910
|
-
return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
102911
|
-
}
|
|
102912
102949
|
async function getClient() {
|
|
102913
102950
|
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
102914
102951
|
let apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
|
|
@@ -102958,15 +102995,17 @@ function getContext() {
|
|
|
102958
102995
|
global2[CONTEXT_KEY] = {
|
|
102959
102996
|
agentId: null,
|
|
102960
102997
|
skillsDirectory: null,
|
|
102998
|
+
noSkills: false,
|
|
102961
102999
|
conversationId: null
|
|
102962
103000
|
};
|
|
102963
103001
|
}
|
|
102964
103002
|
return global2[CONTEXT_KEY];
|
|
102965
103003
|
}
|
|
102966
103004
|
var context = getContext();
|
|
102967
|
-
function setAgentContext(agentId, skillsDirectory) {
|
|
103005
|
+
function setAgentContext(agentId, skillsDirectory, noSkills) {
|
|
102968
103006
|
context.agentId = agentId;
|
|
102969
103007
|
context.skillsDirectory = skillsDirectory || null;
|
|
103008
|
+
context.noSkills = noSkills ?? false;
|
|
102970
103009
|
}
|
|
102971
103010
|
function setConversationId(conversationId) {
|
|
102972
103011
|
context.conversationId = conversationId;
|
|
@@ -103043,8 +103082,9 @@ function extractUserMessagePreview(message) {
|
|
|
103043
103082
|
for (let i = content.length - 1;i >= 0; i--) {
|
|
103044
103083
|
const part = content[i];
|
|
103045
103084
|
if (part?.type === "text" && part.text) {
|
|
103046
|
-
if (part.text.startsWith(SYSTEM_REMINDER_OPEN))
|
|
103085
|
+
if (part.text.startsWith(SYSTEM_REMINDER_OPEN) || part.text.startsWith(SYSTEM_ALERT_OPEN)) {
|
|
103047
103086
|
continue;
|
|
103087
|
+
}
|
|
103048
103088
|
textToShow = part.text;
|
|
103049
103089
|
break;
|
|
103050
103090
|
}
|
|
@@ -106270,12 +106310,12 @@ EXAMPLES
|
|
|
106270
106310
|
console.log(usage);
|
|
106271
106311
|
}
|
|
106272
106312
|
async function printInfo() {
|
|
106273
|
-
const { join:
|
|
106313
|
+
const { join: join34 } = await import("path");
|
|
106274
106314
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
|
|
106275
106315
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
|
|
106276
106316
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
106277
106317
|
const cwd2 = process.cwd();
|
|
106278
|
-
const skillsDir =
|
|
106318
|
+
const skillsDir = join34(cwd2, SKILLS_DIR3);
|
|
106279
106319
|
const skillsExist = exists3(skillsDir);
|
|
106280
106320
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
106281
106321
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -106476,8 +106516,10 @@ Auto-update failed due to filesystem issue (ENOTEMPTY).`);
|
|
|
106476
106516
|
"pre-load-skills": { type: "string" },
|
|
106477
106517
|
"from-af": { type: "string" },
|
|
106478
106518
|
import: { type: "string" },
|
|
106519
|
+
tags: { type: "string" },
|
|
106479
106520
|
memfs: { type: "boolean" },
|
|
106480
106521
|
"no-memfs": { type: "boolean" },
|
|
106522
|
+
"no-skills": { type: "boolean" },
|
|
106481
106523
|
"max-turns": { type: "string" }
|
|
106482
106524
|
},
|
|
106483
106525
|
strict: true,
|
|
@@ -106556,6 +106598,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
106556
106598
|
const skillsDirectory = values.skills ?? undefined;
|
|
106557
106599
|
const memfsFlag = values.memfs;
|
|
106558
106600
|
const noMemfsFlag = values["no-memfs"];
|
|
106601
|
+
const noSkillsFlag = values["no-skills"];
|
|
106559
106602
|
const fromAfFile = values.import ?? values["from-af"];
|
|
106560
106603
|
const isHeadless = values.prompt || values.run || !process.stdin.isTTY;
|
|
106561
106604
|
if (command && !isHeadless) {
|
|
@@ -106821,7 +106864,7 @@ Error: ${message}`);
|
|
|
106821
106864
|
await loadTools2(modelForTools);
|
|
106822
106865
|
markMilestone2("TOOLS_LOADED");
|
|
106823
106866
|
const { handleHeadlessCommand: handleHeadlessCommand2 } = await init_headless().then(() => exports_headless);
|
|
106824
|
-
await handleHeadlessCommand2(process.argv, specifiedModel, skillsDirectory);
|
|
106867
|
+
await handleHeadlessCommand2(process.argv, specifiedModel, skillsDirectory, noSkillsFlag);
|
|
106825
106868
|
return;
|
|
106826
106869
|
}
|
|
106827
106870
|
markMilestone2("TUI_MODE_START");
|
|
@@ -107269,32 +107312,14 @@ Error: ${message}`);
|
|
|
107269
107312
|
}
|
|
107270
107313
|
} catch {}
|
|
107271
107314
|
}
|
|
107272
|
-
setAgentContext(agent.id, skillsDirectory2);
|
|
107315
|
+
setAgentContext(agent.id, skillsDirectory2, noSkillsFlag);
|
|
107273
107316
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
107274
|
-
|
|
107275
|
-
const
|
|
107276
|
-
|
|
107277
|
-
|
|
107278
|
-
|
|
107279
|
-
|
|
107280
|
-
settingsManager2.setMemfsEnabled(agent.id, true);
|
|
107281
|
-
} else if (noMemfsFlag) {
|
|
107282
|
-
settingsManager2.setMemfsEnabled(agent.id, false);
|
|
107283
|
-
}
|
|
107284
|
-
if (settingsManager2.isMemfsEnabled(agent.id) && memfsFlag) {
|
|
107285
|
-
const { detachMemoryTools: detachMemoryTools3 } = await init_toolset2().then(() => exports_toolset2);
|
|
107286
|
-
await detachMemoryTools3(agent.id);
|
|
107287
|
-
}
|
|
107288
|
-
if (memfsFlag || noMemfsFlag) {
|
|
107289
|
-
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs3 } = await init_modify2().then(() => exports_modify2);
|
|
107290
|
-
await updateAgentSystemPromptMemfs3(agent.id, settingsManager2.isMemfsEnabled(agent.id));
|
|
107291
|
-
}
|
|
107292
|
-
if (settingsManager2.isMemfsEnabled(agent.id)) {
|
|
107293
|
-
const { addGitMemoryTag: addGitMemoryTag3, isGitRepo: isGitRepo3, cloneMemoryRepo: cloneMemoryRepo3 } = await init_memoryGit2().then(() => exports_memoryGit2);
|
|
107294
|
-
await addGitMemoryTag3(agent.id);
|
|
107295
|
-
if (!isGitRepo3(agent.id)) {
|
|
107296
|
-
await cloneMemoryRepo3(agent.id);
|
|
107297
|
-
}
|
|
107317
|
+
try {
|
|
107318
|
+
const { applyMemfsFlags: applyMemfsFlags3 } = await Promise.resolve().then(() => (init_memoryFilesystem2(), exports_memoryFilesystem2));
|
|
107319
|
+
await applyMemfsFlags3(agent.id, memfsFlag, noMemfsFlag);
|
|
107320
|
+
} catch (error) {
|
|
107321
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
107322
|
+
process.exit(1);
|
|
107298
107323
|
}
|
|
107299
107324
|
const isResumingProject = !shouldCreateNew && !!resumingAgentId;
|
|
107300
107325
|
const isReusingExistingAgent = !shouldCreateNew && !fromAfFile2 && agent && agent.id;
|
|
@@ -107547,4 +107572,4 @@ Error during initialization: ${message}`);
|
|
|
107547
107572
|
}
|
|
107548
107573
|
main();
|
|
107549
107574
|
|
|
107550
|
-
//# debugId=
|
|
107575
|
+
//# debugId=90C1BD0F21F7961E64756E2164756E21
|