Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/ai-providers/server-ai-langchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ context = Context.builder("user-123").build()

async def main():
# Create a ManagedModel backed by the LangChain provider
model = await ai_client.create_model(
model = ai_client.create_model(
"ai-config-key",
context,
AICompletionConfigDefault(
Expand All @@ -74,7 +74,7 @@ LaunchDarkly AI config flag, selects the LangChain runner automatically, and
returns a `ManagedModel` that wraps the runner:

```python
model = await ai_client.create_model("ai-config-key", context)
model = ai_client.create_model("ai-config-key", context)

if model:
result = await model.run("What is feature flagging?")
Expand Down Expand Up @@ -121,7 +121,7 @@ print(result.parsed) # {"sentiment": "positive", "confidence": 0.95}
`LDAIConfigTracker`. For manual tracking, use the tracker directly:

```python
model = await ai_client.create_model("ai-config-key", context)
model = ai_client.create_model("ai-config-key", context)

if model:
result = await model.run("Explain feature flags.")
Expand Down
6 changes: 3 additions & 3 deletions packages/ai-providers/server-ai-openai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ context = Context.builder("user-123").build()

async def main():
# Create a ManagedModel backed by the OpenAI provider
model = await ai_client.create_model(
model = ai_client.create_model(
"ai-config-key",
context,
AICompletionConfigDefault(
Expand All @@ -61,7 +61,7 @@ LaunchDarkly AI config flag, selects the OpenAI runner automatically, and
returns a `ManagedModel` that wraps the runner:

```python
model = await ai_client.create_model("ai-config-key", context)
model = ai_client.create_model("ai-config-key", context)

if model:
result = await model.run("What is feature flagging?")
Expand Down Expand Up @@ -107,7 +107,7 @@ print(result.parsed) # {"sentiment": "positive", "confidence": 0.95}
`LDAIConfigTracker`. For manual tracking, use the tracker directly:

```python
model = await ai_client.create_model("ai-config-key", context)
model = ai_client.create_model("ai-config-key", context)

if model:
result = await model.run("Explain feature flags.")
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/server-ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ from ldai import LDAIClient, AICompletionConfigDefault, ModelConfig, LDMessage
# Use the same default_config from the retrieval section above
async def main():
context = Context.create("user-123")
model = await ai_client.create_model(
model = ai_client.create_model(
'customer-support-chat',
context,
default_config,
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/server-ai/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ non_interactive = true
[tool.pytest.ini_options]
addopts = ["-ra"]
testpaths = ["tests"]
asyncio_mode = "strict"

[tool.isort]
profile = "black"
12 changes: 6 additions & 6 deletions packages/sdk/server-ai/src/ldai/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def _build_evaluator(
judge_instances.append(judge)
return Evaluator(judge_instances)

async def create_model(
def create_model(
self,
key: str,
context: Context,
Expand All @@ -404,7 +404,7 @@ async def create_model(

Example::

model = await client.create_model(
model = client.create_model(
"customer-support-chat",
context,
AICompletionConfigDefault(
Expand Down Expand Up @@ -435,7 +435,7 @@ async def create_model(

return ManagedModel(config, runner)

async def create_agent(
def create_agent(
self,
key: str,
context: Context,
Expand Down Expand Up @@ -463,7 +463,7 @@ async def create_agent(

Example::

agent = await client.create_agent(
agent = client.create_agent(
"customer-support-agent",
context,
tools={"get-order": fetch_order_fn},
Expand Down Expand Up @@ -722,7 +722,7 @@ def graph_tracker_factory() -> AIGraphTracker:
create_tracker=graph_tracker_factory,
)

async def create_agent_graph(
def create_agent_graph(
self,
key: str,
context: Context,
Expand All @@ -748,7 +748,7 @@ async def create_agent_graph(

Example::

graph = await client.create_agent_graph(
graph = client.create_agent_graph(
"travel-assistant-graph",
context,
tools={
Expand Down
6 changes: 3 additions & 3 deletions packages/sdk/server-ai/src/ldai/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ def evaluate(
"""
Run all configured judges against the given input/output pair.

Schedules the judge evaluations as an asyncio Task and returns it
immediately. The caller can await the task to get results or pass it
to tracking helpers.
The returned Task starts judge evaluations immediately. The caller
must retain a reference to the results until it resolves to ensure
Judge evaluations are completed.

:param input_text: The input that was provided to the AI model
:param output_text: The AI-generated output to evaluate
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/server-ai/src/ldai/managed_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async def run(self, input: str) -> ManagedResult:
lambda: self._agent_runner.run(input),
)

evaluations_task = self._track_judge_results(tracker, input, result.content)
evaluations_task = await self._track_judge_results(tracker, input, result.content)

return ManagedResult(
content=result.content,
Expand All @@ -54,7 +54,7 @@ async def run(self, input: str) -> ManagedResult:
evaluations=evaluations_task,
)

def _track_judge_results(
async def _track_judge_results(
self,
tracker: LDAIConfigTracker,
input_text: str,
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/server-ai/src/ldai/managed_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async def run(self, prompt: str) -> ManagedResult:
lambda: self._model_runner.run(prompt),
)

evaluations_task = self._track_judge_results(tracker, prompt, result.content)
evaluations_task = await self._track_judge_results(tracker, prompt, result.content)

return ManagedResult(
content=result.content,
Expand All @@ -54,7 +54,7 @@ async def run(self, prompt: str) -> ManagedResult:
evaluations=evaluations_task,
)

def _track_judge_results(
async def _track_judge_results(
self,
tracker: LDAIConfigTracker,
input_text: str,
Expand Down
15 changes: 6 additions & 9 deletions packages/sdk/server-ai/tests/test_managed_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,30 +310,27 @@ async def _evaluate_coro(input_text: str, output_text: str) -> List[JudgeResult]
class TestLDAIClientCreateAgent:
"""Tests for LDAIClient.create_agent."""

@pytest.mark.asyncio
async def test_returns_none_when_agent_is_disabled(self, ldai_client: LDAIClient):
def test_returns_none_when_agent_is_disabled(self, ldai_client: LDAIClient):
"""Should return None when agent config is disabled."""
context = Context.create('user-key')
result = await ldai_client.create_agent('disabled-agent', context)
result = ldai_client.create_agent('disabled-agent', context)

assert result is None

@pytest.mark.asyncio
async def test_returns_none_when_provider_unavailable(self, ldai_client: LDAIClient):
def test_returns_none_when_provider_unavailable(self, ldai_client: LDAIClient):
"""Should return None when no AI provider is available."""
import ldai.providers.runner_factory as rf
context = Context.create('user-key')

original = rf.RunnerFactory.create_agent
rf.RunnerFactory.create_agent = MagicMock(return_value=None)
try:
result = await ldai_client.create_agent('customer-support-agent', context)
result = ldai_client.create_agent('customer-support-agent', context)
assert result is None
finally:
rf.RunnerFactory.create_agent = original

@pytest.mark.asyncio
async def test_returns_managed_agent_when_runner_available(self, ldai_client: LDAIClient):
def test_returns_managed_agent_when_runner_available(self, ldai_client: LDAIClient):
"""Should return ManagedAgent when runner is successfully created."""
import ldai.providers.runner_factory as rf
context = Context.create('user-key')
Expand All @@ -346,7 +343,7 @@ async def test_returns_managed_agent_when_runner_available(self, ldai_client: LD
original = rf.RunnerFactory.create_agent
rf.RunnerFactory.create_agent = MagicMock(return_value=mock_runner)
try:
result = await ldai_client.create_agent('customer-support-agent', context)
result = ldai_client.create_agent('customer-support-agent', context)
assert isinstance(result, ManagedAgent)
assert result.get_agent_runner() is mock_runner
finally:
Expand Down
10 changes: 5 additions & 5 deletions packages/sdk/server-ai/tests/test_managed_agent_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ async def test_create_agent_graph_returns_managed_agent_graph(ldai_client: LDAIC
'ldai.providers.runner_factory.RunnerFactory.create_agent_graph',
new=MagicMock(return_value=stub_runner),
):
managed = await ldai_client.create_agent_graph('travel-graph', context)
managed = ldai_client.create_agent_graph('travel-graph', context)

assert managed is not None
assert isinstance(managed, ManagedAgentGraph)
Expand All @@ -313,7 +313,7 @@ async def test_create_agent_graph_returns_managed_agent_graph(ldai_client: LDAIC
@pytest.mark.asyncio
async def test_create_agent_graph_returns_none_when_disabled(ldai_client: LDAIClient):
context = Context.create('user-key')
managed = await ldai_client.create_agent_graph('disabled-graph', context)
managed = ldai_client.create_agent_graph('disabled-graph', context)
assert managed is None


Expand All @@ -325,7 +325,7 @@ async def test_create_agent_graph_returns_none_when_runner_factory_fails(ldai_cl
'ldai.providers.runner_factory.RunnerFactory.create_agent_graph',
new=MagicMock(return_value=None),
):
managed = await ldai_client.create_agent_graph('travel-graph', context)
managed = ldai_client.create_agent_graph('travel-graph', context)

assert managed is None

Expand All @@ -344,7 +344,7 @@ def fake_create_agent_graph(graph_def, tools_arg, default_ai_provider=None):
'ldai.providers.runner_factory.RunnerFactory.create_agent_graph',
new=fake_create_agent_graph,
):
await ldai_client.create_agent_graph('travel-graph', context, tools=tools)
ldai_client.create_agent_graph('travel-graph', context, tools=tools)

assert captured['tools'] is tools

Expand All @@ -357,7 +357,7 @@ async def test_create_agent_graph_run_produces_result(ldai_client: LDAIClient):
'ldai.providers.runner_factory.RunnerFactory.create_agent_graph',
new=MagicMock(return_value=StubAgentGraphRunner("final answer")),
):
managed = await ldai_client.create_agent_graph('travel-graph', context)
managed = ldai_client.create_agent_graph('travel-graph', context)

assert managed is not None
result = await managed.run("find restaurants")
Expand Down
Loading