Skip to main content

carries_tools

Function carries_tools 

Source
pub fn carries_tools(body: &Value) -> bool
Expand description

Whether the request carries a non-empty tools array.

§This identifies an agentic turn, not a tool-emission turn

The distinction matters and was learned the hard way. This answers “could this turn produce a tool call?”, never “will it?”. VS Code Copilot in agent mode sends the tools array on essentially every request — including prose, planning, summarising and thinking turns — so in the client this was built for, the answer is permanently yes.

Anything keyed on this therefore applies to a whole agentic session, not to the moment a call is emitted. Adjustments hanging off it must be safe for prose, because they will spend most of their time there.

§Why there is no better signal

Every candidate fails. tool_choice is "auto" on every turn. The last message’s role does not predict what comes next. A history containing prior tool_calls only says “this is an agentic session”, which is the thing already known. This is the same wall super::constrain documents for grammars: you cannot know before decoding whether the model will emit a call. The only true discriminator is mid-stream marker detection, which is a different and much larger piece of machinery.

§Deliberately more lenient than the grammar path

constrain needs the complete list of tool names to build a GBNF alternation, so it rejects a tools array in which any entry is missing function.name. That strictness is right for originating a grammar and wrong here: a request with one malformed tool entry is still an agentic turn.

A tools key that is present but not a non-empty array — null, [], an object — reads as no tools. tool_choice is not consulted at all: it can appear without tools (nothing strips it), and on its own it does not make a turn agentic.