Skip to content

feat: add tools with instructions and examples to completion and agent configs#106

Open
ld-paul wants to merge 3 commits intomainfrom
devin/1773277027-add-tool-instructions-examples
Open

feat: add tools with instructions and examples to completion and agent configs#106
ld-paul wants to merge 3 commits intomainfrom
devin/1773277027-add-tool-instructions-examples

Conversation

@ld-paul
Copy link

@ld-paul ld-paul commented Mar 12, 2026

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

Part of a coordinated multi-repo change to add instructions and examples fields to AI Tools. Companion PRs:

Describe the solution you've provided

Adds a new AITool dataclass and wires tools through both completion and agent configurations so the SDK can surface tool metadata (including the new instructions and examples fields) returned by the LaunchDarkly API.

Changes:

  • models.py: New frozen AITool dataclass with key, version, instructions, examples, and custom_parameters fields. Added tools: Optional[List[AITool]] to AIAgentConfig, AIAgentConfigDefault, AICompletionConfig, and AICompletionConfigDefault, with serialization support in all to_dict() methods.
  • client.py: Both _completion_config and __evaluate_agent now parse tools from the variation dictionary, constructing AITool instances. Falls back to default.tools when the variation has no tools.
  • __init__.py: Exports AITool.
  • tests/test_tools.py: 14 new tests covering tool parsing, serialization, default fallback, and edge cases for both completion and agent configs.

Updates since last revision

  • Added tools field to AICompletionConfig and AICompletionConfigDefault (previously only on agent configs)
  • _completion_config in client.py now parses tools from variation data, mirroring the agent pattern
  • Added comprehensive test suite (test_tools.py) — all 91 tests pass (14 new tool tests + 77 existing)

⚠️ Key items for reviewer

  1. Duplicated tool-parsing logic: The tool parsing block in _completion_config (lines ~59-72) and __evaluate_agent (lines ~733-745) is identical. Consider extracting to a shared helper if this is a concern.
  2. Empty list → None coercion ([...] or None): if all tools fail the filter, the result is None rather than []. Verify this is the desired behavior.
  3. Default version=0 (tool.get('version', 0)): tools missing a version key silently default to 0. Confirm this is acceptable vs raising or skipping.
  4. Fallback expression: tools if tools is not None else (default.tools if default.tools else None) is equivalent to tools if tools is not None else default.tools since default.tools already defaults to None.

Describe alternatives you've considered

  • Could have parsed tools at the __evaluate level (alongside messages, model, etc.) instead of in both _completion_config and __evaluate_agent. Chose per-method parsing to keep the shared __evaluate method unchanged and limit blast radius.

Additional context


Note

Medium Risk
Moderate risk because it changes the shape and parsing/serialization of returned config objects (completion_config/agent_config), which could affect downstream consumers and default/fallback behavior (notably distinguishing missing tools from an explicit empty list).

Overview
Adds a new frozen AITool model (including instructions, examples, and customParameters) and wires tools through both completion and agent config types (AICompletionConfig*, AIAgentConfig*) with to_dict() support.

Updates LDAIClient to parse a tools array from flag variation payloads in _completion_config and __evaluate_agent, falling back to default.tools only when the server does not send tools (while preserving an explicit empty list), and exports AITool from ldai.__init__.

Adds tests/test_tools.py to cover tool parsing, serialization, default fallback, and empty/missing tool edge cases for both completion and agent configs.

Written by Cursor Bugbot for commit 0996e4e. This will update automatically on new commits. Configure here.

Co-Authored-By: Paul Loeb <ploeb@launchdarkly.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@ld-paul
Copy link
Author

ld-paul commented Mar 12, 2026

make sure to add test coverage and verify the tests pass

Co-Authored-By: Paul Loeb <ploeb@launchdarkly.com>
@devin-ai-integration devin-ai-integration bot changed the title feat: add tools with instructions and examples to agent config types feat: add tools with instructions and examples to completion and agent configs Mar 12, 2026
@devin-ai-integration
Copy link
Contributor

Note: This PR needs the devin-pr label added.

@ld-paul ld-paul marked this pull request as ready for review March 12, 2026 01:56
@ld-paul ld-paul requested a review from a team as a code owner March 12, 2026 01:56
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

)
for tool in variation['tools']
if isinstance(tool, dict) and 'key' in tool
] or None
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated tool-parsing logic across two methods

Low Severity

The tool-parsing block in _completion_config and __evaluate_agent is completely identical — same list comprehension, same AITool construction, same filter, same or None coercion. This duplication means any future bug fix or field addition needs to be applied in both places, risking divergence. Extracting to a shared helper (similar to how __evaluate is shared) would eliminate this risk.

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid observation. The duplication is intentional to keep the shared __evaluate method unchanged and limit blast radius. Extracting to a helper is a reasonable follow-up refactor but deferring for now to keep this PR focused on the feature addition.

Co-Authored-By: Paul Loeb <ploeb@launchdarkly.com>
@jsonbailey jsonbailey self-requested a review March 12, 2026 14:09
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