agentle 0.9.35__py3-none-any.whl → 0.9.36__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.
- agentle/generations/providers/openrouter/_adapters/agentle_message_to_openrouter_message_adapter.py +127 -7
- agentle/generations/providers/openrouter/openrouter_generation_provider.py +17 -8
- {agentle-0.9.35.dist-info → agentle-0.9.36.dist-info}/METADATA +1 -1
- {agentle-0.9.35.dist-info → agentle-0.9.36.dist-info}/RECORD +6 -6
- {agentle-0.9.35.dist-info → agentle-0.9.36.dist-info}/WHEEL +0 -0
- {agentle-0.9.35.dist-info → agentle-0.9.36.dist-info}/licenses/LICENSE +0 -0
agentle/generations/providers/openrouter/_adapters/agentle_message_to_openrouter_message_adapter.py
CHANGED
|
@@ -29,14 +29,17 @@ from agentle.generations.providers.openrouter._types import (
|
|
|
29
29
|
OpenRouterMessage,
|
|
30
30
|
OpenRouterSystemMessage,
|
|
31
31
|
OpenRouterToolCall,
|
|
32
|
+
OpenRouterToolMessage,
|
|
32
33
|
OpenRouterUserMessage,
|
|
33
34
|
)
|
|
35
|
+
from agentle.generations.tools.tool_execution_result import ToolExecutionResult
|
|
36
|
+
import json
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
class AgentleMessageToOpenRouterMessageAdapter(
|
|
37
40
|
Adapter[
|
|
38
41
|
AssistantMessage | DeveloperMessage | UserMessage,
|
|
39
|
-
OpenRouterMessage,
|
|
42
|
+
OpenRouterMessage | list[OpenRouterMessage],
|
|
40
43
|
]
|
|
41
44
|
):
|
|
42
45
|
"""
|
|
@@ -44,15 +47,18 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
44
47
|
|
|
45
48
|
Handles conversion of:
|
|
46
49
|
- DeveloperMessage -> OpenRouterSystemMessage
|
|
47
|
-
- UserMessage -> OpenRouterUserMessage
|
|
50
|
+
- UserMessage -> OpenRouterUserMessage (or OpenRouterToolMessage if contains tool results)
|
|
48
51
|
- AssistantMessage -> OpenRouterAssistantMessage (with tool calls)
|
|
52
|
+
|
|
53
|
+
Note: When a message contains ToolExecutionResult parts, they are extracted
|
|
54
|
+
and returned as separate OpenRouterToolMessage objects.
|
|
49
55
|
"""
|
|
50
56
|
|
|
51
57
|
@override
|
|
52
58
|
def adapt(
|
|
53
59
|
self,
|
|
54
60
|
_f: AssistantMessage | DeveloperMessage | UserMessage,
|
|
55
|
-
) -> OpenRouterMessage:
|
|
61
|
+
) -> OpenRouterMessage | list[OpenRouterMessage]:
|
|
56
62
|
"""
|
|
57
63
|
Convert an Agentle message to OpenRouter format.
|
|
58
64
|
|
|
@@ -60,7 +66,9 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
60
66
|
_f: The Agentle message to convert.
|
|
61
67
|
|
|
62
68
|
Returns:
|
|
63
|
-
The corresponding OpenRouter message.
|
|
69
|
+
The corresponding OpenRouter message(s). Returns a list when the message
|
|
70
|
+
contains ToolExecutionResult parts that need to be split into separate
|
|
71
|
+
tool messages.
|
|
64
72
|
"""
|
|
65
73
|
message = _f
|
|
66
74
|
part_adapter = AgentlePartToOpenRouterPartAdapter()
|
|
@@ -76,12 +84,28 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
76
84
|
)
|
|
77
85
|
|
|
78
86
|
case UserMessage():
|
|
87
|
+
# Check if this message contains tool execution results
|
|
88
|
+
tool_results = [
|
|
89
|
+
p for p in message.parts if isinstance(p, ToolExecutionResult)
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
if tool_results:
|
|
93
|
+
# Convert each tool result to a separate tool message
|
|
94
|
+
return [
|
|
95
|
+
OpenRouterToolMessage(
|
|
96
|
+
role="tool",
|
|
97
|
+
tool_call_id=result.suggestion.id,
|
|
98
|
+
content=self._serialize_tool_result(result.result),
|
|
99
|
+
)
|
|
100
|
+
for result in tool_results
|
|
101
|
+
]
|
|
102
|
+
|
|
79
103
|
# User messages can have multimodal content
|
|
80
|
-
# Filter out non-content parts (like tool execution suggestions)
|
|
104
|
+
# Filter out non-content parts (like tool execution suggestions and results)
|
|
81
105
|
content_parts = [
|
|
82
106
|
p
|
|
83
107
|
for p in message.parts
|
|
84
|
-
if not isinstance(p, ToolExecutionSuggestion)
|
|
108
|
+
if not isinstance(p, (ToolExecutionSuggestion, ToolExecutionResult))
|
|
85
109
|
]
|
|
86
110
|
|
|
87
111
|
# If only text parts, concatenate into a string
|
|
@@ -102,6 +126,69 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
102
126
|
)
|
|
103
127
|
|
|
104
128
|
case AssistantMessage():
|
|
129
|
+
# Check if this message contains tool execution results
|
|
130
|
+
tool_results = [
|
|
131
|
+
p for p in message.parts if isinstance(p, ToolExecutionResult)
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
if tool_results:
|
|
135
|
+
# If assistant message has tool results, we need to split it
|
|
136
|
+
# First, create the assistant message with tool calls (if any)
|
|
137
|
+
messages: list[OpenRouterMessage] = []
|
|
138
|
+
|
|
139
|
+
# Separate text content from tool calls
|
|
140
|
+
text_parts = [p for p in message.parts if isinstance(p, TextPart)]
|
|
141
|
+
tool_suggestions = [
|
|
142
|
+
p
|
|
143
|
+
for p in message.parts
|
|
144
|
+
if isinstance(p, ToolExecutionSuggestion)
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
# Only create assistant message if there's content or tool calls
|
|
148
|
+
if text_parts or tool_suggestions:
|
|
149
|
+
content = (
|
|
150
|
+
"".join(str(p) for p in text_parts) if text_parts else None
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
tool_calls: list[OpenRouterToolCall] = [
|
|
154
|
+
OpenRouterToolCall(
|
|
155
|
+
id=suggestion.id,
|
|
156
|
+
type="function",
|
|
157
|
+
function={
|
|
158
|
+
"name": suggestion.tool_name,
|
|
159
|
+
"arguments": self._serialize_tool_arguments(
|
|
160
|
+
suggestion.args
|
|
161
|
+
),
|
|
162
|
+
},
|
|
163
|
+
)
|
|
164
|
+
for suggestion in tool_suggestions
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
assistant_msg = OpenRouterAssistantMessage(
|
|
168
|
+
role="assistant",
|
|
169
|
+
content=content,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if tool_calls:
|
|
173
|
+
assistant_msg["tool_calls"] = tool_calls
|
|
174
|
+
|
|
175
|
+
if hasattr(message, "reasoning") and message.reasoning:
|
|
176
|
+
assistant_msg["reasoning"] = message.reasoning
|
|
177
|
+
|
|
178
|
+
messages.append(assistant_msg)
|
|
179
|
+
|
|
180
|
+
# Add tool result messages
|
|
181
|
+
for result in tool_results:
|
|
182
|
+
messages.append(
|
|
183
|
+
OpenRouterToolMessage(
|
|
184
|
+
role="tool",
|
|
185
|
+
tool_call_id=result.suggestion.id,
|
|
186
|
+
content=self._serialize_tool_result(result.result),
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
return messages
|
|
191
|
+
|
|
105
192
|
# Separate text content from tool calls
|
|
106
193
|
text_parts = [p for p in message.parts if isinstance(p, TextPart)]
|
|
107
194
|
tool_suggestions = [
|
|
@@ -118,7 +205,9 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
118
205
|
type="function",
|
|
119
206
|
function={
|
|
120
207
|
"name": suggestion.tool_name,
|
|
121
|
-
"arguments":
|
|
208
|
+
"arguments": self._serialize_tool_arguments(
|
|
209
|
+
suggestion.args
|
|
210
|
+
),
|
|
122
211
|
},
|
|
123
212
|
)
|
|
124
213
|
for suggestion in tool_suggestions
|
|
@@ -137,3 +226,34 @@ class AgentleMessageToOpenRouterMessageAdapter(
|
|
|
137
226
|
result["reasoning"] = message.reasoning
|
|
138
227
|
|
|
139
228
|
return result
|
|
229
|
+
|
|
230
|
+
def _serialize_tool_arguments(self, args: object) -> str:
|
|
231
|
+
"""
|
|
232
|
+
Serialize tool arguments to JSON string.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
args: The arguments to serialize.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
JSON string representation of the arguments.
|
|
239
|
+
"""
|
|
240
|
+
if isinstance(args, str):
|
|
241
|
+
return args
|
|
242
|
+
return json.dumps(args)
|
|
243
|
+
|
|
244
|
+
def _serialize_tool_result(self, result: object) -> str:
|
|
245
|
+
"""
|
|
246
|
+
Serialize tool execution result to string.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
result: The result to serialize.
|
|
250
|
+
|
|
251
|
+
returns:
|
|
252
|
+
String representation of the result.
|
|
253
|
+
"""
|
|
254
|
+
if isinstance(result, str):
|
|
255
|
+
return result
|
|
256
|
+
try:
|
|
257
|
+
return json.dumps(result)
|
|
258
|
+
except (TypeError, ValueError):
|
|
259
|
+
return str(result)
|
|
@@ -71,6 +71,7 @@ from agentle.generations.providers.openrouter._types import (
|
|
|
71
71
|
OpenRouterFileParserPlugin,
|
|
72
72
|
OpenRouterModelsResponse,
|
|
73
73
|
OpenRouterModel,
|
|
74
|
+
OpenRouterMessage,
|
|
74
75
|
)
|
|
75
76
|
from agentle.generations.providers.openrouter.error_handler import (
|
|
76
77
|
parse_and_raise_openrouter_error,
|
|
@@ -1247,10 +1248,14 @@ class OpenRouterGenerationProvider(GenerationProvider):
|
|
|
1247
1248
|
),
|
|
1248
1249
|
)
|
|
1249
1250
|
|
|
1250
|
-
# Convert messages
|
|
1251
|
-
openrouter_messages = [
|
|
1252
|
-
|
|
1253
|
-
|
|
1251
|
+
# Convert messages - adapter may return single message or list of messages
|
|
1252
|
+
openrouter_messages: list[OpenRouterMessage] = []
|
|
1253
|
+
for message in messages_list:
|
|
1254
|
+
adapted = self.message_adapter.adapt(message)
|
|
1255
|
+
if isinstance(adapted, list):
|
|
1256
|
+
openrouter_messages.extend(adapted)
|
|
1257
|
+
else:
|
|
1258
|
+
openrouter_messages.append(adapted)
|
|
1254
1259
|
|
|
1255
1260
|
# Convert tools if provided
|
|
1256
1261
|
openrouter_tools = (
|
|
@@ -1404,10 +1409,14 @@ class OpenRouterGenerationProvider(GenerationProvider):
|
|
|
1404
1409
|
"""
|
|
1405
1410
|
_generation_config = self._normalize_generation_config(generation_config)
|
|
1406
1411
|
|
|
1407
|
-
# Convert messages
|
|
1408
|
-
openrouter_messages = [
|
|
1409
|
-
|
|
1410
|
-
|
|
1412
|
+
# Convert messages - adapter may return single message or list of messages
|
|
1413
|
+
openrouter_messages: list[OpenRouterMessage] = []
|
|
1414
|
+
for message in messages:
|
|
1415
|
+
adapted = self.message_adapter.adapt(message)
|
|
1416
|
+
if isinstance(adapted, list):
|
|
1417
|
+
openrouter_messages.extend(adapted)
|
|
1418
|
+
else:
|
|
1419
|
+
openrouter_messages.append(adapted)
|
|
1411
1420
|
|
|
1412
1421
|
# Convert tools if provided
|
|
1413
1422
|
openrouter_tools = (
|
|
@@ -355,9 +355,9 @@ agentle/generations/providers/openrouter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
|
355
355
|
agentle/generations/providers/openrouter/_types.py,sha256=VSAf1auxopTqhYwLHPWl_Q0-okWUfLKJa0JmWlAFuGg,10557
|
|
356
356
|
agentle/generations/providers/openrouter/error_handler.py,sha256=4qm8v_cjdrB-59UXyCJLnIkOxzIfmsltZY8Q137-8Qg,8075
|
|
357
357
|
agentle/generations/providers/openrouter/exceptions.py,sha256=o3_-tuyhewc0v5L2cAXH0f9ixHyyDgZbHq0KX5cUyPE,23179
|
|
358
|
-
agentle/generations/providers/openrouter/openrouter_generation_provider.py,sha256=
|
|
358
|
+
agentle/generations/providers/openrouter/openrouter_generation_provider.py,sha256=XhXU_Ix10jmWl2SzRUHwsVSPRIWq6zHnia7IMaY6Yy4,67129
|
|
359
359
|
agentle/generations/providers/openrouter/_adapters/__init__.py,sha256=orgZeEBqH4X_cpyOMiClvfZHY5cLwLNqhAYLqNjGIH4,1826
|
|
360
|
-
agentle/generations/providers/openrouter/_adapters/agentle_message_to_openrouter_message_adapter.py,sha256=
|
|
360
|
+
agentle/generations/providers/openrouter/_adapters/agentle_message_to_openrouter_message_adapter.py,sha256=IvaovVP0ChYEreysiDyqF8SXdXxnD_Y9MjA2raEoncw,9790
|
|
361
361
|
agentle/generations/providers/openrouter/_adapters/agentle_part_to_openrouter_part_adapter.py,sha256=eIfwQQ9BokHy3FQ90GJ4i_J3L46XCiSBd1RWnzu-gAo,5967
|
|
362
362
|
agentle/generations/providers/openrouter/_adapters/agentle_tool_to_openrouter_tool_adapter.py,sha256=41i3B6awaTNZsdQ46Oi1e10cuNhQqWL-KBJ5V_sHkiI,9547
|
|
363
363
|
agentle/generations/providers/openrouter/_adapters/openrouter_message_to_generated_assistant_message_adapter.py,sha256=uB4TYc0fuwsoYdRnEnLhbwQISyaZ2Z2RWkPFGQXUc80,5295
|
|
@@ -1018,7 +1018,7 @@ agentle/web/actions/scroll.py,sha256=WqVVAORNDK3BL1oASZBPmXJYeSVkPgAOmWA8ibYO82I
|
|
|
1018
1018
|
agentle/web/actions/viewport.py,sha256=KCwm88Pri19Qc6GLHC69HsRxmdJz1gEEAODfggC_fHo,287
|
|
1019
1019
|
agentle/web/actions/wait.py,sha256=IKEywjf-KC4ni9Gkkv4wgc7bY-hk7HwD4F-OFWlyf2w,571
|
|
1020
1020
|
agentle/web/actions/write_text.py,sha256=9mxfHcpKs_L7BsDnJvOYHQwG8M0GWe61SRJAsKk3xQ8,748
|
|
1021
|
-
agentle-0.9.
|
|
1022
|
-
agentle-0.9.
|
|
1023
|
-
agentle-0.9.
|
|
1024
|
-
agentle-0.9.
|
|
1021
|
+
agentle-0.9.36.dist-info/METADATA,sha256=hSUSyQ9vk4kdTs91_EW7Yb1tEi41flD2JGVlqugY4YA,86849
|
|
1022
|
+
agentle-0.9.36.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
1023
|
+
agentle-0.9.36.dist-info/licenses/LICENSE,sha256=T90S9vqRS6qP-voULxAcvwEs558wRRo6dHuZrjgcOUI,1085
|
|
1024
|
+
agentle-0.9.36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|