Skip to content

Commit d47de6d

Browse files
feat: add tools with instructions and examples to agent config types
Co-Authored-By: Paul Loeb <ploeb@launchdarkly.com>
1 parent a14761d commit d47de6d

3 files changed

Lines changed: 59 additions & 4 deletions

File tree

packages/sdk/server-ai/src/ldai/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
AIAgentConfig, AIAgentConfigDefault, AIAgentConfigRequest,
1111
AIAgentGraphConfig, AIAgents, AICompletionConfig,
1212
AICompletionConfigDefault, AIConfig, AIJudgeConfig, AIJudgeConfigDefault,
13-
Edge, JudgeConfiguration, LDAIAgent, LDAIAgentConfig, LDAIAgentDefaults,
14-
LDMessage, ModelConfig, ProviderConfig)
13+
AITool, Edge, JudgeConfiguration, LDAIAgent, LDAIAgentConfig,
14+
LDAIAgentDefaults, LDMessage, ModelConfig, ProviderConfig)
1515
from ldai.providers.types import EvalScore, JudgeResponse
1616
from ldai.tracker import AIGraphTracker
1717

@@ -23,6 +23,7 @@
2323
'AIAgents',
2424
'AIAgentGraphConfig',
2525
'AIGraphTracker',
26+
'AITool',
2627
'Edge',
2728
'AICompletionConfig',
2829
'AICompletionConfigDefault',

packages/sdk/server-ai/src/ldai/client.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ldai.models import (AIAgentConfig, AIAgentConfigDefault,
1212
AIAgentConfigRequest, AIAgentGraphConfig, AIAgents,
1313
AICompletionConfig, AICompletionConfigDefault,
14-
AIJudgeConfig, AIJudgeConfigDefault, Edge,
14+
AIJudgeConfig, AIJudgeConfigDefault, AITool, Edge,
1515
JudgeConfiguration, LDMessage, ModelConfig,
1616
ProviderConfig)
1717
from ldai.providers.ai_provider_factory import AIProviderFactory
@@ -706,19 +706,35 @@ def __evaluate_agent(
706706
:param variables: Variables for interpolation.
707707
:return: Configured AIAgentConfig instance.
708708
"""
709-
model, provider, messages, instructions, tracker, enabled, judge_configuration, _ = self.__evaluate(
709+
model, provider, messages, instructions, tracker, enabled, judge_configuration, variation = self.__evaluate(
710710
key, context, default.to_dict(), variables
711711
)
712712

713713
# For agents, prioritize instructions over messages
714714
final_instructions = instructions if instructions is not None else default.instructions
715715

716+
# Parse tools from variation data
717+
tools = None
718+
if 'tools' in variation and isinstance(variation['tools'], list):
719+
tools = [
720+
AITool(
721+
key=tool['key'],
722+
version=tool.get('version', 0),
723+
instructions=tool.get('instructions'),
724+
examples=tool.get('examples'),
725+
custom_parameters=tool.get('customParameters'),
726+
)
727+
for tool in variation['tools']
728+
if isinstance(tool, dict) and 'key' in tool
729+
] or None
730+
716731
return AIAgentConfig(
717732
key=key,
718733
enabled=bool(enabled) if enabled is not None else (default.enabled or False),
719734
model=model or default.model,
720735
provider=provider or default.provider,
721736
instructions=final_instructions,
737+
tools=tools if tools is not None else (default.tools if default.tools else None),
722738
tracker=tracker,
723739
judge_configuration=judge_configuration or default.judge_configuration,
724740
)

packages/sdk/server-ai/src/ldai/models.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,38 @@ def to_dict(self) -> dict:
139139
}
140140

141141

142+
# ============================================================================
143+
# Tool Types
144+
# ============================================================================
145+
146+
@dataclass(frozen=True)
147+
class AITool:
148+
"""
149+
Configuration for an AI tool.
150+
"""
151+
key: str
152+
version: int
153+
instructions: Optional[str] = None
154+
examples: Optional[str] = None
155+
custom_parameters: Optional[Dict[str, Any]] = None
156+
157+
def to_dict(self) -> dict:
158+
"""
159+
Render the tool as a dictionary object.
160+
"""
161+
result: Dict[str, Any] = {
162+
'key': self.key,
163+
'version': self.version,
164+
}
165+
if self.instructions is not None:
166+
result['instructions'] = self.instructions
167+
if self.examples is not None:
168+
result['examples'] = self.examples
169+
if self.custom_parameters is not None:
170+
result['customParameters'] = self.custom_parameters
171+
return result
172+
173+
142174
# ============================================================================
143175
# Base AI Config Types
144176
# ============================================================================
@@ -249,6 +281,7 @@ class AIAgentConfigDefault(AIConfigDefault):
249281
Default Agent-specific AI Config with instructions.
250282
"""
251283
instructions: Optional[str] = None
284+
tools: Optional[List[AITool]] = None
252285
judge_configuration: Optional[JudgeConfiguration] = None
253286

254287
def to_dict(self) -> Dict[str, Any]:
@@ -258,6 +291,8 @@ def to_dict(self) -> Dict[str, Any]:
258291
result = self._base_to_dict()
259292
if self.instructions is not None:
260293
result['instructions'] = self.instructions
294+
if self.tools is not None:
295+
result['tools'] = [tool.to_dict() for tool in self.tools]
261296
if self.judge_configuration is not None:
262297
result['judgeConfiguration'] = self.judge_configuration.to_dict()
263298
return result
@@ -269,6 +304,7 @@ class AIAgentConfig(AIConfig):
269304
Agent-specific AI Config with instructions.
270305
"""
271306
instructions: Optional[str] = None
307+
tools: Optional[List[AITool]] = None
272308
judge_configuration: Optional[JudgeConfiguration] = None
273309

274310
def to_dict(self) -> Dict[str, Any]:
@@ -278,6 +314,8 @@ def to_dict(self) -> Dict[str, Any]:
278314
result = self._base_to_dict()
279315
if self.instructions is not None:
280316
result['instructions'] = self.instructions
317+
if self.tools is not None:
318+
result['tools'] = [tool.to_dict() for tool in self.tools]
281319
if self.judge_configuration is not None:
282320
result['judgeConfiguration'] = self.judge_configuration.to_dict()
283321
return result

0 commit comments

Comments
 (0)