Skip to content

Commit a907d63

Browse files
committed
fix: restore log.warning on judge init failure; update LangChain README to new run() API
1 parent e0f6613 commit a907d63

2 files changed

Lines changed: 70 additions & 78 deletions

File tree

packages/ai-providers/server-ai-langchain/README.md

Lines changed: 68 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -38,79 +38,68 @@ pip install langchain-google-genai
3838
import asyncio
3939
from ldclient import LDClient, Config, Context
4040
from ldai import init
41-
from ldai_langchain import LangChainProvider
41+
from ldai.models import AICompletionConfigDefault, ModelConfig, ProviderConfig
4242

4343
# Initialize LaunchDarkly client
4444
ld_client = LDClient(Config("your-sdk-key"))
4545
ai_client = init(ld_client)
4646

47-
# Get AI configuration. Pass a default for improved resiliency when the flag is unavailable or
48-
# LaunchDarkly is unreachable; omit for a disabled default. Example:
49-
# from ldai.models import AICompletionConfigDefault, LDMessage, ModelConfig, ProviderConfig
50-
# default = AICompletionConfigDefault(
51-
# enabled=True,
52-
# model=ModelConfig("gpt-4"),
53-
# provider=ProviderConfig("openai"),
54-
# messages=[LDMessage(role="system", content="You are a helpful assistant.")]
55-
# )
56-
# config = ai_client.config("ai-config-key", context, default)
5747
context = Context.builder("user-123").build()
58-
config = ai_client.config("ai-config-key", context)
5948

6049
async def main():
61-
# Create a LangChain provider from the AI configuration
62-
provider = await LangChainProvider.create(config)
63-
64-
# Use the provider to invoke the model
65-
from ldai.models import LDMessage
66-
messages = [
67-
LDMessage(role="system", content="You are a helpful assistant."),
68-
LDMessage(role="user", content="Hello, how are you?"),
69-
]
70-
71-
response = await provider.invoke_model(messages)
72-
print(response.message.content)
50+
# Create a ManagedModel backed by the LangChain provider
51+
model = await ai_client.create_model(
52+
"ai-config-key",
53+
context,
54+
AICompletionConfigDefault(
55+
enabled=True,
56+
model=ModelConfig("gpt-4"),
57+
provider=ProviderConfig("langchain"),
58+
),
59+
)
60+
61+
if model:
62+
result = await model.run("Hello, how are you?")
63+
print(result.content)
7364

7465
asyncio.run(main())
7566
```
7667

7768
## Usage
7869

79-
### Using LangChainProvider with the Create Factory
70+
### Using `create_model` (recommended)
8071

81-
The simplest way to use the LangChain provider is with the static `create` factory method, which automatically creates the appropriate LangChain model based on your LaunchDarkly AI configuration:
72+
The recommended entry point is `LDAIClient.create_model`, which evaluates a
73+
LaunchDarkly AI config flag, selects the LangChain runner automatically, and
74+
returns a `ManagedModel` that wraps the runner:
8275

8376
```python
84-
from ldai_langchain import LangChainProvider
77+
model = await ai_client.create_model("ai-config-key", context)
8578

86-
# Create provider from AI configuration
87-
provider = await LangChainProvider.create(ai_config)
88-
89-
# Invoke the model
90-
response = await provider.invoke_model(messages)
79+
if model:
80+
result = await model.run("What is feature flagging?")
81+
print(result.content)
9182
```
9283

93-
### Using an Existing LangChain Model
84+
### Using the runner directly
9485

95-
If you already have a LangChain model configured, you can use it directly:
86+
If you need to construct a runner manually (e.g. for testing), you can use
87+
`LangChainRunnerFactory` from the `ldai_langchain` package:
9688

9789
```python
9890
from langchain_openai import ChatOpenAI
99-
from ldai_langchain import LangChainProvider
91+
from ldai_langchain import LangChainRunnerFactory
10092

101-
# Create your own LangChain model
10293
llm = ChatOpenAI(model="gpt-4", temperature=0.7)
94+
runner = LangChainModelRunner(llm)
10395

104-
# Wrap it with LangChainProvider
105-
provider = LangChainProvider(llm)
106-
107-
# Use with LaunchDarkly tracking
108-
response = await provider.invoke_model(messages)
96+
result = await runner.run("Hello!")
97+
print(result.content)
10998
```
11099

111100
### Structured Output
112101

113-
The provider supports structured output using LangChain's `with_structured_output`:
102+
Pass a JSON schema dict as `output_type` to request structured output:
114103

115104
```python
116105
response_structure = {
@@ -122,91 +111,93 @@ response_structure = {
122111
"required": ["sentiment", "confidence"],
123112
}
124113

125-
result = await provider.invoke_structured_model(messages, response_structure)
126-
print(result.data) # {"sentiment": "positive", "confidence": 0.95}
114+
result = await runner.run(messages, output_type=response_structure)
115+
print(result.parsed) # {"sentiment": "positive", "confidence": 0.95}
127116
```
128117

129118
### Tracking Metrics
130119

131-
Use the provider with LaunchDarkly's tracking capabilities:
120+
`ManagedModel.run()` automatically tracks metrics via the associated
121+
`LDAIConfigTracker`. For manual tracking, use the tracker directly:
132122

133123
```python
134-
# Get the AI config with tracker
135-
config = ai_client.config("ai-config-key", context)
136-
137-
# Create provider
138-
provider = await LangChainProvider.create(config)
139-
140-
# Track metrics automatically
141-
async def invoke():
142-
return await provider.invoke_model(messages)
124+
model = await ai_client.create_model("ai-config-key", context)
143125

144-
response = await config.tracker.track_metrics_of_async(
145-
invoke,
146-
lambda r: r.metrics
147-
)
126+
if model:
127+
result = await model.run("Explain feature flags.")
128+
# Metrics are tracked automatically; access them via result.metrics
129+
print(result.metrics.usage)
148130
```
149131

150132
### Static Utility Methods
151133

152-
The `LangChainProvider` class provides several utility methods:
134+
The `ldai_langchain` helper module provides several utility functions:
153135

154136
#### Converting Messages
155137

156138
```python
157139
from ldai.models import LDMessage
158-
from ldai_langchain import LangChainProvider
140+
from ldai_langchain.langchain_helper import convert_messages_to_langchain
159141

160142
messages = [
161143
LDMessage(role="system", content="You are helpful."),
162144
LDMessage(role="user", content="Hello!"),
163145
]
164146

165-
# Convert to LangChain messages
166-
langchain_messages = LangChainProvider.convert_messages_to_langchain(messages)
147+
langchain_messages = convert_messages_to_langchain(messages)
167148
```
168149

169150
#### Extracting Metrics
170151

171152
```python
172-
from ldai_langchain import LangChainProvider
153+
from ldai_langchain.langchain_helper import get_ai_metrics_from_response
173154

174155
# After getting a response from LangChain
175-
metrics = LangChainProvider.get_ai_metrics_from_response(ai_message)
156+
metrics = get_ai_metrics_from_response(ai_message)
176157
print(f"Success: {metrics.success}")
177158
print(f"Tokens used: {metrics.usage.total if metrics.usage else 'N/A'}")
178159
```
179160

180161
#### Provider Name Mapping
181162

182163
```python
164+
from ldai_langchain.langchain_helper import map_provider_name
165+
183166
# Map LaunchDarkly provider names to LangChain provider names
184-
langchain_provider = LangChainProvider.map_provider("gemini") # Returns "google-genai"
167+
langchain_provider = map_provider_name("gemini") # Returns "google-genai"
185168
```
186169

187170
## API Reference
188171

189-
### LangChainProvider
172+
### LangChainModelRunner
173+
174+
`LangChainModelRunner` implements the `Runner` protocol for LangChain chat models.
190175

191176
#### Constructor
192177

193178
```python
194-
LangChainProvider(llm: BaseChatModel, logger: Optional[Any] = None)
179+
LangChainModelRunner(llm: BaseChatModel)
195180
```
196181

197-
#### Static Methods
182+
#### Methods
183+
184+
- `run(input, output_type=None) -> RunnerResult` — Run the model with a string prompt or list of `LDMessage` objects. Pass `output_type` (JSON schema dict) for structured output.
185+
- `get_llm() -> BaseChatModel` — Return the underlying LangChain model.
198186

199-
- `create(ai_config: AIConfigKind, logger: Optional[Any] = None) -> LangChainProvider` - Factory method to create a provider from AI configuration
200-
- `convert_messages_to_langchain(messages: List[LDMessage]) -> List[BaseMessage]` - Convert LaunchDarkly messages to LangChain messages
201-
- `get_ai_metrics_from_response(response: AIMessage) -> LDAIMetrics` - Extract metrics from a LangChain response
202-
- `map_provider(ld_provider_name: str) -> str` - Map LaunchDarkly provider names to LangChain names
203-
- `create_langchain_model(ai_config: AIConfigKind) -> BaseChatModel` - Create a LangChain model from AI configuration
187+
### LangChainAgentRunner
188+
189+
`LangChainAgentRunner` implements the `Runner` protocol for compiled LangChain agent graphs.
190+
191+
#### Constructor
192+
193+
```python
194+
LangChainAgentRunner(agent: Any)
195+
```
204196

205-
#### Instance Methods
197+
#### Methods
206198

207-
- `invoke_model(messages: List[LDMessage]) -> ChatResponse` - Invoke the model with messages
208-
- `invoke_structured_model(messages: List[LDMessage], response_structure: Dict[str, Any]) -> StructuredResponse` - Invoke with structured output
209-
- `get_chat_model() -> BaseChatModel` - Get the underlying LangChain model
199+
- `run(input, output_type=None) -> RunnerResult` — Run the agent with the given input. Returns `RunnerResult` with `content`, `metrics` (including `tool_calls`), and `raw`.
200+
- `get_agent() -> Any` — Return the underlying compiled agent graph.
210201

211202
## Documentation
212203

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ def _create_judge_instance(
340340
return None
341341

342342
return Judge(judge_config, provider, sample_rate=sample_rate)
343-
except Exception as error:
343+
except Exception as e:
344+
log.warning('Failed to initialize judge %r: %s', key, e)
344345
return None
345346

346347
def _build_evaluator(

0 commit comments

Comments
 (0)