@letta-ai/letta-code 0.34.17 → 0.34.18
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/README.md +12 -0
- package/dist/agent-presets.js +5 -1
- package/dist/agent-presets.js.map +2 -2
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +2 -2
- package/dist/mcp-oauth.js.map +1 -1
- package/dist/types/agent/client-skills.d.ts.map +1 -1
- package/dist/types/agent/preloaded-skills.d.ts +4 -0
- package/dist/types/agent/preloaded-skills.d.ts.map +1 -0
- package/dist/types/agent/subagents/child-send-tracking.d.ts.map +1 -1
- package/dist/types/agent/subagents/index.d.ts.map +1 -1
- package/dist/types/agent/subagents/remote-turn-wait.d.ts.map +1 -1
- package/dist/types/agent/subagents/subagent-stream.d.ts.map +1 -1
- package/dist/types/auth/oauth.d.ts +8 -1
- package/dist/types/auth/oauth.d.ts.map +1 -1
- package/dist/types/backend/api/conversation-enqueue.d.ts +4 -1
- package/dist/types/backend/api/conversation-enqueue.d.ts.map +1 -1
- package/dist/types/headless-listener-launch.d.ts +5 -3
- package/dist/types/headless-listener-launch.d.ts.map +1 -1
- package/dist/types/headless-super-run-wait.d.ts +1 -1
- package/dist/types/headless-super-run-wait.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts +1 -0
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/task-stop.d.ts.map +1 -1
- package/dist/types/tools/impl/workflow.d.ts +5 -0
- package/dist/types/tools/impl/workflow.d.ts.map +1 -1
- package/dist/types/tools/workflow/sdk-spawner.d.ts.map +1 -1
- package/dist/types/tools/workflow/types.d.ts +2 -0
- package/dist/types/tools/workflow/types.d.ts.map +1 -1
- package/letta.js +355 -412
- package/npm-shrinkwrap.json +86 -86
- package/package.json +2 -2
- package/scripts/source-file-size-baseline.json +1 -1
- package/skills/maintaining-core-memory/SKILL.md +101 -0
- package/skills/maintaining-deferred-memory/SKILL.md +84 -0
- package/skills/workflow-authoring/SKILL.md +3 -1
package/letta.js
CHANGED
|
@@ -3411,6 +3411,7 @@ __export(exports_oauth, {
|
|
|
3411
3411
|
validateCredentialsWithResult: () => validateCredentialsWithResult,
|
|
3412
3412
|
validateCredentials: () => validateCredentials,
|
|
3413
3413
|
revokeToken: () => revokeToken,
|
|
3414
|
+
resolveAuthBaseUrl: () => resolveAuthBaseUrl,
|
|
3414
3415
|
requestDeviceCode: () => requestDeviceCode2,
|
|
3415
3416
|
refreshAccessToken: () => refreshAccessToken3,
|
|
3416
3417
|
pollForToken: () => pollForToken2,
|
|
@@ -3418,6 +3419,28 @@ __export(exports_oauth, {
|
|
|
3418
3419
|
OAUTH_CONFIG: () => OAUTH_CONFIG,
|
|
3419
3420
|
LETTA_CLOUD_API_URL: () => LETTA_CLOUD_API_URL
|
|
3420
3421
|
});
|
|
3422
|
+
function resolveAuthBaseUrl() {
|
|
3423
|
+
const override = process.env.LETTA_AUTH_BASE_URL?.trim();
|
|
3424
|
+
if (!override) {
|
|
3425
|
+
return DEFAULT_AUTH_BASE_URL;
|
|
3426
|
+
}
|
|
3427
|
+
let warning = null;
|
|
3428
|
+
try {
|
|
3429
|
+
const url = new URL(override);
|
|
3430
|
+
const isLocalhost = url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
|
3431
|
+
if (url.protocol === "https:" || url.protocol === "http:" && isLocalhost) {
|
|
3432
|
+
return url.origin;
|
|
3433
|
+
}
|
|
3434
|
+
warning = "must be an https origin (http is allowed for localhost)";
|
|
3435
|
+
} catch {
|
|
3436
|
+
warning = "is not a valid URL";
|
|
3437
|
+
}
|
|
3438
|
+
if (!hasWarnedAboutInvalidAuthBaseUrl) {
|
|
3439
|
+
hasWarnedAboutInvalidAuthBaseUrl = true;
|
|
3440
|
+
console.warn(`Ignoring invalid LETTA_AUTH_BASE_URL (${JSON.stringify(override)}): ${warning}. Falling back to ${DEFAULT_AUTH_BASE_URL}.`);
|
|
3441
|
+
}
|
|
3442
|
+
return DEFAULT_AUTH_BASE_URL;
|
|
3443
|
+
}
|
|
3421
3444
|
function getOAuthAuthHost() {
|
|
3422
3445
|
try {
|
|
3423
3446
|
return new URL(OAUTH_CONFIG.authBaseUrl).host;
|
|
@@ -3776,7 +3799,7 @@ function classifyCredentialValidationError(error) {
|
|
|
3776
3799
|
}
|
|
3777
3800
|
return { ok: false, reason: "unknown", message };
|
|
3778
3801
|
}
|
|
3779
|
-
var LETTA_CLOUD_API_URL = "https://api.letta.com", OAUTH_CONFIG, OAuthRefreshError, DEVICE_CODE_REQUEST_MAX_ATTEMPTS = 2, DEVICE_CODE_RETRY_DELAY_MS = 100, TOKEN_POLL_RESPONSE_FAILURE_LIMIT = 2, OAUTH_REQUEST_ID_HEADERS, OAuthTransientResponseError;
|
|
3802
|
+
var LETTA_CLOUD_API_URL = "https://api.letta.com", DEFAULT_AUTH_BASE_URL = "https://app.letta.com", hasWarnedAboutInvalidAuthBaseUrl = false, OAUTH_CONFIG, OAuthRefreshError, DEVICE_CODE_REQUEST_MAX_ATTEMPTS = 2, DEVICE_CODE_RETRY_DELAY_MS = 100, TOKEN_POLL_RESPONSE_FAILURE_LIMIT = 2, OAUTH_REQUEST_ID_HEADERS, OAuthTransientResponseError;
|
|
3780
3803
|
var init_oauth = __esm(() => {
|
|
3781
3804
|
init_letta_client();
|
|
3782
3805
|
init_error();
|
|
@@ -3784,7 +3807,9 @@ var init_oauth = __esm(() => {
|
|
|
3784
3807
|
OAUTH_CONFIG = {
|
|
3785
3808
|
clientId: "ci-let-724dea7e98f4af6f8f370f4b1466200c",
|
|
3786
3809
|
clientSecret: "",
|
|
3787
|
-
authBaseUrl
|
|
3810
|
+
get authBaseUrl() {
|
|
3811
|
+
return resolveAuthBaseUrl();
|
|
3812
|
+
},
|
|
3788
3813
|
apiBaseUrl: LETTA_CLOUD_API_URL
|
|
3789
3814
|
};
|
|
3790
3815
|
OAuthRefreshError = class OAuthRefreshError extends Error {
|
|
@@ -5916,7 +5941,7 @@ var package_default;
|
|
|
5916
5941
|
var init_package = __esm(() => {
|
|
5917
5942
|
package_default = {
|
|
5918
5943
|
name: "@letta-ai/letta-code",
|
|
5919
|
-
version: "0.34.
|
|
5944
|
+
version: "0.34.18",
|
|
5920
5945
|
lettaStartupLogProtocol: 1,
|
|
5921
5946
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5922
5947
|
type: "module",
|
|
@@ -6191,7 +6216,7 @@ var init_package = __esm(() => {
|
|
|
6191
6216
|
},
|
|
6192
6217
|
lettaLifecycleProtocol: 1,
|
|
6193
6218
|
lettaRuntimeGraphProtocol: 1,
|
|
6194
|
-
lettaRuntimeGraphSha512: "sha512-
|
|
6219
|
+
lettaRuntimeGraphSha512: "sha512-cubBaizY8rbgiq9dfHU/uRyZBgkGvLfJc+8+ovpV1raZnQjE+tRsAKFAKP69UHWhNFRE49viVTyqmLIiSK8v8Q=="
|
|
6195
6220
|
};
|
|
6196
6221
|
});
|
|
6197
6222
|
|
|
@@ -99266,6 +99291,8 @@ You may also have access to shared memory: memory created independently of any s
|
|
|
99266
99291
|
|
|
99267
99292
|
Unlike the rest of your external memory, shared memory is not scoped to *you* specifically (since it may be attached to multiple agents at the same time), so each shared memory repository will have a different local projection root and remote git origin.
|
|
99268
99293
|
|
|
99294
|
+
Attached shared-memory mounts are shallow checkouts containing only the latest commit. If you need past history, run \`git fetch --deepen=<n>\` or \`git fetch --unshallow\` inside the mount only when needed, since some repositories have very long histories.
|
|
99295
|
+
|
|
99269
99296
|
Commit intended changes inside read/write attached shared-memory repositories. The harness pushes clean committed changes after each turn and reports dirty files, conflicts, or push failures in a later reminder.
|
|
99270
99297
|
|
|
99271
99298
|
### Syncing memory, state, and context
|
|
@@ -99823,6 +99850,8 @@ You may also have access to shared memory: memory created independently of any s
|
|
|
99823
99850
|
|
|
99824
99851
|
Unlike the rest of your external memory, shared memory is not scoped to *you* specifically (since it may be attached to multiple agents at the same time), so each shared memory repository will have a different local projection root and remote git origin.
|
|
99825
99852
|
|
|
99853
|
+
Attached shared-memory mounts are shallow checkouts containing only the latest commit. If you need past history, run \`git fetch --deepen=<n>\` or \`git fetch --unshallow\` inside the mount only when needed, since some repositories have very long histories.
|
|
99854
|
+
|
|
99826
99855
|
Commit intended changes inside read/write attached shared-memory repositories. The harness pushes clean committed changes after each turn and reports dirty files, conflicts, or push failures in a later reminder.
|
|
99827
99856
|
|
|
99828
99857
|
### Syncing memory, state, and context
|
|
@@ -103471,7 +103500,7 @@ async function syncRepoMount(args) {
|
|
|
103471
103500
|
await withRepositoryCheckout(args.directory, async (directory, fresh) => {
|
|
103472
103501
|
args = { ...args, publishedDirectory: args.directory, directory };
|
|
103473
103502
|
if (fresh) {
|
|
103474
|
-
await runGitWithRetry(directory, ["clone", args.remoteUrl, "."], args.token, {
|
|
103503
|
+
await runGitWithRetry(directory, ["clone", "--depth", "1", args.remoteUrl, "."], args.token, {
|
|
103475
103504
|
operation: `clone repository ${args.repositoryName}`,
|
|
103476
103505
|
timeoutMs: GIT_CLONE_TIMEOUT_MS
|
|
103477
103506
|
});
|
|
@@ -106605,34 +106634,29 @@ name: memory
|
|
|
106605
106634
|
description: Background memory upkeep during another task; when memory is the user's main request, edit it directly instead. Runs silently with no notification or result, so continue immediately. Make the assignment self-contained and quote the user's corrections and exceptions verbatim.
|
|
106606
106635
|
tools: Bash, Read, Edit, Write
|
|
106607
106636
|
model: inherit
|
|
106608
|
-
skills: creating-skills
|
|
106637
|
+
skills: creating-skills, maintaining-core-memory, maintaining-deferred-memory
|
|
106609
106638
|
fork: false
|
|
106610
106639
|
launchProfile: memory-subagent
|
|
106611
106640
|
---
|
|
106612
106641
|
|
|
106613
|
-
You are
|
|
106614
|
-
|
|
106615
|
-
Your tools are Bash, Read, Edit, and Write. Your working memory repository is \`$MEMORY_DIR\`; the assignment also gives the exact path. For a memory update it is a private worktree of the agent's memory: the harness merges your commits into the main checkout when you finish, and anything left uncommitted is discarded. For a Git repair it is the checkout itself. Read current files before editing; memory may have changed since the assignment. Keep all writes inside this repository. Do not modify git configuration or hook files.
|
|
106616
|
-
|
|
106617
|
-
## Updating memory
|
|
106618
|
-
|
|
106619
|
-
Capture the requested facts, preferences, corrections, or deletions. Use the assignment directly when it is sufficient. Consult the parent transcript only for a specific missing fact or ambiguity; do not read it for general orientation. Preserve the exact scope of facts and exceptions without adding inferred preferences. Keep quoted factual corrections and constraints verbatim rather than generalizing them. Update existing entries rather than duplicating them, and replace stale information at its source. Preserve unrelated content and established identity. Do not store secrets or ephemeral task logs. Update indexes when adding, moving, or deleting files.
|
|
106620
|
-
|
|
106621
|
-
Make focused edits. Reorganize or defragment memory only when explicitly requested. Do not perform transcript reflection or unrelated skill maintenance. For requested skill changes, apply the preloaded \`creating-skills\` guidance in \`$MEMORY_DIR/skills/\`; maintain skills in place rather than packaging them for distribution.
|
|
106642
|
+
You are a background memory subagent. Make the memory change in the assignment below, following the preloaded skills; consult the parent transcript only for a specific missing fact or ambiguity.
|
|
106622
106643
|
|
|
106623
106644
|
## Git
|
|
106624
106645
|
|
|
106625
|
-
|
|
106626
|
-
|
|
106627
|
-
For a repair-only request, stop after repairing the reported Git or validation state; if it has already been resolved, make no changes.
|
|
106646
|
+
\`$MEMORY_DIR\` is a private worktree of the agent's memory. The harness merges your commits into the main checkout when you finish and handles sync, so commit but do not push; uncommitted edits are discarded. If a merge or rebase is already in progress, resolve it by reading both sides and preserving the intended memory, then finish the operation; do not abort, reset, stash, or amend.
|
|
106628
106647
|
|
|
106629
|
-
|
|
106648
|
+
Stage only the files you changed, by explicit path, and commit them in one call:
|
|
106630
106649
|
|
|
106631
|
-
|
|
106650
|
+
\`\`\`bash
|
|
106651
|
+
cd "$MEMORY_DIR"
|
|
106652
|
+
git add <file>...
|
|
106653
|
+
git commit -m "<type>(memory): <summary>
|
|
106632
106654
|
|
|
106633
|
-
|
|
106655
|
+
Updates:
|
|
106656
|
+
- <what changed and why>"
|
|
106657
|
+
\`\`\`
|
|
106634
106658
|
|
|
106635
|
-
|
|
106659
|
+
\`<type>\` is \`fix\` for correcting wrong or stale memory, \`feat\` for new memory, and \`chore\` for reorganization or minor edits. Do not change git configuration or bypass hooks; if the commit fails, report the failure rather than claiming success.
|
|
106636
106660
|
`;
|
|
106637
106661
|
var init_memory_v2 = () => {};
|
|
106638
106662
|
|
|
@@ -106862,121 +106886,28 @@ name: reflection
|
|
|
106862
106886
|
description: Background agent that reflects on recent conversations to update memory and maintain skills
|
|
106863
106887
|
tools: Bash, Edit
|
|
106864
106888
|
model: inherit
|
|
106865
|
-
skills: creating-skills
|
|
106889
|
+
skills: creating-skills, maintaining-core-memory, maintaining-deferred-memory
|
|
106866
106890
|
launchProfile: memory-subagent
|
|
106867
106891
|
---
|
|
106892
|
+
You are a reflection subagent tasked with improving a primary agent's capabilities and knowledge to perform better on future tasks.
|
|
106893
|
+
Using recent conversation transcripts, identify potential repeatable workflows (which can be converted into skills), behavior failures (which require updates to prompts), and general information and knowledge.
|
|
106894
|
+
The primary agent's context (prompts, skills, and deferred memory) is stored in $MEMORY_DIR, which contains the "Memory Filesystem" of the primary agent.
|
|
106895
|
+
Read through the transcript to identify and make updates to memory. You run autonomously and return a single final report when done. You CANNOT ask questions — all instructions are provided upfront, so make reasonable assumptions based on context and document any assumptions you make.
|
|
106868
106896
|
|
|
106869
|
-
You are
|
|
106870
|
-
|
|
106871
|
-
**You are NOT the primary agent.** You are reviewing conversations that already happened:
|
|
106872
|
-
- "system" messages are the primary agent's system prompt — use them only to understand the agent's identity and what's relevant to the user. They are not something you edit directly; memory edits flow through files in \`$MEMORY_DIR\`.
|
|
106873
|
-
- "assistant" messages are from the primary agent
|
|
106874
|
-
- "user" messages are from the primary agent's user
|
|
106875
|
-
|
|
106876
|
-
Your job is to turn lasting learnings from those conversations into changes to the primary agent's memory filesystem: memory edits for facts, preferences, and corrections, and — only when a reusable procedure appears — skill changes. Then commit them.
|
|
106877
|
-
|
|
106878
|
-
## The Memory Filesystem
|
|
106879
|
-
|
|
106880
|
-
The primary agent's context (its prompts, skills, and external memory files) is stored in a git-backed "memory filesystem" rooted at \`$MEMORY_DIR\`. Committed changes are reflected in the primary agent's context. Every piece of memory lives in one of three tiers, and the tier decides when the agent sees it and how it should be written:
|
|
106881
|
-
|
|
106882
|
-
| | **Root files** | **Deferred memory** | **Skills** |
|
|
106883
|
-
|---|---|---|---|
|
|
106884
|
-
| **Location** | Markdown files directly in \`$MEMORY_DIR\` | Directories under \`$MEMORY_DIR\` (other than \`skills/\`) | \`$MEMORY_DIR/skills/<name>/\` |
|
|
106885
|
-
| **When the agent sees it** | Every turn, in full — part of the system prompt | Only when the agent opens the directory with \`Memory(<dir>)\` or reads a file | Name and description every turn; the body only when the agent loads the skill |
|
|
106886
|
-
| **Cost** | Paid on every turn | Paid only when opened | Description on every turn; body only when loaded |
|
|
106887
|
-
| **What belongs here** | Identity, standing instructions, and facts that matter on every turn; the root \`MEMORY.md\` index of deferred memory | Knowledge about a subject (a person, project, repo, system, or incident) that the agent looks up when that subject comes up | Procedures with a clear "use when" trigger — usually a repeatable, multi-step workflow |
|
|
106888
|
-
| **Written as** | Instructions to the agent | Reference notes: instructions about the subject first, then facts | A procedure: steps, exact commands, pitfalls |
|
|
106889
|
-
| **Description says** | What belongs in the file | What the memory is *about* | What the skill does (third person) and when to use it |
|
|
106890
|
-
|
|
106891
|
-
### Choosing a tier
|
|
106892
|
-
|
|
106893
|
-
Decide placement for each learning in this order:
|
|
106894
|
-
|
|
106895
|
-
1. **Should it change how the agent behaves or what it knows on every turn?** Put it in a root file, written as an instruction. Root is expensive, so this bar is high.
|
|
106896
|
-
2. **Can you write a clear "Use when the user wants to …" trigger for it, and is it a procedure?** Make it a skill (see "Skills" below for when a skill is warranted).
|
|
106897
|
-
3. **Otherwise it is knowledge about a subject.** Put it in deferred memory, in the directory for that subject.
|
|
106898
|
-
|
|
106899
|
-
One-off task state belongs nowhere.
|
|
106900
|
-
|
|
106901
|
-
### Root files
|
|
106902
|
-
|
|
106903
|
-
Root Markdown files are part of the primary agent's system prompt: always in context and visible to the agent. Use them to define the core behavior of the agent: what it always knows, and the prompting that controls how it behaves.
|
|
106904
|
-
|
|
106905
|
-
Writing root files:
|
|
106906
|
-
* Write instructions, not explicit feedback. User or environment feedback tells you how the agent's behavior or knowledge should change. Write a prompt to affect this change, rather than simply recording the feedback.
|
|
106907
|
-
* Leave out the evidence or context for the edit. All context modifications are git-tracked with commit messages, so do not require an explanation for why an edit was made within the edit or details about the context under which the edit was made.
|
|
106908
|
-
* Minimize bloat. Too many tokens can distract agents and add cost to every turn. Instructions that are only needed sometimes belong in a skill (if a trigger can be defined) or in deferred memory.
|
|
106909
|
-
* Root files that define the agent's identity and behavior (such as \`persona.md\`) are load-bearing. Edit them surgically — append, modify specific entries, adjust wording. Never rewrite them wholesale or silently overwrite established identity.
|
|
106897
|
+
You are not the primary agent and do not reply to anyone. In the transcript, "assistant" messages are the primary agent, "user" messages are its user, and "system" messages are its system prompt, compiled from the memory files you edit.
|
|
106910
106898
|
|
|
106911
|
-
|
|
106912
|
-
|
|
106913
|
-
\`\`\`
|
|
106914
|
-
- [letta-code/](letta-code/MEMORY.md) — repo conventions, CI, release process. Open before working in letta-code.
|
|
106915
|
-
\`\`\`
|
|
106916
|
-
|
|
106917
|
-
This is where "when to use" belongs for deferred memory — in the parent's link, not in the memory's own description.
|
|
106918
|
-
|
|
106919
|
-
### Deferred memory
|
|
106920
|
-
|
|
106921
|
-
Directories contain *deferred memory*. Higher directory levels hold memory that is accessed more often; more deeply nested directories hold memory needed less often. Place related memory in the same directory so it can be loaded together. Each directory has a \`MEMORY.md\`, which is the directory's top level: when the primary agent calls \`Memory(<dir>)\`, it reads \`<dir>/MEMORY.md\` in full, plus a listing of the directory's other entries (each file's \`description\` and the first paragraph of each subdirectory's \`MEMORY.md\`). The listing shows at most 10 entries, most recently edited first. The agent can also read files directly with other tools.
|
|
106922
|
-
|
|
106923
|
-
Decide what goes in a \`MEMORY.md\` by what the agent should get from opening that directory:
|
|
106924
|
-
* **Small topic: put everything in \`MEMORY.md\`.** If the whole topic fits comfortably (well under 20,000 characters) and most of it is useful whenever the topic comes up, keep it in \`MEMORY.md\` with no other files. Splitting adds reads without saving context.
|
|
106925
|
-
* **Large topic, or one rarely needed in full: \`MEMORY.md\` holds what is needed every time, plus a map.** Keep only what the agent needs whenever it opens the directory, and defer the rest into files, or into subdirectories when a subtopic is itself large. \`MEMORY.md\` must then tell the agent where to go next, or that it can stop: say what each deferred file or subdirectory covers and when it is worth opening, using ordinary relative Markdown links. Do not rely on the listing, since it shows only the 10 most recently edited entries and stable files fall out of it.
|
|
106926
|
-
* **Either way, start \`MEMORY.md\` with a short plain-prose paragraph stating the directory's scope.** That paragraph is what the parent directory's listing shows, so do not open with a heading or a list.
|
|
106927
|
-
* Aim for fewer than 10 entries (files plus subdirectories) per directory so the listing stays complete; group related files into subdirectories only within the configured \`maxDepth\` (see below). At the depth limit, use clearly scoped sibling files and explicit links in \`MEMORY.md\`, or reorganize topics into shallower directories. The depth limit takes precedence over the fewer-than-10-entries guideline.
|
|
106928
|
-
|
|
106929
|
-
Writing deferred memory contents (in \`MEMORY.md\` and in other files):
|
|
106930
|
-
* **One subject per file**, named the way a future request would name it. If two files cover the same subject, merge them.
|
|
106931
|
-
* **Instructions first, then facts.** The agent opens deferred memory because it is about to act on that subject, so lead with what it should do differently — conventions, gotchas, things to avoid — written as instructions, like root files. Background facts follow.
|
|
106932
|
-
* **Make each statement stand alone.** Name the subject ("The letta-code release workflow …") rather than "it" or "the repo"; the agent may read only part of a file.
|
|
106933
|
-
* **Organize by topic under stable headings, not as a dated log.** Record the current state and fix contradictions in place. Use absolute dates only for facts that are genuinely time-bound.
|
|
106934
|
-
* **Leave out evidence and history**, as with root files. Git keeps it.
|
|
106935
|
-
|
|
106936
|
-
Writing memory descriptions (every deferred file other than \`MEMORY.md\`):
|
|
106937
|
-
* Describe what the memory is *about*, not when to use it. Lead with the subject (a person, project, repo, system, or incident) using the names a future request would mention, then the subtopics it covers.
|
|
106938
|
-
* If you can write a clear "use when the user wants to…" trigger, the content is procedural and belongs in a skill.
|
|
106939
|
-
* Make siblings distinguishable by subject; if two files cover the same subject, merge them.
|
|
106940
|
-
* Describe scope, not current contents: no entry lists, dates, status, or why the file was created.
|
|
106941
|
-
|
|
106942
|
-
### Skills
|
|
106943
|
-
|
|
106944
|
-
The \`skills/\` folder contains skills (folders which adhere to the skills specification). Skills are loaded by the primary agent with a \`Skill\` tool. Skill names and descriptions are automatically provided to the agent in context, so skills do not need to be indexed by \`MEMORY.md\` unless they relate to a specific memory.
|
|
106945
|
-
|
|
106946
|
-
Skills are not the default. A one-off task, a fact, or a preference belongs in memory, not a skill. Use a skill only when the conversation reveals a repeatable procedure that clearly generalizes beyond this session and has a trigger you can state.
|
|
106947
|
-
|
|
106948
|
-
Apply the preloaded \`creating-skills\` guidance to skills in \`$MEMORY_DIR/skills/\`; maintain them in place rather than packaging them for distribution.
|
|
106949
|
-
|
|
106950
|
-
### Frontmatter, size, and nesting limits
|
|
106951
|
-
|
|
106952
|
-
* \`MEMORY.md\` files (root and child) have no frontmatter.
|
|
106953
|
-
* Every other memory Markdown file has exactly \`name\` and \`description\` frontmatter; the memory repo's pre-commit check rejects missing or extra keys.
|
|
106954
|
-
* \`SKILL.md\` files are exempt from that check and follow the preloaded \`creating-skills\` guidance instead.
|
|
106955
|
-
* By default the memory repo's pre-commit check blocks any memory file over 20,000 characters and root Markdown totaling over 65,536 characters (\`.memfs.config.json\` may override these). Root files are paid for on every turn, so keep them well below the limits and move detail into child directories rather than growing root.
|
|
106956
|
-
* **Nesting is bounded by \`maxDepth\` in \`$MEMORY_DIR/.memfs.config.json\`.** The default configuration sets \`maxDepth: 2\`. Depth counts directories between the repo root and a memory file: \`persona.md\` is depth 0, \`topic/MEMORY.md\` is depth 1, and \`topic/subtopic/notes.md\` is depth 2. With that default, \`topic/subtopic/detail/notes.md\` is rejected at depth 3. Read the repo's configuration before adding or moving memory; an omitted \`maxDepth\` imposes no depth limit. This constraint excludes \`skills/\`. Fit memory to the configured limit rather than changing the configuration to permit deeper nesting.
|
|
106957
|
-
|
|
106958
|
-
You can create, delete, or modify files (contents, names, descriptions). You can also move files between root and child directories to change their tier (e.g., root → child directory removes it from in-context).
|
|
106959
|
-
|
|
106960
|
-
## Process
|
|
106899
|
+
## Trajectory Format
|
|
106961
106900
|
|
|
106962
106901
|
The payload is at \`$TRANSCRIPT_PATH\`. It may be either:
|
|
106963
106902
|
|
|
106964
106903
|
1. a JSON message array for one conversation, or
|
|
106965
106904
|
2. a \`multi_transcript_reflection_payload\` manifest. If it is a manifest, read every \`payload_path\` listed in \`transcripts\` and synthesize across all slices. Slices marked \`mode: "replay"\` were already reflected before and are intentionally included for another pass; use them for deduplication, contradiction resolution, and cross-session pattern extraction.
|
|
106966
106905
|
|
|
106967
|
-
When reviewing multiple transcripts, prefer patterns supported across sessions, resolve contradictions in favor of the latest evidence, and avoid recording one-off task state.
|
|
106968
|
-
|
|
106969
|
-
### Phase 1 — Investigate
|
|
106970
|
-
|
|
106971
|
-
Understand the current memory landscape before changing anything. Your user prompt already includes a \`<memory_filesystem>\` tree of memory file names (no descriptions; \`skills/\` is omitted) and the full content of every root file inlined in \`<memory>\` blocks — start there, since those are the parent agent's in-context prompts.
|
|
106972
|
-
|
|
106973
|
-
Read \`$MEMORY_DIR/.memfs.config.json\` if present to identify the repo's nesting and size limits before planning its structure.
|
|
106974
|
-
|
|
106975
|
-
For deferred memory, read the relevant child \`MEMORY.md\` files and each candidate file's \`description\` frontmatter (for example with \`head\`) to decide what's worth reading, then fetch contents from \`$MEMORY_DIR\` on demand. Follow ordinary relative Markdown links from \`MEMORY.md\` when relevant. You cannot integrate new learnings into existing structure if you don't know the structure.
|
|
106906
|
+
When reviewing multiple transcripts, prefer patterns supported across sessions, resolve contradictions in favor of the latest evidence, and avoid recording one-off task state.
|
|
106976
106907
|
|
|
106977
|
-
|
|
106908
|
+
Read transcripts in bounded chunks: check the size first, read files up to 15000 bytes in full, and use targeted reads on larger ones (\`head\`, \`tail\`, \`grep\`, \`sed -n\` on Unix; \`Get-Content\`, \`Select-String\` in PowerShell, which the Bash tool runs on Windows).
|
|
106978
106909
|
|
|
106979
|
-
|
|
106910
|
+
## Trajectory review
|
|
106980
106911
|
|
|
106981
106912
|
Review the conversation and identify candidate learnings worth persisting. Prioritize in this order:
|
|
106982
106913
|
|
|
@@ -106986,132 +106917,59 @@ Review the conversation and identify candidate learnings worth persisting. Prior
|
|
|
106986
106917
|
4. **Contradictions** — anything that conflicts with what's currently stored in memory
|
|
106987
106918
|
5. **Reusable procedures** — repeatable, multi-step workflows that may belong in skills
|
|
106988
106919
|
|
|
106989
|
-
|
|
106990
|
-
|
|
106991
|
-
- **Lasting or ephemeral?** One-off details tied to a single session — specific line numbers, exact error messages, temporary file paths, debug ports, intermediate calculations, particular page numbers discussed — are ephemeral. Don't store them.
|
|
106992
|
-
- **Already captured?** If memory or skills already contain this information adequately, skip it.
|
|
106993
|
-
- **Generalizable?** Distill reusable patterns, not event transcripts. "Write short chapters that end on cliffhangers" is worth storing; "User edited chapter 3 paragraph 2 on Tuesday" is not. "Hedge FX exposure on quarterly positions" is worth storing; "Sold 500 shares of AAPL at $187.50" is not. "Write table-driven tests with testify" is worth storing; "User ran tests at 3pm on Tuesday" is not. The raw conversation is already searchable — don't re-record it.
|
|
106994
|
-
- **Temporal references?** Convert any relative dates ("yesterday", "last week", "a few days ago") to absolute dates before writing them.
|
|
106995
|
-
- **Which tier?** Apply "Choosing a tier" above.
|
|
106996
|
-
|
|
106997
|
-
If nothing survives filtering, make no changes and skip to Phase 5 with no commit.
|
|
106998
|
-
|
|
106999
|
-
### Phase 3 — Update
|
|
107000
|
-
|
|
107001
|
-
For each learning that survived Phase 2, make surgical, well-placed changes.
|
|
107002
|
-
|
|
107003
|
-
#### Memory edits
|
|
107004
|
-
|
|
107005
|
-
- **Placement**: Put the learning in the tier chosen in Phase 2, written the way that tier's section above describes.
|
|
107006
|
-
- **Integration**: If an existing file already covers this subject, update it. Only create a new file when the subject is genuinely distinct and has no natural home in existing files. Fragmentation makes memory harder to navigate.
|
|
107007
|
-
- **Contradiction resolution**: If new information contradicts existing memory, fix the stale entry at the source. Do not append the new version alongside the old.
|
|
107008
|
-
- **Discovery paths**: When adding or moving content, update the links in root \`MEMORY.md\` and any affected child \`MEMORY.md\` files so every deferred file stays reachable. Keep \`name\` and \`description\` frontmatter accurate.
|
|
107009
|
-
|
|
107010
|
-
#### Skills (only when a reusable procedure appears)
|
|
107011
|
-
|
|
107012
|
-
Only make a skill change when the conversation demonstrates a repeatable, multi-step workflow with enough concrete detail to be actionable. Pick **at most one** operation, listed in rough order of preference (prefer modifying an existing skill over creating a new one):
|
|
107013
|
-
|
|
107014
|
-
- \`update\` — an existing skill covers the workflow, but the conversation revealed a wrong, dangerous, or outdated step. Read the existing file, then fix that step in place with Edit; preserve the rest.
|
|
107015
|
-
- \`extend\` — an existing skill covers a similar workflow, and the conversation revealed a new variant or edge case. Add a new section with Edit rather than duplicating the skill or rewriting existing sections.
|
|
107016
|
-
- \`deprecate\` — an existing skill is obsolete, harmful, or replaced. Either \`rm -r skills/<name>/\` (delete mode), or add \`deprecated: "true"\` (and optionally \`replaced_by: <skill-name>\`) under the frontmatter \`metadata\` map, start the description with "Deprecated:" followed by the replacement skill's name, and add a short note at the top of the body explaining why (marker mode).
|
|
107017
|
-
- \`split\` — an existing skill has drifted to bundle two distinct procedures and the conversation makes that painful. Write both replacement \`SKILL.md\` files (plus relevant companion files for each) with Bash, then delete the source skill with Bash or trim it with Edit. Use sparingly.
|
|
107018
|
-
- \`create\` — a genuinely novel, repeatable procedure with concrete detail (commands, tool patterns, config values), and no existing skill covers it even partially.
|
|
107019
|
-
- \`none\` — one-off, trivial, informational, already covered, or better stored as ordinary memory. Make no skill changes.
|
|
106920
|
+
Skip anything ephemeral (one-off task state, line numbers, exact errors, temporary paths) or already captured. Convert relative dates to absolute ones. If nothing survives, make no changes and do not commit.
|
|
107020
106921
|
|
|
107021
|
-
|
|
106922
|
+
## Making memory updates
|
|
107022
106923
|
|
|
107023
|
-
|
|
106924
|
+
Write each change the way the preloaded skills describe. Before editing, read the relevant existing files so you integrate rather than duplicate. For skills, prefer updating or extending an existing skill over creating one, make at most one skill change per run, and when unsure whether a procedure deserves a skill, make none.
|
|
107024
106925
|
|
|
107025
|
-
|
|
106926
|
+
Use Edit for files that already exist. Create new files with a quoted heredoc on Unix, or on Windows a single-quoted here-string piped to \`Set-Content -Encoding utf8\`; memory files must stay UTF-8. Edit does not expand environment variables: resolve absolute paths first (\`printf "%s/persona.md\\n" "$MEMORY_DIR"\`, or \`Join-Path $env:MEMORY_DIR "persona.md"\` in PowerShell) and pass the printed path. Keep all writes inside \`$MEMORY_DIR\`.
|
|
107026
106927
|
|
|
107027
|
-
|
|
107028
|
-
|
|
107029
|
-
Quick sanity pass before committing.
|
|
107030
|
-
|
|
107031
|
-
- **No secrets or junk**: Do not persist sensitive values, raw logs, or ephemeral transcript details.
|
|
107032
|
-
|
|
107033
|
-
#### Memory
|
|
107034
|
-
|
|
107035
|
-
- **Stale content**: Did the conversation make anything in existing memory obsolete or superseded? Remove or update it now.
|
|
107036
|
-
- **Cross-reference integrity**: If you deleted or moved a file, check whether any ordinary relative Markdown links point to the old location and update them.
|
|
107037
|
-
- **Tier check**: Did you add anything to root that's really deferred material? Move it to a child directory. Did you leave something in a child directory that the agent needs on every turn? Promote it to root.
|
|
107038
|
-
- **Nesting check**: Confirm every added or moved memory file stays within the configured \`maxDepth\`, including each directory's \`MEMORY.md\`.
|
|
107039
|
-
- **Discoverability**: For each deferred file you added or moved, confirm the primary agent can reach it from root \`MEMORY.md\` through each intermediate directory's \`MEMORY.md\`, that each link says when the target is worth opening, and that its \`description\` says what it is about.
|
|
107040
|
-
|
|
107041
|
-
#### Skills (only if you made a skill change)
|
|
107042
|
-
|
|
107043
|
-
- **No near-duplicates**: For \`create\`, scan the tree once more — is there really no existing skill that covers this? If you spot a partial overlap you missed, switch to \`extend\`.
|
|
107044
|
-
- **Companion file completeness**: For \`create\`/\`split\`, if \`SKILL.md\` references files under \`scripts/\`, \`references/\`, or \`templates/\`, verify those paths actually exist.
|
|
107045
|
-
- **Stale skill references**: For \`deprecate\` (delete mode) or \`split\`, check whether any memory or skill file references the old skill path, and update those references.
|
|
107046
|
-
|
|
107047
|
-
### Phase 5 — Commit
|
|
106928
|
+
## Commit
|
|
107048
106929
|
|
|
107049
106930
|
Before writing the commit, resolve the actual ID values:
|
|
107050
106931
|
\`\`\`bash
|
|
107051
106932
|
echo "CHILD_AGENT_ID=$LETTA_AGENT_ID"
|
|
107052
|
-
echo "PARENT_AGENT_ID=$LETTA_PARENT_AGENT_ID"
|
|
107053
106933
|
\`\`\`
|
|
107054
106934
|
|
|
107055
|
-
Use the printed
|
|
106935
|
+
Use the printed value (e.g., \`agent-abc123...\`) in the trailer. If it is empty or unset, omit the trailer. Never write a literal variable name like \`$LETTA_AGENT_ID\` in the commit message. Run git commands only from \`$MEMORY_DIR\`. Use plain \`-m "..."\` with an embedded multi-line string exactly as shown below:
|
|
107056
106936
|
|
|
107057
106937
|
\`\`\`bash
|
|
107058
106938
|
cd $MEMORY_DIR
|
|
107059
106939
|
git add -A
|
|
107060
106940
|
git commit --author="Reflection Subagent <<CHILD_AGENT_ID>@letta.com>" -m "<type>(reflection): <summary> 🔮
|
|
107061
106941
|
|
|
107062
|
-
Reviewed
|
|
106942
|
+
Reviewed transcripts:
|
|
106943
|
+
- <transcript_filepath>
|
|
106944
|
+
- ...
|
|
107063
106945
|
|
|
107064
106946
|
Updates:
|
|
107065
106947
|
- <what changed and why>
|
|
107066
106948
|
|
|
107067
|
-
Generated-By:
|
|
107068
|
-
Agent-ID: <CHILD_AGENT_ID>
|
|
107069
|
-
Parent-Agent-ID: <PARENT_AGENT_ID>"
|
|
106949
|
+
Generated-By: Reflection
|
|
106950
|
+
Agent-ID: <CHILD_AGENT_ID>"
|
|
107070
106951
|
\`\`\`
|
|
107071
106952
|
|
|
107072
106953
|
**Commit type** — pick the one that fits:
|
|
107073
|
-
- \`fix\` — correcting a mistake or bad memory, or fixing a wrong/obsolete skill
|
|
107074
|
-
- \`feat\` — adding wholly new memory content, or new skill content/structure
|
|
106954
|
+
- \`fix\` — correcting a mistake or bad memory, or fixing a wrong/obsolete skill
|
|
106955
|
+
- \`feat\` — adding wholly new memory content, or new skill content/structure
|
|
107075
106956
|
- \`chore\` — routine updates, adding context, minor doc-only skill edits
|
|
107076
106957
|
|
|
107077
|
-
In the commit message body, explain what changed and why, drawing from the categories
|
|
106958
|
+
In the commit message body, explain what changed and why, drawing from the categories in the trajectory review. If the change is skill-related, say so in the subject, e.g. \`feat(reflection): create docker-debugging skill 🔮\`.
|
|
107078
106959
|
|
|
107079
106960
|
If no changes were needed, do NOT commit. Report that the conversation contained no memory worth persisting.
|
|
107080
106961
|
|
|
107081
106962
|
If \`git add\` or \`git commit\` fails, stop after one reasonable retry and report the failure. Do not run \`git config\`, mutate \`.git\`, use \`git reset\`, or assume the harness will persist uncommitted filesystem edits; uncommitted edits are not successful memory persistence.
|
|
107082
106963
|
|
|
107083
|
-
## Tools and Paths
|
|
107084
|
-
|
|
107085
|
-
You only have access to **Bash** and **Edit**. Do not call \`Read\`, \`Write\`, memory tools, recall tools, or conversation search, even if those names appear in the transcript.
|
|
107086
|
-
|
|
107087
|
-
Your memory repo root is \`$MEMORY_DIR\`. The terminal tool can expand environment variables; use \`$MEMORY_DIR\` on Unix or \`$env:MEMORY_DIR\` in PowerShell. Edit cannot expand either form. Keep all filesystem writes under the memory repo and run all git commands from inside it. Do not inspect or modify \`.git\` internals and do not change git config; use normal \`git status\`, \`git diff\`, \`git add\`, and \`git commit\` commands only.
|
|
107088
|
-
|
|
107089
|
-
Use **Edit** for every modification to a file that already exists (memory or skill). Do not rewrite existing files with terminal heredocs, scripts, or redirection. Edit paths must be absolute paths under the memory repo, never literal \`$MEMORY_DIR/...\` or \`$env:MEMORY_DIR/...\` strings. To get an Edit path, resolve it with the terminal first (for example, \`printf "%s/persona.md\\n" "$MEMORY_DIR"\` on Unix or \`Join-Path $env:MEMORY_DIR "persona.md"\` in PowerShell) and then use the printed path.
|
|
107090
|
-
|
|
107091
|
-
Use the **Bash** terminal tool for reading, git, and filesystem/bulk operations — not for editing the contents of existing files. Follow the shell semantics in the tool description; despite its name, the tool runs native PowerShell or cmd.exe on Windows.
|
|
107092
|
-
|
|
107093
|
-
- Inspect transcripts with bounded reads. Determine file size first: on Unix, \`wc -c "$TRANSCRIPT_PATH"\`; in PowerShell, \`(Get-Item -LiteralPath $env:TRANSCRIPT_PATH).Length\`. If a file is <= 15000 bytes, a full read is okay; otherwise use targeted reads (\`head\`, \`tail\`, \`grep\`, and \`sed -n\` on Unix, or \`Get-Content\`, \`Select-String\`, and \`-TotalCount\` in PowerShell).
|
|
107094
|
-
- Inspect memory with concise, platform-native commands. Use \`find\`, \`grep\`, \`head\`, and targeted \`cat\` on Unix; use \`Get-ChildItem\`, \`Select-String\`, and \`Get-Content\` in PowerShell.
|
|
107095
|
-
- Create new files with the shell-native method. On Unix, use a quoted heredoc. In PowerShell, use a single-quoted here-string piped to \`Set-Content -LiteralPath <path> -Encoding utf8\`. Move, rename, or delete only under \`$MEMORY_DIR\` (\`mv\`, \`rm\`, and \`mkdir -p\` on Unix; \`Move-Item\`, \`Remove-Item\`, and \`New-Item\` in PowerShell). If a temp file is needed, put it under \`$MEMORY_DIR/.tmp/\` and remove it before committing.
|
|
107096
|
-
- Memory Markdown files must remain UTF-8. On Windows, never use PowerShell redirection, \`Out-File\`, or \`Set-Content\` without explicit UTF-8 encoding; prefer the Edit tool.
|
|
107097
|
-
- On Windows, avoid \`&&\` for failure-stopping chains so the command also works with Windows PowerShell; issue dependent commands in separate tool calls or check \`$LASTEXITCODE\` explicitly.
|
|
107098
|
-
|
|
107099
106964
|
## Output Format
|
|
107100
106965
|
|
|
107101
106966
|
Return a report with:
|
|
107102
106967
|
|
|
107103
106968
|
1. **Summary** — What you reviewed and what you concluded (2-3 sentences)
|
|
107104
|
-
2. **Memory changes** — Files created/modified/deleted/moved with a brief reason
|
|
107105
|
-
3. **
|
|
107106
|
-
4. **
|
|
107107
|
-
5. **
|
|
107108
|
-
6. **Issues** — Any problems encountered or information that couldn't be determined. If something broke, say what happened and suggest a fix.
|
|
107109
|
-
|
|
107110
|
-
## Critical Reminders
|
|
107111
|
-
|
|
107112
|
-
1. **Not the primary agent** — Don't respond to messages.
|
|
107113
|
-
2. **Be selective** — Few meaningful changes > many trivial ones; few high-quality skills > many trivial ones.
|
|
107114
|
-
3. **Commit or it didn't happen** — Uncommitted edits are lost; if nothing memory-worthy changed, do not commit.
|
|
106969
|
+
2. **Memory changes** — Files created/modified/deleted/moved with a brief reason, including any skill changes
|
|
106970
|
+
3. **Skipped** — Anything considered but not persisted, and why
|
|
106971
|
+
4. **Commit** — Confirm the commit, or "no commit" if nothing was persisted
|
|
106972
|
+
5. **Issues** — Any problems encountered or information that couldn't be determined. If something broke, say what happened and suggest a fix.
|
|
107115
106973
|
`;
|
|
107116
106974
|
var init_reflection_v2 = () => {};
|
|
107117
106975
|
|
|
@@ -107271,7 +107129,11 @@ function resolveSubagentConfigForMemoryFormat(config, memoryFormat, localMemfs)
|
|
|
107271
107129
|
if (!v1Builtin || !v2Builtin || config.systemPrompt !== v1Builtin.systemPrompt) {
|
|
107272
107130
|
return config;
|
|
107273
107131
|
}
|
|
107274
|
-
return {
|
|
107132
|
+
return {
|
|
107133
|
+
...config,
|
|
107134
|
+
systemPrompt: v2Builtin.systemPrompt,
|
|
107135
|
+
skills: config.skills.join(",") === v1Builtin.skills.join(",") ? [...v2Builtin.skills] : config.skills
|
|
107136
|
+
};
|
|
107275
107137
|
}
|
|
107276
107138
|
function getBuiltinSubagentNames() {
|
|
107277
107139
|
return new Set(Object.keys(getBuiltinSubagents()));
|
|
@@ -210966,7 +210828,7 @@ var init_mcp_client = __esm(() => {
|
|
|
210966
210828
|
init_streamableHttp();
|
|
210967
210829
|
DEFAULT_CLIENT_INFO = {
|
|
210968
210830
|
name: "letta-code",
|
|
210969
|
-
version: "0.34.
|
|
210831
|
+
version: "0.34.18"
|
|
210970
210832
|
};
|
|
210971
210833
|
});
|
|
210972
210834
|
|
|
@@ -229651,7 +229513,7 @@ async function buildClientSkillsPayload(options = {}) {
|
|
|
229651
229513
|
path: skill.path,
|
|
229652
229514
|
source: skill.source
|
|
229653
229515
|
})),
|
|
229654
|
-
skillPathById: Object.fromEntries(
|
|
229516
|
+
skillPathById: Object.fromEntries(discovery.skills.filter((skill) => typeof skill.path === "string" && skill.path.length > 0).map((skill) => [skill.id, skill.path])),
|
|
229655
229517
|
errors: errors6
|
|
229656
229518
|
};
|
|
229657
229519
|
if (useCache && generationBeforeDiscovery === getCacheGeneration() && checkoutGenerationBeforeDiscovery === getCheckoutGeneration()) {
|
|
@@ -233255,6 +233117,9 @@ async function executeScript(spawner, options, meta2) {
|
|
|
233255
233117
|
if (opts.maxToolCalls !== undefined && (!Number.isSafeInteger(opts.maxToolCalls) || opts.maxToolCalls <= 0)) {
|
|
233256
233118
|
throw new Error("agent() maxToolCalls must be a positive safe integer.");
|
|
233257
233119
|
}
|
|
233120
|
+
if (opts.skills !== undefined && (!Array.isArray(opts.skills) || !opts.skills.every((id2) => typeof id2 === "string" && id2.trim()))) {
|
|
233121
|
+
throw new Error("agent() skills must be an array of skill names.");
|
|
233122
|
+
}
|
|
233258
233123
|
const callIndex = callCounter++;
|
|
233259
233124
|
const label = opts.label ?? defaultLabel(prompt);
|
|
233260
233125
|
const phase2 = opts.phase ?? currentPhase;
|
|
@@ -241429,6 +241294,12 @@ async function waitForShutdownRetry(delayMs, signal) {
|
|
|
241429
241294
|
onAbort();
|
|
241430
241295
|
});
|
|
241431
241296
|
}
|
|
241297
|
+
function getEnqueueAgentId(receipt) {
|
|
241298
|
+
const id2 = receipt.agent_id ?? receipt.parent_agent_id;
|
|
241299
|
+
if (!id2)
|
|
241300
|
+
throw new Error("Queued conversation has no agent or parent agent.");
|
|
241301
|
+
return id2;
|
|
241302
|
+
}
|
|
241432
241303
|
async function enqueueConversationMessage(input, signal, request = apiRequest) {
|
|
241433
241304
|
const body3 = {
|
|
241434
241305
|
agent_id: input.agentId,
|
|
@@ -241543,14 +241414,14 @@ function assistantText(messages) {
|
|
|
241543
241414
|
return text2.trim() ? text2 : null;
|
|
241544
241415
|
}
|
|
241545
241416
|
function noReplyMessage(receipt) {
|
|
241546
|
-
return `Remote task finished. Its reply was not collected. Read the conversation with: letta messages list --agent ${receipt
|
|
241417
|
+
return `Remote task finished. Its reply was not collected. Read the conversation with: letta messages list --agent ${getEnqueueAgentId(receipt)} --conversation ${receipt.conversation_id}. Do not launch the task again to retrieve its result.`;
|
|
241547
241418
|
}
|
|
241548
241419
|
async function waitForAcceptedSuperRun(receipt, signal, deps) {
|
|
241549
241420
|
const pollMs = deps.pollMs ?? 1000;
|
|
241550
241421
|
const sleep11 = deps.sleep ?? ((ms, waitSignal) => delay3(ms, undefined, { signal: waitSignal }));
|
|
241551
241422
|
while (true) {
|
|
241552
241423
|
signal.throwIfAborted();
|
|
241553
|
-
const exact = await retryRead(() => deps.exact(receipt
|
|
241424
|
+
const exact = await retryRead(() => deps.exact(getEnqueueAgentId(receipt), receipt.super_run_id, AbortSignal.any([signal, AbortSignal.timeout(30000)])), signal, sleep11, `Cloud status read for accepted Super Run ${receipt.super_run_id} failed`);
|
|
241554
241425
|
if (exact.id !== receipt.super_run_id) {
|
|
241555
241426
|
throw new RemoteExecutionFailed(`Exact Super Run read returned ${exact.id} for ${receipt.super_run_id}.`);
|
|
241556
241427
|
}
|
|
@@ -241588,6 +241459,7 @@ async function waitForAcceptedSuperRun(receipt, signal, deps) {
|
|
|
241588
241459
|
var RemoteExecutionFailed;
|
|
241589
241460
|
var init_headless_super_run_wait = __esm(() => {
|
|
241590
241461
|
init_letta_client();
|
|
241462
|
+
init_conversation_enqueue();
|
|
241591
241463
|
init_request();
|
|
241592
241464
|
RemoteExecutionFailed = class RemoteExecutionFailed extends Error {
|
|
241593
241465
|
};
|
|
@@ -241632,10 +241504,10 @@ function trackChildSend(input) {
|
|
|
241632
241504
|
const subagentId = generateSubagentId();
|
|
241633
241505
|
registerSubagent(subagentId, child.type, child.name, undefined, true, false, parentScope, input.prompt, false);
|
|
241634
241506
|
updateSubagent(subagentId, {
|
|
241635
|
-
agentId: receipt.agent_id,
|
|
241507
|
+
agentId: receipt.agent_id ?? undefined,
|
|
241636
241508
|
conversationId: receipt.conversation_id,
|
|
241637
241509
|
superRunId: receipt.super_run_id,
|
|
241638
|
-
agentURL: buildAgentReference(receipt
|
|
241510
|
+
agentURL: buildAgentReference(getEnqueueAgentId(receipt), {
|
|
241639
241511
|
conversationId: receipt.conversation_id
|
|
241640
241512
|
})
|
|
241641
241513
|
});
|
|
@@ -242398,7 +242270,7 @@ class CodexAppServerClient {
|
|
|
242398
242270
|
await this.request("initialize", {
|
|
242399
242271
|
clientInfo: {
|
|
242400
242272
|
name: "letta-code",
|
|
242401
|
-
version: "0.34.
|
|
242273
|
+
version: "0.34.18"
|
|
242402
242274
|
},
|
|
242403
242275
|
capabilities: null
|
|
242404
242276
|
});
|
|
@@ -246327,8 +246199,11 @@ async function createListenerClient(connectionId, scope) {
|
|
|
246327
246199
|
});
|
|
246328
246200
|
}
|
|
246329
246201
|
async function cancelListenerInput(params) {
|
|
246202
|
+
const agentId = params.scope.agent_id ?? params.parentAgentId;
|
|
246203
|
+
if (!agentId)
|
|
246204
|
+
throw new Error("Listener cancellation requires an agent or parent agent.");
|
|
246330
246205
|
const removed = await (params.dequeue ?? dequeueConversationMessage)({
|
|
246331
|
-
agentId
|
|
246206
|
+
agentId,
|
|
246332
246207
|
conversationId: params.scope.conversation_id,
|
|
246333
246208
|
clientMessageId: params.clientMessageId,
|
|
246334
246209
|
actingUserId: params.scope.acting_user_id
|
|
@@ -246352,7 +246227,7 @@ async function cancelListenerInput(params) {
|
|
|
246352
246227
|
}
|
|
246353
246228
|
async function cancelAcceptedListenerInput(receipt) {
|
|
246354
246229
|
const removed = await dequeueConversationMessage({
|
|
246355
|
-
agentId: receipt
|
|
246230
|
+
agentId: getEnqueueAgentId(receipt),
|
|
246356
246231
|
conversationId: receipt.conversation_id,
|
|
246357
246232
|
clientMessageId: receipt.client_message_id,
|
|
246358
246233
|
actingUserId: receipt.acting_user_id
|
|
@@ -246376,6 +246251,7 @@ async function cancelAcceptedListenerInput(receipt) {
|
|
|
246376
246251
|
return await cancelListenerInput({
|
|
246377
246252
|
client,
|
|
246378
246253
|
scope,
|
|
246254
|
+
parentAgentId: receipt.parent_agent_id,
|
|
246379
246255
|
clientMessageId: receipt.client_message_id,
|
|
246380
246256
|
dequeue: async () => removed,
|
|
246381
246257
|
readState: () => ({ loop, cancelled: false })
|
|
@@ -246386,6 +246262,9 @@ async function cancelAcceptedListenerInput(receipt) {
|
|
|
246386
246262
|
}
|
|
246387
246263
|
}
|
|
246388
246264
|
async function launchListenerConversation(params, deps = {}) {
|
|
246265
|
+
const agentId = params.scope.agent_id ?? params.parentAgentId;
|
|
246266
|
+
if (!agentId)
|
|
246267
|
+
throw new Error("Listener delivery requires an agent or parent agent.");
|
|
246389
246268
|
const client = deps.client ?? await createListenerClient(params.connectionId, params.scope);
|
|
246390
246269
|
const clientMessageId = params.clientMessageId ?? randomUUID37();
|
|
246391
246270
|
const runIds = new Set;
|
|
@@ -246472,7 +246351,7 @@ async function launchListenerConversation(params, deps = {}) {
|
|
|
246472
246351
|
if (interrupted)
|
|
246473
246352
|
throw new Error("Launch cancelled before input was sent");
|
|
246474
246353
|
const accepted = await (deps.enqueue ?? enqueueConversationMessage)({
|
|
246475
|
-
agentId
|
|
246354
|
+
agentId,
|
|
246476
246355
|
conversationId: params.scope.conversation_id,
|
|
246477
246356
|
clientMessageId,
|
|
246478
246357
|
content: params.content,
|
|
@@ -246482,7 +246361,12 @@ async function launchListenerConversation(params, deps = {}) {
|
|
|
246482
246361
|
if (params.noWait)
|
|
246483
246362
|
return {
|
|
246484
246363
|
status: "queued",
|
|
246485
|
-
receipt: {
|
|
246364
|
+
receipt: {
|
|
246365
|
+
...accepted,
|
|
246366
|
+
connection_id: params.connectionId,
|
|
246367
|
+
agent_id: params.scope.agent_id,
|
|
246368
|
+
...params.scope.agent_id === null ? { parent_agent_id: agentId } : {}
|
|
246369
|
+
}
|
|
246486
246370
|
};
|
|
246487
246371
|
while (true) {
|
|
246488
246372
|
if (disconnected)
|
|
@@ -246496,6 +246380,7 @@ async function launchListenerConversation(params, deps = {}) {
|
|
|
246496
246380
|
if (await cancelListenerInput({
|
|
246497
246381
|
client,
|
|
246498
246382
|
scope: params.scope,
|
|
246383
|
+
parentAgentId: params.parentAgentId,
|
|
246499
246384
|
clientMessageId,
|
|
246500
246385
|
dequeue: deps.dequeue,
|
|
246501
246386
|
readState: () => ({ loop, cancelled })
|
|
@@ -246615,7 +246500,7 @@ function handleToolReturnEvent(event, state2) {
|
|
|
246615
246500
|
}
|
|
246616
246501
|
}
|
|
246617
246502
|
function isEnqueueReceipt(event) {
|
|
246618
|
-
return event.status === "queued" && typeof event.agent_id === "string" && typeof event.conversation_id === "string" && typeof event.client_message_id === "string" && typeof event.super_run_id === "string" && typeof event.workflow_id === "string" && (event.acting_user_id === undefined || event.acting_user_id === null || typeof event.acting_user_id === "string");
|
|
246503
|
+
return event.status === "queued" && (typeof event.agent_id === "string" || event.agent_id === null && typeof event.parent_agent_id === "string") && (event.parent_agent_id === undefined || typeof event.parent_agent_id === "string") && typeof event.conversation_id === "string" && typeof event.client_message_id === "string" && typeof event.super_run_id === "string" && typeof event.workflow_id === "string" && (event.acting_user_id === undefined || event.acting_user_id === null || typeof event.acting_user_id === "string");
|
|
246619
246504
|
}
|
|
246620
246505
|
function getResultEnvelopeError(event) {
|
|
246621
246506
|
return event.error || event.result || "Unknown error";
|
|
@@ -246626,6 +246511,7 @@ function handleResultEvent(event, state2, subagentId) {
|
|
|
246626
246511
|
state2.enqueueReceipt = {
|
|
246627
246512
|
status: "queued",
|
|
246628
246513
|
agent_id: event.agent_id,
|
|
246514
|
+
...event.parent_agent_id ? { parent_agent_id: event.parent_agent_id } : {},
|
|
246629
246515
|
conversation_id: event.conversation_id,
|
|
246630
246516
|
client_message_id: event.client_message_id,
|
|
246631
246517
|
super_run_id: event.super_run_id,
|
|
@@ -246757,9 +246643,9 @@ var init_subagent_stream = __esm(() => {
|
|
|
246757
246643
|
async function collectRemoteTurnResult(receipt, state2, subagentId, signal = new AbortController().signal) {
|
|
246758
246644
|
const startedAt = Date.now();
|
|
246759
246645
|
updateSubagent(subagentId, {
|
|
246760
|
-
agentId: receipt.agent_id,
|
|
246646
|
+
agentId: receipt.agent_id ?? undefined,
|
|
246761
246647
|
conversationId: receipt.conversation_id,
|
|
246762
|
-
agentURL: buildAgentReference(receipt
|
|
246648
|
+
agentURL: buildAgentReference(getEnqueueAgentId(receipt), {
|
|
246763
246649
|
conversationId: receipt.conversation_id
|
|
246764
246650
|
})
|
|
246765
246651
|
});
|
|
@@ -246779,7 +246665,7 @@ async function collectRemoteTurnResult(receipt, state2, subagentId, signal = new
|
|
|
246779
246665
|
}
|
|
246780
246666
|
});
|
|
246781
246667
|
return {
|
|
246782
|
-
agentId: receipt.agent_id,
|
|
246668
|
+
agentId: receipt.agent_id ?? "",
|
|
246783
246669
|
conversationId: receipt.conversation_id,
|
|
246784
246670
|
report: reply.text,
|
|
246785
246671
|
success: true,
|
|
@@ -246792,7 +246678,7 @@ async function collectRemoteTurnResult(receipt, state2, subagentId, signal = new
|
|
|
246792
246678
|
detail = cancelled ? INTERRUPTED_BY_USER : `${INTERRUPTED_BY_USER} (could not confirm cancellation of remote Super Run ${receipt.super_run_id})`;
|
|
246793
246679
|
}
|
|
246794
246680
|
return {
|
|
246795
|
-
agentId: receipt.agent_id,
|
|
246681
|
+
agentId: receipt.agent_id ?? "",
|
|
246796
246682
|
conversationId: receipt.conversation_id,
|
|
246797
246683
|
report: "",
|
|
246798
246684
|
success: false,
|
|
@@ -248730,12 +248616,13 @@ async function launchRemoteExternalCodingAgent(params, deps) {
|
|
|
248730
248616
|
durationMs: final.duration_ms || Date.now() - startedAt
|
|
248731
248617
|
};
|
|
248732
248618
|
} catch (error5) {
|
|
248619
|
+
const remoteWorkerStopped = signal?.reason === REMOTE_EXTERNAL_WORKER_STOPPED;
|
|
248733
248620
|
return {
|
|
248734
248621
|
agentId: parentScope.agentId,
|
|
248735
248622
|
model,
|
|
248736
248623
|
report: "",
|
|
248737
248624
|
success: false,
|
|
248738
|
-
error: error5 instanceof RemoteWorkerLostError && !signal?.aborted ? `The ${type3} worker on ${computer} is no longer listed: it may have finished while this session was disconnected (results are kept for 30 minutes), or the listener restarted. Check ${computer} or launch it again if the work is still needed.` : `${signal?.aborted ? "Stopped following this subagent" : errorMessage3(error5)}. The ${type3} worker may still be running on ${computer}.`,
|
|
248625
|
+
error: error5 instanceof RemoteWorkerLostError && !signal?.aborted ? `The ${type3} worker on ${computer} is no longer listed: it may have finished while this session was disconnected (results are kept for 30 minutes), or the listener restarted. Check ${computer} or launch it again if the work is still needed.` : remoteWorkerStopped ? `Stopped the ${type3} worker on ${computer}.` : `${signal?.aborted ? "Stopped following this subagent" : errorMessage3(error5)}. The ${type3} worker may still be running on ${computer}.`,
|
|
248739
248626
|
durationMs: Date.now() - startedAt
|
|
248740
248627
|
};
|
|
248741
248628
|
} finally {
|
|
@@ -248880,7 +248767,7 @@ async function sendRemoteExternalCodingAgentMessage(params, deps = {}) {
|
|
|
248880
248767
|
outputFile: tracked.outputFile
|
|
248881
248768
|
};
|
|
248882
248769
|
}
|
|
248883
|
-
var DISPLAY_NAMES, RemoteWorkerLostError;
|
|
248770
|
+
var REMOTE_EXTERNAL_WORKER_STOPPED, DISPLAY_NAMES, RemoteWorkerLostError;
|
|
248884
248771
|
var init_remote_external_coding_agent = __esm(() => {
|
|
248885
248772
|
init_subagent_state();
|
|
248886
248773
|
init_app_server_client();
|
|
@@ -248890,6 +248777,7 @@ var init_remote_external_coding_agent = __esm(() => {
|
|
|
248890
248777
|
init_headless_environment_response();
|
|
248891
248778
|
init_headless_listener_launch();
|
|
248892
248779
|
init_external_coding_agent();
|
|
248780
|
+
REMOTE_EXTERNAL_WORKER_STOPPED = Symbol("remote external worker stopped");
|
|
248893
248781
|
DISPLAY_NAMES = {
|
|
248894
248782
|
"claude-code": "Claude Code",
|
|
248895
248783
|
codex: "Codex",
|
|
@@ -250479,6 +250367,7 @@ async function task_stop(args, deps = {}) {
|
|
|
250479
250367
|
const child = getSubagents().find((agent) => agent.id === task2.subagentId);
|
|
250480
250368
|
const external3 = parseExternalCodingAgentId(child?.agentId ?? undefined);
|
|
250481
250369
|
let remote;
|
|
250370
|
+
let remoteExternalStopped = false;
|
|
250482
250371
|
if (external3?.computer) {
|
|
250483
250372
|
try {
|
|
250484
250373
|
if (!task2.runtimeScope)
|
|
@@ -250495,6 +250384,7 @@ async function task_stop(args, deps = {}) {
|
|
|
250495
250384
|
killed: result3.stopped,
|
|
250496
250385
|
output: result3.stopped ? "Stopped the remote external subagent" : "The remote external subagent was not running"
|
|
250497
250386
|
};
|
|
250387
|
+
remoteExternalStopped = result3.stopped;
|
|
250498
250388
|
} catch (error5) {
|
|
250499
250389
|
remote = {
|
|
250500
250390
|
killed: false,
|
|
@@ -250506,7 +250396,7 @@ async function task_stop(args, deps = {}) {
|
|
|
250506
250396
|
}
|
|
250507
250397
|
if (remote && !remote.killed)
|
|
250508
250398
|
return remote;
|
|
250509
|
-
task2.abortController.abort();
|
|
250399
|
+
task2.abortController.abort(remoteExternalStopped ? REMOTE_EXTERNAL_WORKER_STOPPED : undefined);
|
|
250510
250400
|
task2.error = "Aborted by user";
|
|
250511
250401
|
await task2.completion;
|
|
250512
250402
|
task2.status = "failed";
|
|
@@ -251874,6 +251764,36 @@ var init_sdk_loader = __esm(() => {
|
|
|
251874
251764
|
SDK_PACKAGE = ["@letta-ai", "letta-agent-sdk"].join("/");
|
|
251875
251765
|
});
|
|
251876
251766
|
|
|
251767
|
+
// src/agent/preloaded-skills.ts
|
|
251768
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
251769
|
+
async function loadPreloadedSkills(ids, options = {}) {
|
|
251770
|
+
if (ids.length === 0)
|
|
251771
|
+
return "";
|
|
251772
|
+
const { skillPathById } = await buildClientSkillsPayload({
|
|
251773
|
+
...options,
|
|
251774
|
+
skillSources: options.skillSources?.length === 0 ? ["bundled"] : options.skillSources
|
|
251775
|
+
});
|
|
251776
|
+
const contents = [];
|
|
251777
|
+
for (const id2 of ids) {
|
|
251778
|
+
const path31 = skillPathById[id2];
|
|
251779
|
+
if (!path31)
|
|
251780
|
+
continue;
|
|
251781
|
+
try {
|
|
251782
|
+
contents.push(`<${id2}>
|
|
251783
|
+
${await readFile18(path31, "utf-8")}
|
|
251784
|
+
</${id2}>`);
|
|
251785
|
+
} catch {}
|
|
251786
|
+
}
|
|
251787
|
+
return contents.length ? `<loaded_skills>
|
|
251788
|
+
${contents.join(`
|
|
251789
|
+
|
|
251790
|
+
`)}
|
|
251791
|
+
</loaded_skills>` : "";
|
|
251792
|
+
}
|
|
251793
|
+
var init_preloaded_skills = __esm(() => {
|
|
251794
|
+
init_client_skills();
|
|
251795
|
+
});
|
|
251796
|
+
|
|
251877
251797
|
// src/tools/workflow/sdk-spawner.ts
|
|
251878
251798
|
async function latestWorkerRun(conversationId) {
|
|
251879
251799
|
const backend3 = getBackend();
|
|
@@ -252115,6 +252035,19 @@ function createSdkSpawner(client, config2) {
|
|
|
252115
252035
|
error: `Unknown model "${options.model}". Run \`letta model list\` for valid handles.`
|
|
252116
252036
|
};
|
|
252117
252037
|
}
|
|
252038
|
+
const loadedSkills = options.skills?.length ? await loadPreloadedSkills(options.skills, {
|
|
252039
|
+
agentId: config2.parentAgentId,
|
|
252040
|
+
...config2.cwd ? { workingDirectory: config2.cwd } : {}
|
|
252041
|
+
}) : "";
|
|
252042
|
+
const missingSkills = (options.skills ?? []).filter((id2) => !loadedSkills.includes(`<${id2}>
|
|
252043
|
+
`));
|
|
252044
|
+
if (missingSkills.length) {
|
|
252045
|
+
return {
|
|
252046
|
+
value: null,
|
|
252047
|
+
failed: true,
|
|
252048
|
+
error: `Unknown skill(s): ${missingSkills.join(", ")}.`
|
|
252049
|
+
};
|
|
252050
|
+
}
|
|
252118
252051
|
if (signal.aborted) {
|
|
252119
252052
|
return {
|
|
252120
252053
|
value: null,
|
|
@@ -252133,7 +252066,9 @@ function createSdkSpawner(client, config2) {
|
|
|
252133
252066
|
let query3;
|
|
252134
252067
|
try {
|
|
252135
252068
|
query3 = client.query({
|
|
252136
|
-
prompt
|
|
252069
|
+
prompt: loadedSkills ? `${loadedSkills}
|
|
252070
|
+
|
|
252071
|
+
${prompt}` : prompt,
|
|
252137
252072
|
options: {
|
|
252138
252073
|
...buildQueryOptions(options, model, config2, request2.callIndex),
|
|
252139
252074
|
...resumeId ? { conversationId: resumeId } : {}
|
|
@@ -252259,6 +252194,7 @@ function createSdkSpawner(client, config2) {
|
|
|
252259
252194
|
}
|
|
252260
252195
|
var DEFAULT_SUBAGENT_TIMEOUT_MS, DEFAULT_MAX_SUBAGENT_TOOL_CALLS = 1000, MAX_IDENTICAL_TOOL_CALLS = 3, SUBAGENT_PREAMBLE = `You are a subagent inside a deterministic workflow. You are not talking to a human: your final output is consumed by a script. Return raw data with no preamble, no markdown framing, and no questions.`, JSON_PREAMBLE = `Your final message must be a single JSON value and nothing else: no prose, no markdown code fence.`;
|
|
252261
252196
|
var init_sdk_spawner = __esm(async () => {
|
|
252197
|
+
init_preloaded_skills();
|
|
252262
252198
|
init_backend2();
|
|
252263
252199
|
init_tool_registry();
|
|
252264
252200
|
init_tool_name_mapping();
|
|
@@ -252399,6 +252335,14 @@ function jsonSafe(value) {
|
|
|
252399
252335
|
return String(value);
|
|
252400
252336
|
}
|
|
252401
252337
|
}
|
|
252338
|
+
function formatFailureResult(error5, agentsDone, journalPath) {
|
|
252339
|
+
const lines = [`Workflow failed: ${error5 ?? "unknown error"}`];
|
|
252340
|
+
if (agentsDone > 0) {
|
|
252341
|
+
lines.push(`${agentsDone} agent call${agentsDone === 1 ? "" : "s"} completed before the failure. Their full results are saved in ${journalPath} (one line per completed call; the return value is outcome.value).`);
|
|
252342
|
+
}
|
|
252343
|
+
return lines.join(`
|
|
252344
|
+
`);
|
|
252345
|
+
}
|
|
252402
252346
|
function formatCompletionResult(run, executionDir) {
|
|
252403
252347
|
const payload = JSON.stringify({
|
|
252404
252348
|
result: jsonSafe(run.result),
|
|
@@ -252590,7 +252534,7 @@ async function workflow(args) {
|
|
|
252590
252534
|
processState.status = outcome.run ? "completed" : "failed";
|
|
252591
252535
|
processState.exitCode = outcome.run ? 0 : 1;
|
|
252592
252536
|
}
|
|
252593
|
-
const result3 = outcome.run ? formatCompletionResult(outcome.run, executionDir) :
|
|
252537
|
+
const result3 = outcome.run ? formatCompletionResult(outcome.run, executionDir) : formatFailureResult(outcome.error, getWorkflowExecution(taskId)?.agentsDone ?? 0, journalPath);
|
|
252594
252538
|
appendToOutputFile(outputFile, outcome.run ? `
|
|
252595
252539
|
[result]
|
|
252596
252540
|
${result3}
|
|
@@ -261164,7 +261108,7 @@ var init_environments4 = __esm(() => {
|
|
|
261164
261108
|
});
|
|
261165
261109
|
|
|
261166
261110
|
// src/cli/subcommands/feedback.ts
|
|
261167
|
-
import { readFile as
|
|
261111
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
261168
261112
|
import { parseArgs as parseArgs8 } from "node:util";
|
|
261169
261113
|
function printUsage6(stdout = console.log) {
|
|
261170
261114
|
stdout(`
|
|
@@ -261214,7 +261158,7 @@ async function runFeedbackSubcommand(argv, deps = {}) {
|
|
|
261214
261158
|
let rawMessage = typeof inlineMessage === "string" ? inlineMessage : "";
|
|
261215
261159
|
if (typeof messageFile === "string") {
|
|
261216
261160
|
try {
|
|
261217
|
-
rawMessage = await (deps.readMessageFile ?? ((path32) =>
|
|
261161
|
+
rawMessage = await (deps.readMessageFile ?? ((path32) => readFile19(path32, "utf8")))(messageFile);
|
|
261218
261162
|
} catch {
|
|
261219
261163
|
stderr(`Could not read feedback file: ${messageFile}`);
|
|
261220
261164
|
return 1;
|
|
@@ -263427,7 +263371,7 @@ var init_listen_log = __esm(() => {
|
|
|
263427
263371
|
|
|
263428
263372
|
// src/utils/machine-metadata.ts
|
|
263429
263373
|
import { execFile as execFile19 } from "node:child_process";
|
|
263430
|
-
import { readFile as
|
|
263374
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
263431
263375
|
import { cpus, totalmem } from "node:os";
|
|
263432
263376
|
function getMachineMetadata() {
|
|
263433
263377
|
machineMetadata ??= collectMachineMetadata().catch(() => ({
|
|
@@ -263442,7 +263386,7 @@ function localSources() {
|
|
|
263442
263386
|
architecture: process.arch,
|
|
263443
263387
|
cpu: cpus()[0]?.model,
|
|
263444
263388
|
memoryBytes: Math.min(totalmem(), limit4 || Number.POSITIVE_INFINITY),
|
|
263445
|
-
read: (path32, signal) =>
|
|
263389
|
+
read: (path32, signal) => readFile20(path32, { encoding: "utf8", signal }),
|
|
263446
263390
|
run: (command, args, signal) => new Promise((resolve39, reject2) => {
|
|
263447
263391
|
execFile19(command, args, {
|
|
263448
263392
|
encoding: "utf8",
|
|
@@ -264021,7 +263965,7 @@ var init_auth3 = __esm(() => {
|
|
|
264021
263965
|
|
|
264022
263966
|
// src/websocket/listener/manual-instance-lock.ts
|
|
264023
263967
|
import { createHash as createHash14, randomUUID as randomUUID47 } from "node:crypto";
|
|
264024
|
-
import { link as link4, mkdir as mkdir13, readFile as
|
|
263968
|
+
import { link as link4, mkdir as mkdir13, readFile as readFile21, rm as rm11, unlink as unlink3, writeFile as writeFile15 } from "node:fs/promises";
|
|
264025
263969
|
import { homedir as homedir38 } from "node:os";
|
|
264026
263970
|
import path32 from "node:path";
|
|
264027
263971
|
function hasErrorCode3(error5, code2) {
|
|
@@ -264108,7 +264052,7 @@ async function recoverDeadOwner(lockPath, staleContents, recoveryOwnerContents,
|
|
|
264108
264052
|
}
|
|
264109
264053
|
let claimContents;
|
|
264110
264054
|
try {
|
|
264111
|
-
claimContents = await
|
|
264055
|
+
claimContents = await readFile21(claimPath, "utf-8");
|
|
264112
264056
|
} catch (error5) {
|
|
264113
264057
|
if (hasErrorCode3(error5, "ENOENT")) {
|
|
264114
264058
|
continue;
|
|
@@ -264128,7 +264072,7 @@ async function recoverDeadOwner(lockPath, staleContents, recoveryOwnerContents,
|
|
|
264128
264072
|
}
|
|
264129
264073
|
let currentContents;
|
|
264130
264074
|
try {
|
|
264131
|
-
currentContents = await
|
|
264075
|
+
currentContents = await readFile21(lockPath, "utf-8");
|
|
264132
264076
|
} catch (error5) {
|
|
264133
264077
|
return hasErrorCode3(error5, "ENOENT");
|
|
264134
264078
|
}
|
|
@@ -264178,7 +264122,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
264178
264122
|
return;
|
|
264179
264123
|
let currentContents;
|
|
264180
264124
|
try {
|
|
264181
|
-
currentContents = await
|
|
264125
|
+
currentContents = await readFile21(lockPath, "utf-8");
|
|
264182
264126
|
} catch (error5) {
|
|
264183
264127
|
if (hasErrorCode3(error5, "ENOENT")) {
|
|
264184
264128
|
released = true;
|
|
@@ -264198,7 +264142,7 @@ async function acquireManualListenerLock(scope, overrides = {}) {
|
|
|
264198
264142
|
}
|
|
264199
264143
|
let incumbentContents;
|
|
264200
264144
|
try {
|
|
264201
|
-
incumbentContents = await
|
|
264145
|
+
incumbentContents = await readFile21(lockPath, "utf-8");
|
|
264202
264146
|
} catch (error5) {
|
|
264203
264147
|
if (hasErrorCode3(error5, "ENOENT")) {
|
|
264204
264148
|
continue;
|
|
@@ -266750,7 +266694,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
266750
266694
|
ensureLocalMemfsCheckout: ensureLocalMemfsCheckout2,
|
|
266751
266695
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
266752
266696
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
266753
|
-
const { readFile:
|
|
266697
|
+
const { readFile: readFile22 } = await import("node:fs/promises");
|
|
266754
266698
|
const { existsSync: existsSync52 } = await import("node:fs");
|
|
266755
266699
|
const { isAbsolute: isAbsolute25, join: join77, normalize: normalize4, relative: relative8, sep: sep8 } = await import("node:path");
|
|
266756
266700
|
if (isAbsolute25(parsed.path) || parsed.path.length === 0) {
|
|
@@ -266776,7 +266720,7 @@ function handleMemoryProtocolCommand(parsed, context3) {
|
|
|
266776
266720
|
return;
|
|
266777
266721
|
}
|
|
266778
266722
|
}
|
|
266779
|
-
const buffer = await
|
|
266723
|
+
const buffer = await readFile22(absolutePath);
|
|
266780
266724
|
const content = encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf-8");
|
|
266781
266725
|
const pathspec = rel.split(sep8).join("/");
|
|
266782
266726
|
safeSocketSend(socket, {
|
|
@@ -276035,7 +275979,7 @@ ${lanes.join(`
|
|
|
276035
275979
|
writeOutputIsTTY() {
|
|
276036
275980
|
return process.stdout.isTTY;
|
|
276037
275981
|
},
|
|
276038
|
-
readFile:
|
|
275982
|
+
readFile: readFile22,
|
|
276039
275983
|
writeFile: writeFile22,
|
|
276040
275984
|
watchFile: watchFile2,
|
|
276041
275985
|
watchDirectory,
|
|
@@ -276228,7 +276172,7 @@ ${lanes.join(`
|
|
|
276228
276172
|
function fsWatchWorker(fileOrDirectory, recursive, callback) {
|
|
276229
276173
|
return _fs.watch(fileOrDirectory, fsSupportsRecursiveFsWatch ? { persistent: true, recursive: !!recursive } : { persistent: true }, callback);
|
|
276230
276174
|
}
|
|
276231
|
-
function
|
|
276175
|
+
function readFile22(fileName, _encoding) {
|
|
276232
276176
|
let buffer;
|
|
276233
276177
|
try {
|
|
276234
276178
|
buffer = _fs.readFileSync(fileName);
|
|
@@ -307175,7 +307119,7 @@ ${lanes.join(`
|
|
|
307175
307119
|
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics2.optionDeclarations, getOptionName);
|
|
307176
307120
|
return possibleOption ? createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics2.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics2.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
|
|
307177
307121
|
}
|
|
307178
|
-
function parseCommandLineWorker(diagnostics2, commandLine,
|
|
307122
|
+
function parseCommandLineWorker(diagnostics2, commandLine, readFile22) {
|
|
307179
307123
|
const options = {};
|
|
307180
307124
|
let watchOptions;
|
|
307181
307125
|
const fileNames = [];
|
|
@@ -307213,7 +307157,7 @@ ${lanes.join(`
|
|
|
307213
307157
|
}
|
|
307214
307158
|
}
|
|
307215
307159
|
function parseResponseFile(fileName) {
|
|
307216
|
-
const text3 = tryReadFile(fileName,
|
|
307160
|
+
const text3 = tryReadFile(fileName, readFile22 || ((fileName2) => sys.readFile(fileName2)));
|
|
307217
307161
|
if (!isString7(text3)) {
|
|
307218
307162
|
errors6.push(text3);
|
|
307219
307163
|
return;
|
|
@@ -307316,8 +307260,8 @@ ${lanes.join(`
|
|
|
307316
307260
|
unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
|
|
307317
307261
|
optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument
|
|
307318
307262
|
};
|
|
307319
|
-
function parseCommandLine2(commandLine,
|
|
307320
|
-
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine,
|
|
307263
|
+
function parseCommandLine2(commandLine, readFile22) {
|
|
307264
|
+
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile22);
|
|
307321
307265
|
}
|
|
307322
307266
|
function getOptionFromName(optionName, allowShort) {
|
|
307323
307267
|
return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
|
|
@@ -307385,8 +307329,8 @@ ${lanes.join(`
|
|
|
307385
307329
|
result3.originalFileName = result3.fileName;
|
|
307386
307330
|
return parseJsonSourceFileConfigFileContent(result3, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd2), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd2), undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend);
|
|
307387
307331
|
}
|
|
307388
|
-
function readConfigFile(fileName,
|
|
307389
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
307332
|
+
function readConfigFile(fileName, readFile22) {
|
|
307333
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile22);
|
|
307390
307334
|
return isString7(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
|
|
307391
307335
|
}
|
|
307392
307336
|
function parseConfigFileTextToJson(fileName, jsonText) {
|
|
@@ -307396,14 +307340,14 @@ ${lanes.join(`
|
|
|
307396
307340
|
error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
|
|
307397
307341
|
};
|
|
307398
307342
|
}
|
|
307399
|
-
function readJsonConfigFile(fileName,
|
|
307400
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
307343
|
+
function readJsonConfigFile(fileName, readFile22) {
|
|
307344
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile22);
|
|
307401
307345
|
return isString7(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] };
|
|
307402
307346
|
}
|
|
307403
|
-
function tryReadFile(fileName,
|
|
307347
|
+
function tryReadFile(fileName, readFile22) {
|
|
307404
307348
|
let text3;
|
|
307405
307349
|
try {
|
|
307406
|
-
text3 =
|
|
307350
|
+
text3 = readFile22(fileName);
|
|
307407
307351
|
} catch (e2) {
|
|
307408
307352
|
return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e2.message);
|
|
307409
307353
|
}
|
|
@@ -374833,12 +374777,12 @@ ${lanes.join(`
|
|
|
374833
374777
|
function createCompilerHost(options, setParentNodes) {
|
|
374834
374778
|
return createCompilerHostWorker(options, setParentNodes);
|
|
374835
374779
|
}
|
|
374836
|
-
function createGetSourceFile(
|
|
374780
|
+
function createGetSourceFile(readFile22, setParentNodes) {
|
|
374837
374781
|
return (fileName, languageVersionOrOptions, onError) => {
|
|
374838
374782
|
let text3;
|
|
374839
374783
|
try {
|
|
374840
374784
|
mark2("beforeIORead");
|
|
374841
|
-
text3 =
|
|
374785
|
+
text3 = readFile22(fileName);
|
|
374842
374786
|
mark2("afterIORead");
|
|
374843
374787
|
measure("I/O Read", "beforeIORead", "afterIORead");
|
|
374844
374788
|
} catch (e2) {
|
|
@@ -375629,7 +375573,7 @@ ${lanes.join(`
|
|
|
375629
375573
|
getRedirectFromOutput,
|
|
375630
375574
|
forEachResolvedProjectReference: forEachResolvedProjectReference2
|
|
375631
375575
|
});
|
|
375632
|
-
const
|
|
375576
|
+
const readFile22 = host.readFile.bind(host);
|
|
375633
375577
|
(_e = tracing) == null || _e.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
|
|
375634
375578
|
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
|
375635
375579
|
(_f = tracing) == null || _f.pop();
|
|
@@ -375805,7 +375749,7 @@ ${lanes.join(`
|
|
|
375805
375749
|
shouldTransformImportCall,
|
|
375806
375750
|
emitBuildInfo,
|
|
375807
375751
|
fileExists,
|
|
375808
|
-
readFile:
|
|
375752
|
+
readFile: readFile22,
|
|
375809
375753
|
directoryExists: directoryExists2,
|
|
375810
375754
|
getSymlinkCache,
|
|
375811
375755
|
realpath: (_o = host.realpath) == null ? undefined : _o.bind(host),
|
|
@@ -443139,6 +443083,94 @@ var init_chatgpt_plan_rotation = __esm(() => {
|
|
|
443139
443083
|
init_backend2();
|
|
443140
443084
|
});
|
|
443141
443085
|
|
|
443086
|
+
// src/agent/ephemeral-conversation.ts
|
|
443087
|
+
async function buildEphemeralConversationCreateBody(options) {
|
|
443088
|
+
const system2 = options.systemPromptCustom ? options.systemPromptCustom : await resolveAndBuildSystemPrompt(options.systemPromptPreset, options.memoryPromptMode ?? "standard");
|
|
443089
|
+
const request2 = await buildCreateAgentRequest({
|
|
443090
|
+
model: options.model,
|
|
443091
|
+
system: system2,
|
|
443092
|
+
memoryPromptMode: "standard",
|
|
443093
|
+
enableMemfs: false,
|
|
443094
|
+
isSubagent: true,
|
|
443095
|
+
baseTools: []
|
|
443096
|
+
});
|
|
443097
|
+
const modelSettings = options.model ? getModelUpdateArgs(options.model) : undefined;
|
|
443098
|
+
const contextWindow = modelSettings?.context_window ?? await getModelContextWindow(request2.model);
|
|
443099
|
+
return {
|
|
443100
|
+
model: request2.model,
|
|
443101
|
+
system: request2.system ?? system2,
|
|
443102
|
+
...modelSettings ? { model_settings: modelSettings } : {},
|
|
443103
|
+
...contextWindow ? { context_window_limit: contextWindow } : {}
|
|
443104
|
+
};
|
|
443105
|
+
}
|
|
443106
|
+
function projectConversationState(conversation) {
|
|
443107
|
+
if (!conversation.model) {
|
|
443108
|
+
throw new Error("Cannot resume a conversation without a persisted model.");
|
|
443109
|
+
}
|
|
443110
|
+
return {
|
|
443111
|
+
id: conversation.id,
|
|
443112
|
+
name: "Ephemeral conversation",
|
|
443113
|
+
system: conversation.system ?? "",
|
|
443114
|
+
tools: [],
|
|
443115
|
+
memory: { blocks: [] },
|
|
443116
|
+
llm_config: {
|
|
443117
|
+
handle: conversation.model,
|
|
443118
|
+
model: conversation.model,
|
|
443119
|
+
context_window: conversation.context_window_limit ?? undefined,
|
|
443120
|
+
model_settings: conversation.model_settings ?? {}
|
|
443121
|
+
},
|
|
443122
|
+
model_settings: conversation.model_settings ?? {},
|
|
443123
|
+
message_buffer_autoclear: false
|
|
443124
|
+
};
|
|
443125
|
+
}
|
|
443126
|
+
async function createEphemeralConversation2(options) {
|
|
443127
|
+
const body3 = await buildEphemeralConversationCreateBody(options);
|
|
443128
|
+
const conversation = await createEphemeralConversation(body3);
|
|
443129
|
+
return {
|
|
443130
|
+
agent: projectConversationState({ ...body3, id: conversation.id }),
|
|
443131
|
+
conversationId: conversation.id
|
|
443132
|
+
};
|
|
443133
|
+
}
|
|
443134
|
+
async function retrieveResumeState(agentId, conversationId, backend3 = getBackend()) {
|
|
443135
|
+
return agentId ? backend3.retrieveAgent(agentId) : projectConversationState(await backend3.retrieveConversation(conversationId));
|
|
443136
|
+
}
|
|
443137
|
+
async function createLocalEphemeralConversation(options) {
|
|
443138
|
+
const body3 = await buildEphemeralConversationCreateBody(options);
|
|
443139
|
+
const backend3 = getBackend();
|
|
443140
|
+
const internalAgent = await backend3.createAgent({
|
|
443141
|
+
agent_type: "letta_v1_agent",
|
|
443142
|
+
name: "Ephemeral conversation",
|
|
443143
|
+
model: body3.model,
|
|
443144
|
+
system: body3.system,
|
|
443145
|
+
memory_blocks: [],
|
|
443146
|
+
tags: [],
|
|
443147
|
+
tools: [],
|
|
443148
|
+
include_base_tools: false,
|
|
443149
|
+
include_base_tool_rules: false,
|
|
443150
|
+
initial_message_sequence: [],
|
|
443151
|
+
parallel_tool_calls: true,
|
|
443152
|
+
hidden: true
|
|
443153
|
+
});
|
|
443154
|
+
const conversation = await backend3.createConversation({
|
|
443155
|
+
agent_id: internalAgent.id,
|
|
443156
|
+
model: body3.model,
|
|
443157
|
+
...body3.model_settings ? { model_settings: body3.model_settings } : {},
|
|
443158
|
+
...body3.context_window_limit ? { context_window_limit: body3.context_window_limit } : {}
|
|
443159
|
+
});
|
|
443160
|
+
return {
|
|
443161
|
+
agent: internalAgent,
|
|
443162
|
+
conversationId: conversation.id
|
|
443163
|
+
};
|
|
443164
|
+
}
|
|
443165
|
+
var init_ephemeral_conversation = __esm(() => {
|
|
443166
|
+
init_available_models();
|
|
443167
|
+
init_create_agent_request();
|
|
443168
|
+
init_model();
|
|
443169
|
+
init_system_prompt_resolution();
|
|
443170
|
+
init_backend2();
|
|
443171
|
+
init_ephemeral_conversations();
|
|
443172
|
+
});
|
|
443173
|
+
|
|
443142
443174
|
// src/cli/helpers/compaction-utils.ts
|
|
443143
443175
|
function extractCompactionSummary(text3) {
|
|
443144
443176
|
try {
|
|
@@ -447193,7 +447225,7 @@ async function tryResumeBusyConversationStream(params) {
|
|
|
447193
447225
|
}
|
|
447194
447226
|
}
|
|
447195
447227
|
async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
447196
|
-
if (!runtime.agentId)
|
|
447228
|
+
if (!runtime.agentId && runtime.conversationId === "default")
|
|
447197
447229
|
return null;
|
|
447198
447230
|
const getResumeDataImpl = deps.getResumeData ?? getResumeDataFromBackend;
|
|
447199
447231
|
const prepareToolExecutionContext = deps.prepareToolExecutionContext ?? prepareToolExecutionContextForScope;
|
|
@@ -447208,7 +447240,10 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
447208
447240
|
const backend3 = getBackend();
|
|
447209
447241
|
let agent;
|
|
447210
447242
|
try {
|
|
447211
|
-
agent = await (
|
|
447243
|
+
agent = await retrieveResumeState(runtime.agentId, runtime.conversationId, {
|
|
447244
|
+
retrieveAgent: deps.retrieveAgent ?? backend3.retrieveAgent.bind(backend3),
|
|
447245
|
+
retrieveConversation: deps.retrieveConversation ?? backend3.retrieveConversation.bind(backend3)
|
|
447246
|
+
});
|
|
447212
447247
|
} catch (err) {
|
|
447213
447248
|
assertCurrentTurnLease();
|
|
447214
447249
|
if (isBackendNotFoundError(err)) {
|
|
@@ -447241,14 +447276,14 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
447241
447276
|
agent_id: runtime.agentId,
|
|
447242
447277
|
conversation_id: recoveryConversationId
|
|
447243
447278
|
};
|
|
447244
|
-
const modAdapters = await ensureListenerModAdaptersForAgent(runtime.listener, runtime.agentId);
|
|
447279
|
+
const modAdapters = runtime.agentId ? await ensureListenerModAdaptersForAgent(runtime.listener, runtime.agentId) : [];
|
|
447245
447280
|
const preparedToolContext = await prepareToolExecutionContext({
|
|
447246
447281
|
connectionId: resolveTurnExecutionConnectionId(runtime.listener, scope, runtime.activeConnectionId ?? undefined),
|
|
447247
447282
|
agentId: runtime.agentId,
|
|
447248
447283
|
conversationId: recoveryConversationId,
|
|
447249
447284
|
workingDirectory: recoveryWorkingDirectory,
|
|
447250
447285
|
permissionModeState: getOrCreateConversationPermissionModeStateRef(runtime.listener, runtime.agentId, runtime.conversationId),
|
|
447251
|
-
modContext: createListenerAgentModContext(runtime.agentId),
|
|
447286
|
+
...runtime.agentId ? { modContext: createListenerAgentModContext(runtime.agentId) } : {},
|
|
447252
447287
|
modAdapters,
|
|
447253
447288
|
modEvents: createListenerModEvents(modAdapters)
|
|
447254
447289
|
});
|
|
@@ -447641,6 +447676,7 @@ var init_send = __esm(async () => {
|
|
|
447641
447676
|
init_error();
|
|
447642
447677
|
init_approval_recovery();
|
|
447643
447678
|
init_check_approval();
|
|
447679
|
+
init_ephemeral_conversation();
|
|
447644
447680
|
init_turn_recovery_policy();
|
|
447645
447681
|
init_backend2();
|
|
447646
447682
|
init_error_formatter();
|
|
@@ -451706,12 +451742,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
451706
451742
|
}
|
|
451707
451743
|
return calls;
|
|
451708
451744
|
}
|
|
451709
|
-
function
|
|
451745
|
+
function contentText2(content) {
|
|
451710
451746
|
if (typeof content === "string") {
|
|
451711
451747
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
451712
451748
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
451713
451749
|
try {
|
|
451714
|
-
return
|
|
451750
|
+
return contentText2(JSON.parse(encoded));
|
|
451715
451751
|
} catch {
|
|
451716
451752
|
return encoded;
|
|
451717
451753
|
}
|
|
@@ -451797,7 +451833,7 @@ var init_hermes = __esm(() => {
|
|
|
451797
451833
|
});
|
|
451798
451834
|
};
|
|
451799
451835
|
if (row.role === "user") {
|
|
451800
|
-
const content =
|
|
451836
|
+
const content = contentText2(row.content);
|
|
451801
451837
|
if (content) {
|
|
451802
451838
|
emit({
|
|
451803
451839
|
type: "message",
|
|
@@ -451817,7 +451853,7 @@ var init_hermes = __esm(() => {
|
|
|
451817
451853
|
...timestamp ? { timestamp } : {}
|
|
451818
451854
|
});
|
|
451819
451855
|
}
|
|
451820
|
-
const content =
|
|
451856
|
+
const content = contentText2(row.content);
|
|
451821
451857
|
if (content) {
|
|
451822
451858
|
emit({
|
|
451823
451859
|
type: "message",
|
|
@@ -451840,7 +451876,7 @@ var init_hermes = __esm(() => {
|
|
|
451840
451876
|
if (row.role === "tool") {
|
|
451841
451877
|
emit({
|
|
451842
451878
|
type: "tool_result",
|
|
451843
|
-
content:
|
|
451879
|
+
content: contentText2(row.content),
|
|
451844
451880
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
451845
451881
|
...timestamp ? { timestamp } : {}
|
|
451846
451882
|
});
|
|
@@ -453832,7 +453868,7 @@ var exports_reflection_memory_v2 = {};
|
|
|
453832
453868
|
__export(exports_reflection_memory_v2, {
|
|
453833
453869
|
buildMemfsV2ParentMemorySnapshot: () => buildMemfsV2ParentMemorySnapshot
|
|
453834
453870
|
});
|
|
453835
|
-
import { readFile as
|
|
453871
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
453836
453872
|
function renderProjectedTree(files) {
|
|
453837
453873
|
const root2 = { directories: new Map, files: [] };
|
|
453838
453874
|
for (const file of files) {
|
|
@@ -453885,7 +453921,7 @@ async function buildMemfsV2ParentMemorySnapshot(memoryDir, requestedMaxChars) {
|
|
|
453885
453921
|
`).length - prefix.length - suffix.length - 20;
|
|
453886
453922
|
if (remaining <= 0)
|
|
453887
453923
|
break;
|
|
453888
|
-
const content = (await
|
|
453924
|
+
const content = (await readFile22(file.fullPath, "utf-8")).slice(0, remaining);
|
|
453889
453925
|
lines.push(`${prefix}${content}${suffix}`);
|
|
453890
453926
|
}
|
|
453891
453927
|
lines.push("</parent_memory>");
|
|
@@ -453903,7 +453939,7 @@ import {
|
|
|
453903
453939
|
appendFile,
|
|
453904
453940
|
mkdir as mkdir14,
|
|
453905
453941
|
readdir as readdir9,
|
|
453906
|
-
readFile as
|
|
453942
|
+
readFile as readFile23,
|
|
453907
453943
|
stat as stat13,
|
|
453908
453944
|
writeFile as writeFile16
|
|
453909
453945
|
} from "node:fs/promises";
|
|
@@ -453951,7 +453987,7 @@ async function collectParentMemoryFiles(memoryDir) {
|
|
|
453951
453987
|
continue;
|
|
453952
453988
|
}
|
|
453953
453989
|
try {
|
|
453954
|
-
const content = await
|
|
453990
|
+
const content = await readFile23(entryPath, "utf-8");
|
|
453955
453991
|
const { frontmatter } = parseFrontmatter(content);
|
|
453956
453992
|
const description = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
|
|
453957
453993
|
files.push({
|
|
@@ -454254,7 +454290,7 @@ async function ensurePaths(paths) {
|
|
|
454254
454290
|
}
|
|
454255
454291
|
async function readTranscriptLines(paths) {
|
|
454256
454292
|
try {
|
|
454257
|
-
const raw2 = await
|
|
454293
|
+
const raw2 = await readFile23(paths.transcriptPath, "utf-8");
|
|
454258
454294
|
return raw2.split(`
|
|
454259
454295
|
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
454260
454296
|
} catch {
|
|
@@ -454327,7 +454363,7 @@ function buildUnreflectedStateFromTranscript(lines) {
|
|
|
454327
454363
|
async function readState(paths) {
|
|
454328
454364
|
let raw2 = null;
|
|
454329
454365
|
try {
|
|
454330
|
-
raw2 = await
|
|
454366
|
+
raw2 = await readFile23(paths.statePath, "utf-8");
|
|
454331
454367
|
} catch {
|
|
454332
454368
|
raw2 = null;
|
|
454333
454369
|
}
|
|
@@ -454659,7 +454695,7 @@ function isReflectionAutoPriority(value) {
|
|
|
454659
454695
|
return value === "high" || value === "medium" || value === "low";
|
|
454660
454696
|
}
|
|
454661
454697
|
async function readReflectionAutoSelection(options) {
|
|
454662
|
-
const raw2 = options.selectionReport ?? (options.selectionOutputPath ? await
|
|
454698
|
+
const raw2 = options.selectionReport ?? (options.selectionOutputPath ? await readFile23(options.selectionOutputPath, "utf-8") : "");
|
|
454663
454699
|
const parsed = parseReflectionAutoSelectionJson(raw2);
|
|
454664
454700
|
if (!parsed || typeof parsed !== "object") {
|
|
454665
454701
|
throw new Error("Reflection selector did not return valid JSON.");
|
|
@@ -456368,36 +456404,6 @@ var init_turn_send = __esm(async () => {
|
|
|
456368
456404
|
]);
|
|
456369
456405
|
});
|
|
456370
456406
|
|
|
456371
|
-
// src/agent/preloaded-skills.ts
|
|
456372
|
-
import { readFile as readFile23 } from "node:fs/promises";
|
|
456373
|
-
async function loadPreloadedSkills(ids, options = {}) {
|
|
456374
|
-
if (ids.length === 0)
|
|
456375
|
-
return "";
|
|
456376
|
-
const { skillPathById } = await buildClientSkillsPayload({
|
|
456377
|
-
...options,
|
|
456378
|
-
skillSources: options.skillSources?.length === 0 ? ["bundled"] : options.skillSources
|
|
456379
|
-
});
|
|
456380
|
-
const contents = [];
|
|
456381
|
-
for (const id2 of ids) {
|
|
456382
|
-
const path42 = skillPathById[id2];
|
|
456383
|
-
if (!path42)
|
|
456384
|
-
continue;
|
|
456385
|
-
try {
|
|
456386
|
-
contents.push(`<${id2}>
|
|
456387
|
-
${await readFile23(path42, "utf-8")}
|
|
456388
|
-
</${id2}>`);
|
|
456389
|
-
} catch {}
|
|
456390
|
-
}
|
|
456391
|
-
return contents.length ? `<loaded_skills>
|
|
456392
|
-
${contents.join(`
|
|
456393
|
-
|
|
456394
|
-
`)}
|
|
456395
|
-
</loaded_skills>` : "";
|
|
456396
|
-
}
|
|
456397
|
-
var init_preloaded_skills = __esm(() => {
|
|
456398
|
-
init_client_skills();
|
|
456399
|
-
});
|
|
456400
|
-
|
|
456401
456407
|
// src/reminders/listen-context.ts
|
|
456402
456408
|
function buildListenReminderContext(params) {
|
|
456403
456409
|
return {
|
|
@@ -457222,7 +457228,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
|
|
|
457222
457228
|
conversationId
|
|
457223
457229
|
});
|
|
457224
457230
|
try {
|
|
457225
|
-
const agent = await
|
|
457231
|
+
const agent = await retrieveResumeState(agentId, conversationId);
|
|
457226
457232
|
const { pendingApprovals: existingApprovals } = await getResumeDataFromBackend(agent, requestedConversationId);
|
|
457227
457233
|
turnInput = rebuildTurnInputWithFreshDenials(turnInput, existingApprovals ?? [], STALE_APPROVAL_RECOVERY_DENIAL_REASON, isApprovalPendingError(errorDetail3));
|
|
457228
457234
|
} catch {
|
|
@@ -457635,8 +457641,8 @@ var init_turn = __esm(async () => {
|
|
|
457635
457641
|
init_approval_recovery();
|
|
457636
457642
|
init_chatgpt_plan_rotation();
|
|
457637
457643
|
init_check_approval();
|
|
457644
|
+
init_ephemeral_conversation();
|
|
457638
457645
|
init_turn_recovery_policy();
|
|
457639
|
-
init_backend2();
|
|
457640
457646
|
init_accumulator();
|
|
457641
457647
|
init_telemetry();
|
|
457642
457648
|
init_error_reporting();
|
|
@@ -482031,88 +482037,6 @@ var init_headless_cloud_send = __esm(() => {
|
|
|
482031
482037
|
init_headless_environment_response();
|
|
482032
482038
|
});
|
|
482033
482039
|
|
|
482034
|
-
// src/agent/ephemeral-conversation.ts
|
|
482035
|
-
async function buildEphemeralConversationCreateBody(options) {
|
|
482036
|
-
const system2 = options.systemPromptCustom ? options.systemPromptCustom : await resolveAndBuildSystemPrompt(options.systemPromptPreset, options.memoryPromptMode ?? "standard");
|
|
482037
|
-
const request3 = await buildCreateAgentRequest({
|
|
482038
|
-
model: options.model,
|
|
482039
|
-
system: system2,
|
|
482040
|
-
memoryPromptMode: "standard",
|
|
482041
|
-
enableMemfs: false,
|
|
482042
|
-
isSubagent: true,
|
|
482043
|
-
baseTools: []
|
|
482044
|
-
});
|
|
482045
|
-
const modelSettings = options.model ? getModelUpdateArgs(options.model) : undefined;
|
|
482046
|
-
const contextWindow = modelSettings?.context_window ?? await getModelContextWindow(request3.model);
|
|
482047
|
-
return {
|
|
482048
|
-
model: request3.model,
|
|
482049
|
-
system: request3.system ?? system2,
|
|
482050
|
-
...modelSettings ? { model_settings: modelSettings } : {},
|
|
482051
|
-
...contextWindow ? { context_window_limit: contextWindow } : {}
|
|
482052
|
-
};
|
|
482053
|
-
}
|
|
482054
|
-
function projectEphemeralAgent(conversationId, body3) {
|
|
482055
|
-
return {
|
|
482056
|
-
id: conversationId,
|
|
482057
|
-
name: "Ephemeral conversation",
|
|
482058
|
-
system: body3.system,
|
|
482059
|
-
tools: [],
|
|
482060
|
-
memory: { blocks: [] },
|
|
482061
|
-
llm_config: {
|
|
482062
|
-
handle: body3.model,
|
|
482063
|
-
model: body3.model,
|
|
482064
|
-
context_window: body3.context_window_limit ?? undefined,
|
|
482065
|
-
model_settings: body3.model_settings ?? {}
|
|
482066
|
-
},
|
|
482067
|
-
model_settings: body3.model_settings ?? {},
|
|
482068
|
-
message_buffer_autoclear: false
|
|
482069
|
-
};
|
|
482070
|
-
}
|
|
482071
|
-
async function createEphemeralConversation2(options) {
|
|
482072
|
-
const body3 = await buildEphemeralConversationCreateBody(options);
|
|
482073
|
-
const conversation = await createEphemeralConversation(body3);
|
|
482074
|
-
return {
|
|
482075
|
-
agent: projectEphemeralAgent(conversation.id, body3),
|
|
482076
|
-
conversationId: conversation.id
|
|
482077
|
-
};
|
|
482078
|
-
}
|
|
482079
|
-
async function createLocalEphemeralConversation(options) {
|
|
482080
|
-
const body3 = await buildEphemeralConversationCreateBody(options);
|
|
482081
|
-
const backend3 = getBackend();
|
|
482082
|
-
const internalAgent = await backend3.createAgent({
|
|
482083
|
-
agent_type: "letta_v1_agent",
|
|
482084
|
-
name: "Ephemeral conversation",
|
|
482085
|
-
model: body3.model,
|
|
482086
|
-
system: body3.system,
|
|
482087
|
-
memory_blocks: [],
|
|
482088
|
-
tags: [],
|
|
482089
|
-
tools: [],
|
|
482090
|
-
include_base_tools: false,
|
|
482091
|
-
include_base_tool_rules: false,
|
|
482092
|
-
initial_message_sequence: [],
|
|
482093
|
-
parallel_tool_calls: true,
|
|
482094
|
-
hidden: true
|
|
482095
|
-
});
|
|
482096
|
-
const conversation = await backend3.createConversation({
|
|
482097
|
-
agent_id: internalAgent.id,
|
|
482098
|
-
model: body3.model,
|
|
482099
|
-
...body3.model_settings ? { model_settings: body3.model_settings } : {},
|
|
482100
|
-
...body3.context_window_limit ? { context_window_limit: body3.context_window_limit } : {}
|
|
482101
|
-
});
|
|
482102
|
-
return {
|
|
482103
|
-
agent: internalAgent,
|
|
482104
|
-
conversationId: conversation.id
|
|
482105
|
-
};
|
|
482106
|
-
}
|
|
482107
|
-
var init_ephemeral_conversation = __esm(() => {
|
|
482108
|
-
init_available_models();
|
|
482109
|
-
init_create_agent_request();
|
|
482110
|
-
init_model();
|
|
482111
|
-
init_system_prompt_resolution();
|
|
482112
|
-
init_backend2();
|
|
482113
|
-
init_ephemeral_conversations();
|
|
482114
|
-
});
|
|
482115
|
-
|
|
482116
482040
|
// src/headless-ephemeral-startup.ts
|
|
482117
482041
|
function prepareHeadlessEphemeralBackend(enabled) {
|
|
482118
482042
|
if (enabled && isLocalBackendEnabled()) {
|
|
@@ -482144,6 +482068,18 @@ function clearHeadlessClientToolRules(agent) {
|
|
|
482144
482068
|
debugWarn("headless startup", `Failed to clear persisted client tool rules for ${agent.id}: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
482145
482069
|
});
|
|
482146
482070
|
}
|
|
482071
|
+
async function retrieveHeadlessConversation(backend3, conversationId) {
|
|
482072
|
+
const conversation = await backend3.retrieveConversation(conversationId);
|
|
482073
|
+
const detached = conversation.agent_id === null;
|
|
482074
|
+
const parentId = Reflect.get(conversation, "parent_agent_id");
|
|
482075
|
+
return {
|
|
482076
|
+
agent: detached ? projectConversationState(conversation) : await backend3.retrieveAgent(conversation.agent_id, {
|
|
482077
|
+
include: ["agent.tools", "agent.tags"]
|
|
482078
|
+
}),
|
|
482079
|
+
detached,
|
|
482080
|
+
parentAgentId: detached && typeof parentId === "string" ? parentId : null
|
|
482081
|
+
};
|
|
482082
|
+
}
|
|
482147
482083
|
var init_headless_ephemeral_startup = __esm(async () => {
|
|
482148
482084
|
init_ephemeral_conversation();
|
|
482149
482085
|
init_backend2();
|
|
@@ -482929,6 +482865,8 @@ In headless mode, use:
|
|
|
482929
482865
|
let specifiedAgentIdFromAmbient = false;
|
|
482930
482866
|
const forceNew = values4["new-agent"];
|
|
482931
482867
|
const ephemeralFlag = values4.ephemeral;
|
|
482868
|
+
let isDetached = Boolean(ephemeralFlag);
|
|
482869
|
+
let parentAgentId = null;
|
|
482932
482870
|
const systemPromptPreset = values4.system;
|
|
482933
482871
|
const systemCustom = values4["system-custom"];
|
|
482934
482872
|
const personalityInput = values4.personality;
|
|
@@ -483089,10 +483027,11 @@ In headless mode, use:
|
|
|
483089
483027
|
if (specifiedConversationId && specifiedConversationId !== "default") {
|
|
483090
483028
|
try {
|
|
483091
483029
|
debugLog("conversations", `retrieve(${specifiedConversationId}) [headless conv→agent lookup]`);
|
|
483092
|
-
|
|
483093
|
-
|
|
483094
|
-
|
|
483095
|
-
|
|
483030
|
+
({
|
|
483031
|
+
agent,
|
|
483032
|
+
detached: isDetached,
|
|
483033
|
+
parentAgentId
|
|
483034
|
+
} = await retrieveHeadlessConversation(startupBackend, specifiedConversationId));
|
|
483096
483035
|
} catch (error5) {
|
|
483097
483036
|
trackHeadlessBoundaryError("headless_conversation_lookup_failed", error5, "headless_startup_conversation_lookup");
|
|
483098
483037
|
console.error(`Conversation ${specifiedConversationId} not found`);
|
|
@@ -483215,9 +483154,9 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483215
483154
|
process.exit(1);
|
|
483216
483155
|
}
|
|
483217
483156
|
markMilestone("HEADLESS_AGENT_RESOLVED");
|
|
483218
|
-
const publicAgentId =
|
|
483157
|
+
const publicAgentId = isDetached ? null : agent.id;
|
|
483219
483158
|
telemetry.setCurrentAgent(publicAgentId, agent.tags);
|
|
483220
|
-
const isResumingAgent = !
|
|
483159
|
+
const isResumingAgent = !isDetached && !!(specifiedAgentId || !forceNew);
|
|
483221
483160
|
let conversationModel;
|
|
483222
483161
|
if (isResumingAgent) {
|
|
483223
483162
|
const modelHandle = model ? resolveModel(model) : undefined;
|
|
@@ -483240,7 +483179,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483240
483179
|
let effectiveReflectionSettings;
|
|
483241
483180
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
483242
483181
|
let startupMemfsFlag = autoEnableMemfsForFreshAgent ? true : memfsFlag;
|
|
483243
|
-
if (!isStatelessSession && backend3.capabilities.remoteMemfs && !autoEnableMemfsForFreshAgent) {
|
|
483182
|
+
if (!isStatelessSession && !isDetached && backend3.capabilities.remoteMemfs && !autoEnableMemfsForFreshAgent) {
|
|
483244
483183
|
const { hydrateMemfsSettingFromAgent: hydrateMemfsSettingFromAgent2, isLettaCloud: isLettaCloud2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
483245
483184
|
const memfsEnabled = await hydrateMemfsSettingFromAgent2(agent);
|
|
483246
483185
|
if (!memfsEnabled && await isLettaCloud2()) {
|
|
@@ -483248,9 +483187,9 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483248
483187
|
}
|
|
483249
483188
|
}
|
|
483250
483189
|
let memfsBgPromise;
|
|
483251
|
-
const secretsAgentId =
|
|
483190
|
+
const secretsAgentId = isDetached ? undefined : agent?.id;
|
|
483252
483191
|
const secretsInitPromise = secretsAgentId ? Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store)).then(({ initSecretsFromServer: initSecretsFromServer2 }) => initSecretsFromServer2(secretsAgentId)) : Promise.resolve();
|
|
483253
|
-
if (isStatelessSession) {
|
|
483192
|
+
if (isStatelessSession || isDetached) {
|
|
483254
483193
|
settingsManager.setMemfsEnabled(agent.id, false);
|
|
483255
483194
|
} else if (!backend3.capabilities.remoteMemfs) {
|
|
483256
483195
|
if (backend3.capabilities.localMemfs) {
|
|
@@ -483332,11 +483271,11 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483332
483271
|
memoryMode: getMemoryPromptModeForAgent2(taggedAgent.id)
|
|
483333
483272
|
});
|
|
483334
483273
|
}
|
|
483335
|
-
if (!
|
|
483274
|
+
if (!isDetached) {
|
|
483336
483275
|
clearHeadlessClientToolRules(agent);
|
|
483337
483276
|
}
|
|
483338
483277
|
try {
|
|
483339
|
-
if (
|
|
483278
|
+
if (isDetached) {
|
|
483340
483279
|
effectiveReflectionSettings = { trigger: "off", stepCount: 0 };
|
|
483341
483280
|
} else {
|
|
483342
483281
|
const resolvedReflectionSettings = await applyHeadlessReflectionOverrides(agent.id, reflectionOverrides);
|
|
@@ -483388,7 +483327,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483388
483327
|
}
|
|
483389
483328
|
markMilestone("HEADLESS_CONVERSATION_READY");
|
|
483390
483329
|
setConversationId(conversationId);
|
|
483391
|
-
if (!
|
|
483330
|
+
if (!isDetached && shouldPersistSessionState()) {
|
|
483392
483331
|
await settingsManager.loadLocalProjectSettings();
|
|
483393
483332
|
settingsManager.persistSession(agent.id, conversationId);
|
|
483394
483333
|
}
|
|
@@ -483530,7 +483469,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483530
483469
|
const resolveAllPendingApprovals = async (mode = "send_immediately") => {
|
|
483531
483470
|
const { getResumeDataFromBackend: getResumeDataFromBackend2 } = await Promise.resolve().then(() => (init_check_approval(), exports_check_approval));
|
|
483532
483471
|
while (true) {
|
|
483533
|
-
const freshAgent =
|
|
483472
|
+
const freshAgent = isDetached ? agent : await backend3.retrieveAgent(agent.id);
|
|
483534
483473
|
let resume;
|
|
483535
483474
|
try {
|
|
483536
483475
|
resume = await getResumeDataFromBackend2(freshAgent, conversationId);
|
|
@@ -483590,7 +483529,7 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483590
483529
|
}
|
|
483591
483530
|
}
|
|
483592
483531
|
};
|
|
483593
|
-
if (isResumingAgent) {
|
|
483532
|
+
if (isResumingAgent || !usesRemoteEnvironment && isDetached && !ephemeralFlag) {
|
|
483594
483533
|
try {
|
|
483595
483534
|
await resolveAllPendingApprovals("queue_for_next_turn");
|
|
483596
483535
|
} catch (approvalError) {
|
|
@@ -483650,9 +483589,12 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483650
483589
|
pushPart(prompt);
|
|
483651
483590
|
telemetry.trackUserInput(prompt, "user", reportModel ?? "unknown");
|
|
483652
483591
|
if (usesRemoteEnvironment) {
|
|
483592
|
+
const agentId = publicAgentId ?? parentAgentId;
|
|
483593
|
+
if (!agentId)
|
|
483594
|
+
throw new Error("Listener delivery requires a conversation with an agent or parent agent.");
|
|
483653
483595
|
const environmentSelector = explicitEnvironmentSelector ?? "";
|
|
483654
483596
|
const useCloudSandbox = isCloudEnvironmentSelector(environmentSelector);
|
|
483655
|
-
const environmentRouting = environmentSelector ? useCloudSandbox ? await resolveAgentSandboxConnectionId(
|
|
483597
|
+
const environmentRouting = environmentSelector ? useCloudSandbox ? await resolveAgentSandboxConnectionId(agentId, { conversationId }) : await resolveEnvironmentConnectionId(environmentSelector) : null;
|
|
483656
483598
|
const connectionId = environmentRouting?.connectionId ?? inheritedListenerConnectionId;
|
|
483657
483599
|
if (!connectionId)
|
|
483658
483600
|
throw new Error("No listener connection was resolved for this launch");
|
|
@@ -483666,8 +483608,9 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
483666
483608
|
noWait: isAgentLaunch || Boolean(values4["no-wait"]),
|
|
483667
483609
|
clientMessageId: values4["client-message-id"],
|
|
483668
483610
|
connectionId,
|
|
483611
|
+
parentAgentId: parentAgentId ?? undefined,
|
|
483669
483612
|
scope: {
|
|
483670
|
-
agent_id:
|
|
483613
|
+
agent_id: publicAgentId,
|
|
483671
483614
|
conversation_id: conversationId,
|
|
483672
483615
|
acting_user_id: resolveActingUserId()
|
|
483673
483616
|
},
|
|
@@ -534800,4 +534743,4 @@ function registerBunOAuthFlows() {
|
|
|
534800
534743
|
registerBunOAuthFlows();
|
|
534801
534744
|
await init_src5().then(() => exports_src2);
|
|
534802
534745
|
|
|
534803
|
-
//# debugId=
|
|
534746
|
+
//# debugId=25D231F0C01DA6C764756E2164756E21
|