Skip to content

Per-session availability for static tools, including workflow tools #5024

Open

Description

@gustavovalverde

What problem are you trying to solve?

Static tools, including workflow tools, cannot be scoped per session without becoming dynamic. Subagents already can: eve always compiles a subagent's resources (instructions, tools, skills, and sandbox), and a resolver decides whether a session sees it. "Return null to omit it from the parent's model-visible tools" (dynamic-capabilities.md L64-69, L99-103). Static tools have no equivalent: disableTool() is decided at build time, and a dynamic tool loses two static features:

  1. A result-based endsTurn. Dynamic tools reject a function-valued endsTurn (dynamic-tool-lifecycle.ts L366-374). The error suggests deciding in the resolver, but the resolver runs before the call and cannot see the execute output.
  2. Workflow bodies. A resolver cannot return defineWorkflowTool() (L102-111).

Example: a WhatsApp ordering agent on eve serves many merchants from one deployment, and each conversation is a session for one merchant. A pizzeria's sessions need a tool that turns "16 slices" into pizza sizes and ends the turn only on some results, and a workflow tool that waits for the shopper to tap a button. A store's sessions should not see either tool. Today both tools stay advertised to every merchant and return "not applicable" where they don't fit.

Proposed solution

Let static tools, including workflow tools, declare their availability per session. The definition stays static, so the workflow body, endsTurn function, approval policy, and schemas are unchanged. Only the tool's presence in the session's model-visible tools varies.

export default defineWorkflowTool({
  // ...
  available: (ctx) => merchantKind(ctx.session.auth.current) === "pizzeria",
});

This is the authored-tool counterpart of #1543, which asks for per-session availability of built-in tools. An agent-level allowlist, like option (b) there, could serve both.

Availability would be evaluated at session.started, and optionally at turn.started, as for dynamic subagents. Session scope keeps the tool list stable for prompt caching. The result is a set of tool names stored in durable context, so no callback replay is needed. A call to an unavailable tool should fail before execute. Availability is not an authorization boundary.

Other frameworks filter statically defined tools per run or per step the same way: OpenAI Agents SDK isEnabled (source), Google ADK tool_filter (source), and AI SDK prepareStep with activeTools (source).

Prompt or implementation plan for our agents (optional)

Add per-session availability for static tools, including defineWorkflowTool tools and tools contributed by extensions, modeled on dynamic subagent availability. Start from packages/eve/src/harness/model-call/tools.ts, where eve assembles the model's tools and endsTurnTools. It is done when a workflow tool hidden in one session is visible in another, a function-valued endsTurn still ends the turn, and a call to a hidden tool fails before execute, including after resumption in a new process. Update the dynamic capabilities and tools docs.

Alternatives considered

  • A durable endsTurn callback for dynamic tools. This fixes only the first limit and leaves workflow tools unscoped. It is worth doing separately.
  • Static tools that return "not applicable". This is the current workaround. It costs tokens on every step and invites calls that can only fail.

Activity

  1. roboeve commented on Oct 19, 2026

    @roboeve
    Contributor

    Triaged as a feature request (tools, p2). Not a duplicate.

    The cited constraints hold on current main: dynamic resolvers reject defineWorkflowTool() and workflow-tool names, dynamic tool metadata only accepts a literal endsTurn, and disableTool() applies to the whole agent.

    Related: #1543 asks for the same per-session gate over framework built-ins and is still open. One availability mechanism over all static tools (authored, workflow, extension, built-in) would likely cover both, so they should be designed together.

    Next step: this adds public API, so it needs a short design doc under research/ that picks one shape (per-tool available predicate or an agent-level allowlist resolver) and pins the semantics before implementation:

    • evaluation scope: session only, or turn too
    • whether a parked workflow tool call is re-checked on resume
    • how it composes with disableTool() and defaultTools: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions