diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index fde20cd9..9b35b395 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -43,6 +43,7 @@ updates:
- "/src/agent_env/agents/agents/claude-code"
- "/src/agent_env/agents/agents/codex"
- "/src/agent_env/agents/agents/gemini"
+ - "/src/agent_env/agents/agents/letta-code"
- "/src/agent_env/agents/agents/opencode"
- "/src/agent_env/agents/agents/openhands"
- "/src/agent_env/agents/agents/pi"
diff --git a/.github/scripts/infra_build.py b/.github/scripts/infra_build.py
index 4826777d..121caa52 100644
--- a/.github/scripts/infra_build.py
+++ b/.github/scripts/infra_build.py
@@ -34,6 +34,7 @@
"agentenv-claude-code": "src/agent_env/agents/agents/claude-code/Dockerfile",
"agentenv-codex": "src/agent_env/agents/agents/codex/Dockerfile",
"agentenv-gemini": "src/agent_env/agents/agents/gemini/Dockerfile",
+ "agentenv-letta-code": "src/agent_env/agents/agents/letta-code/Dockerfile",
"agentenv-opencode": "src/agent_env/agents/agents/opencode/Dockerfile",
"agentenv-openhands": "src/agent_env/agents/agents/openhands/Dockerfile",
"agentenv-pi": "src/agent_env/agents/agents/pi/Dockerfile",
@@ -72,6 +73,8 @@
'codex --version && mcp-remote --help >/dev/null && python -c "import a2a_server"'],
"agentenv-gemini": ["docker", "run", "--rm", "--entrypoint", "sh", "{image}", "-c",
'gemini --version && python -c "import a2a_server"'],
+ "agentenv-letta-code": ["docker", "run", "--rm", "--entrypoint", "sh", "{image}", "-c",
+ 'letta --version && python -c "import a2a_server"'],
"agentenv-opencode": ["docker", "run", "--rm", "--entrypoint", "sh", "{image}", "-c",
'opencode --version && python -c "import a2a_server"'],
"agentenv-openhands": ["docker", "run", "--rm", "--entrypoint", "sh", "{image}", "-c", 'python -c "import a2a_server"'],
diff --git a/src/agent_env/agents/README.md b/src/agent_env/agents/README.md
index d9a8cd42..720aa4bf 100644
--- a/src/agent_env/agents/README.md
+++ b/src/agent_env/agents/README.md
@@ -61,6 +61,14 @@ OpenAI-compatible one, `/v1/chat/completions`, and takes its model from th
`anthropic/claude-sonnet-4-6`. It declares `install/v1` too, into a container or onto a `vm` sandbox's Linux host,
with glibc. Its folder's `README.md` covers the extensions it implements.
+`agents/letta-code/` runs [Letta Code](https://github.com/letta-ai/letta-code) behind the protocol's A2A agent
+framework: each turn is one `letta --backend local -p --output-format stream-json` run, resumed in the context's
+conversation, with a separate local agent and memory per context. Name it as `letta-code`, its alias, or by its id,
+`@local/agentenv-framework/agents/letta-code`. It calls the `[model]` endpoint as an OpenAI-compatible one through
+a relay that adds task attribution, and takes its model from the prompt, else `openai/gpt-4.1-mini`. It declares
+`install/v1` too, into a container or onto a Linux host with glibc. Its folder's `README.md` covers the extensions
+it implements. Run its smoke task with `agent-env run agents --task letta-code-smoke`.
+
`agents/openhands/` runs the [OpenHands](https://github.com/OpenHands/software-agent-sdk) agent behind the
protocol's A2A agent framework, driving the OpenHands SDK in process rather than a CLI: each turn is one run of a
persisted SDK conversation, the task env's MCP servers go to its `mcp_config`, and its SDK events are the turn's
diff --git a/src/agent_env/agents/agents/letta-code/.dockerignore b/src/agent_env/agents/agents/letta-code/.dockerignore
new file mode 100644
index 00000000..513f7394
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/.dockerignore
@@ -0,0 +1,3 @@
+node_modules
+__pycache__
+*.pyc
diff --git a/src/agent_env/agents/agents/letta-code/Dockerfile b/src/agent_env/agents/agents/letta-code/Dockerfile
new file mode 100644
index 00000000..53cc4b5a
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/Dockerfile
@@ -0,0 +1,38 @@
+FROM public.ecr.aws/docker/library/python:3.11-slim@sha256:c20888b6acdd1e63e1c433a185bf3ad162c0288fe484616ce062e0d28add2900
+# Node to install the Letta Code CLI, a native binary, and for the model's commands, checked against its published
+# checksum; install.sh brings the same. poppler-utils renders a PDF attachment to the page images the model reads.
+ARG NODE_VERSION=22.23.4
+ARG NODE_SHA256_X64=b8492284c76a54baf58d61668dd0e41ee0fc98adabf9503d30f05d08f55b4406
+ARG NODE_SHA256_ARM64=f7a1e486dbc8b286847815b477d4fb5e9fb963ed4489c3e1588853d685f589f9
+RUN set -eu; \
+ apt-get update && apt-get install -y --no-install-recommends ca-certificates curl poppler-utils git \
+ && rm -rf /var/lib/apt/lists/*; \
+ case "$(uname -m)" in x86_64) cpu=x64 sha256=$NODE_SHA256_X64 ;; aarch64) cpu=arm64 sha256=$NODE_SHA256_ARM64 ;; \
+ *) echo "Node has no build for $(uname -m)" >&2; exit 1 ;; esac; \
+ curl -fsSL --retry 3 "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${cpu}.tar.gz" \
+ -o /tmp/node.tar.gz; \
+ echo "$sha256 /tmp/node.tar.gz" | sha256sum -c -; \
+ tar -xzf /tmp/node.tar.gz -C /usr/local --strip-components=1 --no-same-owner; \
+ rm /tmp/node.tar.gz
+WORKDIR /opt/agent
+# node-pty is interactive-only and has no Linux prebuild. Headless needs only these postinstalls.
+COPY package.json package-lock.json ./
+RUN npm ci --ignore-scripts --omit=dev --no-audit --no-fund --loglevel=error \
+ && npm rebuild @letta-ai/letta-code sharp protobufjs \
+ && npm cache clean --force \
+ && ln -s /opt/agent/node_modules/.bin/letta /usr/local/bin/letta
+COPY requirements.txt ./
+RUN pip install --no-cache-dir -r requirements.txt
+# install.sh and run.sh are install/v1's: in the image, so they stay in its build context.
+COPY mcp_tools.ts a2a_server.py letta_code_bridge.py letta_code_kit.py entrypoint.sh install.sh run.sh ./
+# The CLI's cwd, /app, and its state under /data, fixed so neither follows the uid: Modal runs the image as root.
+RUN useradd --create-home --uid 10001 agent && mkdir -p /app /data \
+ && chown agent:agent /app /data && chmod 0755 entrypoint.sh \
+ && find /opt/agent \( ! -perm -044 -o \( -perm /111 ! -perm -011 \) \) -exec chmod go+rX {} +
+ENV A2A_PORT=8000 PYTHONPATH=/opt/agent HOME=/data XDG_CONFIG_HOME=/data/config XDG_CACHE_HOME=/data/cache \
+ XDG_DATA_HOME=/data/share XDG_STATE_HOME=/data/state
+USER agent
+WORKDIR /app
+EXPOSE 8000
+# CMD rather than ENTRYPOINT: Modal passes a sandbox's env to the image's CMD only.
+CMD ["/opt/agent/entrypoint.sh"]
diff --git a/src/agent_env/agents/agents/letta-code/README.md b/src/agent_env/agents/agents/letta-code/README.md
new file mode 100644
index 00000000..9017d070
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/README.md
@@ -0,0 +1,39 @@
+# Letta Code A2A agent
+
+The [Letta Code](https://github.com/letta-ai/letta-code) CLI wrapped with `agentenv_protocol.a2a_agent`, shipped
+in the `agents` bundle as `@local/agentenv-framework/agents/letta-code`, with alias `letta-code`. This directory
+is the whole build context. The Dockerfile pins the Python base by digest and Node by version and checksum;
+`package-lock.json` pins `@letta-ai/letta-code` to 0.34.25.
+
+Each turn runs `letta --backend local -p --output-format stream-json --yolo`. The bridge creates an agent with
+`letta agents create`; the first turn uses `--agent --new`, and subsequent turns use
+`--conversation `. Each context has a separate home under `$HOME/sessions/`. Different contexts
+run concurrently; turns in one context and snapshot operations are synchronized.
+
+The bridge connects the local backend with `letta connect openai-compatible`. A per-turn loopback relay forwards
+requests to `$LITELLM_BASE_URL/v1`, with `LITELLM_API_KEY`, `[model.headers]` (`LITELLM_EXTRA_HEADERS`), and
+`project_id` / `task_id` as `x-litellm-customer-id` and `x-litellm-tags`. The model defaults to
+`openai/gpt-4.1-mini`. Endpoint credentials stay at the relay. Registered MCP servers retain their names and headers;
+a task role replaces `AgentEnv-Role`. Before each turn, `letta mcp tools --full` discovers the exact schemas. A context-local mod registers them as
+direct Letta Code tools through `letta.tools.register`; each tool executes `letta mcp call` with its full
+`mcp____` name. Peer tools use the same path.
+
+| Extension | Implementation |
+|---|---|
+| `agent-config/v1` | SDK set/get; `model`, `effort`, `system_prompt`, `output_format`, `project_id`, `task_id`, `timeout_seconds`. Before every turn, task instructions are committed to the existing agent's core memory, which the local backend compiles into its system prompt. JSON schema answers are validated locally. |
+| `mcp-config/v1` | SDK registration and listing; servers passed to the context's agent settings each turn, with their discovered schemas exposed as direct tools through the public mods API. |
+| `skill-config/v1` | Inline and bundle skills installed under `$HOME/.letta/skills/`, copied into each context's home before its turn. |
+| `trajectory/v1` | Native stream-json events appended live, format `letta-code-events/1`. |
+| `snapshot/v1` | Save archives the complete context home, including conversations, agent records, settings and git-backed memory; load stages it and restores it into the target context, rewriting stored home paths and binding the saved conversation. Optional workspace archives restore `/app`. The validator reports load/recall as false without its optional Claude Code rubric judge, as it does for the OpenCode baseline; a live cross-context recall probe verifies restore independently. GNU tar changelog captures task-level file increments, including removed roots, using the OpenCode template's implementation. |
+| `peer-agents/v1` | SDK default; its `peer_agents` MCP server is registered alongside task servers. |
+| `attribution-probe/v1` | Reports the project and task attribution used by the last CLI turn. |
+| `install/v1` | Template installer brings checksum-verified Node and uv, the pinned CLI, and a private Python into a container or a Linux host with glibc. Installs git if missing. |
+| `staging/v1` | SDK default. |
+
+The image runs as user `agent` in `/app`, with state under `/data`, and includes git and `pdftoppm`. PDF attachments
+are rendered as page images; other attachments are materialized and their paths passed to the CLI. Headless mode
+never loads node-pty, so installation skips dependency scripts and rebuilds only the CLI, sharp and protobufjs.
+The end of CLI stderr is included in failures. Cancellation and shutdown kill the CLI's process tree.
+
+Run `agent-env run agents --task letta-code-smoke` for the shell smoke task and
+`agent-env a2a-agent validate --id letta-code --sandbox local` for the repository's validator.
diff --git a/src/agent_env/agents/agents/letta-code/a2a_server.py b/src/agent_env/agents/agents/letta-code/a2a_server.py
new file mode 100644
index 00000000..d3bdd762
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/a2a_server.py
@@ -0,0 +1,659 @@
+"""A2A agent wrapping the Letta Code CLI.
+
+Built on agentenv-protocol's `AgentEnvAgent`: the framework serves the Agent Card,
+the A2A task lifecycle and the SDK-owned extensions (agent-config, mcp-config,
+skill listing, task trajectories, peer agents). Each turn is one
+`letta -p --output-format stream-json`, whose events are appended to the framework's
+trajectory log as the CLI prints them. A context's first turn starts a Letta Code
+session, which later turns resume with `--conversation `.
+"""
+from __future__ import annotations
+
+import asyncio
+from collections.abc import Callable
+import base64
+import binascii
+import json
+import logging
+import os
+import re
+import shutil
+import subprocess
+import tempfile
+import uuid
+from contextlib import asynccontextmanager
+from pathlib import Path
+from typing import Any
+from urllib.parse import urlparse
+from weakref import WeakValueDictionary
+
+import httpx
+from a2a.types import AgentSkill
+from agentenv_protocol.a2a_agent import (
+ ATTRIBUTION_PROBE_V1,
+ INSTALL_V1,
+ MCP_CONFIG_V1,
+ PEER_AGENTS_V1,
+ SKILL_CONFIG_V1,
+ SNAPSHOT_V1,
+ TRAJECTORY_V1,
+ AgentConfig,
+ AgentEnvAgent,
+ AgentIdentity,
+ AttributionProbeResponse,
+ BundleSkillRequest,
+ DataPart,
+ FilePart,
+ InlineSkillRequest,
+ NamespaceChangelogEnableRequest,
+ NamespaceUploader,
+ ObjectChangelogApplyRequest,
+ ObjectSnapshotLoadRequest,
+ ObjectSnapshotSaveRequest,
+ SkillAddResponse,
+ TaskRequest,
+ TaskResult,
+ TextPart,
+ Usage,
+ a2a_agent,
+ download,
+ enable,
+ extension,
+ upload,
+)
+from pydantic import Field, field_validator
+from starlette.applications import Starlette
+from starlette.exceptions import HTTPException
+
+from letta_code_bridge import (
+ ERROR_MESSAGE_LIMIT,
+ commit_staged_session,
+ event_session_id,
+ export_session,
+ get_last_attribution_snapshot,
+ kill_running_clis,
+ shielded_thread,
+ stage_session,
+ run_letta_code,
+ validate_output_format,
+)
+from letta_code_kit import DurableSessionRefs, install_skill, json_error_bodies
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+_XDG_CONFIG = os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config"))
+SKILLS_DIR = Path.home() / ".letta" / "skills"
+WORKSPACE_DIR = Path(os.environ.get("LETTA_CODE_WORKSPACE_DIR", "/app"))
+INPUTS_DIR = WORKSPACE_DIR / "inputs"
+# One per port, since agents installed on one host listen on their own.
+_CHANGELOG_DIR = Path(tempfile.gettempdir()) / f"letta_code-changelog-{os.environ.get('A2A_PORT') or 'default'}"
+_CHANGELOG_SNAR = _CHANGELOG_DIR / "state.snar"
+# Each increment's record of the roots it saw removed, in a directory of its own beside the changelog, which captures
+# exclude, and outside its roots: tar dumps a directory it hasn't seen whole, so the record goes in however soon after
+# the last capture it is written.
+_META_DIR_SUFFIX = ".changelog-meta"
+_META_NAME = "letta_code-changelog-meta.json"
+_CHANGELOG_META_DIR = _CHANGELOG_DIR.parent / f"{_CHANGELOG_DIR.name}{_META_DIR_SUFFIX}"
+# A record in an increment: _META_NAME in a sequence's directory under a directory named with _META_DIR_SUFFIX,
+# wherever the capturing agent kept it; a file of that name anywhere else is a file of the layer.
+_META_MEMBER = re.compile(rf"(?:^|/)[^/]+{re.escape(_META_DIR_SUFFIX)}/\d+/{re.escape(_META_NAME)}\Z")
+# Never removed on replay, whatever an increment's record says.
+_SYSTEM_DIRS = frozenset({"/", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/lib32", "/lib64", "/libx32",
+ "/media", "/mnt", "/opt", "/proc", "/root", "/run", "/sbin", "/srv", "/sys", "/tmp", "/usr",
+ "/var"})
+_TAR_VERSION_TIMEOUT_S = 10
+_FILE_DOWNLOAD_TIMEOUT_S = 60
+_PDF_RENDER_TIMEOUT_S = 60
+_PDF_RENDER_DPI = 150
+_SAFE_NAME_RE = re.compile(r"[^A-Za-z0-9._-]")
+# The versioned format of the `letta -p --output-format stream-json` events this agent appends to its trajectory.
+TRAJECTORY_FORMAT = "letta-code-events/1"
+
+
+def _backup_exclusions() -> list[str]:
+ if not WORKSPACE_DIR.exists():
+ return []
+ return [
+ f"--exclude=./{path.name}"
+ for path in WORKSPACE_DIR.iterdir()
+ if path.is_dir()
+ and path.name.startswith(".letta_code-backup-")
+ and (path / "saved").is_dir()
+ ]
+
+
+def _changelog_backup_exclusions() -> list[str]:
+ root = WORKSPACE_DIR.relative_to("/")
+ exclusions = _backup_exclusions()
+ return exclusions + [
+ f"--exclude={root / option.removeprefix('--exclude=./')}"
+ for option in exclusions
+ ]
+
+
+class LettaCodeConfig(AgentConfig):
+ model: str | None = None
+ effort: str | None = None
+ system_prompt: str | None = None
+ output_format: dict[str, Any] | None = None
+ project_id: str | None = None
+ task_id: str | None = None
+ timeout_seconds: int = Field(default=1800, gt=0)
+
+ @field_validator("output_format")
+ @classmethod
+ def check_output_format(cls, value: dict[str, Any] | None) -> dict[str, Any] | None:
+ if value is not None:
+ validate_output_format(value)
+ return value
+
+
+class FilePartMaterializeError(Exception):
+ """A supplied file cannot be passed to Letta Code."""
+
+
+def _safe_name(candidate: str | None, fallback_ext: str = "") -> str:
+ if candidate:
+ candidate = _SAFE_NAME_RE.sub("_", Path(candidate).name)
+ return candidate or f"{uuid.uuid4().hex}{fallback_ext}"
+
+
+def _download_uri_to(uri: str, target: Path) -> None:
+ parsed = urlparse(uri)
+ if parsed.scheme in ("http", "https"):
+ try:
+ with httpx.Client(timeout=_FILE_DOWNLOAD_TIMEOUT_S, follow_redirects=True) as client:
+ response = client.get(uri)
+ response.raise_for_status()
+ target.write_bytes(response.content)
+ except httpx.HTTPError as exc:
+ raise FilePartMaterializeError("HTTP file download failed") from exc
+ else:
+ raise FilePartMaterializeError(f"unsupported file URI scheme {parsed.scheme!r}")
+
+
+def _materialize_and_render(part: FilePart, task_id: str) -> list[str]:
+ directory = INPUTS_DIR / task_id
+ directory.mkdir(parents=True, exist_ok=True)
+ name = _safe_name(part.name)
+ target = directory / name
+ if target.exists():
+ target = directory / f"{uuid.uuid4().hex[:8]}-{name}"
+ if part.bytes is not None:
+ try:
+ target.write_bytes(base64.b64decode(part.bytes, validate=True))
+ except (binascii.Error, ValueError, OSError) as exc:
+ raise FilePartMaterializeError(f"invalid file attachment {name!r}") from exc
+ else:
+ _download_uri_to(part.uri, target)
+ if (part.mime_type or "").lower() != "application/pdf" and target.suffix.lower() != ".pdf":
+ return [str(target)]
+ # The openai-compatible provider can't forward PDF document blocks, so a PDF goes as its pages' images.
+ prefix = str(target.with_suffix("")) + "_page"
+ try:
+ subprocess.run(
+ ["pdftoppm", "-png", "-r", str(_PDF_RENDER_DPI), str(target), prefix],
+ check=True, capture_output=True, timeout=_PDF_RENDER_TIMEOUT_S,
+ )
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
+ logger.warning("PDF rendering failed for %s; passing the PDF directly", target)
+ return [str(target)]
+ pages = sorted(directory.glob(f"{Path(prefix).name}*.png"))
+ return [str(page) for page in pages] or [str(target)]
+
+
+class _WorkspaceBarrier:
+ """Turns share the workspace and snapshots take it alone, so a snapshot's session and files come from a point no
+ turn is writing at, while turns of different contexts run at once. A waiting snapshot holds new turns back, so
+ it is never starved."""
+
+ def __init__(self) -> None:
+ self._condition = asyncio.Condition()
+ self._readers = 0
+ self._writer = False
+ self._waiting_writers = 0
+
+ @asynccontextmanager
+ async def shared(self):
+ async with self._condition:
+ await self._condition.wait_for(lambda: not self._writer and self._waiting_writers == 0)
+ self._readers += 1
+ try:
+ yield
+ finally:
+ async with self._condition:
+ self._readers -= 1
+ if self._readers == 0:
+ self._condition.notify_all()
+
+ @asynccontextmanager
+ async def exclusive(self):
+ async with self._condition:
+ self._waiting_writers += 1
+ try:
+ await self._condition.wait_for(lambda: not self._writer and self._readers == 0)
+ self._writer = True
+ finally:
+ self._waiting_writers -= 1
+ if not self._writer:
+ self._condition.notify_all()
+ try:
+ yield
+ finally:
+ async with self._condition:
+ self._writer = False
+ self._condition.notify_all()
+
+
+@asynccontextmanager
+async def lifespan(app: Starlette):
+ """As the server stops, the CLIs of turns still running are killed, which would otherwise go on in the workspace
+ after it."""
+ try:
+ yield
+ finally:
+ if stopped := kill_running_clis():
+ logger.info(f"Killed {stopped} letta_code CLI(s) still running a turn as the agent shut down")
+
+
+# install.sh, from the build context install_agent unpacks, brings Node, the Letta Code CLI and a Python of the agent's
+# own; the endpoint reaches it as environment, never as arguments.
+_UNPACK = "mkdir -p {work_dir}/agent && tar -xzf {agent_ctx_tar} -C {work_dir}/agent"
+_ENDPOINT = ("LITELLM_API_KEY={litellm_api_key} LITELLM_BASE_URL={litellm_base_url} "
+ "LITELLM_EXTRA_HEADERS={litellm_extra_headers} AGENT_TRUST_ENV={trust_env} ")
+_ENDPOINT_PARAMS = ["litellm_api_key", "litellm_base_url", "litellm_extra_headers", "trust_env"]
+_INSTALL_COMMANDS = [_UNPACK, _ENDPOINT + "bash {work_dir}/agent/install.sh container {container} {a2a_port}"]
+_HOST_WORKDIR = "/app"
+_INSTALL_COMMANDS_HOST = [_UNPACK, _ENDPOINT + f"bash {{work_dir}}/agent/install.sh host {{agent_name}} {{a2a_port}} {_HOST_WORKDIR}"]
+
+
+@a2a_agent(
+ identity=AgentIdentity(
+ name="Letta Code",
+ description="A2A-compliant wrapper around the Letta Code CLI.",
+ version="1.0.0",
+ input_modes=("text", "image/png", "image/jpeg", "image/gif", "image/webp", "application/pdf"),
+ output_modes=("text",),
+ skills=(AgentSkill(
+ id="letta-code", name="letta-code",
+ description="Runs the Letta Code CLI with full tool access (bash, read, edit, glob, grep).",
+ tags=["coding", "agent"],
+ ),),
+ ),
+ config=LettaCodeConfig,
+ extensions=(
+ MCP_CONFIG_V1,
+ enable(TRAJECTORY_V1, live=True),
+ enable(ATTRIBUTION_PROBE_V1),
+ enable(
+ INSTALL_V1,
+ install_commands=_INSTALL_COMMANDS,
+ # Port the agent's A2A server listens on inside the container.
+ a2a_port=8000,
+ # Every placeholder referenced in install_commands must be in this list.
+ required_params=["container", "work_dir", "agent_ctx_tar", "a2a_port", *_ENDPOINT_PARAMS],
+ install_commands_host=_INSTALL_COMMANDS_HOST,
+ required_params_host=["work_dir", "agent_ctx_tar", "a2a_port", "agent_name", *_ENDPOINT_PARAMS],
+ workdir_host=_HOST_WORKDIR,
+ user_host="root",
+ ),
+ # SDK default: the CLI reaches the task's other agents through the SDK's peer_agents MCP tools.
+ PEER_AGENTS_V1,
+ ),
+ lifespan=lifespan,
+ workspace=str(WORKSPACE_DIR),
+)
+class LettaCodeAgent(DurableSessionRefs, AgentEnvAgent):
+ """Bridges A2A tasks onto `letta_code run`."""
+
+ def __init__(self) -> None:
+ self._turn_locks: WeakValueDictionary[str, asyncio.Lock] = WeakValueDictionary()
+ self._changelog: dict[str, Any] | None = None
+ self._changelog_lock = asyncio.Lock()
+ self._workspace = _WorkspaceBarrier()
+
+ def _turn_lock(self, context_id: str) -> asyncio.Lock:
+ return self._turn_locks.setdefault(context_id, asyncio.Lock())
+
+ async def run(self, request: TaskRequest[LettaCodeConfig]) -> TaskResult:
+ # The CLI's JSON events, appended as it prints them, are the turn's
+ # trajectory: readable while it runs, and its final record once it ends.
+ request.trajectory.set_format(TRAJECTORY_FORMAT)
+ prompt = "\n".join(part.text for part in request.parts if isinstance(part, TextPart) and part.text)
+ context_id = request.context_id
+ async with self._workspace.shared(), self._turn_lock(context_id):
+ # Read under the lock rather than from the request: a snapshot load that held it may have just bound this
+ # context to an imported session.
+ session_id = self.session_ref_for_context(context_id)
+
+ def record(event: dict) -> None:
+ request.trajectory.append(event)
+ # A first turn's session is bound as soon as the CLI names it, so a cancel can't lose it.
+ if self.session_ref_for_context(context_id) is None and (started := event_session_id(event)):
+ self.set_session_ref_for_context(context_id, started)
+ try:
+ attachments = []
+ for part in request.parts:
+ if isinstance(part, FilePart):
+ attachments.extend(await asyncio.to_thread(_materialize_and_render, part, request.task_id))
+ except FilePartMaterializeError as exc:
+ return TaskResult.failure("filepart_error", str(exc), error_type="infra_error")
+ try:
+ result = await run_letta_code(
+ prompt=prompt,
+ context_id=context_id,
+ session_id=session_id,
+ model=request.config.model,
+ effort=request.config.effort,
+ mcp_servers=dict(request.mcp_servers),
+ system_prompt=request.config.system_prompt,
+ output_format=request.config.output_format,
+ timeout_s=request.config.timeout_seconds,
+ project_id=request.config.project_id,
+ task_id=request.config.task_id,
+ role=request.config.role,
+ attachment_paths=attachments,
+ event_callback=record,
+ workspace=str(WORKSPACE_DIR),
+ )
+ except Exception:
+ logger.exception("Letta Code invocation failed")
+ return TaskResult.failure(
+ "letta_code_invocation_error", "Letta Code invocation failed", error_type="infra_error"
+ )
+ if result.session_id:
+ self.set_session_ref_for_context(context_id, result.session_id)
+ await self._capture_changelog()
+
+ parts = [TextPart(text=result.response or result.error or "")]
+ usage = Usage(tool_call_count=result.tool_call_count)
+ if result.error:
+ details = {"error_type": "cli_error", "error_message": result.error[:ERROR_MESSAGE_LIMIT]}
+ if result.error_code:
+ details["error_code"] = result.error_code
+ parts.append(DataPart(data=details))
+ return (
+ TaskResult.builder()
+ .failed(result.error_code or "letta_code_cli_error", result.error[:ERROR_MESSAGE_LIMIT])
+ .parts(parts)
+ .session_ref(result.session_id)
+ .usage(usage)
+ .build()
+ )
+ response = (
+ TaskResult.builder()
+ .succeeded()
+ .parts(parts)
+ .session_ref(result.session_id)
+ .usage(usage)
+ )
+ if request.config.output_format is not None:
+ response.add_structured_output(getattr(result, "structured_output", None))
+ return response.build()
+
+ @extension(SKILL_CONFIG_V1.add.inline)
+ async def add_inline_skill(self, request: InlineSkillRequest) -> SkillAddResponse:
+ return await install_skill(request, SKILLS_DIR)
+
+ @extension(SKILL_CONFIG_V1.add.bundle)
+ async def add_bundle_skill(self, request: BundleSkillRequest) -> SkillAddResponse:
+ return await install_skill(request, SKILLS_DIR)
+
+ @extension(ATTRIBUTION_PROBE_V1.probe)
+ async def probe_attribution(self) -> AttributionProbeResponse:
+ """The LiteLLM attribution the last CLI run sent with its model calls."""
+ snapshot = get_last_attribution_snapshot()
+ return AttributionProbeResponse(
+ last_seen_attribution={
+ key: value for key, value in snapshot.items() if key != "last_seen_at_utc" and isinstance(value, str)
+ },
+ last_seen_at_utc=snapshot.get("last_seen_at_utc"),
+ )
+
+ @extension(SNAPSHOT_V1.save)
+ async def save_snapshot(self, request: ObjectSnapshotSaveRequest) -> dict[str, Any]:
+ with tempfile.TemporaryDirectory(prefix="letta_code-snapshot-") as directory:
+ workspace = Path(directory) / "workspace.tgz"
+ async with self._workspace.exclusive(), self._turn_lock(request.context_id):
+ # Read once no turn runs: a context's first turn, or a load into it, may be about to bind it.
+ session_id = self.session_ref_for_context(request.context_id)
+ if not session_id:
+ raise HTTPException(status_code=404, detail="No active session for context_id")
+ session_json = await export_session(request.context_id, session_id)
+ if request.objects.workspace is not None:
+ await asyncio.to_thread(
+ subprocess.run,
+ ["tar", *_backup_exclusions(), "-czf", str(workspace),
+ "-C", str(WORKSPACE_DIR), "."],
+ check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
+ )
+ objects = {"trajectory": (await upload(request.objects.trajectory, session_json)).model_dump(mode="json")}
+ if request.objects.workspace is not None:
+ objects["workspace"] = (await upload(request.objects.workspace, workspace)).model_dump(mode="json")
+ return {"context_id": request.context_id, "objects": objects}
+
+ @extension(SNAPSHOT_V1.load)
+ async def load_snapshot(self, request: ObjectSnapshotLoadRequest) -> dict[str, Any]:
+ target_context_id = request.target_context_id or uuid.uuid4().hex
+ with tempfile.TemporaryDirectory(prefix="letta_code-restore-") as directory:
+ session_file = Path(directory) / "session.json"
+ await download(request.objects.trajectory, session_file)
+ staged = None
+ if request.objects.workspace is not None:
+ archive = Path(directory) / "workspace.tgz"
+ staged = Path(directory) / "workspace"
+ staged.mkdir()
+ await download(request.objects.workspace, archive)
+ await asyncio.to_thread(
+ subprocess.run, ["tar", "-xzf", str(archive), "-C", str(staged)],
+ check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
+ )
+ async with self._workspace.exclusive(), self._turn_lock(target_context_id):
+ # Stage the conversation first, so a bad snapshot changes nothing. The workspace swap and the
+ # conversation swap then run in one thread that cancellation can't abandon: a failed conversation
+ # swap puts /app back, and the context's previous conversation stays in place until both succeed.
+ session_dir = Path(directory) / "session"
+ session_dir.mkdir()
+ imported_session_id, staged_session = await shielded_thread(
+ stage_session, target_context_id, str(session_file), str(session_dir))
+ if not imported_session_id:
+ raise HTTPException(status_code=500, detail="Letta Code import returned no session id")
+
+ def commit_session() -> None:
+ commit_staged_session(target_context_id, staged_session)
+
+ if staged is not None:
+ await shielded_thread(_replace_workspace, staged, commit_session)
+ else:
+ await shielded_thread(commit_session)
+ self.set_session_ref_for_context(target_context_id, imported_session_id)
+ return {"context_id": target_context_id}
+
+ async def _capture_changelog(self) -> None:
+ """One incremental tar of the changelog's roots, uploaded after each turn, with the roots removed since the
+ last; the baseline advances only once the upload succeeds, so a failed capture's changes, and its removals, go
+ with the next."""
+ async with self._changelog_lock:
+ config = self._changelog
+ if config is None:
+ return
+ roots = [root for root in config["roots"] if Path(root).exists()]
+ removed = [root for root in config["present"] if root not in roots]
+ if not roots and not removed:
+ return
+ sequence = config["sequence"]
+ _CHANGELOG_DIR.mkdir(parents=True, exist_ok=True)
+ archive = _CHANGELOG_DIR / f"{sequence:06d}.tgz"
+ pending_snar = _CHANGELOG_DIR / "pending.snar"
+ record = _CHANGELOG_META_DIR / f"{sequence:06d}"
+ try:
+ await asyncio.to_thread(shutil.rmtree, record, True)
+ record.mkdir(parents=True)
+ (record / _META_NAME).write_text(json.dumps({"sequence": sequence, "removed": removed}))
+ await asyncio.to_thread(shutil.copyfile, _CHANGELOG_SNAR, pending_snar)
+ await asyncio.to_thread(
+ subprocess.run,
+ ["tar", f"--listed-incremental={pending_snar}",
+ *_changelog_backup_exclusions(),
+ f"--exclude={_CHANGELOG_DIR}", "-czf", str(archive), *roots, str(record)],
+ check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
+ )
+ await config["uploader"].upload(f"{sequence:06d}.tgz", archive)
+ pending_snar.replace(_CHANGELOG_SNAR)
+ config["present"] = roots
+ config["sequence"] += 1
+ except Exception:
+ logger.exception("Letta Code changelog capture failed")
+ finally:
+ archive.unlink(missing_ok=True)
+ pending_snar.unlink(missing_ok=True)
+ await asyncio.to_thread(shutil.rmtree, record, True)
+
+
+class LettaCodeChangelogAgent(LettaCodeAgent):
+ """With snapshot/v1's changelog, which needs GNU tar's incremental archives. Letta Code has no hook after each tool
+ call, so an increment is a completed turn's changes; conversation state lives outside the captured roots, so
+ apply restores files only."""
+
+ @extension(SNAPSHOT_V1.changelog.enable)
+ async def enable_changelog(self, request: NamespaceChangelogEnableRequest) -> dict[str, Any]:
+ roots = request.roots or [str(WORKSPACE_DIR)]
+ async with self._workspace.exclusive(), self._changelog_lock:
+ await asyncio.to_thread(_baseline_changelog, roots)
+ self._changelog = {"roots": roots, "sequence": 0, "present": [root for root in roots if Path(root).exists()],
+ "uploader": NamespaceUploader(request.write_namespace)}
+ return {"roots": roots}
+
+ @extension(SNAPSHOT_V1.changelog.apply)
+ async def apply_changelog(self, request: ObjectChangelogApplyRequest) -> dict[str, Any]:
+ async with self._workspace.exclusive():
+ with tempfile.TemporaryDirectory(prefix="letta_code-changelog-apply-") as directory:
+ for increment in request.increments:
+ archive = Path(directory) / f"{increment.sequence:06d}.tgz"
+ await download(increment.object, archive)
+ await asyncio.to_thread(_apply_increment, archive, increment.sequence)
+ return {"count": len(request.increments), "context_id": request.target_context_id}
+
+
+def _replace_workspace(staged: Path, then: Callable[[], None] | None = None) -> None:
+ """Swap staged in for /app's contents. When then() raises after the swap, /app's previous contents come back."""
+ WORKSPACE_DIR.mkdir(parents=True, exist_ok=True)
+ backup = Path(tempfile.mkdtemp(prefix=".letta_code-backup-", dir=WORKSPACE_DIR))
+ saved = backup / "saved"
+ saved.mkdir()
+ committed = False
+
+ def restore_saved() -> None:
+ for child in WORKSPACE_DIR.iterdir():
+ if child == backup:
+ continue
+ if child.is_dir() and not child.is_symlink():
+ shutil.rmtree(child)
+ else:
+ child.unlink()
+ for child in saved.iterdir():
+ child.rename(WORKSPACE_DIR / child.name)
+
+ try:
+ try:
+ for child in WORKSPACE_DIR.iterdir():
+ if child != backup:
+ child.rename(saved / child.name)
+ except Exception:
+ for child in saved.iterdir():
+ child.rename(WORKSPACE_DIR / child.name)
+ raise
+ try:
+ for child in staged.iterdir():
+ shutil.move(str(child), str(WORKSPACE_DIR / child.name))
+ if then is not None:
+ then()
+ committed = True
+ except Exception:
+ restore_saved()
+ raise
+ finally:
+ if committed:
+ try:
+ shutil.rmtree(backup)
+ except OSError:
+ logger.warning("Could not remove snapshot backup %s", backup, exc_info=True)
+ elif not any(saved.iterdir()):
+ saved.rmdir()
+ backup.rmdir()
+
+
+def _apply_increment(archive: Path, sequence: int) -> None:
+ """Extract an increment over /, all but its record, then remove the roots its record names."""
+ listing = subprocess.run(["tar", "--incremental", "-tzf", str(archive)], check=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).stdout.decode(errors="replace").splitlines()
+ records = [member for member in listing if _META_MEMBER.search(member)]
+ # The record's directory is the capture's, not part of the layer it restores.
+ excluded = {member.rsplit("/", 1)[0] for member in records}
+ subprocess.run(
+ ["tar", "--incremental", "--no-wildcards", *(f"--exclude={member}" for member in sorted(excluded)),
+ "-xzf", str(archive), "-C", "/"],
+ check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
+ )
+ for member in records:
+ record = subprocess.run(["tar", "-xzOf", str(archive), member], check=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).stdout
+ try:
+ removed = json.loads(record).get("removed")
+ except (ValueError, AttributeError):
+ logger.warning(f"changelog increment {sequence:06d}: unreadable record {member}")
+ continue
+ for path in removed if isinstance(removed, list) else []:
+ if not _removable(path):
+ logger.warning(f"changelog increment {sequence:06d}: not removing {path!r}")
+ continue
+ if os.path.isdir(path) and not os.path.islink(path):
+ shutil.rmtree(path)
+ else:
+ os.unlink(path)
+ logger.info(f"changelog increment {sequence:06d}: removed root {path}")
+
+
+def _removable(path: object) -> bool:
+ """Whether a removed root a record names may be removed on replay: an absolute, normalized path that exists and
+ isn't / or a top-level system directory."""
+ return (isinstance(path, str) and os.path.isabs(path) and os.path.normpath(path) == path
+ and path not in _SYSTEM_DIRS and os.path.lexists(path))
+
+
+def _baseline_changelog(roots: list[str]) -> None:
+ _CHANGELOG_DIR.mkdir(parents=True, exist_ok=True)
+ _CHANGELOG_SNAR.unlink(missing_ok=True)
+ present = [root for root in roots if Path(root).exists()]
+ subprocess.run(
+ ["tar", f"--listed-incremental={_CHANGELOG_SNAR}",
+ *_changelog_backup_exclusions(),
+ "-cf", "/dev/null", *present],
+ check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
+ )
+
+
+def gnu_tar() -> bool:
+ """Whether this host's tar is GNU tar, which the changelog's incremental archives need."""
+ try:
+ version = subprocess.run(["tar", "--version"], capture_output=True, text=True,
+ timeout=_TAR_VERSION_TIMEOUT_S).stdout
+ except (OSError, subprocess.SubprocessError):
+ return False
+ return "GNU tar" in version
+
+
+def agent_for_this_host() -> LettaCodeAgent:
+ """The agent, with the changelog where this host's tar can make its archives."""
+ return LettaCodeChangelogAgent() if gnu_tar() else LettaCodeAgent()
+
+
+def build_app(agent: LettaCodeAgent) -> Starlette:
+ """The agent's Starlette app, answering errors with FastAPI's `{"detail": ...}` bodies."""
+ return json_error_bodies(agent.create_app())
+
+
+app = build_app(agent_for_this_host())
+# agent-env's install/v1 deploys find the install parameters by importing this name from the image.
+AGENT_CARD = app.state.agentenv_a2a.card
diff --git a/src/agent_env/agents/agents/letta-code/entrypoint.sh b/src/agent_env/agents/agents/letta-code/entrypoint.sh
new file mode 100644
index 00000000..c59e6c1c
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/entrypoint.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -e
+# A stop waits this long for open requests, then the server shuts down and kills the CLIs of turns still running.
+exec uvicorn a2a_server:app --host 0.0.0.0 --port "${A2A_PORT:-8000}" --timeout-graceful-shutdown 5
diff --git a/src/agent_env/agents/agents/letta-code/install.sh b/src/agent_env/agents/agents/letta-code/install.sh
new file mode 100644
index 00000000..7197ad11
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/install.sh
@@ -0,0 +1,175 @@
+#!/bin/bash
+# Install this agent from the folder this script is in, and start it on PORT, without an image of its own:
+#
+# install.sh container NAME PORT into the running container NAME, as root, with /app as the CLI's workspace
+# install.sh host NAME PORT WORKDIR onto this Linux host, as agent NAME, with WORKDIR as the CLI's workspace
+#
+# It brings Node and uv, each checked against its published checksum, the Letta Code CLI as package-lock.json pins it, and
+# the agent's requirements in a private Python, so the target's own Node, Python and packages are never touched; a
+# target with no Node or Python of its own gets these at the end of its PATH. Node's builds need glibc, and a target
+# with no bash, which the model's commands run in, gets it from its own package manager. The model endpoint's
+# LITELLM_API_KEY, LITELLM_BASE_URL and LITELLM_EXTRA_HEADERS, and AGENT_TRUST_ENV, the KEY='VALUE' lines of the CA
+# variables the agent needs, come in the environment and are kept in a 0600 file the agent reads.
+set -euo pipefail
+umask 077
+
+mode=$1 target=$2 port=$3
+here=$(cd "$(dirname "$0")" && pwd)
+
+UV_VERSION=0.13.1
+UV_SHA256_X86_64=6c86040a8f045ab9adc9e3ec4cdafa03fd00e9a988ed2bf28971c7fc2d0debd0
+UV_SHA256_AARCH64=345a8308e4d1835cdfaadf692836fd3137a6d45864773f05ad7bf59442b1ba16
+PYTHON_VERSION=3.12
+START_TIMEOUT_S=120
+STOP_TIMEOUT_S=10
+dockerfile_arg() { sed -n "s/^ARG $1=//p" "$here/Dockerfile"; }
+NODE_VERSION=$(dockerfile_arg NODE_VERSION)
+AGENT_FILES="mcp_tools.ts a2a_server.py letta_code_bridge.py letta_code_kit.py requirements.txt run.sh"
+
+# put SRC DEST replaces DEST by a rename, so a binary an earlier install's agent still runs can be replaced; put_dir SRC
+# DEST copies a folder to DEST, which isn't there.
+case $mode in
+ container)
+ root=/opt/agentenv-agent-$port # one per agent: two in a container listen on two ports
+ workspace=/app
+ on() { docker exec -u 0 "$target" sh -c "$1"; }
+ put() { docker cp "$1" "$target:$2.new" > /dev/null && on "mv -f $(quoted "$2.new") $(quoted "$2")"; }
+ put_dir() { docker cp "$1" "$target:$2" > /dev/null; }
+ ;;
+ host)
+ [ "$(uname -s)" = Linux ] || { echo "a host install needs a Linux host, not $(uname -s)" >&2; exit 1; }
+ # Outside the work dir install_agent empties before each attempt, as a container's is, so a retry stops the agent an
+ # earlier attempt started. It ends in the sandbox's id, which names what a local sandbox's teardown removes from
+ # /tmp; a VM's host goes with the VM.
+ root=/tmp/agentenv-agent-$target-$port${AGENTENV_SANDBOX:+-$AGENTENV_SANDBOX}
+ workspace=$4
+ on() { sh -c "$1"; }
+ put() { cp "$1" "$2.new" && mv -f "$2.new" "$2"; }
+ put_dir() { cp -R "$1" "$2"; }
+ ;;
+ *) echo "usage: install.sh container NAME PORT | install.sh host NAME PORT WORKDIR" >&2; exit 2 ;;
+esac
+
+if [ "$mode" = host ]; then
+ # /tmp is shared, and the folder will hold the model key: it is this user's alone, and one another made is refused.
+ if ! mkdir -m 0700 "$root" 2> /dev/null; then
+ [ -d "$root" ] && [ ! -L "$root" ] && [ -O "$root" ] \
+ || { echo "$root is already there and isn't a folder of this user's own" >&2; exit 1; }
+ chmod 0700 "$root"
+ fi
+fi
+
+case $(on 'uname -m') in
+ x86_64|amd64) cpu=x64 uv_cpu=x86_64 uv_sha256=$UV_SHA256_X86_64 node_sha256=$(dockerfile_arg NODE_SHA256_X64) ;;
+ aarch64|arm64) cpu=arm64 uv_cpu=aarch64 uv_sha256=$UV_SHA256_AARCH64 node_sha256=$(dockerfile_arg NODE_SHA256_ARM64) ;;
+ *) echo "Node has no build for $(on 'uname -m')" >&2; exit 1 ;;
+esac
+if on 'for f in /lib/ld-musl-*; do [ -e "$f" ] && exit 0; done; exit 1'; then
+ echo "Node's builds need glibc, and the target's libc is musl" >&2
+ exit 1
+fi
+
+if ! on 'command -v bash >/dev/null'; then
+ on 'if command -v apt-get >/dev/null; then apt-get update -qq && apt-get install -y -qq --no-install-recommends bash
+ elif command -v dnf >/dev/null; then dnf install -y -q bash
+ elif command -v microdnf >/dev/null; then microdnf install -y bash
+ else exit 1; fi' > /dev/null \
+ || { echo "the model's commands run in bash: the target has none, and bash can't be added" >&2; exit 1; }
+fi
+
+# Letta Code keeps agent memory in git, including on freshly installed targets.
+if ! on 'command -v git >/dev/null'; then
+ on 'if command -v apt-get >/dev/null; then apt-get update -qq && apt-get install -y -qq --no-install-recommends git
+ elif command -v dnf >/dev/null; then dnf install -y -q git
+ elif command -v microdnf >/dev/null; then microdnf install -y git
+ else exit 1; fi' > /dev/null \
+ || { echo "Letta Code requires git, and git cannot be added" >&2; exit 1; }
+fi
+
+sha256() { if command -v sha256sum >/dev/null; then sha256sum "$1"; else shasum -a 256 "$1"; fi | cut -d' ' -f1; }
+fetch() { curl -fsSL --retry 3 "$1" -o "$2"; }
+checked() { # checked FILE SHA256: FILE is what was published, or the install stops
+ [ "$(sha256 "$1")" = "$2" ] || { echo "$(basename "$1") doesn't match its published checksum" >&2; exit 1; }
+}
+quoted() { printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"; }
+r=$(quoted "$root") # $root, as the commands run in the target read it
+
+# Beside this script, in the work dir the sandbox's teardown removes, so a killed install leaves nothing elsewhere.
+stage=$(mktemp -d "$here/../stage.XXXXXX")
+trap 'rm -rf "$stage"' EXIT
+
+node_archive=node-v$NODE_VERSION-linux-$cpu.tar.gz
+fetch "https://nodejs.org/dist/v$NODE_VERSION/$node_archive" "$stage/$node_archive"
+checked "$stage/$node_archive" "$node_sha256"
+mkdir "$stage/node"
+tar -xzf "$stage/$node_archive" -C "$stage/node" --strip-components=1
+
+uv_archive=uv-$uv_cpu-unknown-linux-musl.tar.gz
+fetch "https://github.com/astral-sh/uv/releases/download/$UV_VERSION/$uv_archive" "$stage/$uv_archive"
+checked "$stage/$uv_archive" "$uv_sha256"
+tar -xzf "$stage/$uv_archive" -C "$stage"
+chmod 0755 "$stage/uv-$uv_cpu-unknown-linux-musl/uv"
+
+# Use the private Node to execute the pinned CLI.
+printf '#!/bin/sh\nexec %s %s "$@"\n' "$(quoted "$root/node/bin/node")" \
+ "$(quoted "$root/npm/node_modules/@letta-ai/letta-code/letta.js")" > "$stage/letta"
+chmod 0755 "$stage/letta"
+
+# The model endpoint and CA, as the agent's environment, readable by its user only.
+{
+ for name in LITELLM_API_KEY LITELLM_BASE_URL LITELLM_EXTRA_HEADERS; do
+ printf '%s=%s\n' "$name" "$(quoted "${!name:-}")"
+ done
+ [ -z "${AGENT_TRUST_ENV:-}" ] || printf '%s\n' "$AGENT_TRUST_ENV"
+ # Letta Code's state, its sessions and skills, as the image keeps it under /data.
+ printf 'A2A_PORT=%s\nLETTA_CODE_WORKSPACE_DIR=%s\nHOME=%s\n' \
+ "$(quoted "$port")" "$(quoted "$workspace")" "$(quoted "$root/data")"
+ for dir in CONFIG:config CACHE:cache DATA:share STATE:state; do
+ printf 'XDG_%s_HOME=%s\n' "${dir%%:*}" "$(quoted "$root/data/${dir#*:}")"
+ done
+} > "$stage/agent.env"
+
+# An earlier install's agent, a retried step's say, stops first: its files are replaced and its port is freed.
+on "if [ -f $r/agent.pid ]; then pid=\$(cat $r/agent.pid); kill \$pid 2> /dev/null; i=0; \
+ while [ \$i -lt $STOP_TIMEOUT_S ] && kill -0 \$pid 2> /dev/null; do sleep 1; i=\$((i + 1)); done; \
+ kill -9 \$pid 2> /dev/null; rm -f $r/agent.pid; fi; true"
+
+# The agent starts afresh, with no sessions or skills of one it replaces.
+on "rm -rf $r/data $r/node $r/npm && mkdir -p $r/bin $r/app $r/data $r/npm $(quoted "$workspace")"
+put_dir "$stage/node" "$root/node"
+put "$stage/uv-$uv_cpu-unknown-linux-musl/uv" "$root/bin/uv"
+put "$stage/letta" "$root/bin/letta"
+put "$stage/agent.env" "$root/agent.env"
+put "$here/package.json" "$root/npm/package.json"
+put "$here/package-lock.json" "$root/npm/package-lock.json"
+for file in $AGENT_FILES; do
+ put "$here/$file" "$root/app/$file"
+done
+on "chmod 0600 $r/agent.env && chmod 0755 $r/bin/uv $r/bin/letta $r/app/run.sh"
+
+# Install only headless dependencies' required scripts, then the private Python environment.
+on "cd $r/npm && export PATH=$r/node/bin:\$PATH npm_config_cache=$r/cache/npm npm_config_update_notifier=false \
+ && npm ci --ignore-scripts --omit=dev --no-audit --no-fund --loglevel=error > /dev/null \
+ && npm rebuild @letta-ai/letta-code sharp protobufjs > /dev/null \
+ && cd $r && export UV_PYTHON_PREFERENCE=only-managed UV_PYTHON_INSTALL_DIR=$r/python \
+ UV_CACHE_DIR=$r/cache/uv && bin/uv venv --quiet --clear --python $PYTHON_VERSION venv \
+ && bin/uv pip install --quiet --python venv/bin/python -r app/requirements.txt \
+ && rm -rf $r/cache"
+
+if [ "$mode" = container ]; then
+ docker exec -d -u 0 "$target" sh -c "exec $r/app/run.sh $r > $r/agent.log 2>&1"
+else
+ cd "$workspace"
+ nohup "$root/app/run.sh" "$root" > "$root/agent.log" 2>&1 < /dev/null &
+fi
+
+# Done once the agent answers on its port; an agent that exits first fails the install with the end of its log.
+health="import urllib.request; urllib.request.urlopen('http://127.0.0.1:$port/health', timeout=2)"
+for _ in $(seq "$START_TIMEOUT_S"); do
+ on "$r/venv/bin/python -c \"$health\"" 2> /dev/null && exit 0
+ on "[ ! -f $r/agent.pid ] || kill -0 \$(cat $r/agent.pid)" 2> /dev/null || break
+ sleep 1
+done
+echo "the agent didn't start; the end of its log:" >&2
+on "tail -n 40 $r/agent.log" >&2 || true
+exit 1
diff --git a/src/agent_env/agents/agents/letta-code/letta_code_bridge.py b/src/agent_env/agents/agents/letta-code/letta_code_bridge.py
new file mode 100644
index 00000000..dbbe4c09
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/letta_code_bridge.py
@@ -0,0 +1,552 @@
+"""Letta Code local-backend bridge, with isolated context state and a per-turn model relay."""
+from __future__ import annotations
+
+import asyncio
+import contextlib
+import hashlib
+import io
+import json
+import logging
+import os
+import shutil
+import signal
+import subprocess
+import tarfile
+import tempfile
+import threading
+from collections.abc import Callable, Mapping
+from contextlib import asynccontextmanager
+from dataclasses import dataclass, field
+from datetime import datetime, timezone
+from pathlib import Path
+
+from aiohttp import ClientSession, ClientTimeout, web
+from jsonschema import Draft202012Validator, SchemaError, ValidationError
+
+logger = logging.getLogger(__name__)
+
+# The model a run uses when neither the task nor the agent-config names one; the
+# local backend forwards it verbatim as the chat model.
+DEFAULT_MODEL = "openai/gpt-4.1-mini"
+ERROR_MESSAGE_LIMIT = 4000
+ROLE_HEADER = "AgentEnv-Role"
+# What agent-env gives an agent for [model.headers]: a JSON object of header names to values.
+MODEL_HEADERS_ENV = "LITELLM_EXTRA_HEADERS"
+
+# Root under which each A2A context_id gets its own Letta Code data dir; lives
+# under $HOME so host-mode instances don't share session state.
+SESSIONS_ROOT = os.path.join(os.environ.get("HOME", "/data"), "sessions")
+_CLI_TIMEOUT_S = 120
+# Largest model request body the relay accepts from the CLI.
+_RELAY_MAX_REQUEST_BYTES = 100 * 1024**2
+
+
+def _base_url(environ: Mapping[str, str]) -> str:
+ """The endpoint's chat-completions root: agent-env's LITELLM_BASE_URL has no /v1 suffix."""
+ base = (environ.get("LITELLM_BASE_URL") or "").rstrip("/")
+ return base if base.endswith("/v1") else f"{base}/v1"
+
+
+def context_data_dir(context_id: str) -> Path:
+ """Per-context Letta Code data dir. A stable short hash keeps the path clean
+ and filesystem-safe regardless of the context_id's charset."""
+ ctx_hash = hashlib.sha1(context_id.encode()).hexdigest()[:16]
+ return Path(SESSIONS_ROOT) / ctx_hash
+
+
+def _context_env(context_id: str) -> dict[str, str]:
+ home = context_data_dir(context_id)
+ home.mkdir(parents=True, exist_ok=True)
+ return {**os.environ, "HOME": str(home), "LETTA_LOCAL_BACKEND_DIR": str(home / ".letta/lc-local-backend"),
+ "LETTA_LOCAL_BACKEND_EXPERIMENTAL": "1"}
+
+
+async def _communicate(*cmd: str, env: Mapping[str, str], timeout_s: int) -> tuple[int, bytes, bytes]:
+ """Run a short CLI command to its end; one that outlives ``timeout_s`` is killed."""
+ proc = await _started(asyncio.create_subprocess_exec(
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, env=dict(env), start_new_session=True,
+ ))
+ _RUNNING.add(proc)
+ try:
+ out, err = await asyncio.wait_for(proc.communicate(), timeout=timeout_s)
+ except BaseException:
+ _kill_cli(proc)
+ await _reap(proc)
+ raise
+ finally:
+ _RUNNING.discard(proc)
+ return proc.returncode, out, err
+
+
+
+def _archive_session(context_id: str, session_id: str) -> bytes:
+ root = context_data_dir(context_id)
+ (root / "snapshot-session.json").write_text(json.dumps({"session_id": session_id}))
+ buffer = io.BytesIO()
+ with tarfile.open(fileobj=buffer, mode="w:gz") as archive:
+ archive.add(root, arcname="state")
+ return buffer.getvalue()
+
+
+async def export_session(context_id: str, session_id: str) -> bytes:
+ """Capture the conversation, agent, git-backed memory and local settings together, off the event loop."""
+ return await shielded_thread(_archive_session, context_id, session_id)
+
+
+async def shielded_thread(func, *args):
+ """Run blocking file work in a thread that cancellation can't abandon: a cancelled caller still waits for it."""
+ task = asyncio.ensure_future(asyncio.to_thread(func, *args))
+ try:
+ return await asyncio.shield(task)
+ except asyncio.CancelledError:
+ with contextlib.suppress(BaseException):
+ await task
+ raise
+
+
+def stage_session(context_id: str, json_path: str, directory: str) -> tuple[str, Path]:
+ """Extract a snapshot's local state into directory, with paths rewritten for context_id; the target is untouched."""
+ root = context_data_dir(context_id)
+ with tarfile.open(json_path, "r:gz") as archive:
+ archive.extractall(directory, filter="data")
+ staged = Path(directory) / "state"
+ session_id = json.loads((staged / "snapshot-session.json").read_text())["session_id"]
+ if not isinstance(session_id, str) or not session_id:
+ raise ValueError("Snapshot has no conversation id")
+ # Memory repos and settings may contain absolute paths to the original context.
+ source = json.loads((staged / "context.json").read_text())["home"]
+ for path in staged.rglob("*.json"):
+ if ".git" not in path.parts:
+ path.write_text(path.read_text().replace(source, str(root)))
+ return session_id, staged
+
+
+def commit_staged_session(context_id: str, staged: Path) -> None:
+ """Swap a staged state tree in for the context's; the previous tree is restored if the move fails."""
+ root = context_data_dir(context_id)
+ root.parent.mkdir(parents=True, exist_ok=True)
+ previous = root.with_name(root.name + ".previous")
+ shutil.rmtree(previous, ignore_errors=True)
+ if root.exists():
+ root.rename(previous)
+ try:
+ shutil.move(str(staged), root)
+ except BaseException:
+ if root.exists():
+ shutil.rmtree(root)
+ if previous.exists():
+ previous.rename(root)
+ raise
+ # The swap has succeeded; removing the old tree is cleanup and must not undo it.
+ shutil.rmtree(previous, ignore_errors=True)
+
+
+async def import_session(context_id: str, json_path: str) -> str:
+ """Stage a complete local state tree, then replace the target context's state."""
+ root = context_data_dir(context_id)
+ root.parent.mkdir(parents=True, exist_ok=True)
+ with tempfile.TemporaryDirectory(dir=root.parent) as directory:
+ session_id, staged = await shielded_thread(stage_session, context_id, json_path, directory)
+ await shielded_thread(commit_staged_session, context_id, staged)
+ return session_id
+
+
+@dataclass
+class LettaCodeResult:
+ response: str
+ tool_call_count: int
+ session_id: str | None
+ trajectory: list[dict] = field(default_factory=list)
+ error: str | None = None
+ error_code: str | None = None
+ structured_output: object | None = None
+
+
+def validate_output_format(output_format: dict) -> dict:
+ if output_format.get("type") != "json_schema" or not isinstance(output_format.get("schema"), dict):
+ raise ValueError("output_format must contain type=json_schema and a schema object")
+ try:
+ Draft202012Validator.check_schema(output_format["schema"])
+ except SchemaError as exc:
+ raise ValueError("output_format contains an invalid JSON schema") from exc
+ return output_format["schema"]
+
+
+# The attribution the last run sent, which /ext/attribution-probe reads back so the
+# validator can confirm project_id/task_id were wired through.
+_last_attribution: dict[str, str | None] = {
+ "project_id": None,
+ "task_id": None,
+ "last_seen_at_utc": None,
+}
+_attribution_lock = threading.Lock()
+
+
+def _record_attribution(project_id: str | None, task_id: str | None) -> None:
+ if not project_id and not task_id:
+ return
+ with _attribution_lock:
+ _last_attribution["project_id"] = project_id or None
+ _last_attribution["task_id"] = task_id or None
+ _last_attribution["last_seen_at_utc"] = datetime.now(timezone.utc).isoformat()
+
+
+def get_last_attribution_snapshot() -> dict[str, str | None]:
+ with _attribution_lock:
+ return dict(_last_attribution)
+
+
+def _attribution_headers(project_id: str | None, task_id: str | None) -> dict[str, str]:
+ """LiteLLM cost-attribution headers, x-litellm-customer-id + x-litellm-tags; {} when nothing to attribute."""
+ headers: dict[str, str] = {}
+ if project_id:
+ headers["x-litellm-customer-id"] = project_id
+ tags = [f"projectId:{project_id}"]
+ if task_id:
+ tags.append(f"taskId:{task_id}")
+ headers["x-litellm-tags"] = ",".join(tags)
+ elif task_id:
+ headers["x-litellm-tags"] = f"taskId:{task_id}"
+ return headers
+
+
+def model_headers(raw: str | None) -> dict[str, str]:
+ if not raw:
+ return {}
+ try:
+ headers = json.loads(raw)
+ except json.JSONDecodeError:
+ logger.warning(f"ignoring {MODEL_HEADERS_ENV}, which isn't JSON")
+ return {}
+ if not isinstance(headers, dict):
+ logger.warning(f"ignoring {MODEL_HEADERS_ENV}, which isn't a JSON object")
+ return {}
+ return {str(name): str(value) for name, value in headers.items()}
+
+
+def provider_headers(environ: Mapping[str, str], attribution: Mapping[str, str]) -> dict[str, str]:
+ """The endpoint's [model.headers], then the run's attribution, each replacing a header of the same name in any
+ case."""
+ return {name.lower(): value for layer in (model_headers(environ.get(MODEL_HEADERS_ENV)), attribution)
+ for name, value in layer.items()}
+
+
+def _mcp_headers(headers: Mapping[str, str] | None, role: str | None) -> dict[str, str]:
+ """A server's registered headers; the run's role, when it has one, replaces a role header they name."""
+ merged = dict(headers or {})
+ if role:
+ merged = {name: value for name, value in merged.items() if name.lower() != ROLE_HEADER.lower()}
+ merged[ROLE_HEADER] = role
+ return merged
+
+
+_PROCESS_CLEANUP_TIMEOUT_S = 5
+_RUNNING: set = set()
+
+
+def kill_running_clis() -> int:
+ """Kill every CLI still running a turn, and what each started; how many. The agent's shutdown does: the CLIs, in
+ sessions of their own, would outlive its server, as when a reinstall stops it mid-turn."""
+ running = [proc for proc in _RUNNING if proc.returncode is None]
+ for proc in running:
+ _kill_cli(proc)
+ return len(running)
+
+
+def _kill_cli(proc) -> None:
+ """Kill the CLI and everything under it: its process group, and, found by parent, the tools a CLI starts in a
+ session of their own, which no group or session kill reaches."""
+ pid = getattr(proc, "pid", None)
+ if pid is None:
+ with contextlib.suppress(ProcessLookupError):
+ proc.kill()
+ return
+ if proc.returncode is not None:
+ return # the CLI is gone, and its pid may be another process's by now
+ tree = [pid, *_descendants(pid)]
+ with contextlib.suppress(ProcessLookupError, PermissionError):
+ os.killpg(pid, signal.SIGKILL)
+ for member in tree:
+ with contextlib.suppress(ProcessLookupError, PermissionError):
+ os.kill(member, signal.SIGKILL)
+
+
+async def _started(spawn):
+ """The CLI ``spawn`` starts. A turn cancelled while it starts lets it finish starting, then kills it and what it
+ started: asyncio would kill the CLI alone, and leave its tools running."""
+ start = asyncio.ensure_future(spawn)
+ try:
+ return await asyncio.shield(start)
+ except asyncio.CancelledError:
+ with contextlib.suppress(Exception):
+ proc = await start
+ _kill_cli(proc)
+ await _reap(proc)
+ raise
+
+
+async def _reap(proc) -> None:
+ """Wait for the killed CLI, but not for a process that left its tree and still holds its pipes open."""
+ with contextlib.suppress(asyncio.TimeoutError):
+ await asyncio.wait_for(proc.wait(), _PROCESS_CLEANUP_TIMEOUT_S)
+
+
+def _descendants(pid: int) -> list[int]:
+ """The processes under ``pid``, by parent, read from /proc; none where there is no /proc."""
+ children: dict[int, list[int]] = {}
+ for entry in os.listdir("/proc") if os.path.isdir("/proc") else ():
+ if not entry.isdigit():
+ continue
+ try:
+ with open(f"/proc/{entry}/stat") as stat:
+ parent = int(stat.read().rsplit(")", 1)[1].split()[1])
+ except (OSError, ValueError, IndexError):
+ continue
+ children.setdefault(parent, []).append(int(entry))
+ found, pending = [], [pid]
+ while pending:
+ for child in children.get(pending.pop(), ()):
+ found.append(child)
+ pending.append(child)
+ return found
+
+
+
+@asynccontextmanager
+async def model_relay(headers: dict[str, str], on_forward=None):
+ """Keep endpoint credentials and task attribution on requests to the configured model endpoint only."""
+ base = _base_url(os.environ)
+ async with ClientSession(timeout=ClientTimeout(total=None), auto_decompress=False) as client:
+ async def forward(request):
+ if on_forward is not None:
+ on_forward()
+ outgoing = {"authorization": "Bearer " + os.environ.get("LITELLM_API_KEY", ""), **headers}
+ if request.content_type:
+ outgoing["content-type"] = request.headers.get("Content-Type", "application/json")
+ async with client.request(request.method, base + request.path_qs.removeprefix("/v1"),
+ data=await request.read(), headers=outgoing) as upstream:
+ response = web.StreamResponse(status=upstream.status, headers={
+ name: value for name, value in upstream.headers.items()
+ if name.lower() not in {"content-length", "transfer-encoding", "connection"}
+ })
+ await response.prepare(request)
+ # SSE consumers commonly close immediately after the terminal event.
+ with contextlib.suppress(ConnectionResetError):
+ async for chunk in upstream.content.iter_any():
+ await response.write(chunk)
+ await response.write_eof()
+ return response
+ app = web.Application(client_max_size=_RELAY_MAX_REQUEST_BYTES)
+ app.router.add_route("*", "/{path:.*}", forward)
+ runner = web.AppRunner(app)
+ await runner.setup()
+ site = web.TCPSite(runner, "127.0.0.1", 0)
+ await site.start()
+ port = site._server.sockets[0].getsockname()[1]
+ try:
+ yield f"http://127.0.0.1:{port}/v1"
+ finally:
+ await runner.cleanup()
+
+
+async def _command(env: dict[str, str], *args: str) -> bytes:
+ code, out, err = await _communicate("letta", "--backend", "local", *args, env=env, timeout_s=_CLI_TIMEOUT_S)
+ if code:
+ raise RuntimeError(f"Letta Code {args[0]} failed: {err.decode(errors='replace')[-ERROR_MESSAGE_LIMIT:]}")
+ return out
+
+
+def _configure_agent(home: Path, agent_id: str, servers: dict, role: str | None, system_prompt: str | None):
+ # Core memory's system/ files are compiled into the existing agent's system prompt on every run.
+ memory = home / ".letta/lc-local-backend/memfs" / agent_id / "memory"
+ memory.mkdir(parents=True, exist_ok=True)
+ instructions = system_prompt or ""
+ if servers:
+ instructions += ("\nUse the connected MCP tools directly for services and peer agents. "
+ "They are named mcp____. These services require no repository setup.\n")
+ target = "task_instructions.md" if (memory / "MEMORY.md").exists() else "system/task_instructions.md"
+ path = memory / target
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text("---\nname: Task instructions\ndescription: Instructions for the current task\n---\n" +
+ (instructions or "Follow the user's task.\n"))
+ # The local backend projects committed core memory, not uncommitted working files.
+ for args in (["add", "--", target], ["-c", "user.name=Letta Code", "-c", "user.email=code@letta.com",
+ "-c", "commit.gpgsign=false", "commit", "--quiet", "--allow-empty",
+ "-m", "Update task instructions", "--", target]):
+ subprocess.run(["git", *args], cwd=memory, check=True, capture_output=True)
+
+ settings_path = home / ".letta/settings.json"
+ settings = json.loads(settings_path.read_text()) if settings_path.exists() else {}
+ agents = settings.setdefault("agents", [])
+ matching = [agent for agent in agents if agent.get("agentId") == agent_id]
+ if not matching:
+ matching = [{"agentId": agent_id, "baseUrl": "local:" + str(home / ".letta/lc-local-backend")}]
+ agents.extend(matching)
+ for agent in matching:
+ agent["mcpServers"] = [
+ {"name": name, "transport": "http", "url": info["url"],
+ "headers": _mcp_headers(info.get("headers"), role)} for name, info in servers.items()
+ ]
+ settings_path.parent.mkdir(parents=True, exist_ok=True)
+ settings_path.write_text(json.dumps(settings))
+
+
+def _install_mcp_tools(home: Path, agent_id: str, tools: list[dict]) -> None:
+ """A context-local mod registers the CLI-discovered schemas without renaming their tools."""
+ directory = home / ".letta"
+ (directory / "mods").mkdir(parents=True, exist_ok=True)
+ (directory / "agentenv-mcp-tools.json").write_text(json.dumps({"agentId": agent_id, "tools": tools}))
+ shutil.copyfile(Path(__file__).with_name("mcp_tools.ts"), directory / "mods/agentenv-mcp.ts")
+
+
+async def run_letta_code(
+ prompt: str, context_id: str, session_id: str | None = None, model: str | None = None,
+ mcp_servers: dict[str, dict] | None = None, system_prompt: str | None = None,
+ output_format: dict | None = None, timeout_s: int = 600, project_id: str | None = None,
+ task_id: str | None = None, role: str | None = None, attachment_paths: list[str] | None = None,
+ effort: str | None = None, event_callback: Callable[[dict], None] | None = None, workspace: str = "/app",
+) -> LettaCodeResult:
+ """A bounded CLI turn, including provider setup; cancellation kills the process tree."""
+ try:
+ async with asyncio.timeout(timeout_s):
+ return await _turn(prompt, context_id, session_id, model, mcp_servers, system_prompt, output_format,
+ project_id, task_id, role, attachment_paths, effort, event_callback, workspace)
+ except TimeoutError:
+ return LettaCodeResult(response="", tool_call_count=0, session_id=session_id,
+ error=f"Letta Code timed out after {timeout_s}s")
+
+
+async def _turn(prompt, context_id, session_id, model, mcp_servers, system_prompt, output_format,
+ project_id, task_id, role, attachment_paths, effort, event_callback, workspace):
+ model = model or DEFAULT_MODEL
+ handle = "openai-compatible/" + model
+ env = _context_env(context_id)
+ home = Path(env["HOME"])
+ (home / "context.json").write_text(json.dumps({"home": str(home)}))
+ attribution = _attribution_headers(project_id, task_id)
+ async with model_relay(provider_headers(os.environ, attribution),
+ on_forward=lambda: _record_attribution(project_id, task_id)) as relay:
+ await _command(env, "connect", "openai-compatible", "--base-url", relay, "--api-key", "relay")
+ agent_file = home / "agent-id.json"
+ if agent_file.exists():
+ agent_id = json.loads(agent_file.read_text())["id"]
+ else:
+ agent = json.loads(await _command(env, "agents", "create", "--model", handle))
+ agent_id = agent["id"]
+ agent_file.write_text(json.dumps({"id": agent_id}))
+ _configure_agent(home, agent_id, mcp_servers or {}, role, system_prompt)
+ tools = json.loads(await _command(env, "mcp", "tools", "--full", "--agent", agent_id)) if mcp_servers else []
+ _install_mcp_tools(home, agent_id, tools)
+ skills = Path(os.environ.get("HOME", "/data")) / ".letta/skills"
+ if skills.exists():
+ shutil.copytree(skills, home / ".letta/skills", dirs_exist_ok=True)
+ # The shell tools inherit these, so nested `letta mcp` calls select the same backend and agent.
+ env["LETTA_AGENT_ID"] = agent_id
+ if output_format is not None:
+ schema = validate_output_format(output_format)
+ prompt += "\nReturn only JSON matching this schema: " + json.dumps(schema)
+ for path in attachment_paths or []:
+ prompt += "\nRead the attached file at " + path
+ cmd = ["letta", "--backend", "local", "-p", prompt, "--output-format", "stream-json", "--yolo",
+ "--model", handle, "--toolset", "default"]
+ cmd += ["--conversation", session_id] if session_id else ["--agent", agent_id, "--new"]
+ if effort:
+ target = ["--conversation", session_id] if session_id else ["--agent", agent_id]
+ await _command(env, "model", "set", handle, "--reasoning", effort, *target)
+ proc = await _started(asyncio.create_subprocess_exec(
+ *cmd, cwd=workspace, env=env, stdin=asyncio.subprocess.DEVNULL,
+ stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, start_new_session=True,
+ ))
+ _RUNNING.add(proc)
+ parser = _EventParser(event_callback)
+ try:
+ stderr = await _stream_cli(proc, parser.on_line)
+ except BaseException:
+ _kill_cli(proc)
+ await _reap(proc)
+ raise
+ finally:
+ _RUNNING.discard(proc)
+ result = parser.result(stderr, proc.returncode)
+ if output_format is not None and result.error is None:
+ try:
+ result.structured_output = json.loads(result.response)
+ Draft202012Validator(schema).validate(result.structured_output)
+ except (ValueError, ValidationError) as exc:
+ result.error = f"Letta Code response does not match output_format: {exc}"
+ result.error_code = "invalid_output_format"
+ return result
+
+
+# How much of the CLI's stdout one read takes; a line may span several reads.
+_STDOUT_READ_BYTES = 64 * 1024
+
+
+async def _stream_cli(proc, on_line: Callable[[str], None]) -> bytes:
+ """``proc.communicate()``, handing ``on_line`` each stdout line as it arrives.
+
+ Lines are split as ``stdout.decode(errors="replace").splitlines()`` splits
+ the whole output, so they are the same lines; a line has no length limit,
+ as with ``communicate``. Returns stderr once the CLI has exited."""
+ stderr_task = asyncio.create_task(proc.stderr.read())
+ try:
+ # A line's pieces, joined once when its newline arrives: re-joining them on every read
+ # would cost a long line the square of its length.
+ pieces: list[bytes] = []
+ while chunk := await proc.stdout.read(_STDOUT_READ_BYTES):
+ *ends, rest = chunk.split(b"\n")
+ for end in ends:
+ pieces.append(end)
+ for line in b"".join(pieces).decode(errors="replace").splitlines():
+ on_line(line)
+ pieces = []
+ pieces.append(rest)
+ for line in b"".join(pieces).decode(errors="replace").splitlines():
+ on_line(line)
+ stderr = await stderr_task
+ await proc.wait()
+ return stderr
+ finally:
+ stderr_task.cancel()
+
+
+
+def event_session_id(event: dict) -> str | None:
+ return event.get("conversation_id")
+
+
+class _EventParser:
+ def __init__(self, event_callback=None):
+ self.callback = event_callback
+ self.trajectory = []
+ self.session_id = None
+ self.response = ""
+ self.tools = set()
+ self.completed = False
+ self.error = None
+
+ def on_line(self, line: str):
+ try:
+ event = json.loads(line)
+ except ValueError:
+ return
+ if not isinstance(event, dict):
+ return
+ self.trajectory.append(event)
+ self.session_id = event_session_id(event) or self.session_id
+ if event.get("message_type") == "tool_call_message":
+ self.tools.add((event.get("tool_call") or {}).get("tool_call_id") or event.get("uuid") or str(len(self.tools)))
+ if event.get("type") == "result":
+ self.completed = event.get("subtype") == "success"
+ self.response = event.get("result") or ""
+ if not self.completed:
+ self.error = event.get("stop_reason") or self.response or "Letta Code did not complete"
+ if self.callback:
+ self.callback(event)
+
+ def result(self, stderr: bytes, returncode: int | None) -> LettaCodeResult:
+ error = None if self.completed else (self.error or f"Letta Code exited {returncode} without completing")
+ if error:
+ error = (error + "\n" + stderr.decode(errors="replace")[-ERROR_MESSAGE_LIMIT:])[-ERROR_MESSAGE_LIMIT:]
+ return LettaCodeResult(response=self.response, tool_call_count=len(self.tools), session_id=self.session_id,
+ trajectory=self.trajectory, error=error)
diff --git a/src/agent_env/agents/agents/letta-code/letta_code_kit.py b/src/agent_env/agents/agents/letta-code/letta_code_kit.py
new file mode 100644
index 00000000..d38eb063
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/letta_code_kit.py
@@ -0,0 +1,75 @@
+"""The pieces of agent plumbing this agent shares in shape with other CLI agents, copied from the Claude Code agent's
+``kit.py``: durable session references, skill installs and FastAPI-style error bodies."""
+
+from __future__ import annotations
+
+import logging
+import shutil
+from pathlib import Path
+
+from agentenv_protocol.a2a_agent import BundleSkillRequest, InlineSkillRequest, SkillAddResponse
+from agentenv_protocol.transfers import download
+from starlette.applications import Starlette
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.responses import JSONResponse, Response
+
+logger = logging.getLogger(__name__)
+
+_REFS_ATTR = "_durable_session_refs"
+
+
+class DurableSessionRefs:
+ """Mixin, listed before ``AgentEnvAgent``, that keeps every context's session reference for the life of the
+ process: the framework's own record is a bounded LRU, so an idle context would otherwise start a fresh CLI
+ session."""
+
+ def session_ref_for_context(self, context_id: str) -> str | None:
+ return self.__dict__.get(_REFS_ATTR, {}).get(context_id) or super().session_ref_for_context(context_id)
+
+ def set_session_ref_for_context(self, context_id: str, session_ref: str) -> None:
+ super().set_session_ref_for_context(context_id, session_ref)
+ self.__dict__.setdefault(_REFS_ATTR, {})[context_id] = session_ref
+
+
+_NO_BODY_STATUSES = frozenset({204, 205, 304})
+
+
+async def _detail_body(_request: Request, exc: HTTPException) -> Response:
+ if exc.status_code < 200 or exc.status_code in _NO_BODY_STATUSES:
+ return Response(status_code=exc.status_code, headers=exc.headers)
+ return JSONResponse({"detail": exc.detail}, status_code=exc.status_code, headers=exc.headers)
+
+
+def json_error_bodies(app: Starlette) -> Starlette:
+ """Answer every ``HTTPException`` with a ``{"detail": ...}`` body, as agent-env reads errors."""
+ app.add_exception_handler(HTTPException, _detail_body)
+ return app
+
+
+def _validate_skill_name(name: str) -> None:
+ if name != Path(name).name or ".." in name or "/" in name or "\\" in name:
+ raise HTTPException(status_code=400, detail=f"Invalid skill name '{name}': must not contain path separators or '..'")
+
+
+async def install_skill(request: InlineSkillRequest | BundleSkillRequest, skills_dir: Path) -> SkillAddResponse:
+ """Write ``skills_dir//``: the inline ``SKILL.md``, or every bundle file through its read grant. A failed
+ install leaves no directory behind."""
+ _validate_skill_name(request.name)
+ skill_dir = skills_dir / request.name
+ if skill_dir.exists():
+ raise HTTPException(status_code=409, detail=f"Skill '{request.name}' is already registered")
+ skill_dir.mkdir(parents=True)
+ try:
+ if isinstance(request, BundleSkillRequest):
+ for item in request.skill_bundle.files:
+ await download(item.object, skill_dir / item.path)
+ else:
+ if not request.skill_md or not request.skill_md.strip():
+ raise HTTPException(status_code=400, detail="Skill content must not be empty")
+ (skill_dir / "SKILL.md").write_text(request.skill_md)
+ except BaseException:
+ shutil.rmtree(skill_dir, ignore_errors=True)
+ raise
+ logger.info(f"Registered skill '{request.name}' at {skill_dir}")
+ return SkillAddResponse(name=request.name)
diff --git a/src/agent_env/agents/agents/letta-code/mcp_tools.ts b/src/agent_env/agents/agents/letta-code/mcp_tools.ts
new file mode 100644
index 00000000..688c910b
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/mcp_tools.ts
@@ -0,0 +1,34 @@
+/** Expose the registered MCP schemas as native Letta Code tools through its public mods API. */
+import { execFile } from "node:child_process";
+import { readFileSync } from "node:fs";
+import { homedir } from "node:os";
+import { join } from "node:path";
+
+export default function activate(letta) {
+ const { agentId, tools } = JSON.parse(
+ readFileSync(join(homedir(), ".letta", "agentenv-mcp-tools.json"), "utf8"),
+ );
+ const dispose = tools.map((tool) => letta.tools.register({
+ name: tool.name,
+ description: tool.description || tool.name,
+ parameters: tool.inputSchema,
+ requiresApproval: false,
+ parallelSafe: false,
+ run(ctx) {
+ return new Promise((resolve) => {
+ execFile("letta", ["--backend", "local", "mcp", "call", tool.name,
+ "--agent", agentId, "--args", JSON.stringify(ctx.args)],
+ { signal: ctx.signal, timeout: 120000, maxBuffer: 16 * 1024 * 1024 },
+ (error, stdout, stderr) => {
+ let result;
+ try { result = JSON.parse(stdout); } catch { /* CLI startup errors have only stderr. */ }
+ resolve({
+ content: result ? JSON.stringify(result) : (stderr || error?.message || stdout),
+ isError: Boolean(error) || result?.isError === true,
+ });
+ });
+ });
+ },
+ }));
+ return () => dispose.forEach((remove) => remove());
+}
diff --git a/src/agent_env/agents/agents/letta-code/package-lock.json b/src/agent_env/agents/agents/letta-code/package-lock.json
new file mode 100644
index 00000000..36635e93
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/package-lock.json
@@ -0,0 +1,5447 @@
+{
+ "name": "letta-code",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "@letta-ai/letta-code": "0.34.25"
+ }
+ },
+ "node_modules/@letta-ai/letta-code": {
+ "version": "0.34.25",
+ "resolved": "https://registry.npmjs.org/@letta-ai/letta-code/-/letta-code-0.34.25.tgz",
+ "integrity": "sha512-OrtcoobIWUikWOR6cJGQgZ7uma9fN4kjt8M+OxEtoMBIkaKV4EL7nQ2DWV6Br1rs+PH7vUpGcn/Xl0PKrDAyVw==",
+ "hasInstallScript": true,
+ "hasShrinkwrap": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@earendil-works/pi-ai": "^0.99.1",
+ "@janhapke/sharp-electron": "0.35.3-electron.1",
+ "@letta-ai/letta-agent-sdk": "0.8.38",
+ "@letta-ai/letta-client": "^1.10.2",
+ "@letta-ai/trajectory": "0.2.0",
+ "@modelcontextprotocol/sdk": "1.30.0",
+ "@pierre/diffs": "1.2.2",
+ "@scarf/scarf": "^1.4.0",
+ "@shikijs/langs": "4.0.2",
+ "cron-parser": "^5.6.1",
+ "cross-spawn": "^7.0.6",
+ "glob": "^13.0.0",
+ "ink": "5.2.1",
+ "ink-link": "^4.1.0",
+ "node-pty": "^1.1.0",
+ "open": "^10.2.0",
+ "react": "18.2.0",
+ "sharp": "^0.34.5",
+ "shiki": "^4.0.2",
+ "strip-ansi": "^7.2.0",
+ "ws": "^8.19.0"
+ },
+ "bin": {
+ "letta": "letta.js"
+ },
+ "engines": {
+ "bun": ">=1.3.2",
+ "node": "^22.23.4 || ^24.22.1 || ^26.12.1"
+ },
+ "optionalDependencies": {
+ "@vscode/ripgrep": "^1.17.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@alcalzone/ansi-tokenize": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.1.3.tgz",
+ "integrity": "sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14.13.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@anthropic-ai/sdk": {
+ "version": "0.124.0",
+ "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.124.0.tgz",
+ "integrity": "sha512-cN5O8i9UVxHeOQAzj/XjshWXG8KiibJDw9OGpH2Z/eR3n/RBxdoLxDJOcfqAJWvjaMDFfHTBADU04hWRJVkDyA==",
+ "license": "MIT",
+ "dependencies": {
+ "json-schema-to-ts": "^3.1.1",
+ "standardwebhooks": "^1.0.0"
+ },
+ "bin": {
+ "anthropic-ai-sdk": "bin/cli"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/client-bedrock-runtime": {
+ "version": "3.1127.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1127.0.tgz",
+ "integrity": "sha512-IDl/lrPb90aH+pZFHGNDmgH9nAUQj5PlZH1sJ3w7RikctyjHSnY3oNjZhrLoaBoQn/rNK0zsP6OHEqEhj2tdLA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.977.9",
+ "@aws-sdk/credential-provider-node": "^3.972.82",
+ "@aws-sdk/eventstream-handler-node": "^3.972.34",
+ "@aws-sdk/middleware-eventstream": "^3.972.29",
+ "@aws-sdk/middleware-websocket": "^3.972.52",
+ "@aws-sdk/token-providers": "3.1127.0",
+ "@aws-sdk/types": "^3.974.5",
+ "@smithy/core": "^3.33.3",
+ "@smithy/fetch-http-handler": "^5.7.2",
+ "@smithy/node-http-handler": "^4.11.3",
+ "@smithy/types": "^4.17.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/core": {
+ "version": "3.978.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.978.5.tgz",
+ "integrity": "sha512-ruI0AWqcrfL20XDS6SwZIJFPOBZ6N0ADa9nLzWlBhxk1aoUjbUX3JkTR9vEmk7o35XpAHi68ahZ4T6RE2U9XyA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.975.0",
+ "@aws-sdk/xml-builder": "^3.972.41",
+ "@aws/lambda-invoke-store": "^0.3.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/signature-v4": "^5.7.4",
+ "@smithy/types": "^4.19.0",
+ "bowser": "^2.11.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-env": {
+ "version": "3.972.76",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.76.tgz",
+ "integrity": "sha512-YxmL1Ar7bV9ZkJvtv+lj+MF6le76NnZnbmgySyZuxpZaCv0/1lZ3KxKy6RIj1h9ui2hWnVjZxbmTMeO0y/NrQA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-http": {
+ "version": "3.972.78",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.78.tgz",
+ "integrity": "sha512-3VHknDRngoebsaqyT1iR75b5cBT2zfEtODK6yYmYltljkK1HEAQLs2FEd1IpWqAeOYdMGaG9wikngWLTufY7RA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/fetch-http-handler": "^5.8.0",
+ "@smithy/node-http-handler": "^4.12.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-ini": {
+ "version": "3.973.21",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.21.tgz",
+ "integrity": "sha512-aLx9hbCX6mGAyv4ZZd8UagJ4RASHVJw6BFDSIyuKmLkqNL6H47EjBPK6qaJ4B5TDV6mc+vMa0SJFYyo4mkvVQg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/credential-provider-env": "^3.972.76",
+ "@aws-sdk/credential-provider-http": "^3.972.78",
+ "@aws-sdk/credential-provider-login": "^3.972.83",
+ "@aws-sdk/credential-provider-process": "^3.972.76",
+ "@aws-sdk/credential-provider-sso": "^3.973.20",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.82",
+ "@aws-sdk/nested-clients": "^3.997.50",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/credential-provider-imds": "^4.5.2",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-login": {
+ "version": "3.972.83",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.83.tgz",
+ "integrity": "sha512-9bJU6FjRacF4FK/QHf8Dyxhur7B1grRj8C1Yh4IkpoFW2exQflPdCv0VrbemLW9ZctLNle+AE7TETs9KNvuLYg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/nested-clients": "^3.997.50",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-node": {
+ "version": "3.972.88",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.88.tgz",
+ "integrity": "sha512-AG0KID5qhQPzrFkh5b0Cws1Amytvzo0L0Xj6hMgJXEwD6ZXAqninDhSNAWJiN5zU4YVVZnuidnqwPwYJ04IamA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/credential-provider-env": "^3.972.76",
+ "@aws-sdk/credential-provider-http": "^3.972.78",
+ "@aws-sdk/credential-provider-ini": "^3.973.21",
+ "@aws-sdk/credential-provider-process": "^3.972.76",
+ "@aws-sdk/credential-provider-sso": "^3.973.20",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.82",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/credential-provider-imds": "^4.5.2",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-process": {
+ "version": "3.972.76",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.76.tgz",
+ "integrity": "sha512-pdhKFTXv1zPYhh92MTlp0jVbLWvUEV9v+rziuEkoskGGQ2iJskxHTO38nA8UAbT/N4IM3n8OZJ9rIY5IBO15/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-sso": {
+ "version": "3.973.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.20.tgz",
+ "integrity": "sha512-DlxrAB3MnjNLx/da7b89W+3DyJQYso/q7Ns15MsST2IV2nkAYQOYTUCaffNSjgrpMP99Dm2mV2jxzcbyF94ZfA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/nested-clients": "^3.997.50",
+ "@aws-sdk/token-providers": "3.1155.0",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": {
+ "version": "3.1155.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1155.0.tgz",
+ "integrity": "sha512-iIcQnYLhWuq9qOLQbIWFrxF3PF0svVeZvHnUS4DUnO4zUFmFHIyGyjqrntXG+e/5PUgfavV0pYfDIKHxTzN2LA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/nested-clients": "^3.997.50",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/credential-provider-web-identity": {
+ "version": "3.972.82",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.82.tgz",
+ "integrity": "sha512-LUo46IqPTJ4xKBsrLuoaxiv/D2GTBCcFDMD1y3jKIqPR/p7Rw14RJFZ0iRWftqZtyLPQX9JMGnSi3mBu4y/pNA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/nested-clients": "^3.997.50",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/eventstream-handler-node": {
+ "version": "3.972.38",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.38.tgz",
+ "integrity": "sha512-K7vPKNstDlavHFZgbmcFdJOFIyowsevjddycRziRBbtXH/D9z+i9juCnH17liwSX9T8fJiDQzlEYkRtxkR+1vA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/middleware-eventstream": {
+ "version": "3.972.33",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.33.tgz",
+ "integrity": "sha512-8QUt39D/dk5tdV7rLvIfMMI/ilQff4zth7mkMKpVOLM+M5AQ9W3nPxFVuHQANevmVWi4T5MlxqfKV4Q2drYeBA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/middleware-websocket": {
+ "version": "3.972.58",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.58.tgz",
+ "integrity": "sha512-/BvocdloKozx/zFr4benH+9J1ywB/2dYFHPWNUdo0CBCe00gTm0HPflOq8MH6cuCTbnywSrscGq0/LheN59teQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/fetch-http-handler": "^5.8.0",
+ "@smithy/signature-v4": "^5.7.4",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/nested-clients": {
+ "version": "3.997.50",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.50.tgz",
+ "integrity": "sha512-nKb8qu4QsnpZTq/6JIXc72mzuzfh7BK4sUQkpQznPec2z4W7Ob2xYkcM4i5e1yGTBnbJVeFv/0sf3jcz85hclA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.978.5",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.49",
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/core": "^3.36.1",
+ "@smithy/fetch-http-handler": "^5.8.0",
+ "@smithy/node-http-handler": "^4.12.1",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/signature-v4-multi-region": {
+ "version": "3.996.49",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.49.tgz",
+ "integrity": "sha512-nvuAZNRrRRVCiARRKsYlQ0VnXiEQiq7vXPH+UA+LSo+kN3Djl9eo/V2r0udkw85PnsNshmv2Em1clld5M3j67w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.975.0",
+ "@smithy/signature-v4": "^5.7.4",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/token-providers": {
+ "version": "3.1127.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1127.0.tgz",
+ "integrity": "sha512-Dv2TMWBshJ+tF6ahs2Sy5bh4Iabsd4GAQqVvE9XZmYmnoaVbpS2QKIKE/HRacc7bTtbjEEvP+laGzHvHlf1CiQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.977.9",
+ "@aws-sdk/nested-clients": "^3.997.44",
+ "@aws-sdk/types": "^3.974.5",
+ "@smithy/core": "^3.33.3",
+ "@smithy/types": "^4.17.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/types": {
+ "version": "3.975.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.975.0.tgz",
+ "integrity": "sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws-sdk/xml-builder": {
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.41.tgz",
+ "integrity": "sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@aws/lambda-invoke-store": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz",
+ "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@babel/runtime": {
+ "version": "7.29.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.10.tgz",
+ "integrity": "sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@earendil-works/pi-ai": {
+ "version": "0.99.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.99.2.tgz",
+ "integrity": "sha512-9RFOEdY+ZTJ1AI+UuAFs4RM0tF2Tje/R/CEv9gWTJHt0iTu8XHZs64U/EIZxNSllFmec/4HfwsOxYj1qQek9bg==",
+ "license": "MIT",
+ "dependencies": {
+ "@anthropic-ai/sdk": "0.124.0",
+ "@aws-sdk/client-bedrock-runtime": "3.1127.0",
+ "@earendil-works/pi-telemetry": "^0.99.2",
+ "@google/genai": "2.21.0",
+ "@smithy/node-http-handler": "4.12.1",
+ "http-proxy-agent": "9.1.0",
+ "https-proxy-agent": "9.1.0",
+ "openai": "7.19.0",
+ "partial-json": "0.1.7",
+ "typebox": "1.3.27"
+ },
+ "bin": {
+ "pi-ai": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@earendil-works/pi-telemetry": {
+ "version": "0.99.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-telemetry/-/pi-telemetry-0.99.2.tgz",
+ "integrity": "sha512-WThYU4XM6jjjzH4FzLdreN7QAPS9SDdokL0W0Ldheg1ssCIJkfpK7PgebFm7/PoQub7OiXx+SRF6B/oF7z7lXA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@emnapi/runtime": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
+ "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@google/genai": {
+ "version": "2.21.0",
+ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-2.21.0.tgz",
+ "integrity": "sha512-+PDtco2/Z0ONdzCGekCoCT+O1VJS9xJQNN4XzQpXG/t3El/SWWMkCWlFRO1KmivOHPa4Q0VjUYu1HBKCZ/v33Q==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "google-auth-library": "^10.3.0",
+ "p-retry": "^4.6.2",
+ "protobufjs": "^7.5.4",
+ "ws": "^8.18.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "@modelcontextprotocol/sdk": "^1.25.2"
+ },
+ "peerDependenciesMeta": {
+ "@modelcontextprotocol/sdk": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@hono/node-server": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.5.tgz",
+ "integrity": "sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "peerDependencies": {
+ "hono": "^4 || ^5.0.0-0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
+ "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-freebsd-wasm32/node_modules/@img/sharp-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
+ "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
+ "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-webcontainers-wasm32/node_modules/@img/sharp-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
+ "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron": {
+ "version": "0.35.3-electron.1",
+ "resolved": "https://registry.npmjs.org/@janhapke/sharp-electron/-/sharp-electron-0.35.3-electron.1.tgz",
+ "integrity": "sha512-ZDnFPMsKolANxS+RDjgxw6/jc6O0JfJ0msu6bgBdPCz6NFm4+K+cPurwXB+rdl5UY2/EQ5bzQ7ENYnRXtdprLQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "sharp": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
+ "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-darwin-x64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
+ "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
+ "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
+ "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
+ "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
+ "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
+ "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
+ "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
+ "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
+ "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
+ "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
+ "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-arm": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
+ "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-arm64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
+ "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
+ "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
+ "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-s390x": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
+ "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linux-x64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
+ "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
+ "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
+ "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-win32-arm64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
+ "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-win32-ia32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
+ "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/@img/sharp-win32-x64": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
+ "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@janhapke/sharp-electron/node_modules/sharp": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
+ "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@img/colour": "^1.1.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.8.5"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.35.3",
+ "@img/sharp-darwin-x64": "0.35.3",
+ "@img/sharp-freebsd-wasm32": "0.35.3",
+ "@img/sharp-libvips-darwin-arm64": "1.3.2",
+ "@img/sharp-libvips-darwin-x64": "1.3.2",
+ "@img/sharp-libvips-linux-arm": "1.3.2",
+ "@img/sharp-libvips-linux-arm64": "1.3.2",
+ "@img/sharp-libvips-linux-ppc64": "1.3.2",
+ "@img/sharp-libvips-linux-riscv64": "1.3.2",
+ "@img/sharp-libvips-linux-s390x": "1.3.2",
+ "@img/sharp-libvips-linux-x64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
+ "@img/sharp-linux-arm": "0.35.3",
+ "@img/sharp-linux-arm64": "0.35.3",
+ "@img/sharp-linux-ppc64": "0.35.3",
+ "@img/sharp-linux-riscv64": "0.35.3",
+ "@img/sharp-linux-s390x": "0.35.3",
+ "@img/sharp-linux-x64": "0.35.3",
+ "@img/sharp-linuxmusl-arm64": "0.35.3",
+ "@img/sharp-linuxmusl-x64": "0.35.3",
+ "@img/sharp-webcontainers-wasm32": "0.35.3",
+ "@img/sharp-win32-arm64": "0.35.3",
+ "@img/sharp-win32-ia32": "0.35.3",
+ "@img/sharp-win32-x64": "0.35.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-agent-sdk": {
+ "version": "0.8.38",
+ "resolved": "https://registry.npmjs.org/@letta-ai/letta-agent-sdk/-/letta-agent-sdk-0.8.38.tgz",
+ "integrity": "sha512-ayMN6fNMRlj368RPRPDBVYQQDujxcawqEnsNmyefEgIm0j0q1+33VZpAUNfVAvB0Vivvx4FTQDx/E9Lbmpafhw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@letta-ai/letta-client": "^1.12.1",
+ "ajv": "^8.20.0"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ },
+ "peerDependencies": {
+ "@letta-ai/letta-code": ">=0.34.9 <0.35.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-client": {
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@letta-ai/letta-client/-/letta-client-1.12.1.tgz",
+ "integrity": "sha512-rYjXMXpkfssj7VBBX3qCp6mdpNRv6YPNrliYsjkhWoQDqGg3J9bsgIQ28ZhQTddabYxRUIwcdzuaizFx8pvZ7A==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@pierre/diffs": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@pierre/diffs/-/diffs-1.2.2.tgz",
+ "integrity": "sha512-MvWLv2oSOJOF8oYXWLdhicguHM11G/VNWu6OPR5ZETolp2NM2/KPQG3cZTnKpJ6ImqEHwvw6Gl6z2gmmy2FQmQ==",
+ "extraneous": true,
+ "license": "apache-2.0",
+ "dependencies": {
+ "@pierre/theme": "1.0.3",
+ "@shikijs/transformers": "^3.0.0",
+ "diff": "8.0.3",
+ "hast-util-to-html": "9.0.5",
+ "lru_map": "0.4.1",
+ "shiki": "^3.0.0"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1 || ^19.0.0",
+ "react-dom": "^18.3.1 || ^19.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@pierre/diffs/node_modules/@shikijs/langs": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz",
+ "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@pierre/diffs/node_modules/shiki": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz",
+ "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "3.23.0",
+ "@shikijs/engine-javascript": "3.23.0",
+ "@shikijs/engine-oniguruma": "3.23.0",
+ "@shikijs/langs": "3.23.0",
+ "@shikijs/themes": "3.23.0",
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@shikijs/core": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz",
+ "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.5"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-javascript": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz",
+ "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^4.3.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-oniguruma": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz",
+ "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@shikijs/themes": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz",
+ "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/@shikijs/types": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz",
+ "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/react-dom": {
+ "version": "19.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz",
+ "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.28.0"
+ },
+ "peerDependencies": {
+ "react": "^19.3.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/letta-code/node_modules/scheduler": {
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz",
+ "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==",
+ "extraneous": true,
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@letta-ai/trajectory": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@letta-ai/trajectory/-/trajectory-0.2.0.tgz",
+ "integrity": "sha512-biCyT0z8nh4Q8kIqBrPgmzoalacPmosmCpvEjdN9ILpL85+T75b8ahcN9MHPHQUVRj/J7UyQuRahJ4/JdrpCcA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@modelcontextprotocol/sdk": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz",
+ "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==",
+ "license": "MIT",
+ "dependencies": {
+ "@hono/node-server": "^1.19.9 || ^2.0.5",
+ "ajv": "^8.17.1",
+ "ajv-formats": "^3.0.1",
+ "content-type": "^1.0.5",
+ "cors": "^2.8.5",
+ "cross-spawn": "^7.0.5",
+ "eventsource": "^3.0.2",
+ "eventsource-parser": "^3.0.0",
+ "express": "^5.2.1",
+ "express-rate-limit": "^8.2.1",
+ "hono": "^4.11.4",
+ "jose": "^6.1.3",
+ "json-schema-typed": "^8.0.2",
+ "pkce-challenge": "^5.0.0",
+ "raw-body": "^3.0.0",
+ "zod": "^3.25 || ^4.0",
+ "zod-to-json-schema": "^3.25.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@cfworker/json-schema": "^4.1.1",
+ "zod": "^3.25 || ^4.0"
+ },
+ "peerDependenciesMeta": {
+ "@cfworker/json-schema": {
+ "optional": true
+ },
+ "zod": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@pierre/diffs": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@pierre/diffs/-/diffs-1.2.2.tgz",
+ "integrity": "sha512-MvWLv2oSOJOF8oYXWLdhicguHM11G/VNWu6OPR5ZETolp2NM2/KPQG3cZTnKpJ6ImqEHwvw6Gl6z2gmmy2FQmQ==",
+ "license": "apache-2.0",
+ "dependencies": {
+ "@pierre/theme": "1.0.3",
+ "@shikijs/transformers": "^3.0.0",
+ "diff": "8.0.3",
+ "hast-util-to-html": "9.0.5",
+ "lru_map": "0.4.1",
+ "shiki": "^3.0.0"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1 || ^19.0.0",
+ "react-dom": "^18.3.1 || ^19.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@pierre/theme": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@pierre/theme/-/theme-1.0.3.tgz",
+ "integrity": "sha512-sWHv11TMoqKxKDgTIk5VbhQjdPhs8DCcBxbjh3mRlS3YOM/OcrWoGX6MM8eBGn9cUu3M46Py0JnxsG2nJaFTuA==",
+ "license": "MIT",
+ "engines": {
+ "vscode": "^1.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/codegen": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
+ "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
+ "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/fetch": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
+ "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@protobufjs/utf8": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz",
+ "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@scarf/scarf": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
+ "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/core": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.5.0.tgz",
+ "integrity": "sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/primitive": "4.5.0",
+ "@shikijs/types": "4.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5",
+ "hast-util-to-html": "^9.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/core/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-javascript": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.5.0.tgz",
+ "integrity": "sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^4.3.6"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-javascript/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-oniguruma": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.5.0.tgz",
+ "integrity": "sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/engine-oniguruma/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/langs": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.0.2.tgz",
+ "integrity": "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.0.2"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/primitive": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.5.0.tgz",
+ "integrity": "sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/primitive/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/themes": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.5.0.tgz",
+ "integrity": "sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.5.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/themes/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/transformers": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.23.0.tgz",
+ "integrity": "sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "3.23.0",
+ "@shikijs/types": "3.23.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/transformers/node_modules/@shikijs/core": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz",
+ "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.5"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/transformers/node_modules/@shikijs/types": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz",
+ "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/types": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.0.2.tgz",
+ "integrity": "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@shikijs/vscode-textmate": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.1.0.tgz",
+ "integrity": "sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/core": {
+ "version": "3.36.2",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.36.2.tgz",
+ "integrity": "sha512-oRw0rB9QSUiCZfEs23G5F4Af+b2rQt1lItIICWu5IejFNd+uPM8SWqiKLMpQ6bX1Q7slsLbjuoE2niErFtkVPQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/credential-provider-imds": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.5.2.tgz",
+ "integrity": "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.33.2",
+ "@smithy/types": "^4.17.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/fetch-http-handler": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.8.0.tgz",
+ "integrity": "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.33.3",
+ "@smithy/types": "^4.18.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/node-http-handler": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.12.1.tgz",
+ "integrity": "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.33.3",
+ "@smithy/types": "^4.18.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/signature-v4": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.7.4.tgz",
+ "integrity": "sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.35.0",
+ "@smithy/types": "^4.19.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@smithy/types": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@stablelib/base64": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz",
+ "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@types/hast": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
+ "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@types/node": {
+ "version": "26.6.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.5.tgz",
+ "integrity": "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~8.9.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@types/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@ungap/structured-clone": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep/-/ripgrep-1.18.0.tgz",
+ "integrity": "sha512-ns5lWe44tSfbTMbVUsyB+I1819PVSw4AdpgK0RNkzfWfwy6+3IUNSxwSrfTno1/oWaS/hERNz+XLWVyga2aJBQ==",
+ "license": "MIT",
+ "optional": true,
+ "optionalDependencies": {
+ "@vscode/ripgrep-darwin-arm64": "1.18.0",
+ "@vscode/ripgrep-darwin-x64": "1.18.0",
+ "@vscode/ripgrep-linux-arm": "1.18.0",
+ "@vscode/ripgrep-linux-arm64": "1.18.0",
+ "@vscode/ripgrep-linux-ia32": "1.18.0",
+ "@vscode/ripgrep-linux-ppc64": "1.18.0",
+ "@vscode/ripgrep-linux-riscv64": "1.18.0",
+ "@vscode/ripgrep-linux-s390x": "1.18.0",
+ "@vscode/ripgrep-linux-x64": "1.18.0",
+ "@vscode/ripgrep-win32-arm64": "1.18.0",
+ "@vscode/ripgrep-win32-ia32": "1.18.0",
+ "@vscode/ripgrep-win32-x64": "1.18.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-darwin-arm64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-darwin-arm64/-/ripgrep-darwin-arm64-1.18.0.tgz",
+ "integrity": "sha512-r3ktHSvbFycQNF6sl7sNDPocpsI7J+mEzh1IaZFkY0spm3k2Z9t8hPAeOK7+p0l6p6/swkQC14XWX01low+94Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-darwin-x64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-darwin-x64/-/ripgrep-darwin-x64-1.18.0.tgz",
+ "integrity": "sha512-25b4gWbL138dGuQU244ebCKKc0q05ULBMoFSz9oAEUHNeqK/lOJViDS7DRvbDazzAzSEdan391Znks/R5mkaTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-arm": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-arm/-/ripgrep-linux-arm-1.18.0.tgz",
+ "integrity": "sha512-GDAvufNDHu8zqLEmXstalQF0Wh6wQvdsBi/Vg3Yi3CK4a8XoFXqqXVEHEZ9xQz3t0NfoSEc9JbvK9DDS6FxyxQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-arm64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-arm64/-/ripgrep-linux-arm64-1.18.0.tgz",
+ "integrity": "sha512-lQ/5zTG++U0E3IhVgS4EPTTn/U4okncaRMM5GOFfOYZywS4nuD31GhkHbNYlDk5CuDC68+hYJ0/eQeyCKJDA+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-ia32": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-ia32/-/ripgrep-linux-ia32-1.18.0.tgz",
+ "integrity": "sha512-YWLkSUtFd4Jh5EepIhA9RJSfv3uMAVMo+2rBIGHPBnvgLrZciIs2cDKei1/p6Wc/aCzUoHyMAg2R6tw4ZCBKGg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-ppc64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-ppc64/-/ripgrep-linux-ppc64-1.18.0.tgz",
+ "integrity": "sha512-quXVY8fwQ8O/lvU1yrSqSl3jlUzysRSb+AfUfCL/tRtphxsKlFvPAejryZ6vg4Bgvn8XL74xb4qMCDmWgYrT5w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-riscv64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-riscv64/-/ripgrep-linux-riscv64-1.18.0.tgz",
+ "integrity": "sha512-f5kBQBrWfQt8Q7OhSORuNDei5dkYagBj3y4jImSUXGMy8B/Ke7SltSRcUtjPv166FAFfHCAmWuZp3+cWnX2/Vw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-s390x": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-s390x/-/ripgrep-linux-s390x-1.18.0.tgz",
+ "integrity": "sha512-rTOcJFGGcl2c07RUOWUo4U1ndnemKhY6A9hnMB18uk7jSgJc0d/QLBGWMWpumdtoJtpizn/wIv5mXIisJukusQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-linux-x64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-linux-x64/-/ripgrep-linux-x64-1.18.0.tgz",
+ "integrity": "sha512-mQ3bVrUpnD2vs7QT0vX90Lt0cnUq467uFtEktIdsJJmW296RoSULRGqWgzG1AKxyBpNDD6l4ZO4qKf6SgyC23Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-win32-arm64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-win32-arm64/-/ripgrep-win32-arm64-1.18.0.tgz",
+ "integrity": "sha512-vfTIjq1OHnzUjxZcHVQAMbnggp8dpGf+0QKFOZHwWPqFwXxQC8eCWM+5NUdoJ6yrElCeMzoUTXoK/LdZaniB+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-win32-ia32": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-win32-ia32/-/ripgrep-win32-ia32-1.18.0.tgz",
+ "integrity": "sha512-//rfAE+BOw5AC2EMmepmiE36jUuevtQYNQqqlw1s3m9FlRxjxEut97RkRPHAu9BG4mSojatZx+kXZXNdyI9caQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/@vscode/ripgrep-win32-x64": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@vscode/ripgrep-win32-x64/-/ripgrep-win32-x64-1.18.0.tgz",
+ "integrity": "sha512-KNPvtElldqILHdnAetujPaowkNbpqJy3ssIGGN6F6Kve9Qi+nNLI2DN01O83JjCEVQbCzl8Ov3QZ9Eov3BR8Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/agent-base": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz",
+ "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ansi-escapes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+ "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ansi-regex": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz",
+ "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/auto-bind": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz",
+ "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/bignumber.js": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
+ "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/body-parser": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.4.0.tgz",
+ "integrity": "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^2.1.0",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.1",
+ "iconv-lite": "^0.7.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.16.1",
+ "raw-body": "^3.0.2",
+ "type-is": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/body-parser/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/bowser": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
+ "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/brace-expansion": {
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+ "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/bundle-name": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.1.tgz",
+ "integrity": "sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==",
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cli-boxes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+ "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cli-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
+ "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cli-truncate/node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/code-excerpt": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz",
+ "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==",
+ "license": "MIT",
+ "dependencies": {
+ "convert-to-spaces": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/content-disposition": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-2.0.1.tgz",
+ "integrity": "sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/convert-to-spaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz",
+ "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cors": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cron-parser": {
+ "version": "5.10.2",
+ "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-5.10.2.tgz",
+ "integrity": "sha512-JfAYMY0LZaWQTuict8PhtF/ksSnq8xefSDmQUnnoqvkPYkU/y3UP0DTWzJKFBz0P1IXsDG8q0vY3zHkoFZOhvw==",
+ "license": "MIT",
+ "dependencies": {
+ "luxon": "^3.7.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/default-browser": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz",
+ "integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==",
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/diff": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz",
+ "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/es-toolkit": {
+ "version": "1.53.0",
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.53.0.tgz",
+ "integrity": "sha512-3+AYXp9fmJ/UhHBMYj2/U+RaUouMD90SzoItyDOB2Za7W6dB7fQApFGnZPl2MF6K8/Tv1koh1JyirSx/kju6Pw==",
+ "license": "MIT",
+ "workspaces": [
+ "docs",
+ "benchmarks",
+ "tests/types",
+ "tests/browser-compat"
+ ]
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/eventsource": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "license": "MIT",
+ "dependencies": {
+ "eventsource-parser": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/eventsource-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz",
+ "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/express": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.3.0.tgz",
+ "integrity": "sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.3.0",
+ "content-disposition": "^2.0.1",
+ "content-type": "^2.0.0",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.8",
+ "qs": "^6.16.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.1.0",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/express-rate-limit": {
+ "version": "8.7.1",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.1.tgz",
+ "integrity": "sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "ip-address": "^10.2.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/express-rate-limit"
+ },
+ "peerDependencies": {
+ "express": ">= 4.11"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/express/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/fast-sha256": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz",
+ "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
+ "license": "Unlicense"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/fast-uri": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
+ "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "license": "MIT",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/gaxios": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.1.tgz",
+ "integrity": "sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^7.0.1",
+ "node-fetch": "^3.3.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/gaxios/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/gaxios/node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/gcp-metadata": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
+ "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "google-logging-utils": "^1.0.0",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/get-east-asian-width": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz",
+ "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/google-auth-library": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.1.tgz",
+ "integrity": "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "gaxios": "^7.1.4",
+ "gcp-metadata": "8.1.2",
+ "google-logging-utils": "1.1.3",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/google-logging-utils": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
+ "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/hono": {
+ "version": "4.13.14",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.14.tgz",
+ "integrity": "sha512-yhRLQ21U6qa9Hsu2N7Qcbh8tE+WKEcoErjIo56LeSGiGXGp9sA7UpE86Ui9uexb61KakiGwuHMn2QdV7w6i6kQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.9.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/http-proxy-agent": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz",
+ "integrity": "sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "9.0.0",
+ "debug": "^4.3.4",
+ "proxy-agent-negotiate": "1.1.0"
+ },
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/https-proxy-agent": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz",
+ "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "9.0.0",
+ "debug": "^4.3.4",
+ "proxy-agent-negotiate": "1.1.0"
+ },
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/iconv-lite": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ink": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/ink/-/ink-5.2.1.tgz",
+ "integrity": "sha512-BqcUyWrG9zq5HIwW6JcfFHsIYebJkWWb4fczNah1goUO0vv5vneIlfwuS85twyJ5hYR/y18FlAYUxrO9ChIWVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@alcalzone/ansi-tokenize": "^0.1.3",
+ "ansi-escapes": "^7.0.0",
+ "ansi-styles": "^6.2.1",
+ "auto-bind": "^5.0.1",
+ "chalk": "^5.3.0",
+ "cli-boxes": "^3.0.0",
+ "cli-cursor": "^4.0.0",
+ "cli-truncate": "^4.0.0",
+ "code-excerpt": "^4.0.0",
+ "es-toolkit": "^1.22.0",
+ "indent-string": "^5.0.0",
+ "is-in-ci": "^1.0.0",
+ "patch-console": "^2.0.0",
+ "react-reconciler": "^0.29.0",
+ "scheduler": "^0.23.0",
+ "signal-exit": "^3.0.7",
+ "slice-ansi": "^7.1.0",
+ "stack-utils": "^2.0.6",
+ "string-width": "^7.2.0",
+ "type-fest": "^4.27.0",
+ "widest-line": "^5.0.0",
+ "wrap-ansi": "^9.0.0",
+ "ws": "^8.18.0",
+ "yoga-layout": "~3.2.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "react": ">=18.0.0",
+ "react-devtools-core": "^4.19.1"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react-devtools-core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ink-link": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ink-link/-/ink-link-4.1.0.tgz",
+ "integrity": "sha512-3nNyJXum0FJIKAXBK8qat2jEOM41nJ1J60NRivwgK9Xh92R5UMN/k4vbz0A9xFzhJVrlf4BQEmmxMgXkCE1Jeg==",
+ "license": "MIT",
+ "dependencies": {
+ "prop-types": "^15.8.1",
+ "terminal-link": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "peerDependencies": {
+ "ink": ">=4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ip-address": {
+ "version": "10.7.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.5.tgz",
+ "integrity": "sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-in-ci": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-1.0.0.tgz",
+ "integrity": "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==",
+ "license": "MIT",
+ "bin": {
+ "is-in-ci": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/jose": {
+ "version": "6.2.13",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.13.tgz",
+ "integrity": "sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/json-schema-to-ts": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
+ "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "ts-algebra": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/json-schema-typed": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/lru_map": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.4.1.tgz",
+ "integrity": "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/lru-cache": {
+ "version": "11.5.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/luxon": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
+ "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/mdast-util-to-hast": {
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/media-typer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz",
+ "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/micromark-util-types": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz",
+ "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/minimatch": {
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.8"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/negotiator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
+ "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/negotiator/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/node-fetch": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "license": "MIT",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/node-pty": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0.tgz",
+ "integrity": "sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-addon-api": "^7.1.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/on-finished": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.2.tgz",
+ "integrity": "sha512-ATWUv387i+nLD49EiDoOft5scf32Vsdz3ktrQJG9bi7jRFmaXTssvyvj1EmeKVVgvesbqUtvQQvaS2TpTukAZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/oniguruma-parser": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
+ "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/oniguruma-to-es": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz",
+ "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==",
+ "license": "MIT",
+ "dependencies": {
+ "oniguruma-parser": "^0.12.2",
+ "regex": "^6.1.0",
+ "regex-recursion": "^6.0.2"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/openai": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-7.19.0.tgz",
+ "integrity": "sha512-MX2s3u2L5racTO0CC/SWpCOasJQBCJrqLKXK+l82cAhdeF8mPMBEe/gxMm0ZFa2xpKpOFLRjxv5afYEZbBXmbQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=22.0.0"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-provider-node": ">=3.972.0 <4",
+ "@smithy/hash-node": ">=4.3.0 <5",
+ "@smithy/signature-v4": ">=5.4.0 <6",
+ "undici": ">=5 <9",
+ "ws": "^8.21.0",
+ "zod": "^3.25 || ^4.0"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-provider-node": {
+ "optional": true
+ },
+ "@smithy/hash-node": {
+ "optional": true
+ },
+ "@smithy/signature-v4": {
+ "optional": true
+ },
+ "undici": {
+ "optional": true
+ },
+ "ws": {
+ "optional": true
+ },
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/p-retry": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+ "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/partial-json": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz",
+ "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/patch-console": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz",
+ "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/path-to-regexp": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
+ "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/pkce-challenge": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/property-information": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz",
+ "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/protobufjs": {
+ "version": "7.6.6",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz",
+ "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.5",
+ "@protobufjs/eventemitter": "^1.1.1",
+ "@protobufjs/fetch": "^1.1.1",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.1",
+ "@types/node": ">=13.7.0",
+ "long": "^5.3.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/proxy-addr": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
+ "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/proxy-agent-negotiate": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz",
+ "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ },
+ "peerDependencies": {
+ "kerberos": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "kerberos": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/qs": {
+ "version": "6.16.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.1.tgz",
+ "integrity": "sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "es-define-property": "^1.0.1",
+ "side-channel": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/range-parser": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
+ "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/react-dom": {
+ "version": "19.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz",
+ "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "scheduler": "^0.28.0"
+ },
+ "peerDependencies": {
+ "react": "^19.3.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/react-reconciler": {
+ "version": "0.29.2",
+ "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz",
+ "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
+ "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/regex-recursion": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz",
+ "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/regex-utilities": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
+ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/restore-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
+ "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/sharp": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
+ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@img/colour": "^1.0.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.5",
+ "@img/sharp-darwin-x64": "0.34.5",
+ "@img/sharp-libvips-darwin-arm64": "1.2.4",
+ "@img/sharp-libvips-darwin-x64": "1.2.4",
+ "@img/sharp-libvips-linux-arm": "1.2.4",
+ "@img/sharp-libvips-linux-arm64": "1.2.4",
+ "@img/sharp-libvips-linux-ppc64": "1.2.4",
+ "@img/sharp-libvips-linux-riscv64": "1.2.4",
+ "@img/sharp-libvips-linux-s390x": "1.2.4",
+ "@img/sharp-libvips-linux-x64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
+ "@img/sharp-linux-arm": "0.34.5",
+ "@img/sharp-linux-arm64": "0.34.5",
+ "@img/sharp-linux-ppc64": "0.34.5",
+ "@img/sharp-linux-riscv64": "0.34.5",
+ "@img/sharp-linux-s390x": "0.34.5",
+ "@img/sharp-linux-x64": "0.34.5",
+ "@img/sharp-linuxmusl-arm64": "0.34.5",
+ "@img/sharp-linuxmusl-x64": "0.34.5",
+ "@img/sharp-wasm32": "0.34.5",
+ "@img/sharp-win32-arm64": "0.34.5",
+ "@img/sharp-win32-ia32": "0.34.5",
+ "@img/sharp-win32-x64": "0.34.5"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/shiki": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.5.0.tgz",
+ "integrity": "sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "4.5.0",
+ "@shikijs/engine-javascript": "4.5.0",
+ "@shikijs/engine-oniguruma": "4.5.0",
+ "@shikijs/langs": "4.5.0",
+ "@shikijs/themes": "4.5.0",
+ "@shikijs/types": "4.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/shiki/node_modules/@shikijs/langs": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.5.0.tgz",
+ "integrity": "sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "4.5.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/shiki/node_modules/@shikijs/types": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
+ "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/slice-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
+ "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/standardwebhooks": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.1.1.tgz",
+ "integrity": "sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@stablelib/base64": "^1.0.0",
+ "fast-sha256": "^1.3.0"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/supports-hyperlinks": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+ "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/terminal-link": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-3.0.0.tgz",
+ "integrity": "sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^5.0.0",
+ "supports-hyperlinks": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/terminal-link/node_modules/ansi-escapes": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz",
+ "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==",
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/terminal-link/node_modules/type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ts-algebra": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
+ "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/type-is": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
+ "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^2.0.0",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/type-is/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/typebox": {
+ "version": "1.3.27",
+ "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.3.27.tgz",
+ "integrity": "sha512-zu+jc1pcy4UiNThxikUr36f0Rybk9PEeCg/NE6adeWr/SKsdNO4EzZHYRDlv2YCVAfj3Odq3dESSo/jNyoBXzA==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/undici-types": {
+ "version": "8.9.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
+ "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unist-util-is": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz",
+ "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unist-util-visit": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.2.0.tgz",
+ "integrity": "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unist-util-visit-parents": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz",
+ "integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/vfile-message": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz",
+ "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/widest-line": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz",
+ "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==",
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/ws": {
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz",
+ "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/yoga-layout": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
+ "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
+ "license": "MIT"
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/zod": {
+ "version": "4.6.7",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz",
+ "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/zod-to-json-schema": {
+ "version": "3.25.2",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
+ "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.25.28 || ^4"
+ }
+ },
+ "node_modules/@letta-ai/letta-code/node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/src/agent_env/agents/agents/letta-code/package.json b/src/agent_env/agents/agents/letta-code/package.json
new file mode 100644
index 00000000..e5c70797
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/package.json
@@ -0,0 +1,6 @@
+{
+ "private": true,
+ "dependencies": {
+ "@letta-ai/letta-code": "0.34.25"
+ }
+}
diff --git a/src/agent_env/agents/agents/letta-code/requirements.txt b/src/agent_env/agents/agents/letta-code/requirements.txt
new file mode 100644
index 00000000..bed7e895
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/requirements.txt
@@ -0,0 +1,6 @@
+# The image installs the newest agentenv-framework-protocol at or above this floor; a release doesn't pin it, so the
+# image is built again only when this folder changes. The floor is the first that serves peer-agents/v1's tools, which
+# the agent advertises without handlers of its own; raise it when the agent needs a newer protocol.
+agentenv-framework-protocol[agent]>=0.1.351
+jsonschema>=4.18,<5
+aiohttp>=3.9,<4
diff --git a/src/agent_env/agents/agents/letta-code/run.sh b/src/agent_env/agents/agents/letta-code/run.sh
new file mode 100644
index 00000000..a40bd7c2
--- /dev/null
+++ b/src/agent_env/agents/agents/letta-code/run.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+# Start an installed agent from ROOT, in this shell's working directory: its environment from ROOT/agent.env, its own
+# Python and the Letta Code CLI, and its Node and Python for the model's commands on a target that has none.
+set -e
+root=$1
+set -a
+. "$root/agent.env"
+set +a
+echo $$ > "$root/agent.pid"
+export PATH="$root/bin:$PATH:$root/node/bin:$root/venv/bin" PYTHONPATH="$root/app"
+# Within install.sh's stop timeout, so a reinstall's stop reaches the shutdown that kills running turns' CLIs.
+exec "$root/venv/bin/uvicorn" a2a_server:app --host 0.0.0.0 --port "$A2A_PORT" --timeout-graceful-shutdown 5
diff --git a/src/agent_env/agents/aliases.toml b/src/agent_env/agents/aliases.toml
index 02d350ed..03725f23 100644
--- a/src/agent_env/agents/aliases.toml
+++ b/src/agent_env/agents/aliases.toml
@@ -6,3 +6,4 @@ gemini = ["gemini"]
opencode = ["opencode"]
pi = ["pi"]
openhands = ["openhands"]
+letta-code = ["letta-code"]
diff --git a/src/agent_env/agents/tasks/letta-code-smoke.json b/src/agent_env/agents/tasks/letta-code-smoke.json
new file mode 100644
index 00000000..7efb0ace
--- /dev/null
+++ b/src/agent_env/agents/tasks/letta-code-smoke.json
@@ -0,0 +1,7 @@
+[
+ {"id": "deploy", "type": "deploy_agent", "a2a_agent_id": "letta-code", "env_ids": [], "sandbox_type": "local"},
+ {"id": "ask", "type": "prompt_agent", "prompt_id": "ask", "depends_on": ["deploy"],
+ "prompt": "Run the shell command `echo $((6 * 7))` and reply with only the number it prints."},
+ {"id": "check", "type": "agent_prompt_response_verifier", "prompt_id": "ask", "verifier_id": "answer",
+ "criteria": [{"type": "response_contains", "needles": ["42"]}], "depends_on": ["ask"]}
+]
diff --git a/tst/unit/agents/letta_code/agent.py b/tst/unit/agents/letta_code/agent.py
new file mode 100644
index 00000000..b29d366a
--- /dev/null
+++ b/tst/unit/agents/letta_code/agent.py
@@ -0,0 +1,20 @@
+"""The Letta Code agent's modules, imported from its folder as its image runs them: by their own names, from the folder
+on the path."""
+
+import importlib
+import importlib.util
+import sys
+from pathlib import Path
+
+import agent_env
+
+AGENT_DIR = Path(agent_env.__file__).parent / "agents" / "agents" / "letta-code"
+sys.path.insert(0, str(AGENT_DIR))
+letta_code_bridge = importlib.import_module("letta_code_bridge")
+letta_code_kit = importlib.import_module("letta_code_kit")
+# By its path: another agent's a2a_server, imported by the same name, may be loaded already.
+_spec = importlib.util.spec_from_file_location("letta_code_a2a_server", AGENT_DIR / "a2a_server.py")
+a2a_server = importlib.util.module_from_spec(_spec)
+# Registered first: pydantic resolves its config's annotations through the module's entry.
+sys.modules[_spec.name] = a2a_server
+_spec.loader.exec_module(a2a_server)
diff --git a/tst/unit/agents/letta_code/test_bridge.py b/tst/unit/agents/letta_code/test_bridge.py
new file mode 100644
index 00000000..c8cb1d6c
--- /dev/null
+++ b/tst/unit/agents/letta_code/test_bridge.py
@@ -0,0 +1,251 @@
+"""Exercise state restore, system instructions, event parsing and cancellation without model calls."""
+import asyncio
+import json
+import subprocess
+from contextlib import asynccontextmanager
+
+import pytest
+
+from tst.unit.agents.letta_code.agent import a2a_server, letta_code_bridge as bridge
+
+
+@pytest.mark.asyncio
+async def test_snapshot_restores_memory_and_conversation_in_another_context(monkeypatch, tmp_path):
+ monkeypatch.setattr(bridge, "SESSIONS_ROOT", str(tmp_path / "sessions"))
+ source = bridge.context_data_dir("source")
+ source.mkdir(parents=True)
+ (source / "context.json").write_text(json.dumps({"home": str(source)}))
+ (source / "agent-id.json").write_text('{"id":"agent-local-1"}')
+ memory = source / ".letta/lc-local-backend/memfs/agent-local-1/memory"
+ memory.mkdir(parents=True)
+ (memory / "MEMORY.md").write_text("Remember violet otters")
+ conversation = source / "conversation.json"
+ conversation.write_text(json.dumps({"id": "local-conv-7", "memory": str(memory), "messages": ["secret"]}))
+ snapshot = tmp_path / "state.tgz"
+ snapshot.write_bytes(await bridge.export_session("source", "local-conv-7"))
+ target = bridge.context_data_dir("target")
+ target.mkdir()
+ (target / "stale").write_text("old target")
+ assert await bridge.import_session("target", str(snapshot)) == "local-conv-7"
+ assert not (target / "stale").exists()
+ assert (target / memory.relative_to(source) / "MEMORY.md").read_text() == "Remember violet otters"
+ restored = json.loads((target / "conversation.json").read_text())
+ assert restored["messages"] == ["secret"]
+ assert restored["memory"] == str(target / memory.relative_to(source))
+ assert (source / "conversation.json").exists()
+
+
+def test_system_prompt_is_committed_and_servers_keep_role_headers(tmp_path):
+ memory = tmp_path / ".letta/lc-local-backend/memfs/agent-local-1/memory"
+ memory.mkdir(parents=True)
+ subprocess.run(["git", "init", "-q", str(memory)], check=True)
+ (memory / "MEMORY.md").write_text("index")
+ bridge._configure_agent(tmp_path, "agent-local-1", {
+ "mail": {"url": "https://mail.example/mcp", "headers": {"Authorization": "token", "AgentEnv-Role": "old"}},
+ }, "reader", "End every answer with ZEBRA")
+ committed = subprocess.check_output(["git", "show", "HEAD:task_instructions.md"], cwd=memory).decode()
+ assert "End every answer with ZEBRA" in committed
+ assert "mcp____" in committed
+ settings = json.loads((tmp_path / ".letta/settings.json").read_text())
+ server = settings["agents"][0]["mcpServers"][0]
+ assert server["headers"] == {"Authorization": "token", "AgentEnv-Role": "reader"}
+ bridge._configure_agent(tmp_path, "agent-local-1", {}, None, "Use TIGER now")
+ committed = subprocess.check_output(["git", "show", "HEAD:task_instructions.md"], cwd=memory).decode()
+ assert "TIGER" in committed and "ZEBRA" not in committed
+
+
+def test_native_events_track_conversation_tools_and_stderr():
+ events = []
+ parser = bridge._EventParser(events.append)
+ for event in [
+ {"type": "system", "conversation_id": "local-conv-2"},
+ {"type": "message", "message_type": "tool_call_message", "tool_call": {"tool_call_id": "call-1"}},
+ {"type": "message", "message_type": "tool_call_message", "tool_call": {"tool_call_id": "call-1"}},
+ {"type": "result", "subtype": "success", "result": "42"},
+ ]:
+ parser.on_line(json.dumps(event))
+ result = parser.result(b"", 0)
+ assert result.response == "42" and result.session_id == "local-conv-2"
+ assert result.tool_call_count == 1 and result.error is None
+ assert len(events) == 4
+ assert "provider failed" in bridge._EventParser().result(b"provider failed", 1).error
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("session_id", [None, "local-conv-7"])
+async def test_cancel_kills_the_turn_process(monkeypatch, tmp_path, session_id):
+ monkeypatch.setattr(bridge, "SESSIONS_ROOT", str(tmp_path / "sessions"))
+ agent = a2a_server.LettaCodeAgent()
+ app = a2a_server.build_app(agent)
+ assert app.state.agentenv_a2a.card.name == "Letta Code"
+ started = asyncio.Event()
+ stopped = asyncio.Event()
+
+ async def command(*args, **kwargs):
+ return b'{"id":"agent-local-1"}'
+
+ async def stream(proc, callback):
+ started.set()
+ await asyncio.Event().wait()
+
+ class Proc:
+ returncode = None
+ def kill(self):
+ self.returncode = -9
+ stopped.set()
+ async def wait(self):
+ return self.returncode
+
+ @asynccontextmanager
+ async def relay(*args, **kwargs):
+ yield "http://relay/v1"
+
+ monkeypatch.setattr(bridge, "model_relay", relay)
+
+ async def spawn(*args, **kwargs):
+ if session_id:
+ assert "--conversation" in args and "--agent" not in args
+ else:
+ assert "--agent" in args and "--new" in args
+ return Proc()
+
+ monkeypatch.setattr(bridge, "_command", command)
+ monkeypatch.setattr(bridge, "_configure_agent", lambda *args: None)
+ monkeypatch.setattr(bridge.asyncio, "create_subprocess_exec", spawn)
+ monkeypatch.setattr(bridge, "_stream_cli", stream)
+ turn = asyncio.create_task(bridge.run_letta_code("wait", "ctx", session_id=session_id, workspace=str(tmp_path)))
+ await asyncio.wait_for(started.wait(), 5)
+ turn.cancel()
+ with pytest.raises(asyncio.CancelledError):
+ await turn
+ assert stopped.is_set() and not bridge._RUNNING
+
+
+def test_direct_mcp_catalog_replaces_previous_context_tools(tmp_path):
+ bridge._install_mcp_tools(tmp_path, "agent-local-1", [{
+ "name": "mcp__mail__search_emails", "description": "Search mail", "inputSchema": {"type": "object"},
+ }])
+ catalog = tmp_path / ".letta/agentenv-mcp-tools.json"
+ assert json.loads(catalog.read_text())["tools"][0]["name"] == "mcp__mail__search_emails"
+ assert (tmp_path / ".letta/mods/agentenv-mcp.ts").exists()
+ bridge._install_mcp_tools(tmp_path, "agent-local-1", [])
+ assert json.loads(catalog.read_text())["tools"] == []
+
+
+def test_failed_workspace_swap_keeps_the_previous_conversation(monkeypatch, tmp_path):
+ monkeypatch.setattr(bridge, "SESSIONS_ROOT", str(tmp_path / "sessions"))
+ monkeypatch.setattr(a2a_server, "WORKSPACE_DIR", tmp_path / "app")
+ target = bridge.context_data_dir("target")
+ target.mkdir(parents=True)
+ (target / "conversation.json").write_text("previous")
+ (tmp_path / "app").mkdir()
+ (tmp_path / "app" / "kept.txt").write_text("previous workspace")
+ staged_state = tmp_path / "staged-state"
+ staged_state.mkdir()
+ (staged_state / "conversation.json").write_text("restored")
+ staged_workspace = tmp_path / "staged-workspace"
+ staged_workspace.mkdir()
+ (staged_workspace / "new.txt").write_text("restored workspace")
+
+ def broken_move(*args, **kwargs):
+ if str(args[0]) == str(staged_state):
+ raise OSError("conversation move failed")
+ return real_move(*args, **kwargs)
+
+ real_move = bridge.shutil.move
+ monkeypatch.setattr(bridge.shutil, "move", broken_move)
+ with pytest.raises(OSError):
+ a2a_server._replace_workspace(staged_workspace, lambda: bridge.commit_staged_session("target", staged_state))
+ assert (tmp_path / "app" / "kept.txt").read_text() == "previous workspace"
+ assert not (tmp_path / "app" / "new.txt").exists()
+ assert (target / "conversation.json").read_text() == "previous"
+
+
+def test_commit_staged_session_restores_previous_state_when_the_move_fails(monkeypatch, tmp_path):
+ monkeypatch.setattr(bridge, "SESSIONS_ROOT", str(tmp_path / "sessions"))
+ target = bridge.context_data_dir("target")
+ target.mkdir(parents=True)
+ (target / "conversation.json").write_text("previous")
+ staged = tmp_path / "staged"
+ staged.mkdir()
+
+ def broken_move(*args, **kwargs):
+ raise OSError("move failed")
+
+ monkeypatch.setattr(bridge.shutil, "move", broken_move)
+ with pytest.raises(OSError):
+ bridge.commit_staged_session("target", staged)
+ assert (target / "conversation.json").read_text() == "previous"
+ assert not target.with_name(target.name + ".previous").exists()
+
+
+@pytest.mark.asyncio
+async def test_cancelled_caller_waits_for_the_file_thread():
+ finished = []
+ release = __import__("threading").Event()
+
+ def work():
+ release.wait(5)
+ finished.append(True)
+
+ task = asyncio.create_task(bridge.shielded_thread(work))
+ await asyncio.sleep(0.05)
+ task.cancel()
+ await asyncio.sleep(0.05)
+ assert not task.done()
+ release.set()
+ with pytest.raises(asyncio.CancelledError):
+ await task
+ assert finished == [True]
+
+
+@pytest.mark.asyncio
+async def test_attribution_is_recorded_only_when_the_relay_forwards(monkeypatch):
+ monkeypatch.setitem(bridge._last_attribution, "project_id", None)
+ monkeypatch.setitem(bridge._last_attribution, "task_id", None)
+ seen = []
+
+ @asynccontextmanager
+ async def relay(headers, on_forward=None):
+ seen.append(on_forward)
+ yield "http://relay/v1"
+
+ monkeypatch.setattr(bridge, "model_relay", relay)
+
+ async def command(*args, **kwargs):
+ return b'{"id":"agent-local-1"}'
+
+ async def spawn(*args, **kwargs):
+ raise OSError("cli did not start")
+
+ monkeypatch.setattr(bridge, "_command", command)
+ monkeypatch.setattr(bridge, "_configure_agent", lambda *args: None)
+ monkeypatch.setattr(bridge.asyncio, "create_subprocess_exec", spawn)
+ with pytest.raises(OSError):
+ await bridge.run_letta_code("hi", "ctx-attr", project_id="p1", task_id="t1", workspace="/tmp")
+ assert bridge.get_last_attribution_snapshot()["project_id"] is None
+ seen[0]()
+ snapshot = bridge.get_last_attribution_snapshot()
+ assert snapshot["project_id"] == "p1" and snapshot["task_id"] == "t1"
+
+
+def test_cleanup_failure_after_a_successful_swap_keeps_the_new_conversation(monkeypatch, tmp_path):
+ monkeypatch.setattr(bridge, "SESSIONS_ROOT", str(tmp_path / "sessions"))
+ target = bridge.context_data_dir("target")
+ target.mkdir(parents=True)
+ (target / "conversation.json").write_text("previous")
+ staged = tmp_path / "staged"
+ staged.mkdir()
+ (staged / "conversation.json").write_text("restored")
+ real_rmtree = bridge.shutil.rmtree
+
+ def rmtree(path, ignore_errors=False, **kwargs):
+ if str(path).endswith(".previous") and not ignore_errors:
+ raise PermissionError("old tree is read-only")
+ if str(path).endswith(".previous"):
+ return None
+ return real_rmtree(path, ignore_errors=ignore_errors, **kwargs)
+
+ monkeypatch.setattr(bridge.shutil, "rmtree", rmtree)
+ bridge.commit_staged_session("target", staged)
+ assert (target / "conversation.json").read_text() == "restored"
diff --git a/tst/unit/bundle/shipped_bundles_test.py b/tst/unit/bundle/shipped_bundles_test.py
index 44495505..e42496f2 100644
--- a/tst/unit/bundle/shipped_bundles_test.py
+++ b/tst/unit/bundle/shipped_bundles_test.py
@@ -45,7 +45,8 @@ def test_the_shipped_aliases_are_agent_envs_alone_and_claude_code_names_the_defa
assert {alias: named.target_id for alias, named in table.aliases.items()} == {
"claude-code": "@local/agentenv-framework/agents/claude-code", "pi": "@local/agentenv-framework/agents/pi",
"openhands": "@local/agentenv-framework/agents/openhands", "codex": "@local/agentenv-framework/agents/codex",
- "gemini": "@local/agentenv-framework/agents/gemini", "opencode": "@local/agentenv-framework/agents/opencode"}
+ "gemini": "@local/agentenv-framework/agents/gemini", "opencode": "@local/agentenv-framework/agents/opencode",
+ "letta-code": "@local/agentenv-framework/agents/letta-code"}
assert table.target("claude-code").target_id == get_config().get_default_a2a_agent_id()
diff --git a/tst/unit/test_infra_images_script.py b/tst/unit/test_infra_images_script.py
index 97c54904..e44825ac 100644
--- a/tst/unit/test_infra_images_script.py
+++ b/tst/unit/test_infra_images_script.py
@@ -62,8 +62,8 @@ def test_plan_only_lists_the_infra_images_or_the_agents_images(script, monkeypat
assert planned == {"infra": [image.name for image in bootstrap.PUBLISHED_IMAGES if image.name not in bundles],
"agents": bundles}
assert "agentenv-gateway" in planned["infra"] and bundles == [
- "agentenv-claude-code", "agentenv-codex", "agentenv-gemini", "agentenv-opencode", "agentenv-openhands",
- "agentenv-pi", "agentenv-proxy", "agentenv-mail-mcp"]
+ "agentenv-claude-code", "agentenv-codex", "agentenv-gemini", "agentenv-letta-code", "agentenv-opencode",
+ "agentenv-openhands", "agentenv-pi", "agentenv-proxy", "agentenv-mail-mcp"]
def test_plan_missing_lists_the_images_the_registry_lacks_or_refuses_to_show(script, monkeypatch, capsys):