feat(groq): built-in-tools request fork + boundary gating (#69 S4)#72
Merged
Conversation
Forks the Groq adapter's request shape by model family and gates built-in
tools at the boundary:
- compound systems (groq/compound, groq/compound-mini) → built-in tools on
compound_custom.tools.enabled_tools, taking the normalized identifiers
verbatim (Groq's compound vocabulary IS our normalized set).
- openai/gpt-oss-120b → OpenAI-style tools:[{type}] entries merged onto the
same array as function tools, translated to gpt-oss's native vocabulary
(web_search → browser_search).
Gating reuses the catalog accessor modelSupportsBuiltInTools(model,'groq',
tool.type) as the single source of truth — no duplicate capability set in
the adapter, so it can't drift from the S3 catalog entries. Only the
wire-translation map (web_search→browser_search) is local, since spelling
isn't a catalog concern. Unsupported (model, tool) pairs throw a
ConfigurationError naming the capable models and, for gpt-oss, its supported
subset. A gate-passed-but-unmapped tool throws an explicit internal error
rather than emitting {type: undefined}.
Also required: groq/compound + groq/compound-mini added to the adapter's
`models` array — base.validateRequest rejects any pinned model not listed
there before formatRequest runs, so a pinned compound request would 400
otherwise. Added matching getModelCapabilities entries (token costs
estimated; built-in surcharges not token-tracked, per issue scope).
Not touched: TOOL_CAPABLE_MODELS (compound function-tool support is
unverified from the S0 spike — conservative reject stands) and
GROQ_RESPONSE_SCHEMA (response parsing is S5; validateSchema already ignores
the undeclared executed_tools field, so real compound traffic passes).
typecheck clean; 398 tests pass (+7 groq adapter tests: compound fork,
five-tool passthrough, gpt-oss translation, function+built-in merge,
function-only rejection, unsupported-tool rejection, pinned-model accept).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closed
8 tasks
The function-only-model rejection test called generateResponse twice; the first ConfigurationError (thrown inside executeWithResiliency) accumulates a circuit-breaker failure, so the second call could throw a breaker error instead of the ConfigurationError. Assert both expectations against one invocation. Surfaced by CI; local runs masked the timing dependence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ase (#69) OSS package — docs travel with the feature. Covers what's shipped through S4 (request side + gating), accurately scoping structured result surfacing (metadata.builtInToolResults) as a follow-up: - README: Features bullet, Groq providers-table row, MODELS.GROQ_COMPOUND/_MINI constants, and a "Built-in Tools (Server-Side)" section (normalized identifiers, per-model wire-shape table, routing/provenance/cost notes). - CHANGELOG: [Unreleased] section enumerating the builtInTools field, the BuiltInTool* types, supportsBuiltInTools, modelSupportsBuiltInTools, the Compound catalog entries, the RESEARCH use case, and the capability-aware routing + request fork. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements S4 of the Groq built-in-tools sprint (#69), on top of the merged S3 catalog (#71).
What
Forks the Groq adapter's request shape by model family and gates built-in tools at the boundary.
groq/compound,groq/compound-minicompound_custom.tools.enabled_tools: [...]openai/gpt-oss-120btools: [{ type }], merged onto the same array as function toolsweb_search→browser_searchGating reuses the catalog — no drift
The capability gate calls
modelSupportsBuiltInTools(model, 'groq', tool.type)(the accessor S3 built) as the single source of truth, rather than a duplicate capability set in the adapter. Only the wire-translation map (web_search→browser_search) is local, since spelling isn't a catalog concern. The enforcement point is still the adapter (satisfies the issue review's "gating belongs in the adapter, not catalog-only" — the accessor takes(model, provider)explicitly, so pinned models that bypass routing are still gated).(model, tool)→ConfigurationErrornaming the capable models and, for gpt-oss, its supported subset (web_search, code_interpreter).{type: undefined}.Also required — the
modelsarraybase.validateRequestrejects any pinned model not in the provider'smodelslist beforeformatRequestruns, somodel: 'groq/compound'would have thrown without this. Added both compound models there + matchinggetModelCapabilities()entries (token costs estimated; built-in surcharges not token-tracked, per issue scope).Deliberately not touched
TOOL_CAPABLE_MODELS— compound's function-tool support is unverified from the S0 spike, so the conservative reject stands (built-in tools are a separate, gated path).GROQ_RESPONSE_SCHEMA— response parsing is S5. ConfirmedvalidateSchemaignores undeclared fields, so the unchanged schema already passes a realexecuted_toolsresponse.Tests
typecheck clean; 398 pass (+7 new): compound fork shape, five-tool verbatim passthrough, gpt-oss translation, function+built-in merge on one array, function-only-model rejection (names capable models), unsupported-tool-on-gpt-oss rejection (names subset), pinned-
groq/compoundaccepted throughvalidateRequest.Next: S5 — parse
executed_tools[].search_results.results→metadata.builtInToolResults, extendGROQ_RESPONSE_SCHEMA.🤖 Generated with Claude Code