Skip to content

✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions (experimental) - #14150

Merged
danny-avila merged 5 commits into
devfrom
claude/keen-archimedes-f10a29
Jul 12, 2026
Merged

✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions (experimental)#14150
danny-avila merged 5 commits into
devfrom
claude/keen-archimedes-f10a29

Conversation

@danny-avila

@danny-avila danny-avila commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

Wires the @librechat/agents stateful sandbox sub-config into LibreChat behind a dual opt-in: a new, off-by-default stateful_code_sessions app capability AND a per-agent toggle in the Agent Builder. When both are on, a conversation's execute_code/bash tools run against a warm per-session Code API workspace instead of a fresh sandbox per call.

Changes

Capability and schema:

  • AgentCapabilities.stateful_code_sessions (off by default; not in defaultAgentCapabilities).
  • New per-agent field stateful_code_sessions (Mongoose schema, IAgent, zod create/update validation, Agent type + create/update params). Field name matches the capability value, following the end_after_tools convention.

Agent Builder (frontend <-> backend plumbing):

  • New toggle in Advanced settings (Advanced/StatefulSessions.tsx), shown only when the app capability is enabled and disabled unless the agent has Code Interpreter on. Persists through composeAgentUpdatePayload -> update/create endpoints -> agent document, and loads back via the standard form seeding.

Backend agent initialization (per-agent gating):

  • initializeAgent resolves the per-agent truth once: statefulCodeSessions = admin capability AND agent.stateful_code_sessions AND effectiveCodeEnvAvailable. The resolved value drives all three surfaces so they cannot disagree:
    • the bash_tool description registered for the LLM (registerCodeExecutionTools, including the skill-catalog path),
    • the execute_code/bash_tool factory params (statefulSessions),
    • createRun, which walks per-agent flags (anyAgentHasStatefulSessions, including nested subagents) to set toolExecution: { sandbox: { statefulSessions: true } }.
  • statefulSessionsAvailable threads through the same call sites as codeEnvAvailable (chat controller, OpenAI-compatible + Responses controllers, handoff discovery, added conversations), so subagents and handoffs resolve it identically.
  • The SDK derives the session hint from thread_id (the conversationId); the server derives the real session id as hash(tenant, user, hint), so none of this is a trust boundary.

How LibreChat learns about AWS (it doesn't)

LibreChat needs zero AWS configuration for this feature. The boundary is deliberate:

  • LibreChat only talks to the Code API over HTTP (CODE_BASEURL + the existing Code API auth). Its only new wire artifact is the runtime_session_hint field.
  • The Code API service (feat: optional AWS Lambda MicroVM stateful sandbox backend LibreChat-AI/code-interpreter#16) owns everything AWS: backend selection (CODEAPI_SANDBOX_BACKEND=lambda-microvm vs the default http), the MicroVM image ARN, execution roles, network connectors, the S3 checkpoint bucket, and AWS credentials via its own environment.
  • Consequences: sandbox/AWS credentials never live in the chat app, and the operator can swap the Code API's execution backend (or run entirely without AWS) with no LibreChat config change. If the backend is stateless http, the hint is ignored and behavior is exactly today's.

Safety

Off by default twice over (app capability + per-agent toggle). All fields ride the variable-not-literal runConfig pattern, so they typecheck and no-op against the currently pinned @librechat/agents; they activate once the SDK is bumped to the version shipping toolExecution.sandbox.

Tests

  • statefulCodeSessions.spec.ts: per-agent walk (top-level, nested subagents, cycles, defaults-off).
  • Full packages/api agents suite (41 suites, 1087 tests) green; api initialize.spec.js (15) and client AgentPanel.helpers.spec.ts (9) green.
  • packages/api tsc 0 errors, client tsc 0 errors, eslint + import-sort clean.

Depends on

The @librechat/agents bump to the version with the sandbox sub-config (companion PR danny-avila/agents#291).


Testing this end to end (from scratch, across the three PRs)

This PR is the top of a three-repo stack. Nothing here is user-visible until the other two are in place, so start by understanding the order:

  1. danny-avila/agents#291 - the SDK surface (toolExecution.sandbox + statefulSessions). The linchpin.
  2. ClickHouse/code-interpreter#16 - the Code API service with the Lambda MicroVM backend and hookless per-request session binding.
  3. This PR - the capability, the per-agent builder toggle, and the run-config + factory wiring.

Activating this PR before the published agents release. LibreChat depends on @librechat/agents, and the sandbox surface is not published yet, so the fields here safely no-op against the pinned version. To test the real behavior, build the agents branch and link it (npm link @librechat/agents against a local build of agents#291, or point the dependency at that branch), then rebuild LibreChat. Until you do, the toggle persists but is inert.

Tier 0 - unit tests (no infra, minutes)

  • agents: npm test (the stateful ToolNode.session / CodeExecutor.stateful / BashExecutor suites).
  • code-interpreter: bun run test in service/ and api/ (fake AWS client + Bun.serve fakes, no AWS).
  • LibreChat (this PR): cd packages/api && npx jest statefulCodeSessions run.spec.

Tier 1 - wiring smoke (local Code API, no AWS)

Verifies capability -> agent toggle -> run config -> SDK -> wire, without needing a stateful backend.

  1. Run the Code API from #16 locally (the default http backend is fine for this tier).
  2. Point LibreChat at it: set CODE_BASEURL to your local Code API and provide Code API credentials the same way you do for execute_code today.
  3. In librechat.yaml, enable the capability:
    endpoints:
      agents:
        capabilities: ["execute_code", "stateful_code_sessions", "actions", "tools"]
  4. In the Agent Builder, enable Code Interpreter on an agent, then open Advanced settings and flip on "Stateful code sessions" (the toggle only appears when the capability is enabled, and stays disabled without Code Interpreter).
  5. Start a chat with that agent and run any code. In the Code API logs you should see runtime_session_hint (= the conversationId) on the /exec request. (The http backend ignores the hint, so there is no persistence yet - expected.)
  6. Negative controls: an agent without the toggle - no hint on the wire; capability removed from the yaml - the toggle disappears from the builder and existing opted-in agents send no hint.

Tier 2 - real statefulness (Code API session backend)

Switch the Code API to the session backend (see #16 for full setup): CODEAPI_SANDBOX_BACKEND=lambda-microvm, CODEAPI_RUNTIME_SESSION_MODE=affinity, and a session-workspace runner image (SANDBOX_SESSION_WORKSPACE_ENABLED=true). For the real-MicroVM path on AWS, #16 documents the hookless image build + RunMicrovm + the two-turn E2E. All AWS setup lives there - LibreChat's config does not change between tiers.

The acceptance test (what "working" looks like)

With the capability on and the agent's toggle on, in one conversation:

  • Message 1: "Using python, compute 6*7 and write only that number to /mnt/data/answer.txt."
  • Message 2: "Read /mnt/data/answer.txt and tell me the number."

The agent reads back 42 in message 2. Flip the agent's toggle off (or the capability) and the same message 2 finds no file (fresh-per-job). That difference is the feature.

Copilot AI review requested due to automatic review settings July 7, 2026 11:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an off-by-default stateful_code_sessions capability to let code-execution tools (bash/execute_code) reuse a warm per-conversation Code API sandbox session when enabled via agents endpoint capabilities, while preserving stateless behavior by default.

Changes:

  • Introduces AgentCapabilities.stateful_code_sessions (not included in defaults).
  • Adds resolveStatefulCodeSessions gating and conditionally injects toolExecution.sandbox.statefulSessions: true into the agents run config.
  • Threads a statefulSessions flag into bash/execute_code tool factories to adjust tool descriptions when the capability is enabled.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/data-provider/src/config.ts Adds new agent capability enum value for stateful code sessions.
packages/api/src/agents/statefulCodeSessions.spec.ts Adds unit tests covering stateful session gating behavior.
packages/api/src/agents/run.ts Implements capability gate and conditionally enables sandbox stateful sessions in run config.
api/server/services/ToolService.js Passes statefulSessions into bash tool creation when capability and code execution are enabled.
api/app/clients/tools/util/handleTools.js Passes statefulSessions into execute_code tool creation based on capability check.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/api/src/agents/run.ts Outdated
if (!codeEnvActive) {
return false;
}
return new Set(agentsEndpointConfig?.capabilities).has(AgentCapabilities.stateful_code_sessions);
@danny-avila danny-avila changed the title ✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions ✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions (experimental) Jul 7, 2026
@danny-avila
danny-avila force-pushed the claude/keen-archimedes-f10a29 branch from 3cd770b to e75185c Compare July 7, 2026 13:01
…essions

Wire the @librechat/agents stateful sandbox sub-config behind a new,
off-by-default stateful_code_sessions agent capability. createRun sets
toolExecution.sandbox.statefulSessions when code execution is active in the
run AND the capability is enabled; execute_code and bash_tool factories get
the param so their descriptions hedge toward persistence. Rides the existing
variable-not-literal runConfig pattern, so it no-ops until @librechat/agents
is bumped to the version shipping the sandbox sub-config.
Stateful sessions now require the agent's own opt-in, not just the admin
capability. New agent field stateful_code_sessions (schema + validation +
types) surfaces as a toggle in Agent Builder Advanced settings, gated on
the app capability and disabled without Code Interpreter. initializeAgent
resolves the per-agent truth (admin capability AND builder opt-in AND
code env) once: the registered bash_tool description, the execute_code
factory, and createRun's toolExecution.sandbox gate all read the same
resolved value. statefulSessionsAvailable threads through the same call
sites as codeEnvAvailable, including handoff discovery and added convos.
…iven tool path

The event-driven ON_TOOL_EXECUTE handler built config.toolCall without the
resolved runtime_session_hint, so BashExecutor/CodeExecutor never sent
runtime_session_hint to the Code API. Every conversation then collapsed onto
the server-derived default session (no per-conversation isolation). Copy
tc.runtimeSessionHint onto toolCallConfig._runtime_session_hint, mirroring the
SDK direct-execution path.
@danny-avila
danny-avila force-pushed the claude/keen-archimedes-f10a29 branch from de52d26 to 45c1cd7 Compare July 9, 2026 14:15
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45c1cd74c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

* `toolExecution.sandbox` gate all agree for this agent. */
const effectiveStatefulSessions =
effectiveCodeEnvAvailable &&
params.statefulSessionsAvailable === true &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forward the stateful capability through the OpenAI service

When using the exported OpenAI-compatible service (packages/api/src/agents/openai/service.ts), it still derives and passes only codeEnvAvailable to deps.initializeAgent. Since this new gate requires params.statefulSessionsAvailable === true, an agent with execute_code, the app-level stateful_code_sessions capability, and agent.stateful_code_sessions: true is initialized with statefulCodeSessions false on that route, so createRun never sends toolExecution.sandbox and the feature silently does nothing. Please derive and pass the new capability alongside codeEnvAvailable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c0919bc. packages/api/src/agents/openai/service.ts now derives statefulSessionsAvailable from the agents endpoint capabilities and passes it to deps.initializeAgent alongside codeEnvAvailable, so this OpenAI-compatible route resolves stateful sessions identically to the in-repo controllers.

Comment on lines +1429 to +1431
...(statefulCodeSessions && {
toolExecution: { sandbox: { statefulSessions: true } },
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep stateful sessions scoped to opted-in agents

In a multi-agent run where one code-capable agent opts into stateful sessions and another code-capable agent does not, this run-level toolExecution switch enables stateful sandbox handling for the whole graph. That means non-opted-in agents in the same run can still have their bash_tool / execute_code calls persisted under the conversation session, even though only the opted-in agent's tool definition was hedged as stateful. Please make the SDK/config gate per-agent or avoid mixing opted-out code agents into a globally stateful run.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid observation — this is an intentional run-level gate for v1. The SDK's toolExecution.sandbox.statefulSessions is a run-config (not per-agent), and the runtime session id is derived per-conversation (hash(tenant, user, thread_id)), so any code-capable agent in the conversation shares the conversation's warm workspace by design; anyAgentHasStatefulSessions enables it when at least one reachable agent opts in.

The residual gap you flag — a non-opted-in code agent's bash_tool/execute_code description isn't hedged as stateful even though its calls persist under the conversation session — is real, but closing it cleanly needs per-agent toolExecution support in @librechat/agents (the run-config can't vary per agent today). Tracking that as a follow-up; keeping the run-level, conversation-scoped behavior here.

Comment on lines +3351 to +3352
if (tc.runtimeSessionHint != null && tc.runtimeSessionHint !== '') {
toolCallConfig._runtime_session_hint = tc.runtimeSessionHint;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass stateful hints through host sandbox tools

When read_file, create_file, or edit_file is the first sandbox operation in a stateful conversation, those host-handled branches return before this generic tool path, and readSandboxFile / writeSandboxFile only receive session_id and files. With no existing session_id yet, their /exec calls still lack the per-conversation runtime hint and fall back to the Code API's default session, so host file reads/writes can leak across conversations or miss the intended stateful workspace. Please thread tc.runtimeSessionHint through the host sandbox helpers as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c0919bc. Threaded the per-conversation runtime_session_hint (tc.runtimeSessionHint) through the host file-authoring path: added it to the readSandboxFile/writeSandboxFile option types (handlers.ts), forwarded it at all three call sites (handleReadFileCall plus the read/write helpers used by create_file/edit_file), and the implementations in api/server/services/Files/Code/process.js now include it in the /exec body. So a host file op that is the first sandbox call in a conversation joins the same runtime session instead of falling back to the Code API's default.

Comment on lines +49 to +50
checked={enabled && codeEnabled === true}
onCheckedChange={handleChange}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the hidden stateful flag when code is disabled

If an agent has stateful sessions enabled and the user later turns off Code Interpreter, this switch renders unchecked and disabled but the form value remains true; composeAgentUpdatePayload still persists stateful_code_sessions: true. The saved agent therefore doesn't match the UI, and re-enabling Code Interpreter later silently reactivates stateful sessions. Please clear the form value when codeEnabled becomes false, or omit/force false in the payload when the code tool is disabled.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c0919bc. StatefulSessions.tsx now clears the form value via a useEffect — when execute_code is turned off it sets stateful_code_sessions to false (dirty), so the saved agent matches the disabled UI and re-enabling Code Interpreter later doesn't silently reactivate stateful sessions.

- OpenAI-compatible service (packages/api/src/agents/openai/service.ts) now
  derives and passes statefulSessionsAvailable alongside codeEnvAvailable, so
  the feature activates on that route (previously statefulCodeSessions resolved
  false there and createRun never sent toolExecution.sandbox).
- Thread runtime_session_hint through the host file-authoring tools
  (create_file/edit_file/read_file): those host branches return before the
  generic tool path, so readSandboxFile/writeSandboxFile now forward the
  per-conversation hint instead of falling back to the Code API default session.
- StatefulSessions builder toggle clears its form value when Code Interpreter is
  disabled, so a saved agent matches the disabled UI and re-enabling code doesn't
  silently reactivate stateful sessions.
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0919bc726

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +27 to +30
useEffect(() => {
if (codeEnabled !== true && enabled) {
setValue(AgentCapabilities.stateful_code_sessions, false, { shouldDirty: true });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear stale stateful opt-in outside Advanced

When a user disables Code Interpreter from the main builder and saves without opening Advanced settings, this effect never runs because StatefulSessions is only mounted in the Advanced panel. composeAgentUpdatePayload will therefore keep sending the existing stateful_code_sessions: true, so re-enabling code later silently turns warm sessions back on despite the prerequisite having been disabled; this normalization needs to live in always-mounted form or payload logic.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 14a34f2. You're right — the round-1 useEffect only fired while the Advanced panel was mounted, so disabling Code Interpreter from the main builder (without opening Advanced) never cleared the opt-in.

Moved the normalization into composeAgentUpdatePayload, the always-run save path:

const normalizedStatefulCodeSessions =
  data.execute_code === true ? stateful_code_sessions : false;

stateful_code_sessions is now forced to false on save whenever execute_code !== true, regardless of whether Advanced was ever opened, so a stale opt-in can't silently reactivate warm sessions when code is re-enabled later. Reverted the mount-scoped useEffect and added spec coverage for both branches.

Comment on lines +1429 to +1430
...(statefulCodeSessions && {
toolExecution: { sandbox: { statefulSessions: true } },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep stateful sandbox config scoped per agent

In a mixed multi-agent run where any one reachable agent opted into stateful sessions, this run-wide toolExecution.sandbox setting is applied to the entire graph. The execution path forwards the resulting runtime session hint for sandbox tool calls, so other code-enabled agents in the same run that left stateful_code_sessions off can still run against the conversation-persistent workspace, violating the per-agent opt-in and changing their /mnt/data lifetime unexpectedly.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same intentional run-level scope as the round-1 thread on this file. The SDK's toolExecution.sandbox.statefulSessions is a run-config, not per-agent, and the runtime session id is hash(tenant, user, thread_id) — conversation-scoped — so once any reachable agent opts in, the conversation's warm workspace is shared by design. The forwarded _runtime_session_hint you flag is that mechanism, not a separate leak: it routes calls to the same conversation session.

The residual gap — a non-opted-in code agent's /mnt/data lifetime changing because it now runs against the persistent workspace — is real, but it can only be closed cleanly with per-agent toolExecution support in @librechat/agents (the run-config can't vary per agent today). Keeping the run-level, conversation-scoped behavior for v1 and tracking per-agent scoping as an SDK follow-up.

… disabled

Addresses Codex review (round 2): a stale `stateful_code_sessions` opt-in
could persist when Code Interpreter (`execute_code`) is disabled from the
main agent builder without opening Advanced settings, silently reactivating
warm sessions if code was later re-enabled.

- AgentPanel: normalize in `composeAgentUpdatePayload` (the always-run save
  path) so `stateful_code_sessions` is forced to `false` whenever
  `execute_code !== true`, regardless of whether Advanced was opened.
- StatefulSessions: revert the mount-scoped useEffect (round-1 approach) —
  it only fired while the Advanced panel was mounted, missing this path.
- Add spec coverage for both branches of the normalization.
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14a34f2152

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// thread_id. Requires @librechat/agents with `toolExecution.sandbox`;
// older versions ignore the field.
...(statefulCodeSessions && {
toolExecution: { sandbox: { statefulSessions: true } },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep stateful sessions scoped to opted-in agents

When a run mixes code-enabled agents and only one has statefulCodeSessions true (for example, a stateless primary delegating to an opted-in subagent), this single run-level toolExecution.sandbox.statefulSessions setting applies to the whole graph. That means sandbox calls from agents whose builder toggle is off can still receive the persistent per-conversation session behavior, so their code may reuse files/packages/state from prior calls despite being configured as stateless. Please scope the session hint per agent/tool, or avoid enabling the run-level setting for mixed graphs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Third pass on this one — and note that Finding A (the stale-opt-in normalization) was not re-raised, so that fix on 14a34f215 is confirmed. Thanks.

On scoping: this is a deliberate v1 tradeoff, and both workarounds you suggest have a failure mode — which is exactly why I'm holding at run-level until the SDK supports per-agent toolExecution:

  • "Scope the session hint per agent/tool" — not possible from LibreChat today. statefulSessions is a single run-level flag in @librechat/agents, and the executor stamps _runtime_session_hint from the run config; LibreChat can't vary it per agent without SDK support. Tracked as an SDK follow-up.
  • "Don't enable for mixed graphs" (i.e. require all code-capable agents to opt in) — trades the reported surprise for the opposite one: an agent whose builder toggle is explicitly on would silently get no persistence in a mixed graph. Silently dropping an explicit opt-in is arguably worse than the current "any reachable opt-in shares the conversation workspace," especially since the session is conversation-scoped (hash(tenant, user, thread_id)) by design.

Keeping the run-level, conversation-scoped behavior for v1 with this documented; the clean per-agent fix lands with SDK support.

@danny-avila
danny-avila merged commit 53e369f into dev Jul 12, 2026
32 checks passed
@danny-avila
danny-avila deleted the claude/keen-archimedes-f10a29 branch July 12, 2026 12:12
fuuuzzy pushed a commit to fuuuzzy/LibreChat that referenced this pull request Aug 7, 2026
…essions (experimental) (danny-avila#14150)

* ✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions

Wire the @librechat/agents stateful sandbox sub-config behind a new,
off-by-default stateful_code_sessions agent capability. createRun sets
toolExecution.sandbox.statefulSessions when code execution is active in the
run AND the capability is enabled; execute_code and bash_tool factories get
the param so their descriptions hedge toward persistence. Rides the existing
variable-not-literal runConfig pattern, so it no-ops until @librechat/agents
is bumped to the version shipping the sandbox sub-config.

* ✨ feat: per-agent stateful code sessions (builder toggle + init gating)

Stateful sessions now require the agent's own opt-in, not just the admin
capability. New agent field stateful_code_sessions (schema + validation +
types) surfaces as a toggle in Agent Builder Advanced settings, gated on
the app capability and disabled without Code Interpreter. initializeAgent
resolves the per-agent truth (admin capability AND builder opt-in AND
code env) once: the registered bash_tool description, the execute_code
factory, and createRun's toolExecution.sandbox gate all read the same
resolved value. statefulSessionsAvailable threads through the same call
sites as codeEnvAvailable, including handoff discovery and added convos.

* 🐛 fix: propagate runtime_session_hint to sandbox executor in event-driven tool path

The event-driven ON_TOOL_EXECUTE handler built config.toolCall without the
resolved runtime_session_hint, so BashExecutor/CodeExecutor never sent
runtime_session_hint to the Code API. Every conversation then collapsed onto
the server-derived default session (no per-conversation isolation). Copy
tc.runtimeSessionHint onto toolCallConfig._runtime_session_hint, mirroring the
SDK direct-execution path.

* 🐛 fix: address Codex review findings for stateful code sessions

- OpenAI-compatible service (packages/api/src/agents/openai/service.ts) now
  derives and passes statefulSessionsAvailable alongside codeEnvAvailable, so
  the feature activates on that route (previously statefulCodeSessions resolved
  false there and createRun never sent toolExecution.sandbox).
- Thread runtime_session_hint through the host file-authoring tools
  (create_file/edit_file/read_file): those host branches return before the
  generic tool path, so readSandboxFile/writeSandboxFile now forward the
  per-conversation hint instead of falling back to the Code API default session.
- StatefulSessions builder toggle clears its form value when Code Interpreter is
  disabled, so a saved agent matches the disabled UI and re-enabling code doesn't
  silently reactivate stateful sessions.

* 🐛 fix: normalize stateful_code_sessions on save when Code Interpreter disabled

Addresses Codex review (round 2): a stale `stateful_code_sessions` opt-in
could persist when Code Interpreter (`execute_code`) is disabled from the
main agent builder without opening Advanced settings, silently reactivating
warm sessions if code was later re-enabled.

- AgentPanel: normalize in `composeAgentUpdatePayload` (the always-run save
  path) so `stateful_code_sessions` is forced to `false` whenever
  `execute_code !== true`, regardless of whether Advanced was opened.
- StatefulSessions: revert the mount-scoped useEffect (round-1 approach) —
  it only fired while the Advanced panel was mounted, missing this path.
- Add spec coverage for both branches of the normalization.
LogicalAbsurd pushed a commit to LogicalAbsurd/LibreChat that referenced this pull request Aug 27, 2026
…essions (experimental) (danny-avila#14150)

* ✨ feat: stateful_code_sessions capability for warm Code API sandbox sessions

Wire the @librechat/agents stateful sandbox sub-config behind a new,
off-by-default stateful_code_sessions agent capability. createRun sets
toolExecution.sandbox.statefulSessions when code execution is active in the
run AND the capability is enabled; execute_code and bash_tool factories get
the param so their descriptions hedge toward persistence. Rides the existing
variable-not-literal runConfig pattern, so it no-ops until @librechat/agents
is bumped to the version shipping the sandbox sub-config.

* ✨ feat: per-agent stateful code sessions (builder toggle + init gating)

Stateful sessions now require the agent's own opt-in, not just the admin
capability. New agent field stateful_code_sessions (schema + validation +
types) surfaces as a toggle in Agent Builder Advanced settings, gated on
the app capability and disabled without Code Interpreter. initializeAgent
resolves the per-agent truth (admin capability AND builder opt-in AND
code env) once: the registered bash_tool description, the execute_code
factory, and createRun's toolExecution.sandbox gate all read the same
resolved value. statefulSessionsAvailable threads through the same call
sites as codeEnvAvailable, including handoff discovery and added convos.

* 🐛 fix: propagate runtime_session_hint to sandbox executor in event-driven tool path

The event-driven ON_TOOL_EXECUTE handler built config.toolCall without the
resolved runtime_session_hint, so BashExecutor/CodeExecutor never sent
runtime_session_hint to the Code API. Every conversation then collapsed onto
the server-derived default session (no per-conversation isolation). Copy
tc.runtimeSessionHint onto toolCallConfig._runtime_session_hint, mirroring the
SDK direct-execution path.

* 🐛 fix: address Codex review findings for stateful code sessions

- OpenAI-compatible service (packages/api/src/agents/openai/service.ts) now
  derives and passes statefulSessionsAvailable alongside codeEnvAvailable, so
  the feature activates on that route (previously statefulCodeSessions resolved
  false there and createRun never sent toolExecution.sandbox).
- Thread runtime_session_hint through the host file-authoring tools
  (create_file/edit_file/read_file): those host branches return before the
  generic tool path, so readSandboxFile/writeSandboxFile now forward the
  per-conversation hint instead of falling back to the Code API default session.
- StatefulSessions builder toggle clears its form value when Code Interpreter is
  disabled, so a saved agent matches the disabled UI and re-enabling code doesn't
  silently reactivate stateful sessions.

* 🐛 fix: normalize stateful_code_sessions on save when Code Interpreter disabled

Addresses Codex review (round 2): a stale `stateful_code_sessions` opt-in
could persist when Code Interpreter (`execute_code`) is disabled from the
main agent builder without opening Advanced settings, silently reactivating
warm sessions if code was later re-enabled.

- AgentPanel: normalize in `composeAgentUpdatePayload` (the always-run save
  path) so `stateful_code_sessions` is forced to `false` whenever
  `execute_code !== true`, regardless of whether Advanced was opened.
- StatefulSessions: revert the mount-scoped useEffect (round-1 approach) —
  it only fired while the Advanced panel was mounted, missing this path.
- Add spec coverage for both branches of the normalization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants