fix: parse model.parameters.tools as list#160
Conversation
The wire format for tools at model.parameters.tools is a list of LDTool objects, while root-level tools is a dict keyed by tool name. Previously _resolve_tools treated both as dicts, causing the model params fallback path to always return None. Removes helper functions and inlines logic into _resolve_tools with no warnings, matching the JS implementation approach of trusting the data shape from the LD API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 05e9c78. Configure here.
| return None | ||
| tools: Dict[str, LDTool] = {} | ||
| for tool_name, tool_dict in tools_data.items(): | ||
| if isinstance(tool_dict, dict): |
There was a problem hiding this comment.
Silent data dropping in inlined parsing logic lacks logging
Low Severity
The removed _parse_tools helper previously logged warnings when discarding malformed tool entries (e.g., non-dict values). That same parsing logic is now inlined into _resolve_tools at lines 63 and 85, where entries failing isinstance checks are silently skipped without any warning or debug log. The rule requires log messages when flag variation data is silently dropped because it doesn't match the expected type. Although _resolve_tools is exempted for navigation type-checks (e.g. if not isinstance(model, dict): return None), the entry-level iteration and filtering on lines 63 and 85 is data-validation/parsing work — the same logic that _parse_tools performed with warnings.
Additional Locations (1)
Triggered by learned rule: Flag silent data dropping in parsing helpers — warn/log on malformed input
Reviewed by Cursor Bugbot for commit 05e9c78. Configure here.


Summary
model.parameters.toolswire format is a list ofLDToolobjects; root-leveltoolsis a dict keyed by tool name. Previously_resolve_toolschecked for a dict in both paths, so the model params fallback always returnedNone._resolve_toolsto checkisinstance(tools_list, list)for the model params path and iterate it to build the tools dict._parse_toolsand_parse_tools_from_listhelpers, inlining the logic. No warnings are emitted — data from the LD API is trusted to be our shape, matching the JS SDK approach.Test plan
uv run pytest tests/test_tools.py— all 11 tools tests passuv run pytest— all 154 tests passuv run mypy src/ldai— no type errors🤖 Generated with Claude Code
Note
Medium Risk
Changes how tool definitions are parsed from AI config flag variations, which can affect which tools are available at runtime for completions/agents. Scope is small and covered by updated/added unit tests for accepted and rejected wire formats.
Overview
Fixes tool resolution so
model.parameters.toolsis parsed from the correct list wire format (building a name-keyed dict), while keeping root-leveltoolsas the higher-priority dict format.Removes the shared
_parse_toolshelper and inlines parsing logic, and updates tests/fixtures to validate list parsing, dict rejection for model params, and skipping malformed list entries.Reviewed by Cursor Bugbot for commit 05e9c78. Bugbot is set up for automated code reviews on this repo. Configure here.