pygpt-net 2.5.14__py3-none-any.whl → 2.5.16__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.
- pygpt_net/CHANGELOG.txt +12 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/chat/input.py +9 -2
- pygpt_net/controller/chat/stream.py +65 -17
- pygpt_net/controller/lang/mapping.py +4 -2
- pygpt_net/controller/model/__init__.py +3 -1
- pygpt_net/controller/model/importer.py +337 -0
- pygpt_net/controller/settings/editor.py +3 -0
- pygpt_net/core/bridge/worker.py +4 -2
- pygpt_net/core/command/__init__.py +33 -2
- pygpt_net/core/models/__init__.py +6 -3
- pygpt_net/core/models/ollama.py +7 -2
- pygpt_net/data/config/config.json +9 -4
- pygpt_net/data/config/models.json +22 -22
- pygpt_net/data/locale/locale.de.ini +18 -0
- pygpt_net/data/locale/locale.en.ini +19 -2
- pygpt_net/data/locale/locale.es.ini +18 -0
- pygpt_net/data/locale/locale.fr.ini +18 -0
- pygpt_net/data/locale/locale.it.ini +18 -0
- pygpt_net/data/locale/locale.pl.ini +19 -1
- pygpt_net/data/locale/locale.uk.ini +18 -0
- pygpt_net/data/locale/locale.zh.ini +17 -0
- pygpt_net/item/ctx.py +2 -1
- pygpt_net/item/model.py +5 -1
- pygpt_net/plugin/cmd_files/__init__.py +2 -2
- pygpt_net/plugin/cmd_files/worker.py +2 -2
- pygpt_net/provider/core/model/json_file.py +3 -0
- pygpt_net/provider/core/model/patch.py +24 -1
- pygpt_net/provider/gpt/__init__.py +54 -21
- pygpt_net/provider/gpt/responses.py +279 -0
- pygpt_net/provider/gpt/vision.py +40 -16
- pygpt_net/provider/llms/ollama.py +7 -2
- pygpt_net/provider/llms/ollama_custom.py +693 -0
- pygpt_net/ui/dialog/models_importer.py +82 -0
- pygpt_net/ui/dialogs.py +3 -1
- pygpt_net/ui/menu/config.py +18 -7
- pygpt_net/ui/widget/dialog/model_importer.py +55 -0
- pygpt_net/ui/widget/lists/model_importer.py +151 -0
- {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.16.dist-info}/METADATA +75 -9
- {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.16.dist-info}/RECORD +43 -37
- {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.16.dist-info}/LICENSE +0 -0
- {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.16.dist-info}/WHEEL +0 -0
- {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.16.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2025.
|
9
|
+
# Updated Date: 2025.06.25 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from httpx_socks import SyncProxyTransport
|
@@ -29,6 +29,7 @@ from .assistants import Assistants
|
|
29
29
|
from .chat import Chat
|
30
30
|
from .completion import Completion
|
31
31
|
from .image import Image
|
32
|
+
from .responses import Responses
|
32
33
|
from .store import Store
|
33
34
|
from .summarizer import Summarizer
|
34
35
|
from .vision import Vision
|
@@ -47,6 +48,7 @@ class Gpt:
|
|
47
48
|
self.chat = Chat(window)
|
48
49
|
self.completion = Completion(window)
|
49
50
|
self.image = Image(window)
|
51
|
+
self.responses = Responses(window)
|
50
52
|
self.store = Store(window)
|
51
53
|
self.summarizer = Summarizer(window)
|
52
54
|
self.vision = Vision(window)
|
@@ -108,6 +110,12 @@ class Gpt:
|
|
108
110
|
ai_name = ctx.output_name
|
109
111
|
thread_id = ctx.thread # from ctx
|
110
112
|
|
113
|
+
# --- Responses API ---- /beta/
|
114
|
+
use_responses_api = False
|
115
|
+
if mode == MODE_CHAT:
|
116
|
+
use_responses_api = True # use responses API for chat, audio, research modes
|
117
|
+
ctx.use_responses_api = use_responses_api # set in context
|
118
|
+
|
111
119
|
# get model id
|
112
120
|
model_id = None
|
113
121
|
if model is not None:
|
@@ -128,20 +136,30 @@ class Gpt:
|
|
128
136
|
)
|
129
137
|
used_tokens = self.completion.get_used_tokens()
|
130
138
|
|
131
|
-
# chat (OpenAI) | research (Perplexity)
|
139
|
+
# chat, audio (OpenAI) | research (Perplexity)
|
132
140
|
elif mode in [
|
133
141
|
MODE_CHAT,
|
134
142
|
MODE_AUDIO,
|
135
143
|
MODE_RESEARCH
|
136
144
|
]:
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
+
# responses API
|
146
|
+
if use_responses_api:
|
147
|
+
response = self.responses.send(
|
148
|
+
context=context,
|
149
|
+
extra=extra,
|
150
|
+
)
|
151
|
+
used_tokens = self.responses.get_used_tokens()
|
152
|
+
else:
|
153
|
+
# chat completion API
|
154
|
+
response = self.chat.send(
|
155
|
+
context=context,
|
156
|
+
extra=extra,
|
157
|
+
)
|
158
|
+
if hasattr(response, "citations"):
|
159
|
+
if response.citations:
|
160
|
+
ctx.urls = response.citations
|
161
|
+
used_tokens = self.chat.get_used_tokens()
|
162
|
+
|
145
163
|
self.vision.append_images(ctx) # append images to ctx if provided
|
146
164
|
|
147
165
|
# image
|
@@ -184,7 +202,7 @@ class Gpt:
|
|
184
202
|
|
185
203
|
# if stream
|
186
204
|
if stream:
|
187
|
-
ctx.stream = response
|
205
|
+
ctx.stream = response # generator
|
188
206
|
ctx.set_output("", ai_name) # set empty output
|
189
207
|
ctx.input_tokens = used_tokens # get from input tokens calculation
|
190
208
|
return True
|
@@ -206,13 +224,21 @@ class Gpt:
|
|
206
224
|
MODE_VISION,
|
207
225
|
MODE_RESEARCH
|
208
226
|
]:
|
209
|
-
if
|
210
|
-
if response.
|
211
|
-
output = response.
|
212
|
-
|
213
|
-
ctx.tool_calls = self.window.core.command.
|
214
|
-
response.
|
227
|
+
if use_responses_api:
|
228
|
+
if response.output_text:
|
229
|
+
output = response.output_text.strip()
|
230
|
+
if response.output:
|
231
|
+
ctx.tool_calls = self.window.core.command.unpack_tool_calls_responses(
|
232
|
+
response.output,
|
215
233
|
)
|
234
|
+
else:
|
235
|
+
if response.choices[0]:
|
236
|
+
if response.choices[0].message.content:
|
237
|
+
output = response.choices[0].message.content.strip()
|
238
|
+
elif response.choices[0].message.tool_calls:
|
239
|
+
ctx.tool_calls = self.window.core.command.unpack_tool_calls(
|
240
|
+
response.choices[0].message.tool_calls,
|
241
|
+
)
|
216
242
|
# audio
|
217
243
|
elif mode in [MODE_AUDIO]:
|
218
244
|
if response.choices[0]:
|
@@ -234,10 +260,17 @@ class Gpt:
|
|
234
260
|
)
|
235
261
|
|
236
262
|
ctx.set_output(output, ai_name)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
263
|
+
|
264
|
+
if not use_responses_api:
|
265
|
+
ctx.set_tokens(
|
266
|
+
response.usage.prompt_tokens,
|
267
|
+
response.usage.completion_tokens,
|
268
|
+
)
|
269
|
+
else:
|
270
|
+
ctx.set_tokens(
|
271
|
+
response.usage.input_tokens,
|
272
|
+
response.usage.output_tokens,
|
273
|
+
)
|
241
274
|
return True
|
242
275
|
|
243
276
|
def quick_call(self, context: BridgeContext, extra: dict = None) -> str:
|
@@ -0,0 +1,279 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# ================================================== #
|
4
|
+
# This file is a part of PYGPT package #
|
5
|
+
# Website: https://pygpt.net #
|
6
|
+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
|
+
# MIT License #
|
8
|
+
# Created By : Marcin Szczygliński #
|
9
|
+
# Updated Date: 2025.06.25 02:00:00 #
|
10
|
+
# ================================================== #
|
11
|
+
|
12
|
+
import json
|
13
|
+
import time
|
14
|
+
from typing import Optional, Dict, Any, List
|
15
|
+
|
16
|
+
from pygpt_net.core.types import (
|
17
|
+
MODE_CHAT,
|
18
|
+
MODE_VISION,
|
19
|
+
MODE_AUDIO,
|
20
|
+
MODE_RESEARCH,
|
21
|
+
)
|
22
|
+
from pygpt_net.core.bridge.context import BridgeContext, MultimodalContext
|
23
|
+
from pygpt_net.item.ctx import CtxItem
|
24
|
+
from pygpt_net.item.model import ModelItem
|
25
|
+
|
26
|
+
from .utils import sanitize_name
|
27
|
+
from pygpt_net.item.attachment import AttachmentItem
|
28
|
+
|
29
|
+
|
30
|
+
class Responses:
|
31
|
+
def __init__(self, window=None):
|
32
|
+
"""
|
33
|
+
Responses API wrapper
|
34
|
+
|
35
|
+
:param window: Window instance
|
36
|
+
"""
|
37
|
+
self.window = window
|
38
|
+
self.input_tokens = 0
|
39
|
+
self.audio_prev_id = None
|
40
|
+
self.audio_prev_expires_ts = None
|
41
|
+
|
42
|
+
def send(
|
43
|
+
self,
|
44
|
+
context: BridgeContext,
|
45
|
+
extra: Optional[Dict[str, Any]] = None
|
46
|
+
):
|
47
|
+
"""
|
48
|
+
Call OpenAI API for chat
|
49
|
+
|
50
|
+
:param context: Bridge context
|
51
|
+
:param extra: Extra arguments
|
52
|
+
:return: response or stream chunks
|
53
|
+
"""
|
54
|
+
prompt = context.prompt
|
55
|
+
stream = context.stream
|
56
|
+
max_tokens = int(context.max_tokens or 0)
|
57
|
+
system_prompt = context.system_prompt
|
58
|
+
mode = context.mode
|
59
|
+
model = context.model
|
60
|
+
functions = context.external_functions
|
61
|
+
attachments = context.attachments
|
62
|
+
multimodal_ctx = context.multimodal_ctx
|
63
|
+
|
64
|
+
ctx = context.ctx
|
65
|
+
if ctx is None:
|
66
|
+
ctx = CtxItem() # create empty context
|
67
|
+
user_name = ctx.input_name # from ctx
|
68
|
+
ai_name = ctx.output_name # from ctx
|
69
|
+
|
70
|
+
client = self.window.core.gpt.get_client(mode)
|
71
|
+
|
72
|
+
# build chat messages
|
73
|
+
messages = self.build(
|
74
|
+
prompt=prompt,
|
75
|
+
system_prompt=system_prompt,
|
76
|
+
model=model,
|
77
|
+
history=context.history,
|
78
|
+
attachments=attachments,
|
79
|
+
ai_name=ai_name,
|
80
|
+
user_name=user_name,
|
81
|
+
multimodal_ctx=multimodal_ctx,
|
82
|
+
)
|
83
|
+
msg_tokens = self.window.core.tokens.from_messages(
|
84
|
+
messages,
|
85
|
+
model.id,
|
86
|
+
)
|
87
|
+
# check if max tokens not exceeded
|
88
|
+
if max_tokens > 0:
|
89
|
+
if msg_tokens + int(max_tokens) > model.ctx:
|
90
|
+
max_tokens = model.ctx - msg_tokens - 1
|
91
|
+
if max_tokens < 0:
|
92
|
+
max_tokens = 0
|
93
|
+
|
94
|
+
# extra API kwargs
|
95
|
+
response_kwargs = {}
|
96
|
+
|
97
|
+
# tools / functions
|
98
|
+
tools = []
|
99
|
+
if functions is not None and isinstance(functions, list):
|
100
|
+
for function in functions:
|
101
|
+
if str(function['name']).strip() == '' or function['name'] is None:
|
102
|
+
continue
|
103
|
+
params = {}
|
104
|
+
if function['params'] is not None and function['params'] != "":
|
105
|
+
params = json.loads(function['params']) # unpack JSON from string
|
106
|
+
tools.append({
|
107
|
+
"type": "function",
|
108
|
+
"name": function['name'],
|
109
|
+
"parameters": params,
|
110
|
+
"description": function['desc'],
|
111
|
+
})
|
112
|
+
|
113
|
+
# extra arguments, o3 only
|
114
|
+
if model.extra and "reasoning_effort" in model.extra:
|
115
|
+
response_kwargs['reasoning'] = {}
|
116
|
+
response_kwargs['reasoning']['effort'] = model.extra["reasoning_effort"]
|
117
|
+
|
118
|
+
# extend tools with external tools
|
119
|
+
if not model.id.startswith("o1") and not model.id.startswith("o3"):
|
120
|
+
tools.append({"type": "web_search_preview"})
|
121
|
+
|
122
|
+
# tool calls are not supported for o1-mini and o1-preview
|
123
|
+
if (model.id is not None
|
124
|
+
and model.id not in ["o1-mini", "o1-preview"]):
|
125
|
+
if len(tools) > 0:
|
126
|
+
response_kwargs['tools'] = tools
|
127
|
+
|
128
|
+
# audio mode
|
129
|
+
if mode in [MODE_AUDIO]:
|
130
|
+
stream = False
|
131
|
+
voice_id = "alloy"
|
132
|
+
tmp_voice = self.window.core.plugins.get_option("audio_output", "openai_voice")
|
133
|
+
if tmp_voice:
|
134
|
+
voice_id = tmp_voice
|
135
|
+
response_kwargs["modalities"] = ["text", "audio"]
|
136
|
+
response_kwargs["audio"] = {
|
137
|
+
"voice": voice_id,
|
138
|
+
"format": "wav"
|
139
|
+
}
|
140
|
+
|
141
|
+
response = client.responses.create(
|
142
|
+
input=messages,
|
143
|
+
model=model.id,
|
144
|
+
stream=stream,
|
145
|
+
**response_kwargs,
|
146
|
+
)
|
147
|
+
return response
|
148
|
+
|
149
|
+
def build(
|
150
|
+
self,
|
151
|
+
prompt: str,
|
152
|
+
system_prompt: str,
|
153
|
+
model: ModelItem,
|
154
|
+
history: Optional[List[CtxItem]] = None,
|
155
|
+
attachments: Optional[Dict[str, AttachmentItem]] = None,
|
156
|
+
ai_name: Optional[str] = None,
|
157
|
+
user_name: Optional[str] = None,
|
158
|
+
multimodal_ctx: Optional[MultimodalContext] = None,
|
159
|
+
) -> list:
|
160
|
+
"""
|
161
|
+
Build list of chat messages
|
162
|
+
|
163
|
+
:param prompt: user prompt
|
164
|
+
:param system_prompt: system prompt
|
165
|
+
:param history: history
|
166
|
+
:param model: model item
|
167
|
+
:param attachments: attachments
|
168
|
+
:param ai_name: AI name
|
169
|
+
:param user_name: username
|
170
|
+
:param multimodal_ctx: Multimodal context
|
171
|
+
:return: messages list
|
172
|
+
"""
|
173
|
+
messages = []
|
174
|
+
|
175
|
+
# tokens config
|
176
|
+
mode = MODE_CHAT
|
177
|
+
allowed_system = True
|
178
|
+
if (model.id is not None
|
179
|
+
and model.id in ["o1-mini", "o1-preview"]):
|
180
|
+
allowed_system = False
|
181
|
+
|
182
|
+
used_tokens = self.window.core.tokens.from_user(
|
183
|
+
prompt,
|
184
|
+
system_prompt,
|
185
|
+
) # threshold and extra included
|
186
|
+
max_ctx_tokens = self.window.core.config.get('max_total_tokens') # max context window
|
187
|
+
|
188
|
+
# fit to max model tokens
|
189
|
+
if max_ctx_tokens > model.ctx:
|
190
|
+
max_ctx_tokens = model.ctx
|
191
|
+
|
192
|
+
# input tokens: reset
|
193
|
+
self.reset_tokens()
|
194
|
+
|
195
|
+
# append system prompt
|
196
|
+
if allowed_system:
|
197
|
+
if system_prompt is not None and system_prompt != "":
|
198
|
+
messages.append({"role": "developer", "content": system_prompt})
|
199
|
+
|
200
|
+
# append messages from context (memory)
|
201
|
+
if self.window.core.config.get('use_context'):
|
202
|
+
items = self.window.core.ctx.get_history(
|
203
|
+
history,
|
204
|
+
model.id,
|
205
|
+
mode,
|
206
|
+
used_tokens,
|
207
|
+
max_ctx_tokens,
|
208
|
+
)
|
209
|
+
for item in items:
|
210
|
+
# input
|
211
|
+
if item.final_input is not None and item.final_input != "":
|
212
|
+
messages.append({
|
213
|
+
"role": "user",
|
214
|
+
"content": item.final_input,
|
215
|
+
})
|
216
|
+
|
217
|
+
# output
|
218
|
+
if item.final_output is not None and item.final_output != "":
|
219
|
+
msg = {
|
220
|
+
"role": "assistant",
|
221
|
+
"content": item.final_output,
|
222
|
+
}
|
223
|
+
# append previous audio ID
|
224
|
+
if MODE_AUDIO in model.mode:
|
225
|
+
if item.audio_id:
|
226
|
+
# at first check expires_at - expired audio throws error in API
|
227
|
+
current_timestamp = time.time()
|
228
|
+
audio_timestamp = int(item.audio_expires_ts) if item.audio_expires_ts else 0
|
229
|
+
if audio_timestamp and audio_timestamp > current_timestamp:
|
230
|
+
msg["audio"] = {
|
231
|
+
"id": item.audio_id
|
232
|
+
}
|
233
|
+
elif self.audio_prev_id:
|
234
|
+
current_timestamp = time.time()
|
235
|
+
audio_timestamp = int(self.audio_prev_expires_ts) if self.audio_prev_expires_ts else 0
|
236
|
+
if audio_timestamp and audio_timestamp > current_timestamp:
|
237
|
+
msg["audio"] = {
|
238
|
+
"id": self.audio_prev_id
|
239
|
+
}
|
240
|
+
messages.append(msg)
|
241
|
+
|
242
|
+
# use vision and audio if available in current model
|
243
|
+
content = str(prompt)
|
244
|
+
if MODE_VISION in model.mode:
|
245
|
+
content = self.window.core.gpt.vision.build_content(
|
246
|
+
content=content,
|
247
|
+
attachments=attachments,
|
248
|
+
responses_api=True,
|
249
|
+
)
|
250
|
+
if MODE_AUDIO in model.mode:
|
251
|
+
content = self.window.core.gpt.audio.build_content(
|
252
|
+
content=content,
|
253
|
+
multimodal_ctx=multimodal_ctx,
|
254
|
+
)
|
255
|
+
|
256
|
+
# append current prompt
|
257
|
+
messages.append({
|
258
|
+
"role": "user",
|
259
|
+
"content": content,
|
260
|
+
})
|
261
|
+
|
262
|
+
# input tokens: update
|
263
|
+
self.input_tokens += self.window.core.tokens.from_messages(
|
264
|
+
messages,
|
265
|
+
model.id,
|
266
|
+
)
|
267
|
+
return messages
|
268
|
+
|
269
|
+
def reset_tokens(self):
|
270
|
+
"""Reset input tokens counter"""
|
271
|
+
self.input_tokens = 0
|
272
|
+
|
273
|
+
def get_used_tokens(self) -> int:
|
274
|
+
"""
|
275
|
+
Get input tokens counter
|
276
|
+
|
277
|
+
:return: input tokens
|
278
|
+
"""
|
279
|
+
return self.input_tokens
|
pygpt_net/provider/gpt/vision.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date:
|
9
|
+
# Updated Date: 2025.06.25 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import base64
|
@@ -168,18 +168,26 @@ class Vision:
|
|
168
168
|
self,
|
169
169
|
content: Union[str, list],
|
170
170
|
attachments: Optional[Dict[str, AttachmentItem]] = None,
|
171
|
+
responses_api: Optional[bool] = False,
|
171
172
|
) -> List[dict]:
|
172
173
|
"""
|
173
174
|
Build vision content
|
174
175
|
|
175
176
|
:param content: content (str or list)
|
176
177
|
:param attachments: attachments (dict, optional)
|
178
|
+
:param responses_api: if True, use responses API format
|
177
179
|
:return: List of contents
|
178
180
|
"""
|
181
|
+
type_text = "text"
|
182
|
+
type_image = "image_url"
|
183
|
+
if responses_api:
|
184
|
+
type_text = "input_text"
|
185
|
+
type_image = "input_image"
|
186
|
+
|
179
187
|
if not isinstance(content, list):
|
180
188
|
content = [
|
181
189
|
{
|
182
|
-
"type":
|
190
|
+
"type": type_text,
|
183
191
|
"text": str(content)
|
184
192
|
}
|
185
193
|
]
|
@@ -193,14 +201,22 @@ class Vision:
|
|
193
201
|
urls = self.extract_urls(prompt)
|
194
202
|
if len(urls) > 0:
|
195
203
|
for url in urls:
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
"
|
204
|
+
if not responses_api:
|
205
|
+
content.append(
|
206
|
+
{
|
207
|
+
"type": type_image,
|
208
|
+
"image_url": {
|
209
|
+
"url": url,
|
210
|
+
}
|
211
|
+
}
|
212
|
+
)
|
213
|
+
else:
|
214
|
+
content.append(
|
215
|
+
{
|
216
|
+
"type": type_image,
|
217
|
+
"image_url": url,
|
201
218
|
}
|
202
|
-
|
203
|
-
)
|
219
|
+
)
|
204
220
|
self.urls.append(url)
|
205
221
|
|
206
222
|
# local images (attachments)
|
@@ -211,14 +227,22 @@ class Vision:
|
|
211
227
|
# check if it's an image
|
212
228
|
if self.is_image(attachment.path):
|
213
229
|
base64_image = self.encode_image(attachment.path)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
"
|
230
|
+
if not responses_api:
|
231
|
+
content.append(
|
232
|
+
{
|
233
|
+
"type": type_image,
|
234
|
+
"image_url": {
|
235
|
+
"url": f"data:image/jpeg;base64,{base64_image}",
|
236
|
+
}
|
219
237
|
}
|
220
|
-
|
221
|
-
|
238
|
+
)
|
239
|
+
else:
|
240
|
+
content.append(
|
241
|
+
{
|
242
|
+
"type": type_image,
|
243
|
+
"image_url": f"data:image/jpeg;base64,{base64_image}",
|
244
|
+
}
|
245
|
+
)
|
222
246
|
self.attachments[id] = attachment.path
|
223
247
|
attachment.consumed = True
|
224
248
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2025.
|
9
|
+
# Updated Date: 2025.06.24 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -14,7 +14,8 @@ from typing import Optional, List, Dict
|
|
14
14
|
|
15
15
|
from langchain_community.chat_models import ChatOllama
|
16
16
|
|
17
|
-
from
|
17
|
+
from .ollama_custom import Ollama
|
18
|
+
|
18
19
|
from llama_index.core.llms.llm import BaseLLM as LlamaBaseLLM
|
19
20
|
from llama_index.core.base.embeddings.base import BaseEmbedding
|
20
21
|
from llama_index.embeddings.ollama import OllamaEmbedding
|
@@ -85,6 +86,8 @@ class OllamaLLM(BaseLLM):
|
|
85
86
|
args = self.parse_args(model.llama_index)
|
86
87
|
if "request_timeout" not in args:
|
87
88
|
args["request_timeout"] = 120
|
89
|
+
if 'OLLAMA_API_BASE' in os.environ:
|
90
|
+
args["base_url"] = os.environ['OLLAMA_API_BASE']
|
88
91
|
return Ollama(**args)
|
89
92
|
|
90
93
|
def get_embeddings_model(
|
@@ -104,6 +107,8 @@ class OllamaLLM(BaseLLM):
|
|
104
107
|
args = self.parse_args({
|
105
108
|
"args": config,
|
106
109
|
})
|
110
|
+
if 'OLLAMA_API_BASE' in os.environ:
|
111
|
+
args["base_url"] = os.environ['OLLAMA_API_BASE']
|
107
112
|
return OllamaEmbedding(**args)
|
108
113
|
|
109
114
|
def init_embeddings(
|