agentrun-sdk 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agentrun-sdk might be problematic. Click here for more details.
- agentrun_operation_sdk/cli/__init__.py +1 -0
- agentrun_operation_sdk/cli/cli.py +19 -0
- agentrun_operation_sdk/cli/common.py +21 -0
- agentrun_operation_sdk/cli/runtime/__init__.py +1 -0
- agentrun_operation_sdk/cli/runtime/commands.py +203 -0
- agentrun_operation_sdk/client/client.py +75 -0
- agentrun_operation_sdk/operations/runtime/__init__.py +8 -0
- agentrun_operation_sdk/operations/runtime/configure.py +101 -0
- agentrun_operation_sdk/operations/runtime/launch.py +82 -0
- agentrun_operation_sdk/operations/runtime/models.py +31 -0
- agentrun_operation_sdk/services/runtime.py +152 -0
- agentrun_operation_sdk/utils/logging_config.py +72 -0
- agentrun_operation_sdk/utils/runtime/config.py +94 -0
- agentrun_operation_sdk/utils/runtime/container.py +280 -0
- agentrun_operation_sdk/utils/runtime/entrypoint.py +203 -0
- agentrun_operation_sdk/utils/runtime/schema.py +56 -0
- agentrun_sdk/__init__.py +7 -0
- agentrun_sdk/agent/__init__.py +25 -0
- agentrun_sdk/agent/agent.py +696 -0
- agentrun_sdk/agent/agent_result.py +46 -0
- agentrun_sdk/agent/conversation_manager/__init__.py +26 -0
- agentrun_sdk/agent/conversation_manager/conversation_manager.py +88 -0
- agentrun_sdk/agent/conversation_manager/null_conversation_manager.py +46 -0
- agentrun_sdk/agent/conversation_manager/sliding_window_conversation_manager.py +179 -0
- agentrun_sdk/agent/conversation_manager/summarizing_conversation_manager.py +252 -0
- agentrun_sdk/agent/state.py +97 -0
- agentrun_sdk/event_loop/__init__.py +9 -0
- agentrun_sdk/event_loop/event_loop.py +499 -0
- agentrun_sdk/event_loop/streaming.py +319 -0
- agentrun_sdk/experimental/__init__.py +4 -0
- agentrun_sdk/experimental/hooks/__init__.py +15 -0
- agentrun_sdk/experimental/hooks/events.py +123 -0
- agentrun_sdk/handlers/__init__.py +10 -0
- agentrun_sdk/handlers/callback_handler.py +70 -0
- agentrun_sdk/hooks/__init__.py +49 -0
- agentrun_sdk/hooks/events.py +80 -0
- agentrun_sdk/hooks/registry.py +247 -0
- agentrun_sdk/models/__init__.py +10 -0
- agentrun_sdk/models/anthropic.py +432 -0
- agentrun_sdk/models/bedrock.py +649 -0
- agentrun_sdk/models/litellm.py +225 -0
- agentrun_sdk/models/llamaapi.py +438 -0
- agentrun_sdk/models/mistral.py +539 -0
- agentrun_sdk/models/model.py +95 -0
- agentrun_sdk/models/ollama.py +357 -0
- agentrun_sdk/models/openai.py +436 -0
- agentrun_sdk/models/sagemaker.py +598 -0
- agentrun_sdk/models/writer.py +449 -0
- agentrun_sdk/multiagent/__init__.py +22 -0
- agentrun_sdk/multiagent/a2a/__init__.py +15 -0
- agentrun_sdk/multiagent/a2a/executor.py +148 -0
- agentrun_sdk/multiagent/a2a/server.py +252 -0
- agentrun_sdk/multiagent/base.py +92 -0
- agentrun_sdk/multiagent/graph.py +555 -0
- agentrun_sdk/multiagent/swarm.py +656 -0
- agentrun_sdk/py.typed +1 -0
- agentrun_sdk/session/__init__.py +18 -0
- agentrun_sdk/session/file_session_manager.py +216 -0
- agentrun_sdk/session/repository_session_manager.py +152 -0
- agentrun_sdk/session/s3_session_manager.py +272 -0
- agentrun_sdk/session/session_manager.py +73 -0
- agentrun_sdk/session/session_repository.py +51 -0
- agentrun_sdk/telemetry/__init__.py +21 -0
- agentrun_sdk/telemetry/config.py +194 -0
- agentrun_sdk/telemetry/metrics.py +476 -0
- agentrun_sdk/telemetry/metrics_constants.py +15 -0
- agentrun_sdk/telemetry/tracer.py +563 -0
- agentrun_sdk/tools/__init__.py +17 -0
- agentrun_sdk/tools/decorator.py +569 -0
- agentrun_sdk/tools/executor.py +137 -0
- agentrun_sdk/tools/loader.py +152 -0
- agentrun_sdk/tools/mcp/__init__.py +13 -0
- agentrun_sdk/tools/mcp/mcp_agent_tool.py +99 -0
- agentrun_sdk/tools/mcp/mcp_client.py +423 -0
- agentrun_sdk/tools/mcp/mcp_instrumentation.py +322 -0
- agentrun_sdk/tools/mcp/mcp_types.py +63 -0
- agentrun_sdk/tools/registry.py +607 -0
- agentrun_sdk/tools/structured_output.py +421 -0
- agentrun_sdk/tools/tools.py +217 -0
- agentrun_sdk/tools/watcher.py +136 -0
- agentrun_sdk/types/__init__.py +5 -0
- agentrun_sdk/types/collections.py +23 -0
- agentrun_sdk/types/content.py +188 -0
- agentrun_sdk/types/event_loop.py +48 -0
- agentrun_sdk/types/exceptions.py +81 -0
- agentrun_sdk/types/guardrails.py +254 -0
- agentrun_sdk/types/media.py +89 -0
- agentrun_sdk/types/session.py +152 -0
- agentrun_sdk/types/streaming.py +201 -0
- agentrun_sdk/types/tools.py +258 -0
- agentrun_sdk/types/traces.py +5 -0
- agentrun_sdk-0.1.2.dist-info/METADATA +51 -0
- agentrun_sdk-0.1.2.dist-info/RECORD +115 -0
- agentrun_sdk-0.1.2.dist-info/WHEEL +5 -0
- agentrun_sdk-0.1.2.dist-info/entry_points.txt +2 -0
- agentrun_sdk-0.1.2.dist-info/top_level.txt +3 -0
- agentrun_wrapper/__init__.py +11 -0
- agentrun_wrapper/_utils/__init__.py +6 -0
- agentrun_wrapper/_utils/endpoints.py +16 -0
- agentrun_wrapper/identity/__init__.py +5 -0
- agentrun_wrapper/identity/auth.py +211 -0
- agentrun_wrapper/memory/__init__.py +6 -0
- agentrun_wrapper/memory/client.py +1697 -0
- agentrun_wrapper/memory/constants.py +103 -0
- agentrun_wrapper/memory/controlplane.py +626 -0
- agentrun_wrapper/py.typed +1 -0
- agentrun_wrapper/runtime/__init__.py +13 -0
- agentrun_wrapper/runtime/app.py +473 -0
- agentrun_wrapper/runtime/context.py +34 -0
- agentrun_wrapper/runtime/models.py +25 -0
- agentrun_wrapper/services/__init__.py +1 -0
- agentrun_wrapper/services/identity.py +192 -0
- agentrun_wrapper/tools/__init__.py +6 -0
- agentrun_wrapper/tools/browser_client.py +325 -0
- agentrun_wrapper/tools/code_interpreter_client.py +186 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""Ollama model provider.
|
|
2
|
+
|
|
3
|
+
- Docs: https://ollama.com/
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Any, AsyncGenerator, Optional, Type, TypeVar, Union, cast
|
|
9
|
+
|
|
10
|
+
import ollama
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
from typing_extensions import TypedDict, Unpack, override
|
|
13
|
+
|
|
14
|
+
from ..types.content import ContentBlock, Messages
|
|
15
|
+
from ..types.streaming import StopReason, StreamEvent
|
|
16
|
+
from ..types.tools import ToolSpec
|
|
17
|
+
from .model import Model
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
T = TypeVar("T", bound=BaseModel)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class OllamaModel(Model):
|
|
25
|
+
"""Ollama model provider implementation.
|
|
26
|
+
|
|
27
|
+
The implementation handles Ollama-specific features such as:
|
|
28
|
+
|
|
29
|
+
- Local model invocation
|
|
30
|
+
- Streaming responses
|
|
31
|
+
- Tool/function calling
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
class OllamaConfig(TypedDict, total=False):
|
|
35
|
+
"""Configuration parameters for Ollama models.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
additional_args: Any additional arguments to include in the request.
|
|
39
|
+
keep_alive: Controls how long the model will stay loaded into memory following the request (default: "5m").
|
|
40
|
+
max_tokens: Maximum number of tokens to generate in the response.
|
|
41
|
+
model_id: Ollama model ID (e.g., "llama3", "mistral", "phi3").
|
|
42
|
+
options: Additional model parameters (e.g., top_k).
|
|
43
|
+
stop_sequences: List of sequences that will stop generation when encountered.
|
|
44
|
+
temperature: Controls randomness in generation (higher = more random).
|
|
45
|
+
top_p: Controls diversity via nucleus sampling (alternative to temperature).
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
additional_args: Optional[dict[str, Any]]
|
|
49
|
+
keep_alive: Optional[str]
|
|
50
|
+
max_tokens: Optional[int]
|
|
51
|
+
model_id: str
|
|
52
|
+
options: Optional[dict[str, Any]]
|
|
53
|
+
stop_sequences: Optional[list[str]]
|
|
54
|
+
temperature: Optional[float]
|
|
55
|
+
top_p: Optional[float]
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
host: Optional[str],
|
|
60
|
+
*,
|
|
61
|
+
ollama_client_args: Optional[dict[str, Any]] = None,
|
|
62
|
+
**model_config: Unpack[OllamaConfig],
|
|
63
|
+
) -> None:
|
|
64
|
+
"""Initialize provider instance.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
host: The address of the Ollama server hosting the model.
|
|
68
|
+
ollama_client_args: Additional arguments for the Ollama client.
|
|
69
|
+
**model_config: Configuration options for the Ollama model.
|
|
70
|
+
"""
|
|
71
|
+
self.host = host
|
|
72
|
+
self.client_args = ollama_client_args or {}
|
|
73
|
+
self.config = OllamaModel.OllamaConfig(**model_config)
|
|
74
|
+
|
|
75
|
+
logger.debug("config=<%s> | initializing", self.config)
|
|
76
|
+
|
|
77
|
+
@override
|
|
78
|
+
def update_config(self, **model_config: Unpack[OllamaConfig]) -> None: # type: ignore
|
|
79
|
+
"""Update the Ollama Model configuration with the provided arguments.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
**model_config: Configuration overrides.
|
|
83
|
+
"""
|
|
84
|
+
self.config.update(model_config)
|
|
85
|
+
|
|
86
|
+
@override
|
|
87
|
+
def get_config(self) -> OllamaConfig:
|
|
88
|
+
"""Get the Ollama model configuration.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The Ollama model configuration.
|
|
92
|
+
"""
|
|
93
|
+
return self.config
|
|
94
|
+
|
|
95
|
+
def _format_request_message_contents(self, role: str, content: ContentBlock) -> list[dict[str, Any]]:
|
|
96
|
+
"""Format Ollama compatible message contents.
|
|
97
|
+
|
|
98
|
+
Ollama doesn't support an array of contents, so we must flatten everything into separate message blocks.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
role: E.g., user.
|
|
102
|
+
content: Content block to format.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Ollama formatted message contents.
|
|
106
|
+
|
|
107
|
+
Raises:
|
|
108
|
+
TypeError: If the content block type cannot be converted to an Ollama-compatible format.
|
|
109
|
+
"""
|
|
110
|
+
if "text" in content:
|
|
111
|
+
return [{"role": role, "content": content["text"]}]
|
|
112
|
+
|
|
113
|
+
if "image" in content:
|
|
114
|
+
return [{"role": role, "images": [content["image"]["source"]["bytes"]]}]
|
|
115
|
+
|
|
116
|
+
if "toolUse" in content:
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
"role": role,
|
|
120
|
+
"tool_calls": [
|
|
121
|
+
{
|
|
122
|
+
"function": {
|
|
123
|
+
"name": content["toolUse"]["toolUseId"],
|
|
124
|
+
"arguments": content["toolUse"]["input"],
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
if "toolResult" in content:
|
|
132
|
+
return [
|
|
133
|
+
formatted_tool_result_content
|
|
134
|
+
for tool_result_content in content["toolResult"]["content"]
|
|
135
|
+
for formatted_tool_result_content in self._format_request_message_contents(
|
|
136
|
+
"tool",
|
|
137
|
+
(
|
|
138
|
+
{"text": json.dumps(tool_result_content["json"])}
|
|
139
|
+
if "json" in tool_result_content
|
|
140
|
+
else cast(ContentBlock, tool_result_content)
|
|
141
|
+
),
|
|
142
|
+
)
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
raise TypeError(f"content_type=<{next(iter(content))}> | unsupported type")
|
|
146
|
+
|
|
147
|
+
def _format_request_messages(self, messages: Messages, system_prompt: Optional[str] = None) -> list[dict[str, Any]]:
|
|
148
|
+
"""Format an Ollama compatible messages array.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
messages: List of message objects to be processed by the model.
|
|
152
|
+
system_prompt: System prompt to provide context to the model.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
An Ollama compatible messages array.
|
|
156
|
+
"""
|
|
157
|
+
system_message = [{"role": "system", "content": system_prompt}] if system_prompt else []
|
|
158
|
+
|
|
159
|
+
return system_message + [
|
|
160
|
+
formatted_message
|
|
161
|
+
for message in messages
|
|
162
|
+
for content in message["content"]
|
|
163
|
+
for formatted_message in self._format_request_message_contents(message["role"], content)
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
def format_request(
|
|
167
|
+
self, messages: Messages, tool_specs: Optional[list[ToolSpec]] = None, system_prompt: Optional[str] = None
|
|
168
|
+
) -> dict[str, Any]:
|
|
169
|
+
"""Format an Ollama chat streaming request.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
messages: List of message objects to be processed by the model.
|
|
173
|
+
tool_specs: List of tool specifications to make available to the model.
|
|
174
|
+
system_prompt: System prompt to provide context to the model.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
An Ollama chat streaming request.
|
|
178
|
+
|
|
179
|
+
Raises:
|
|
180
|
+
TypeError: If a message contains a content block type that cannot be converted to an Ollama-compatible
|
|
181
|
+
format.
|
|
182
|
+
"""
|
|
183
|
+
return {
|
|
184
|
+
"messages": self._format_request_messages(messages, system_prompt),
|
|
185
|
+
"model": self.config["model_id"],
|
|
186
|
+
"options": {
|
|
187
|
+
**(self.config.get("options") or {}),
|
|
188
|
+
**{
|
|
189
|
+
key: value
|
|
190
|
+
for key, value in [
|
|
191
|
+
("num_predict", self.config.get("max_tokens")),
|
|
192
|
+
("temperature", self.config.get("temperature")),
|
|
193
|
+
("top_p", self.config.get("top_p")),
|
|
194
|
+
("stop", self.config.get("stop_sequences")),
|
|
195
|
+
]
|
|
196
|
+
if value is not None
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
"stream": True,
|
|
200
|
+
"tools": [
|
|
201
|
+
{
|
|
202
|
+
"type": "function",
|
|
203
|
+
"function": {
|
|
204
|
+
"name": tool_spec["name"],
|
|
205
|
+
"description": tool_spec["description"],
|
|
206
|
+
"parameters": tool_spec["inputSchema"]["json"],
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
for tool_spec in tool_specs or []
|
|
210
|
+
],
|
|
211
|
+
**({"keep_alive": self.config["keep_alive"]} if self.config.get("keep_alive") else {}),
|
|
212
|
+
**(
|
|
213
|
+
self.config["additional_args"]
|
|
214
|
+
if "additional_args" in self.config and self.config["additional_args"] is not None
|
|
215
|
+
else {}
|
|
216
|
+
),
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
def format_chunk(self, event: dict[str, Any]) -> StreamEvent:
|
|
220
|
+
"""Format the Ollama response events into standardized message chunks.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
event: A response event from the Ollama model.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
The formatted chunk.
|
|
227
|
+
|
|
228
|
+
Raises:
|
|
229
|
+
RuntimeError: If chunk_type is not recognized.
|
|
230
|
+
This error should never be encountered as we control chunk_type in the stream method.
|
|
231
|
+
"""
|
|
232
|
+
match event["chunk_type"]:
|
|
233
|
+
case "message_start":
|
|
234
|
+
return {"messageStart": {"role": "assistant"}}
|
|
235
|
+
|
|
236
|
+
case "content_start":
|
|
237
|
+
if event["data_type"] == "text":
|
|
238
|
+
return {"contentBlockStart": {"start": {}}}
|
|
239
|
+
|
|
240
|
+
tool_name = event["data"].function.name
|
|
241
|
+
return {"contentBlockStart": {"start": {"toolUse": {"name": tool_name, "toolUseId": tool_name}}}}
|
|
242
|
+
|
|
243
|
+
case "content_delta":
|
|
244
|
+
if event["data_type"] == "text":
|
|
245
|
+
return {"contentBlockDelta": {"delta": {"text": event["data"]}}}
|
|
246
|
+
|
|
247
|
+
tool_arguments = event["data"].function.arguments
|
|
248
|
+
return {"contentBlockDelta": {"delta": {"toolUse": {"input": json.dumps(tool_arguments)}}}}
|
|
249
|
+
|
|
250
|
+
case "content_stop":
|
|
251
|
+
return {"contentBlockStop": {}}
|
|
252
|
+
|
|
253
|
+
case "message_stop":
|
|
254
|
+
reason: StopReason
|
|
255
|
+
if event["data"] == "tool_use":
|
|
256
|
+
reason = "tool_use"
|
|
257
|
+
elif event["data"] == "length":
|
|
258
|
+
reason = "max_tokens"
|
|
259
|
+
else:
|
|
260
|
+
reason = "end_turn"
|
|
261
|
+
|
|
262
|
+
return {"messageStop": {"stopReason": reason}}
|
|
263
|
+
|
|
264
|
+
case "metadata":
|
|
265
|
+
return {
|
|
266
|
+
"metadata": {
|
|
267
|
+
"usage": {
|
|
268
|
+
"inputTokens": event["data"].eval_count,
|
|
269
|
+
"outputTokens": event["data"].prompt_eval_count,
|
|
270
|
+
"totalTokens": event["data"].eval_count + event["data"].prompt_eval_count,
|
|
271
|
+
},
|
|
272
|
+
"metrics": {
|
|
273
|
+
"latencyMs": event["data"].total_duration / 1e6,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
case _:
|
|
279
|
+
raise RuntimeError(f"chunk_type=<{event['chunk_type']} | unknown type")
|
|
280
|
+
|
|
281
|
+
@override
|
|
282
|
+
async def stream(
|
|
283
|
+
self,
|
|
284
|
+
messages: Messages,
|
|
285
|
+
tool_specs: Optional[list[ToolSpec]] = None,
|
|
286
|
+
system_prompt: Optional[str] = None,
|
|
287
|
+
**kwargs: Any,
|
|
288
|
+
) -> AsyncGenerator[StreamEvent, None]:
|
|
289
|
+
"""Stream conversation with the Ollama model.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
messages: List of message objects to be processed by the model.
|
|
293
|
+
tool_specs: List of tool specifications to make available to the model.
|
|
294
|
+
system_prompt: System prompt to provide context to the model.
|
|
295
|
+
**kwargs: Additional keyword arguments for future extensibility.
|
|
296
|
+
|
|
297
|
+
Yields:
|
|
298
|
+
Formatted message chunks from the model.
|
|
299
|
+
"""
|
|
300
|
+
logger.debug("formatting request")
|
|
301
|
+
request = self.format_request(messages, tool_specs, system_prompt)
|
|
302
|
+
logger.debug("request=<%s>", request)
|
|
303
|
+
|
|
304
|
+
logger.debug("invoking model")
|
|
305
|
+
tool_requested = False
|
|
306
|
+
|
|
307
|
+
client = ollama.AsyncClient(self.host, **self.client_args)
|
|
308
|
+
response = await client.chat(**request)
|
|
309
|
+
|
|
310
|
+
logger.debug("got response from model")
|
|
311
|
+
yield self.format_chunk({"chunk_type": "message_start"})
|
|
312
|
+
yield self.format_chunk({"chunk_type": "content_start", "data_type": "text"})
|
|
313
|
+
|
|
314
|
+
async for event in response:
|
|
315
|
+
for tool_call in event.message.tool_calls or []:
|
|
316
|
+
yield self.format_chunk({"chunk_type": "content_start", "data_type": "tool", "data": tool_call})
|
|
317
|
+
yield self.format_chunk({"chunk_type": "content_delta", "data_type": "tool", "data": tool_call})
|
|
318
|
+
yield self.format_chunk({"chunk_type": "content_stop", "data_type": "tool", "data": tool_call})
|
|
319
|
+
tool_requested = True
|
|
320
|
+
|
|
321
|
+
yield self.format_chunk({"chunk_type": "content_delta", "data_type": "text", "data": event.message.content})
|
|
322
|
+
|
|
323
|
+
yield self.format_chunk({"chunk_type": "content_stop", "data_type": "text"})
|
|
324
|
+
yield self.format_chunk(
|
|
325
|
+
{"chunk_type": "message_stop", "data": "tool_use" if tool_requested else event.done_reason}
|
|
326
|
+
)
|
|
327
|
+
yield self.format_chunk({"chunk_type": "metadata", "data": event})
|
|
328
|
+
|
|
329
|
+
logger.debug("finished streaming response from model")
|
|
330
|
+
|
|
331
|
+
@override
|
|
332
|
+
async def structured_output(
|
|
333
|
+
self, output_model: Type[T], prompt: Messages, system_prompt: Optional[str] = None, **kwargs: Any
|
|
334
|
+
) -> AsyncGenerator[dict[str, Union[T, Any]], None]:
|
|
335
|
+
"""Get structured output from the model.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
output_model: The output model to use for the agent.
|
|
339
|
+
prompt: The prompt messages to use for the agent.
|
|
340
|
+
system_prompt: System prompt to provide context to the model.
|
|
341
|
+
**kwargs: Additional keyword arguments for future extensibility.
|
|
342
|
+
|
|
343
|
+
Yields:
|
|
344
|
+
Model events with the last being the structured output.
|
|
345
|
+
"""
|
|
346
|
+
formatted_request = self.format_request(messages=prompt, system_prompt=system_prompt)
|
|
347
|
+
formatted_request["format"] = output_model.model_json_schema()
|
|
348
|
+
formatted_request["stream"] = False
|
|
349
|
+
|
|
350
|
+
client = ollama.AsyncClient(self.host, **self.client_args)
|
|
351
|
+
response = await client.chat(**formatted_request)
|
|
352
|
+
|
|
353
|
+
try:
|
|
354
|
+
content = response.message.content.strip()
|
|
355
|
+
yield {"output": output_model.model_validate_json(content)}
|
|
356
|
+
except Exception as e:
|
|
357
|
+
raise ValueError(f"Failed to parse or load content into model: {e}") from e
|