Skip to content

Commit 9523fa7

Browse files
jsonbaileyclaude
andcommitted
fix: resolve lint errors from rebase onto main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0f7752d commit 9523fa7

10 files changed

Lines changed: 48 additions & 36 deletions

File tree

packages/ai-providers/server-ai-langchain/src/ldai_langchain/langchain_agent_runner.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22

33
from typing import Any, Dict, List
44

5+
from langchain_core.messages import (
6+
AIMessage,
7+
BaseMessage,
8+
HumanMessage,
9+
SystemMessage,
10+
ToolMessage,
11+
)
512
from ldai import log
613
from ldai.providers import AgentResult, AgentRunner, ToolRegistry
714
from ldai.providers.types import LDAIMetrics
8-
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage, ToolMessage
915

1016
from ldai_langchain.langchain_helper import get_ai_metrics_from_response
1117

packages/ai-providers/server-ai-langchain/src/ldai_langchain/langchain_helper.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ def get_ai_usage_from_response(response: Any) -> Optional[TokenUsage]:
8888
:return: TokenUsage or None if unavailable
8989
"""
9090
if hasattr(response, 'usage_metadata') and response.usage_metadata:
91-
return TokenUsage(
92-
total=response.usage_metadata.get('total_tokens', 0),
93-
input=response.usage_metadata.get('input_tokens', 0),
94-
output=response.usage_metadata.get('output_tokens', 0),
95-
)
91+
total = response.usage_metadata.get('total_tokens', 0)
92+
inp = response.usage_metadata.get('input_tokens', 0)
93+
out = response.usage_metadata.get('output_tokens', 0)
94+
if total or inp or out:
95+
return TokenUsage(total=total, input=inp, output=out)
9696
if hasattr(response, 'response_metadata') and response.response_metadata:
9797
token_usage = (
9898
response.response_metadata.get('tokenUsage')

packages/ai-providers/server-ai-langchain/src/ldai_langchain/langchain_runner_factory.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
from typing import Any
1+
from typing import TYPE_CHECKING, Any
22

33
from ldai.models import AIConfigKind
44
from ldai.providers import AIProvider, ToolRegistry
55

6+
if TYPE_CHECKING:
7+
from ldai_langchain.langchain_agent_runner import LangChainAgentRunner
8+
69
from ldai_langchain.langchain_helper import create_langchain_model
710
from ldai_langchain.langchain_model_runner import LangChainModelRunner
811

@@ -49,5 +52,5 @@ def create_agent(self, config: Any, tools: Any) -> 'LangChainAgentRunner':
4952
tool_definitions = parameters.pop('tools', []) or []
5053
instructions = config.instructions or '' if hasattr(config, 'instructions') else ''
5154

52-
llm = LangChainHelper.create_langchain_model(config)
55+
llm = create_langchain_model(config)
5356
return LangChainAgentRunner(llm, instructions, tool_definitions, tools or {})

packages/ai-providers/server-ai-langchain/tests/test_langchain_provider.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
LangChainRunnerFactory,
1313
convert_messages_to_langchain,
1414
get_ai_metrics_from_response,
15+
get_ai_usage_from_response,
1516
get_tool_calls_from_response,
1617
map_provider,
1718
sum_token_usage_from_messages,
@@ -142,7 +143,7 @@ def test_usage_metadata_preferred_over_response_metadata(self):
142143
'completionTokens': 499,
143144
},
144145
}
145-
usage = LangChainHelper.get_ai_usage_from_response(mock_response)
146+
usage = get_ai_usage_from_response(mock_response)
146147
assert usage is not None
147148
assert usage.total == 10
148149
assert usage.input == 4
@@ -154,43 +155,43 @@ class TestGetAIUsageFromResponse:
154155

155156
def test_returns_none_when_no_usage(self):
156157
msg = AIMessage(content='hi')
157-
assert LangChainHelper.get_ai_usage_from_response(msg) is None
158+
assert get_ai_usage_from_response(msg) is None
158159

159160
def test_returns_none_when_all_zeros_in_metadata(self):
160161
msg = AIMessage(content='hi')
161162
msg.usage_metadata = {'total_tokens': 0, 'input_tokens': 0, 'output_tokens': 0}
162-
assert LangChainHelper.get_ai_usage_from_response(msg) is None
163+
assert get_ai_usage_from_response(msg) is None
163164

164165

165166
class TestGetToolCallsFromResponse:
166167
"""Tests for LangChainHelper.get_tool_calls_from_response."""
167168

168169
def test_returns_empty_when_no_tool_calls(self):
169170
msg = AIMessage(content='hi')
170-
assert LangChainHelper.get_tool_calls_from_response(msg) == []
171+
assert get_tool_calls_from_response(msg) == []
171172

172173
def test_returns_empty_when_tool_calls_not_a_sequence(self):
173174
msg = AIMessage(content='hi')
174175
msg.tool_calls = None # type: ignore
175-
assert LangChainHelper.get_tool_calls_from_response(msg) == []
176+
assert get_tool_calls_from_response(msg) == []
176177

177178
def test_extracts_names_from_dict_tool_calls(self):
178179
msg = AIMessage(content='')
179180
msg.tool_calls = [ # type: ignore
180181
{'name': 'search', 'args': {}, 'id': '1'},
181182
{'name': 'calc', 'args': {}, 'id': '2'},
182183
]
183-
assert LangChainHelper.get_tool_calls_from_response(msg) == ['search', 'calc']
184+
assert get_tool_calls_from_response(msg) == ['search', 'calc']
184185

185186
def test_returns_empty_when_tool_calls_is_not_a_list(self):
186187
msg = AIMessage(content='hi')
187188
msg.tool_calls = () # type: ignore
188-
assert LangChainHelper.get_tool_calls_from_response(msg) == []
189+
assert get_tool_calls_from_response(msg) == []
189190

190191
def test_skips_entries_without_name(self):
191192
msg = AIMessage(content='')
192193
msg.tool_calls = [{'name': 'a', 'id': '1'}, {}, {'name': 'b', 'id': '2'}] # type: ignore
193-
assert LangChainHelper.get_tool_calls_from_response(msg) == ['a', 'b']
194+
assert get_tool_calls_from_response(msg) == ['a', 'b']
194195

195196

196197
class TestMapProvider:
@@ -419,7 +420,7 @@ def test_creates_agent_runner_with_instructions_and_tool_definitions(self):
419420
'provider': {'name': 'openai'},
420421
}
421422

422-
with patch.object(LangChainHelper, 'create_langchain_model') as mock_create:
423+
with patch('ldai_langchain.langchain_runner_factory.create_langchain_model') as mock_create:
423424
mock_llm = MagicMock()
424425
mock_create.return_value = mock_llm
425426

@@ -442,7 +443,7 @@ def test_creates_agent_runner_with_no_tools(self):
442443
'provider': {'name': 'openai'},
443444
}
444445

445-
with patch.object(LangChainHelper, 'create_langchain_model') as mock_create:
446+
with patch('ldai_langchain.langchain_runner_factory.create_langchain_model') as mock_create:
446447
mock_create.return_value = MagicMock()
447448

448449
factory = LangChainRunnerFactory()

packages/ai-providers/server-ai-openai/src/ldai_openai/openai_helper.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ def get_ai_usage_from_response(response: Any) -> Optional[TokenUsage]:
2828
"""
2929
if hasattr(response, 'usage') and response.usage:
3030
u = response.usage
31-
return TokenUsage(
32-
total=getattr(u, 'total_tokens', None) or 0,
33-
input=getattr(u, 'prompt_tokens', None) or 0,
34-
output=getattr(u, 'completion_tokens', None) or 0,
35-
)
31+
total = getattr(u, 'total_tokens', None) or 0
32+
inp = getattr(u, 'prompt_tokens', None) or 0
33+
out = getattr(u, 'completion_tokens', None) or 0
34+
if total or inp or out:
35+
return TokenUsage(total=total, input=inp, output=out)
3636
return None
3737

3838

packages/ai-providers/server-ai-openai/src/ldai_openai/openai_runner_factory.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import os
2-
from typing import Any, Optional
2+
from typing import TYPE_CHECKING, Any, Optional
33

44
from ldai.models import AIConfigKind
55
from ldai.providers import AIProvider, ToolRegistry
66
from openai import AsyncOpenAI
77

88
from ldai_openai.openai_model_runner import OpenAIModelRunner
99

10+
if TYPE_CHECKING:
11+
from ldai_openai.openai_agent_runner import OpenAIAgentRunner
12+
1013

1114
class OpenAIRunnerFactory(AIProvider):
1215
"""OpenAI ``AIProvider`` implementation for the LaunchDarkly AI SDK."""

packages/ai-providers/server-ai-openai/tests/test_openai_provider.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from ldai import LDMessage
77

8-
from ldai_openai import OpenAIModelRunner, OpenAIRunnerFactory, get_ai_metrics_from_response
8+
from ldai_openai import OpenAIModelRunner, OpenAIRunnerFactory, get_ai_metrics_from_response, get_ai_usage_from_response
99

1010

1111
class TestGetAIUsageFromResponse:
@@ -17,7 +17,7 @@ def test_returns_usage_when_present(self):
1717
mock_response.usage.prompt_tokens = 50
1818
mock_response.usage.completion_tokens = 50
1919
mock_response.usage.total_tokens = 100
20-
u = OpenAIHelper.get_ai_usage_from_response(mock_response)
20+
u = get_ai_usage_from_response(mock_response)
2121
assert u is not None
2222
assert u.total == 100
2323
assert u.input == 50
@@ -26,15 +26,15 @@ def test_returns_usage_when_present(self):
2626
def test_returns_none_when_usage_missing(self):
2727
mock_response = MagicMock()
2828
mock_response.usage = None
29-
assert OpenAIHelper.get_ai_usage_from_response(mock_response) is None
29+
assert get_ai_usage_from_response(mock_response) is None
3030

3131
def test_returns_none_when_all_counts_zero(self):
3232
mock_response = MagicMock()
3333
mock_response.usage = MagicMock()
3434
mock_response.usage.total_tokens = 0
3535
mock_response.usage.prompt_tokens = 0
3636
mock_response.usage.completion_tokens = 0
37-
assert OpenAIHelper.get_ai_usage_from_response(mock_response) is None
37+
assert get_ai_usage_from_response(mock_response) is None
3838

3939

4040
class TestGetAIMetricsFromResponse:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ async def create_agent(
425425
if not config.enabled or not config.tracker:
426426
return None
427427

428-
runner = await RunnerFactory.create_agent(config, tools or {}, default_ai_provider)
428+
runner = RunnerFactory.create_agent(config, tools or {}, default_ai_provider)
429429
if not runner:
430430
return None
431431

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"""ManagedAgent — LaunchDarkly managed wrapper for agent invocations."""
22

33
from ldai.models import AIAgentConfig
4-
from ldai.runners.agent_runner import AgentRunner
5-
from ldai.runners.types import AgentResult
4+
from ldai.providers import AgentResult, AgentRunner
65
from ldai.tracker import LDAIConfigTracker
76

87

packages/sdk/server-ai/tests/test_managed_agent.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from ldai import LDAIClient, ManagedAgent
77
from ldai.managed_agent import ManagedAgent
88
from ldai.models import AIAgentConfig, AIAgentConfigDefault, ModelConfig, ProviderConfig
9-
from ldai.runners.types import AgentResult
9+
from ldai.providers import AgentResult
1010
from ldai.providers.types import LDAIMetrics
1111

1212
from ldclient import Config, Context, LDClient
@@ -56,7 +56,7 @@ async def test_run_delegates_to_agent_runner(self):
5656
"""Should delegate run() to the underlying AgentRunner."""
5757
mock_config = MagicMock(spec=AIAgentConfig)
5858
mock_tracker = MagicMock()
59-
mock_tracker.track_metrics_of = AsyncMock(
59+
mock_tracker.track_metrics_of_async = AsyncMock(
6060
return_value=AgentResult(
6161
output="Test response",
6262
raw=None,
@@ -77,7 +77,7 @@ async def test_run_delegates_to_agent_runner(self):
7777

7878
assert result.output == "Test response"
7979
assert result.metrics.success is True
80-
mock_tracker.track_metrics_of.assert_called_once()
80+
mock_tracker.track_metrics_of_async.assert_called_once()
8181

8282
def test_get_agent_runner_returns_runner(self):
8383
"""Should return the underlying AgentRunner."""
@@ -119,7 +119,7 @@ async def test_returns_none_when_provider_unavailable(self, ldai_client: LDAICli
119119
context = Context.create('user-key')
120120

121121
original = rf.RunnerFactory.create_agent
122-
rf.RunnerFactory.create_agent = AsyncMock(return_value=None)
122+
rf.RunnerFactory.create_agent = MagicMock(return_value=None)
123123
try:
124124
result = await ldai_client.create_agent('customer-support-agent', context)
125125
assert result is None
@@ -138,7 +138,7 @@ async def test_returns_managed_agent_when_runner_available(self, ldai_client: LD
138138
)
139139

140140
original = rf.RunnerFactory.create_agent
141-
rf.RunnerFactory.create_agent = AsyncMock(return_value=mock_runner)
141+
rf.RunnerFactory.create_agent = MagicMock(return_value=mock_runner)
142142
try:
143143
result = await ldai_client.create_agent('customer-support-agent', context)
144144
assert isinstance(result, ManagedAgent)

0 commit comments

Comments
 (0)