Skip to content

Add provider-agnostic toolChoice option and ToolChoice validator - #25

Merged
MarcelloDuarte merged 1 commit into
mainfrom
v0.13-tool-choice
Jul 25, 2026
Merged

Add provider-agnostic toolChoice option and ToolChoice validator#25
MarcelloDuarte merged 1 commit into
mainfrom
v0.13-tool-choice

Conversation

@MarcelloDuarte

Copy link
Copy Markdown
Contributor

First step of v0.13 (forced tool choice). Core-only; providers follow once this is released.

What

  • Add PapiAI\Core\ToolChoice: validates and normalises the toolChoice chat option ("auto", "none", "required", or ["name" => "<tool>"]) against the declared tools, throwing InvalidArgumentException before any HTTP call on an unknown value, on none/required/specific with no tools declared, or a name not among the declared tools. It never silently drops an unenforceable choice.
  • Define the chat options bag once as a reusable @psalm-type ChatOptions on ProviderInterface; providers import it with @psalm-import-type ChatOptions from ProviderInterface, so adding an option no longer drifts across per-provider docblocks.
  • Document toolChoice on the contract.

Design note

This is the deliberate option-bag design (the option flows through verbatim; each provider maps and validates it). The ISP-clean alternative (a segregated ToolCallingProviderInterface, a supportsToolChoice() capability query, and first-class ChatOptions/ToolChoice value objects) is parked as #24 for the v1.0 interface audit.

Tests

217 passed (10 new ToolChoice tests), lint and Psalm (level 4) clean.

Introduce the ToolChoice value object that validates and normalises the
toolChoice chat option ("auto", "none", "required", or ["name" => "<tool>"]),
throwing before any HTTP call on an unknown value or an unenforceable choice
(no tools declared, or a name not among the declared tools).

Define the chat options bag once as a reusable @psalm-type ChatOptions on
ProviderInterface so providers import it with @psalm-import-type instead of
repeating the shape across per-provider docblocks.
@MarcelloDuarte
MarcelloDuarte merged commit 0ed0475 into main Jul 25, 2026
6 checks passed
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.

1 participant