Skip to main content

is_observation_batch

Function is_observation_batch 

Source
pub fn is_observation_batch(calls: &[ToolCall], patterns: &[String]) -> bool
Expand description

Return true if every call in calls is an observation-only tool.

A tool call is classified as observation-only when its lowercased name contains at least one pattern in patterns as a substring. Matching is case-insensitive (both sides are lowercased before comparison).

A substring captures more than it names, which matters for a hand-written list, since a user’s observation_tools replaces the shipped one whole: a pattern read also matches thread_create and spreadsheet_update, and tools that change state get the read-only allowance. The shipped coding-agent patterns are long enough that everything they capture is read-only (see AgentConfig::observation_tools); the browser ones are not, and snapshot also matches delete_snapshot. Whole-segment matching, the rule is_costly_batch uses, would stop list_dir covering list_directory and click covering get_clickable_elements, and over-capturing here is the cheaper error.

An empty patterns list means no tools are ever classified as observation-only, so the function always returns false.

An empty calls slice returns true (vacuous truth), but the caller (crate::domain::agent::LoopDetector::check) is never invoked with an empty batch — both the agent loop and the proxy’s history scan skip loop detection when there are no tool calls. That is now load bearing rather than merely tidy: an empty batch would hash to a signature of its own and break the consecutive run.