Skip to content

[pull] main from danny-avila:main#131

Merged
pull[bot] merged 6 commits into
innFactory:mainfrom
danny-avila:main
Jul 7, 2026
Merged

[pull] main from danny-avila:main#131
pull[bot] merged 6 commits into
innFactory:mainfrom
danny-avila:main

Conversation

@pull

@pull pull Bot commented Jul 7, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

danny-avila and others added 6 commits July 7, 2026 06:57
#289)

* feat: host-suppliable AgentInputs.graphTools for in-graph direct tools

Hosts running event-driven (definitions-only) tool execution had no way to make
a specific tool execute IN-PROCESS inside the graph's ToolNode: the event
partition routes purely by directToolNames, and the host-side ON_TOOL_EXECUTE
handler runs outside the Pregel task frame — where a tool body calling
LangGraph interrupt() (e.g. one built on the SDK's askUserQuestion() helper)
throws 'Called interrupt() outside the context of a graph.'

- AgentInputs.graphTools: host-supplied tool instances that join the existing
  graph-managed direct path — bound to the model alongside schema-only event
  tools, added to the ToolNode toolMap, and marked direct (Graph already wires
  agentContext.graphTools this way for handoff/subagent tools)
- AgentContext.fromConfig copies the array (never aliases — the SDK pushes
  subagent tools into it later and must not mutate host input)
- buildChildInputs clears graphTools for subagent children (including the
  self-spawn shape, which shallow-spreads the parent's _sourceInputs): child
  graphs compile without a checkpointer, so an interrupt-capable direct tool
  would deterministically fail with 'No checkpointer set' there

Tests: direct tool in event-driven mode raises ask_user_question from its body
(event dispatch never sees the call) and resumes with the answer as its
ToolMessage; fromConfig copy + event-mode binding; child-input clearing.

* fix: Codex round-1 findings — scoped child scrub, executable-only graphTools, honest tool count

- buildChildInputs scrubs graphTools ONLY from self-spawn configs (whose
  agentInputs are a shallow spread of the parent's _sourceInputs); an explicit
  child config that lists its own graphTools is a deliberate host choice and
  keeps them (P2)
- AgentInputs.graphTools narrowed from GraphTools to GenericTool[]: the wider
  union admits schema-only shapes (BindToolsInput / Google tool objects) that
  initializeTools cannot register in the ToolNode direct map — the model would
  bind a tool advertised as in-process but unexecutable (P2)
- getToolCount now includes graphTools: graph-managed + host-supplied direct
  tools are bound and token-accounted, so omitting them under-reported the
  run's public tool surface (P3)

* fix: seed traditional toolMap from base tools when graphTools force a merge

ToolNode treats a supplied toolMap as authoritative (it only derives one from
`tools` when the param is undefined), so the merged map built for graphTools
must seed an absent currentToolMap from the BASE tools — otherwise ordinary
tools stay bound to the model but vanish from the execution map, and every
call to them fails as an unknown tool. Smoke test pins both names present.
* feat: reshape Langfuse traces per Langfuse team feedback

- Drop noise spans: langgraph __start__ seeds and anonymous RunnableLambda
  pass-throughs are no longer exported
- Strip the ephemeral agent id (provider__model) from agent=/tools= node
  names so observation names stay stable across model switches
- Rename tool node spans to the actual pending tool name(s) and scope
  their input to the tool-call args instead of the full chat history
- Set root span and trace input/output to the user question and
  assistant response so the session view reads as a conversation
- Rename title-chain runNames (ExtractTitle -> ParseTitleFromResponse,
  etc.) for clearer observation names

* test: update title observation name in langfuse routing spec
…291)

* feat: stateful sandbox sessions via toolExecution.sandbox sub-config

Surfaces the Code API's best-effort stateful runtime sessions without a
new ToolExecutionEngine value (the remote sandbox tools are host-
constructed with closure-held auth/files, and the backend speaks the
same /exec protocol — so a sub-config, not a transport swap).

- ToolExecutionConfig.sandbox { statefulSessions, runtimeSessionHint };
  statefulSessions factory param on the 4 remote tools (prompt text only).
- ToolNode injects _runtime_session_hint into config.toolCall (explicit
  hint else configurable.thread_id), independent of the transient
  exec-session block, on both the direct and event-driven paths.
- execute_code + bash_tool send runtime_session_hint on the request and
  get hedged 'best-effort' descriptions (usually persists, may reset,
  only /mnt/data is durable); bash wording is filesystem-tier. PTC/BashPTC
  plumb the wire hint on the initial request only but keep their stateless
  prompt in v1 (flipping the 'fresh interpreter' contract is the biggest
  behavior change; gate it separately once server sessions are proven).
- Artifacts + ExecuteResult echo runtime_session_id / runtime_status.
  Fully additive: stateless servers ignore the field; the flag is
  prompt-only and never hits the wire.

Verified end-to-end with a real Anthropic model (claude-sonnet-4-5)
driving execute_code across two turns against a session-mode runner:
turn 1 wrote /mnt/data/answer.txt, turn 2 read it back (new->reused),
every request carried runtime_session_hint. Unit: 30/30 ToolNode
session, 6/6 CodeExecutor stateful+wire, 9/9 BashExecutor.

* fix: carry runtimeSessionHint through event-driven request planning

buildToolExecutionRequestPlan dropped runtimeSessionHint: ToolExecutionPlanCall
didn't declare it and the builder never copied it onto the ToolCallRequest, so
event-driven and eager execute_code/bash_tool calls never carried the hint and
couldn't reuse the configured stateful runtime (only the direct ToolNode path
did). Add the field to the plan call + request, extract a shared
resolveRuntimeSessionHint used by ToolNode and the stream.ts eager planner, and
resolve+pass the hint in the eager path. Regression tests on the builder +
resolver.

* fix: harden stateful sandbox against speculative + model-controlled hints

Addresses Codex review on 5f95acf:

- Never eagerly prestart execute_code/bash when statefulSessions is on: the
  eager path is speculative, and a revised/discarded turn would leave writes
  applied to the durable warm workspace. isEagerExecutionExcludedTool now
  excludes CODE_EXECUTION_TOOLS under stateful (stateless keeps the throwaway-VM
  optimization). The eager planner no longer attaches runtimeSessionHint at all.
- Strip model-supplied runtime_session_hint from raw tool args in CodeExecutor
  and BashExecutor: the hint is host-controlled and must only come from
  ToolNode's injected _runtime_session_hint, else a tool call could opt itself
  into / pick a stateful runtime with statefulSessions off.
- Remove the no-op statefulSessions option from the PTC factory params: PTC is
  stateless in v1 and never read it, so it was a misleading public knob.

Regression tests: model-hint stripping + injected-hint-wins in
CodeExecutor.stateful.

* docs: clarify the two-gate stateful-sandbox contract

Codex flagged that enabling run-scoped toolExecution.sandbox.statefulSessions
without the tool-factory statefulSessions param leaves the model told the
environment is stateless while the backend runs statefully. The dual gate is
intentional: tool descriptions bind to the LLM at construction time (before the
run config is applied inside the graph), so the run config cannot retroactively
change what the model was shown — only the factory param can. Spell that out on
both fields and the required 'set both from one flag' pairing (non-corrupting
if they drift: the model just won't exploit persistence).
@pull pull Bot locked and limited conversation to collaborators Jul 7, 2026
@pull pull Bot added the ⤵️ pull label Jul 7, 2026
@pull
pull Bot merged commit 328a7e8 into innFactory:main Jul 7, 2026
1 check passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants