pygpt-net 2.6.45__py3-none-any.whl → 2.6.47__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.
Files changed (77) hide show
  1. pygpt_net/CHANGELOG.txt +12 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/controller/__init__.py +1 -3
  4. pygpt_net/controller/audio/audio.py +2 -0
  5. pygpt_net/controller/chat/text.py +2 -1
  6. pygpt_net/controller/debug/debug.py +11 -9
  7. pygpt_net/controller/dialogs/debug.py +40 -29
  8. pygpt_net/controller/notepad/notepad.py +0 -2
  9. pygpt_net/controller/theme/theme.py +5 -5
  10. pygpt_net/controller/ui/tabs.py +40 -2
  11. pygpt_net/core/debug/agent.py +19 -14
  12. pygpt_net/core/debug/assistants.py +22 -24
  13. pygpt_net/core/debug/attachments.py +11 -7
  14. pygpt_net/core/debug/config.py +22 -23
  15. pygpt_net/core/debug/context.py +63 -63
  16. pygpt_net/core/debug/db.py +1 -4
  17. pygpt_net/core/debug/events.py +14 -11
  18. pygpt_net/core/debug/indexes.py +41 -76
  19. pygpt_net/core/debug/kernel.py +11 -8
  20. pygpt_net/core/debug/models.py +20 -15
  21. pygpt_net/core/debug/plugins.py +9 -6
  22. pygpt_net/core/debug/presets.py +16 -11
  23. pygpt_net/core/debug/tabs.py +28 -22
  24. pygpt_net/core/debug/ui.py +25 -22
  25. pygpt_net/core/render/web/renderer.py +5 -2
  26. pygpt_net/core/tabs/tab.py +16 -3
  27. pygpt_net/data/config/config.json +3 -3
  28. pygpt_net/data/config/models.json +3 -3
  29. pygpt_net/data/config/settings.json +15 -17
  30. pygpt_net/data/css/style.dark.css +6 -0
  31. pygpt_net/data/css/web-blocks.css +4 -0
  32. pygpt_net/data/css/web-blocks.light.css +1 -1
  33. pygpt_net/data/css/web-chatgpt.css +4 -0
  34. pygpt_net/data/css/web-chatgpt.light.css +1 -1
  35. pygpt_net/data/css/web-chatgpt_wide.css +4 -0
  36. pygpt_net/data/css/web-chatgpt_wide.light.css +1 -1
  37. pygpt_net/data/js/app.js +1804 -1688
  38. pygpt_net/data/locale/locale.de.ini +1 -1
  39. pygpt_net/data/locale/locale.en.ini +1 -1
  40. pygpt_net/data/locale/locale.es.ini +1 -1
  41. pygpt_net/data/locale/locale.fr.ini +1 -1
  42. pygpt_net/data/locale/locale.it.ini +1 -1
  43. pygpt_net/data/locale/locale.pl.ini +2 -2
  44. pygpt_net/data/locale/locale.uk.ini +1 -1
  45. pygpt_net/data/locale/locale.zh.ini +1 -1
  46. pygpt_net/item/model.py +4 -1
  47. pygpt_net/js_rc.py +14303 -14540
  48. pygpt_net/provider/api/anthropic/__init__.py +3 -1
  49. pygpt_net/provider/api/anthropic/tools.py +1 -1
  50. pygpt_net/provider/api/google/__init__.py +7 -1
  51. pygpt_net/provider/api/x_ai/__init__.py +5 -1
  52. pygpt_net/provider/core/config/patch.py +14 -1
  53. pygpt_net/provider/llms/anthropic.py +37 -5
  54. pygpt_net/provider/llms/azure_openai.py +3 -1
  55. pygpt_net/provider/llms/base.py +13 -1
  56. pygpt_net/provider/llms/deepseek_api.py +13 -3
  57. pygpt_net/provider/llms/google.py +14 -1
  58. pygpt_net/provider/llms/hugging_face_api.py +105 -24
  59. pygpt_net/provider/llms/hugging_face_embedding.py +88 -0
  60. pygpt_net/provider/llms/hugging_face_router.py +28 -16
  61. pygpt_net/provider/llms/local.py +2 -0
  62. pygpt_net/provider/llms/mistral.py +60 -3
  63. pygpt_net/provider/llms/open_router.py +4 -2
  64. pygpt_net/provider/llms/openai.py +4 -1
  65. pygpt_net/provider/llms/perplexity.py +66 -5
  66. pygpt_net/provider/llms/utils.py +39 -0
  67. pygpt_net/provider/llms/voyage.py +50 -0
  68. pygpt_net/provider/llms/x_ai.py +70 -10
  69. pygpt_net/ui/widget/lists/db.py +1 -0
  70. pygpt_net/ui/widget/lists/debug.py +1 -0
  71. pygpt_net/ui/widget/tabs/body.py +23 -4
  72. pygpt_net/ui/widget/textarea/notepad.py +0 -4
  73. {pygpt_net-2.6.45.dist-info → pygpt_net-2.6.47.dist-info}/METADATA +16 -4
  74. {pygpt_net-2.6.45.dist-info → pygpt_net-2.6.47.dist-info}/RECORD +77 -74
  75. {pygpt_net-2.6.45.dist-info → pygpt_net-2.6.47.dist-info}/LICENSE +0 -0
  76. {pygpt_net-2.6.45.dist-info → pygpt_net-2.6.47.dist-info}/WHEEL +0 -0
  77. {pygpt_net-2.6.45.dist-info → pygpt_net-2.6.47.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.09.05 01:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, Dict, Any
@@ -64,6 +64,8 @@ class ApiAnthropic:
64
64
  filtered = {}
65
65
  if args.get("api_key"):
66
66
  filtered["api_key"] = args["api_key"]
67
+ if args.get("api_proxy"):
68
+ filtered["api_proxy"] = args["api_proxy"]
67
69
 
68
70
  # Optionally honor custom base_url if present in config (advanced)
69
71
  # base_url = self.window.core.config.get("api_native_anthropic.base_url", "").strip()
@@ -174,7 +174,7 @@ class Tools:
174
174
  tools: List[dict] = []
175
175
 
176
176
  # sonnet-3.5 is not supported
177
- if model and model.id and model.id.startswith("claude-3.5"):
177
+ if model and model.id and model.id.startswith("claude-3-5"):
178
178
  return tools
179
179
 
180
180
  # Web Search tool
@@ -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.09.01 23:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -72,6 +72,12 @@ class ApiGoogle:
72
72
  filtered = {}
73
73
  if args.get("api_key"):
74
74
  filtered["api_key"] = args["api_key"]
75
+ if args.get("api_proxy"):
76
+ http_options = gtypes.HttpOptions(
77
+ client_args={"proxy": args["api_proxy"]},
78
+ async_client_args={"proxy": args["api_proxy"]},
79
+ )
80
+ filtered["http_options"] = http_options
75
81
 
76
82
  # setup VertexAI if enabled
77
83
  use_vertex = self.setup_env()
@@ -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.09.05 01:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, Dict, Any
@@ -74,6 +74,7 @@ class ApiXAI:
74
74
  cfg = self.window.core.config
75
75
  api_key = cfg.get("api_key_xai") or os.environ.get("XAI_API_KEY") or ""
76
76
  timeout = cfg.get("api_native_xai.timeout") # optional
77
+ proxy = cfg.get("api_proxy") or ""
77
78
 
78
79
  kwargs: Dict[str, Any] = {}
79
80
  if api_key:
@@ -81,6 +82,9 @@ class ApiXAI:
81
82
  if timeout is not None:
82
83
  # Official SDK supports setting a global timeout on client init.
83
84
  kwargs["timeout"] = timeout
85
+ if proxy:
86
+ kwargs["channel_options"] = []
87
+ kwargs["channel_options"].append(("grpc.http_proxy", proxy))
84
88
 
85
89
  self.client = xai_sdk.Client(**kwargs)
86
90
  return self.client
@@ -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.09.12 23:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -75,6 +75,19 @@ class Patch:
75
75
  data["render.msg.user.collapse.px"] = 1500
76
76
  updated = True
77
77
 
78
+ # < 2.6.46
79
+ if old < parse_version("2.6.46"):
80
+ print("Migrating config from < 2.6.46...")
81
+ # output stream margin-top: 0
82
+ patch_css('web-chatgpt.css', True)
83
+ patch_css('web-chatgpt_wide.css', True)
84
+ patch_css('web-blocks.css', True)
85
+ patch_css('style.dark.css', True)
86
+ patch_css('web-blocks.light.css', True)
87
+ patch_css('web-chatgpt.light.css', True)
88
+ patch_css('web-chatgpt_wide.light.css', True)
89
+ updated = True
90
+
78
91
  # update file
79
92
  migrated = False
80
93
  if updated:
@@ -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.08.28 09:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import List, Dict, Optional
@@ -50,12 +50,35 @@ class AnthropicLLM(BaseLLM):
50
50
  :return: LLM provider instance
51
51
  """
52
52
  from llama_index.llms.anthropic import Anthropic
53
+ class AnthropicWithProxy(Anthropic):
54
+ def __init__(self, *args, proxy: str = None, **kwargs):
55
+ super().__init__(*args, **kwargs)
56
+ if not proxy:
57
+ return
58
+
59
+ # sync
60
+ from anthropic import DefaultHttpxClient
61
+ self._client = self._client.with_options(
62
+ http_client=DefaultHttpxClient(proxy=proxy)
63
+ )
64
+
65
+ # async
66
+ import httpx
67
+ try:
68
+ async_http = httpx.AsyncClient(proxy=proxy) # httpx >= 0.28
69
+ except TypeError:
70
+ async_http = httpx.AsyncClient(proxies=proxy) # httpx <= 0.27
71
+
72
+ self._aclient = self._aclient.with_options(http_client=async_http)
73
+
53
74
  args = self.parse_args(model.llama_index, window)
75
+ proxy = window.core.config.get("api_proxy", None)
54
76
  if "model" not in args:
55
77
  args["model"] = model.id
56
78
  if "api_key" not in args or args["api_key"] == "":
57
79
  args["api_key"] = window.core.config.get("api_key_anthropic", "")
58
- return Anthropic(**args)
80
+
81
+ return AnthropicWithProxy(**args, proxy=proxy)
59
82
 
60
83
  def get_embeddings_model(
61
84
  self,
@@ -69,7 +92,7 @@ class AnthropicLLM(BaseLLM):
69
92
  :param config: config keyword arguments list
70
93
  :return: Embedding provider instance
71
94
  """
72
- from llama_index.embeddings.voyageai import VoyageEmbedding
95
+ from .voyage import VoyageEmbeddingWithProxy
73
96
  args = {}
74
97
  if config is not None:
75
98
  args = self.parse_args({
@@ -81,7 +104,16 @@ class AnthropicLLM(BaseLLM):
81
104
  args["voyage_api_key"] = window.core.config.get("api_key_voyage", "")
82
105
  if "model" in args and "model_name" not in args:
83
106
  args["model_name"] = args.pop("model")
84
- return VoyageEmbedding(**args)
107
+
108
+ timeout = window.core.config.get("api_native_voyage.timeout")
109
+ max_retries = window.core.config.get("api_native_voyage.max_retries")
110
+ proxy = window.core.config.get("api_proxy")
111
+ return VoyageEmbeddingWithProxy(
112
+ **args,
113
+ proxy=proxy,
114
+ timeout=timeout,
115
+ max_retries=max_retries,
116
+ )
85
117
 
86
118
  def get_models(
87
119
  self,
@@ -104,4 +136,4 @@ class AnthropicLLM(BaseLLM):
104
136
  "id": item.id,
105
137
  "name": item.id,
106
138
  })
107
- return items
139
+ return items
@@ -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.08.26 19:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict
@@ -94,6 +94,7 @@ class AzureOpenAILLM(BaseLLM):
94
94
  args["api_key"] = window.core.config.get("api_key", "")
95
95
  if "model" not in args:
96
96
  args["model"] = model.id
97
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
97
98
  return LlamaAzureOpenAI(**args)
98
99
 
99
100
  def get_embeddings_model(
@@ -118,4 +119,5 @@ class AzureOpenAILLM(BaseLLM):
118
119
  args["api_key"] = window.core.config.get("api_key", "")
119
120
  if "model" in args and "model_name" not in args:
120
121
  args["model_name"] = args.pop("model")
122
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
121
123
  return AzureOpenAIEmbedding(**args)
@@ -6,12 +6,13 @@
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.08.28 09:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
13
  from typing import Optional, List, Dict
14
14
 
15
+ import httpx
15
16
  from llama_index.core.base.embeddings.base import BaseEmbedding
16
17
  from llama_index.core.llms.llm import BaseLLM as LlamaBaseLLM
17
18
  from llama_index.core.multi_modal_llms import MultiModalLLM as LlamaMultiModalLLM
@@ -226,3 +227,14 @@ class BaseLLM:
226
227
  mode=MODE_CHAT,
227
228
  model=model,
228
229
  )
230
+
231
+ def inject_llamaindex_http_clients(self, args: dict, cfg) -> dict:
232
+ import httpx
233
+ proxy = (cfg.get("api_proxy") or "").strip() # e.g. "http://user:pass@host:3128"
234
+ common_kwargs = dict(timeout=60.0, follow_redirects=True)
235
+ if proxy:
236
+ common_kwargs["proxy"] = proxy # httpx>=0.28
237
+
238
+ args["http_client"] = httpx.Client(**common_kwargs)
239
+ args["async_http_client"] = httpx.AsyncClient(**common_kwargs)
240
+ return args
@@ -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.08.26 19:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import List, Dict, Optional
@@ -49,6 +49,7 @@ class DeepseekApiLLM(BaseLLM):
49
49
  args["model"] = model.id
50
50
  if "api_key" not in args or args["api_key"] == "":
51
51
  args["api_key"] = window.core.config.get("api_key_deepseek", "")
52
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
52
53
  return DeepSeek(**args)
53
54
 
54
55
  def get_embeddings_model(
@@ -63,7 +64,7 @@ class DeepseekApiLLM(BaseLLM):
63
64
  :param config: config keyword arguments list
64
65
  :return: Embedding provider instance
65
66
  """
66
- from llama_index.embeddings.voyageai import VoyageEmbedding
67
+ from .voyage import VoyageEmbeddingWithProxy
67
68
  args = {}
68
69
  if config is not None:
69
70
  args = self.parse_args({
@@ -75,7 +76,16 @@ class DeepseekApiLLM(BaseLLM):
75
76
  args["voyage_api_key"] = window.core.config.get("api_key_voyage", "")
76
77
  if "model" in args and "model_name" not in args:
77
78
  args["model_name"] = args.pop("model")
78
- return VoyageEmbedding(**args)
79
+
80
+ timeout = window.core.config.get("api_native_voyage.timeout")
81
+ max_retries = window.core.config.get("api_native_voyage.max_retries")
82
+ proxy = window.core.config.get("api_proxy")
83
+ return VoyageEmbeddingWithProxy(
84
+ **args,
85
+ proxy=proxy,
86
+ timeout=timeout,
87
+ max_retries=max_retries,
88
+ )
79
89
 
80
90
  def get_models(
81
91
  self,
@@ -6,11 +6,12 @@
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.08.30 06:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict
13
13
 
14
+ from google.genai import types as gtypes
14
15
  from llama_index.core.llms.llm import BaseLLM as LlamaBaseLLM
15
16
  from llama_index.core.base.embeddings.base import BaseEmbedding
16
17
 
@@ -57,6 +58,7 @@ class GoogleLLM(BaseLLM):
57
58
  args["api_key"] = window.core.config.get("api_key_google", "")
58
59
 
59
60
  window.core.api.google.setup_env() # setup VertexAI if configured
61
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
60
62
  return GoogleGenAI(**args)
61
63
 
62
64
  def get_embeddings_model(
@@ -83,6 +85,7 @@ class GoogleLLM(BaseLLM):
83
85
  args["model_name"] = args.pop("model")
84
86
 
85
87
  window.core.api.google.setup_env() # setup VertexAI if configured
88
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
86
89
  return GoogleGenAIEmbedding(**args)
87
90
 
88
91
  def get_models(
@@ -105,3 +108,13 @@ class GoogleLLM(BaseLLM):
105
108
  "name": id, # TODO: token limit get from API
106
109
  })
107
110
  return items
111
+
112
+ def inject_llamaindex_http_clients(self, args: dict, cfg) -> dict:
113
+ proxy = cfg.get("api_proxy")
114
+ if proxy:
115
+ http_options = gtypes.HttpOptions(
116
+ client_args={"proxy": proxy},
117
+ async_client_args={"proxy": proxy},
118
+ )
119
+ args["http_options"] = http_options
120
+ return args
@@ -36,44 +36,125 @@ class HuggingFaceApiLLM(BaseLLM):
36
36
  stream: bool = False
37
37
  ) -> LlamaBaseLLM:
38
38
  """
39
- Return LLM provider instance for llama
40
-
41
- :param window: window instance
42
- :param model: model instance
43
- :param stream: stream mode
44
- :return: LLM provider instance
39
+ Return LLM provider instance for llama (Hugging Face Inference API) z obsługą proxy.
45
40
  """
46
- from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
41
+ from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI as LIHF
42
+
43
+ class HuggingFaceInferenceAPIWithProxy(LIHF):
44
+ def __init__(self, *, proxy=None, trust_env=None, **kwargs):
45
+ """
46
+ proxy: str or dict compatible with huggingface_hub (e.g. "http://user:pass@host:3128"
47
+ lub {"http": "...", "https": "..."})
48
+ trust_env: forAsyncInferenceClient (default False) - whether to trust environment variables
49
+ """
50
+ # alias: api_key -> token
51
+ if "api_key" in kwargs and "token" not in kwargs:
52
+ kwargs["token"] = kwargs.pop("api_key")
53
+
54
+ super().__init__(**kwargs)
55
+
56
+ if proxy is None and trust_env is None:
57
+ return
58
+
59
+ if isinstance(proxy, str):
60
+ hf_proxies = {"http": proxy, "https": proxy}
61
+ else:
62
+ hf_proxies = proxy
63
+
64
+ base_kwargs = {}
65
+ if hasattr(self, "_get_inference_client_kwargs"):
66
+ try:
67
+ base_kwargs = self._get_inference_client_kwargs() # type: ignore
68
+ except Exception:
69
+ base_kwargs = {}
70
+
71
+ # fallback
72
+ if not base_kwargs:
73
+ for src in ["model", "token", "timeout", "headers", "cookies", "base_url", "task"]:
74
+ if hasattr(self, src):
75
+ val = getattr(self, src)
76
+ if val not in (None, ""):
77
+ base_kwargs[src] = val
78
+
79
+ from huggingface_hub import InferenceClient, AsyncInferenceClient
80
+
81
+ sync_kwargs = dict(base_kwargs)
82
+ async_kwargs = dict(base_kwargs)
83
+ if hf_proxies is not None:
84
+ sync_kwargs["proxies"] = hf_proxies
85
+ async_kwargs["proxies"] = hf_proxies
86
+ if trust_env is not None:
87
+ async_kwargs["trust_env"] = trust_env # default False
88
+
89
+ sync_client = InferenceClient(**sync_kwargs)
90
+ async_client = AsyncInferenceClient(**async_kwargs)
91
+
92
+ for name, client in (("_client", sync_client), ("_sync_client", sync_client), ("client", sync_client)):
93
+ if hasattr(self, name):
94
+ setattr(self, name, client)
95
+ for name, client in (("_aclient", async_client), ("_async_client", async_client)):
96
+ if hasattr(self, name):
97
+ setattr(self, name, client)
98
+
99
+ cfg = window.core.config
47
100
  args = self.parse_args(model.llama_index, window)
101
+
102
+ # model
48
103
  if "model" not in args:
49
104
  args["model"] = model.id
50
- if "api_key" not in args or args["api_key"] == "":
51
- args["api_key"] = window.core.config.get("api_key_hugging_face", "")
52
- return HuggingFaceInferenceAPI(**args)
105
+
106
+ # token / api_key
107
+ if "token" not in args:
108
+ if "api_key" in args and args["api_key"]:
109
+ args["token"] = args.pop("api_key")
110
+ else:
111
+ args["token"] = cfg.get("api_key_hugging_face", "")
112
+
113
+ # Inference Endpoint / router
114
+ base_url = cfg.get("api_endpoint_hugging_face", "").strip()
115
+ if base_url and "base_url" not in args:
116
+ args["base_url"] = base_url
117
+
118
+ # proxy + trust_env (async)
119
+ proxy = cfg.get("api_proxy") or cfg.get("api_native_hf.proxy")
120
+ trust_env = cfg.get("api_native_hf.trust_env", False)
121
+
122
+ return HuggingFaceInferenceAPIWithProxy(proxy=proxy, trust_env=trust_env, **args)
53
123
 
54
124
  def get_embeddings_model(
55
125
  self,
56
126
  window,
57
127
  config: Optional[List[Dict]] = None
58
128
  ) -> BaseEmbedding:
59
- """
60
- Return provider instance for embeddings
129
+ from .hugging_face_embedding import (
130
+ HuggingFaceInferenceAPIEmbeddingWithProxy as HFEmbed,
131
+ )
61
132
 
62
- :param window: window instance
63
- :param config: config keyword arguments list
64
- :return: Embedding provider instance
65
- """
66
- from llama_index.embeddings.huggingface_api import HuggingFaceInferenceAPIEmbedding
67
- args = {}
133
+ args: Dict = {}
68
134
  if config is not None:
69
- args = self.parse_args({
70
- "args": config,
71
- }, window)
72
- if "api_key" not in args or args["api_key"] == "":
73
- args["api_key"] = window.core.config.get("api_key_hugging_face", "")
135
+ args = self.parse_args({"args": config}, window)
136
+
137
+ # token / api_key
138
+ if "token" not in args:
139
+ if "api_key" in args:
140
+ args["token"] = args.pop("api_key")
141
+ else:
142
+ args["token"] = window.core.config.get("api_key_hugging_face", "")
143
+
144
+ # model_name alias
74
145
  if "model" in args and "model_name" not in args:
75
146
  args["model_name"] = args.pop("model")
76
- return HuggingFaceInferenceAPIEmbedding(**args)
147
+
148
+ # Inference Endpoint / router
149
+ base_url = window.core.config.get("api_endpoint_hugging_face", "").strip()
150
+ if base_url and "base_url" not in args:
151
+ args["base_url"] = base_url
152
+
153
+ # proxy + trust_env (async)
154
+ proxy = window.core.config.get("api_proxy") or window.core.config.get("api_native_hf.proxy")
155
+ trust_env = window.core.config.get("api_native_hf.trust_env", False)
156
+
157
+ return HFEmbed(proxy=proxy, trust_env=trust_env, **args)
77
158
 
78
159
  def init_embeddings(
79
160
  self,
@@ -0,0 +1,88 @@
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.09.15 01:00:00 #
10
+ # ================================================== #
11
+
12
+ from typing import Optional, Dict, Any, Union
13
+
14
+ from llama_index.embeddings.huggingface_api import (
15
+ HuggingFaceInferenceAPIEmbedding as _HFEmbed,
16
+ )
17
+
18
+ class HuggingFaceInferenceAPIEmbeddingWithProxy(_HFEmbed):
19
+ def __init__(
20
+ self,
21
+ *,
22
+ proxy: Optional[Union[str, Dict[str, str]]] = None,
23
+ trust_env: Optional[bool] = None,
24
+ **kwargs: Any,
25
+ ) -> None:
26
+ """
27
+ proxy: e.g. "http://user:pass@host:3128" albo {"http": "...", "https": "..."}
28
+ trust_env: AsyncInferenceClient; if True, then use the system's proxy settings
29
+ """
30
+
31
+ if "api_key" in kwargs and "token" not in kwargs:
32
+ kwargs["token"] = kwargs.pop("api_key")
33
+ if "model" in kwargs and "model_name" not in kwargs:
34
+ kwargs["model_name"] = kwargs.pop("model")
35
+
36
+ super().__init__(**kwargs)
37
+
38
+ # if no proxy and no trust_env, then do nothing
39
+ if proxy is None and trust_env is None:
40
+ return
41
+
42
+ # dict proxies for huggingface_hub.*
43
+ hf_proxies: Optional[Union[str, Dict[str, str]]] = None
44
+ if proxy is not None:
45
+ hf_proxies = {"http": proxy, "https": proxy} if isinstance(proxy, str) else proxy
46
+
47
+ base_kwargs: Dict[str, Any] = {}
48
+
49
+ for src, dst in [
50
+ ("model_name", "model"),
51
+ ("token", "token"),
52
+ ("timeout", "timeout"),
53
+ ("headers", "headers"),
54
+ ("cookies", "cookies"),
55
+ ("base_url", "base_url"),
56
+ ]:
57
+ if hasattr(self, src):
58
+ val = getattr(self, src)
59
+ if val is not None and val != "":
60
+ base_kwargs[dst] = val
61
+
62
+ from huggingface_hub import InferenceClient, AsyncInferenceClient
63
+
64
+ sync_kwargs = dict(base_kwargs)
65
+ async_kwargs = dict(base_kwargs)
66
+
67
+ if hf_proxies is not None:
68
+ sync_kwargs["proxies"] = hf_proxies
69
+ async_kwargs["proxies"] = hf_proxies
70
+ if trust_env is not None:
71
+ async_kwargs["trust_env"] = trust_env # default False w AsyncInferenceClient
72
+
73
+ sync_client = InferenceClient(**sync_kwargs)
74
+ async_client = AsyncInferenceClient(**async_kwargs)
75
+
76
+ for name, client in (
77
+ ("_sync_client", sync_client),
78
+ ("_client", sync_client),
79
+ ):
80
+ if hasattr(self, name):
81
+ setattr(self, name, client)
82
+
83
+ for name, client in (
84
+ ("_async_client", async_client),
85
+ ("_aclient", async_client),
86
+ ):
87
+ if hasattr(self, name):
88
+ setattr(self, name, client)
@@ -6,10 +6,10 @@
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.08.26 19:00:00 #
9
+ # Updated Date: 2025.09.15 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
- from typing import Optional, List, Dict
12
+ from typing import Optional, List, Dict, Union
13
13
 
14
14
  from llama_index.core.llms.llm import BaseLLM as LlamaBaseLLM
15
15
  from llama_index.core.multi_modal_llms import MultiModalLLM as LlamaMultiModalLLM
@@ -82,6 +82,7 @@ class HuggingFaceRouterLLM(BaseLLM):
82
82
  args["model"] = model.id
83
83
  if "api_key" not in args or args["api_key"] == "":
84
84
  args["api_key"] = window.core.config.get("api_key_hugging_face", "")
85
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
85
86
  return OpenAILike(**args)
86
87
 
87
88
  def llama_multimodal(
@@ -105,24 +106,35 @@ class HuggingFaceRouterLLM(BaseLLM):
105
106
  window,
106
107
  config: Optional[List[Dict]] = None
107
108
  ) -> BaseEmbedding:
108
- """
109
- Return provider instance for embeddings
109
+ from .hugging_face_embedding import (
110
+ HuggingFaceInferenceAPIEmbeddingWithProxy as HFEmbed,
111
+ )
110
112
 
111
- :param window: window instance
112
- :param config: config keyword arguments list
113
- :return: Embedding provider instance
114
- """
115
- from llama_index.embeddings.huggingface_api import HuggingFaceInferenceAPIEmbedding
116
- args = {}
113
+ args: Dict = {}
117
114
  if config is not None:
118
- args = self.parse_args({
119
- "args": config,
120
- }, window)
121
- if "api_key" not in args or args["api_key"] == "":
122
- args["api_key"] = window.core.config.get("api_key_hugging_face", "")
115
+ args = self.parse_args({"args": config}, window)
116
+
117
+ # token / api_key
118
+ if "token" not in args:
119
+ if "api_key" in args:
120
+ args["token"] = args.pop("api_key")
121
+ else:
122
+ args["token"] = window.core.config.get("api_key_hugging_face", "")
123
+
124
+ # model_name alias
123
125
  if "model" in args and "model_name" not in args:
124
126
  args["model_name"] = args.pop("model")
125
- return HuggingFaceInferenceAPIEmbedding(**args)
127
+
128
+ # Inference Endpoint / router
129
+ base_url = window.core.config.get("api_endpoint_hugging_face", "").strip()
130
+ if base_url and "base_url" not in args:
131
+ args["base_url"] = base_url
132
+
133
+ # proxy + trust_env (async)
134
+ proxy = window.core.config.get("api_proxy") or window.core.config.get("api_native_hf.proxy")
135
+ trust_env = window.core.config.get("api_native_hf.trust_env", False)
136
+
137
+ return HFEmbed(proxy=proxy, trust_env=trust_env, **args)
126
138
 
127
139
  def get_models(
128
140
  self,
@@ -47,6 +47,7 @@ class LocalLLM(BaseLLM):
47
47
  }, window)
48
48
  if "model" in args and "model_name" not in args:
49
49
  args["model_name"] = args.pop("model")
50
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
50
51
  return OpenAILikeEmbedding(**args)
51
52
 
52
53
  def llama(
@@ -71,4 +72,5 @@ class LocalLLM(BaseLLM):
71
72
  args["is_chat_model"] = True
72
73
  if "is_function_calling_model" not in args:
73
74
  args["is_function_calling_model"] = model.tool_calls
75
+ args = self.inject_llamaindex_http_clients(args, window.core.config)
74
76
  return OpenAILike(**args)