openrouter-provider 1.0.7__py3-none-any.whl → 1.0.9__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 openrouter-provider might be problematic. Click here for more details.
- openrouter/message.py +4 -1
- openrouter/openrouter.py +78 -36
- openrouter/openrouter_provider.py +2 -0
- {openrouter_provider-1.0.7.dist-info → openrouter_provider-1.0.9.dist-info}/METADATA +1 -1
- openrouter_provider-1.0.9.dist-info/RECORD +10 -0
- openrouter_provider-1.0.7.dist-info/RECORD +0 -10
- {openrouter_provider-1.0.7.dist-info → openrouter_provider-1.0.9.dist-info}/WHEEL +0 -0
- {openrouter_provider-1.0.7.dist-info → openrouter_provider-1.0.9.dist-info}/top_level.txt +0 -0
openrouter/message.py
CHANGED
|
@@ -3,6 +3,7 @@ from dataclasses import dataclass
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from io import BytesIO
|
|
5
5
|
import base64
|
|
6
|
+
import uuid
|
|
6
7
|
from typing import Optional, Any
|
|
7
8
|
|
|
8
9
|
from PIL import Image
|
|
@@ -34,8 +35,10 @@ class Message:
|
|
|
34
35
|
images: Optional[list[Image.Image]] = None,
|
|
35
36
|
role: Role = Role.user,
|
|
36
37
|
answered_by: Optional[LLMModel] = None,
|
|
37
|
-
raw_response: Optional[ChatCompletion] = None
|
|
38
|
+
raw_response: Optional[ChatCompletion] = None,
|
|
39
|
+
id: Optional[str] = None
|
|
38
40
|
) -> None:
|
|
41
|
+
self.id = id if id is not None else str(uuid.uuid4())
|
|
39
42
|
self.role = role
|
|
40
43
|
self.text = text
|
|
41
44
|
self.images = self._process_image(images)
|
openrouter/openrouter.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import json
|
|
3
3
|
import time
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from typing import Iterator, AsyncIterator
|
|
5
6
|
|
|
6
7
|
from dotenv import load_dotenv
|
|
@@ -35,9 +36,57 @@ class OpenRouterClient:
|
|
|
35
36
|
system_prompt = _base_system_prompt
|
|
36
37
|
system_prompt = system_prompt.replace("[TIME]", f"{month}/{day}/{year}")
|
|
37
38
|
system_prompt = system_prompt.replace("[SYSTEM_INSTRUCTION]", prompt)
|
|
38
|
-
|
|
39
|
+
|
|
39
40
|
self._system_prompt = Message(text=system_prompt, role=Role.system)
|
|
40
|
-
|
|
41
|
+
|
|
42
|
+
def _execute_tools(self, reply: Message, tools: list[tool_model]) -> Message:
|
|
43
|
+
if not reply.tool_calls:
|
|
44
|
+
return reply
|
|
45
|
+
|
|
46
|
+
reply_copy = deepcopy(reply)
|
|
47
|
+
|
|
48
|
+
for requested_tool in reply_copy.tool_calls:
|
|
49
|
+
args = requested_tool.arguments
|
|
50
|
+
if isinstance(args, str):
|
|
51
|
+
args = json.loads(args)
|
|
52
|
+
|
|
53
|
+
for tool in tools:
|
|
54
|
+
if tool.name == requested_tool.name:
|
|
55
|
+
result = tool(**args)
|
|
56
|
+
requested_tool.result = result
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
return reply_copy
|
|
60
|
+
|
|
61
|
+
def execute_tool(self, reply: Message, tool_index: int, tools: List[tool_model] = []) -> Message:
|
|
62
|
+
if not reply.tool_calls:
|
|
63
|
+
return reply
|
|
64
|
+
|
|
65
|
+
if tool_index < 0 or tool_index >= len(reply.tool_calls):
|
|
66
|
+
raise IndexError(f"Tool index {tool_index} is out of range. Available tools: {len(reply.tool_calls)}")
|
|
67
|
+
|
|
68
|
+
requested_tool = reply.tool_calls[tool_index]
|
|
69
|
+
|
|
70
|
+
args = requested_tool.arguments
|
|
71
|
+
if isinstance(args, str):
|
|
72
|
+
args = json.loads(args)
|
|
73
|
+
|
|
74
|
+
all_tools = self.tools + tools
|
|
75
|
+
for tool in all_tools:
|
|
76
|
+
if tool.name == requested_tool.name:
|
|
77
|
+
result = tool(**args)
|
|
78
|
+
requested_tool.result = result
|
|
79
|
+
break
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError(f"Tool '{requested_tool.name}' not found in registered tools")
|
|
82
|
+
|
|
83
|
+
for i, msg in enumerate(self._memory):
|
|
84
|
+
if msg.id == reply.id:
|
|
85
|
+
self._memory[i] = reply
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
return reply
|
|
89
|
+
|
|
41
90
|
def clear_memory(self) -> None:
|
|
42
91
|
self._memory = []
|
|
43
92
|
|
|
@@ -80,15 +129,17 @@ class OpenRouterClient:
|
|
|
80
129
|
def invoke(
|
|
81
130
|
self,
|
|
82
131
|
model: LLMModel,
|
|
83
|
-
query: Message,
|
|
132
|
+
query: Message = None,
|
|
84
133
|
tools: list[tool_model] = None,
|
|
85
134
|
provider: ProviderConfig = None,
|
|
86
|
-
temperature: float = 0.3
|
|
135
|
+
temperature: float = 0.3,
|
|
136
|
+
auto_tool_exec: bool = True
|
|
87
137
|
) -> Message:
|
|
88
138
|
tools = tools or []
|
|
89
|
-
|
|
139
|
+
if query is not None:
|
|
140
|
+
self._memory.append(query)
|
|
90
141
|
client = OpenRouterProvider()
|
|
91
|
-
|
|
142
|
+
|
|
92
143
|
reply = client.invoke(
|
|
93
144
|
model=model,
|
|
94
145
|
temperature=temperature,
|
|
@@ -100,20 +151,19 @@ class OpenRouterClient:
|
|
|
100
151
|
reply.answered_by = model
|
|
101
152
|
self._memory.append(reply)
|
|
102
153
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return reply
|
|
154
|
+
if auto_tool_exec and reply.tool_calls:
|
|
155
|
+
reply = self._execute_tools(reply, self.tools + tools)
|
|
156
|
+
self._memory[-1] = reply
|
|
157
|
+
|
|
158
|
+
reply = client.invoke(
|
|
159
|
+
model=model,
|
|
160
|
+
temperature=temperature,
|
|
161
|
+
system_prompt=self._system_prompt,
|
|
162
|
+
querys=self._memory,
|
|
163
|
+
provider=provider
|
|
164
|
+
)
|
|
165
|
+
reply.answered_by = model
|
|
166
|
+
self._memory.append(reply)
|
|
117
167
|
|
|
118
168
|
return reply
|
|
119
169
|
|
|
@@ -147,13 +197,15 @@ class OpenRouterClient:
|
|
|
147
197
|
async def async_invoke(
|
|
148
198
|
self,
|
|
149
199
|
model: LLMModel,
|
|
150
|
-
query: Message,
|
|
200
|
+
query: Message = None,
|
|
151
201
|
tools: list[tool_model] = None,
|
|
152
202
|
provider: ProviderConfig = None,
|
|
153
|
-
temperature: float = 0.3
|
|
203
|
+
temperature: float = 0.3,
|
|
204
|
+
auto_tool_exec: bool = True
|
|
154
205
|
) -> Message:
|
|
155
206
|
tools = tools or []
|
|
156
|
-
|
|
207
|
+
if query is not None:
|
|
208
|
+
self._memory.append(query)
|
|
157
209
|
client = OpenRouterProvider()
|
|
158
210
|
reply = await client.async_invoke(
|
|
159
211
|
model=model,
|
|
@@ -166,19 +218,8 @@ class OpenRouterClient:
|
|
|
166
218
|
reply.answered_by = model
|
|
167
219
|
self._memory.append(reply)
|
|
168
220
|
|
|
169
|
-
if reply.tool_calls:
|
|
170
|
-
|
|
171
|
-
args = requested_tool.arguments
|
|
172
|
-
if isinstance(args, str):
|
|
173
|
-
args = json.loads(args)
|
|
174
|
-
|
|
175
|
-
for tool in (self.tools + tools):
|
|
176
|
-
if tool.name == requested_tool.name:
|
|
177
|
-
result = tool(**args)
|
|
178
|
-
requested_tool.result = result
|
|
179
|
-
break
|
|
180
|
-
else:
|
|
181
|
-
return reply
|
|
221
|
+
if auto_tool_exec and reply.tool_calls:
|
|
222
|
+
reply = self._execute_tools(reply, self.tools + tools)
|
|
182
223
|
|
|
183
224
|
reply = await client.async_invoke(
|
|
184
225
|
model=model,
|
|
@@ -243,3 +284,4 @@ class OpenRouterClient:
|
|
|
243
284
|
self._memory.append(Message(text=reply.model_dump_json(), role=Role.ai, answered_by=model))
|
|
244
285
|
|
|
245
286
|
return reply
|
|
287
|
+
|
|
@@ -122,6 +122,8 @@ class OpenRouterProvider:
|
|
|
122
122
|
for tool in response.choices[0].message.tool_calls:
|
|
123
123
|
reply.tool_calls.append(ToolCall(id=tool.id, name=tool.function.name, arguments=tool.function.arguments))
|
|
124
124
|
return reply
|
|
125
|
+
|
|
126
|
+
|
|
125
127
|
|
|
126
128
|
def invoke_stream(
|
|
127
129
|
self,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
openrouter/__init__.py,sha256=xuIzdm8-l3Tmc-zrNIXTicv05c9HCMxTS9xynKpWK-Q,123
|
|
2
|
+
openrouter/llms.py,sha256=zmujFW5BmQA0Fm6z8skuO3ipLpaUMy1VBZxYkPE9OcM,3391
|
|
3
|
+
openrouter/message.py,sha256=ESI4YT6x0TuPZ0AY29ZPlBCv72KrQad1-IeNmrfGD0w,2978
|
|
4
|
+
openrouter/openrouter.py,sha256=T1n3Mi26StAMzJ5yNNY5ww6fympiHBfp5M4pzYPmaV8,8993
|
|
5
|
+
openrouter/openrouter_provider.py,sha256=_Rt85X5pJ1IGbJeITfnzEG0QSp0qTo_PrDWIqtbd0xg,8577
|
|
6
|
+
openrouter/tool.py,sha256=tUUNLosz1XhzPIwY1zHXWNM3ePs7hcVD1a_W5hWTCWk,1975
|
|
7
|
+
openrouter_provider-1.0.9.dist-info/METADATA,sha256=4HR6qiN7tDmtfGczhobO0oZsFtrYbyNS8pZ9rryZmT8,11503
|
|
8
|
+
openrouter_provider-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
openrouter_provider-1.0.9.dist-info/top_level.txt,sha256=0jnlCcRirGeYZLm5ZbWQRUonIp4tTPl_9mq-ds_1SEo,11
|
|
10
|
+
openrouter_provider-1.0.9.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
openrouter/__init__.py,sha256=xuIzdm8-l3Tmc-zrNIXTicv05c9HCMxTS9xynKpWK-Q,123
|
|
2
|
-
openrouter/llms.py,sha256=zmujFW5BmQA0Fm6z8skuO3ipLpaUMy1VBZxYkPE9OcM,3391
|
|
3
|
-
openrouter/message.py,sha256=0q0OYdTl3f1TOx79TJRwPYyFuTxoYI9tSCpQN-N8G-A,2870
|
|
4
|
-
openrouter/openrouter.py,sha256=jywShAm6oALzaNxrw5K6Jd7XizDpyEhVc_pJnJ0KIjI,7695
|
|
5
|
-
openrouter/openrouter_provider.py,sha256=w6isS1VX7iMf71zwQ5tMv7v5X0yeMbLF6vqimOrB724,8567
|
|
6
|
-
openrouter/tool.py,sha256=tUUNLosz1XhzPIwY1zHXWNM3ePs7hcVD1a_W5hWTCWk,1975
|
|
7
|
-
openrouter_provider-1.0.7.dist-info/METADATA,sha256=rwtcuUZFVUe7unjlVEfjIKZ4Mk1weMyT3GJiLATGg9w,11503
|
|
8
|
-
openrouter_provider-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
-
openrouter_provider-1.0.7.dist-info/top_level.txt,sha256=0jnlCcRirGeYZLm5ZbWQRUonIp4tTPl_9mq-ds_1SEo,11
|
|
10
|
-
openrouter_provider-1.0.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|