pygpt-net 2.6.52__py3-none-any.whl → 2.6.54__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 (61) hide show
  1. pygpt_net/CHANGELOG.txt +11 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +4 -0
  4. pygpt_net/controller/audio/audio.py +22 -1
  5. pygpt_net/controller/chat/chat.py +5 -1
  6. pygpt_net/controller/chat/remote_tools.py +116 -0
  7. pygpt_net/controller/lang/mapping.py +2 -1
  8. pygpt_net/controller/mode/mode.py +5 -2
  9. pygpt_net/controller/plugins/plugins.py +29 -3
  10. pygpt_net/controller/realtime/realtime.py +8 -3
  11. pygpt_net/controller/ui/mode.py +17 -5
  12. pygpt_net/core/agents/provider.py +16 -9
  13. pygpt_net/core/models/models.py +25 -1
  14. pygpt_net/core/render/web/renderer.py +3 -1
  15. pygpt_net/data/config/config.json +5 -4
  16. pygpt_net/data/config/models.json +3 -3
  17. pygpt_net/data/icons/web_off.svg +1 -0
  18. pygpt_net/data/icons/web_on.svg +1 -0
  19. pygpt_net/data/js/app.js +19 -0
  20. pygpt_net/data/locale/locale.de.ini +1 -0
  21. pygpt_net/data/locale/locale.en.ini +3 -2
  22. pygpt_net/data/locale/locale.es.ini +1 -0
  23. pygpt_net/data/locale/locale.fr.ini +1 -0
  24. pygpt_net/data/locale/locale.it.ini +1 -0
  25. pygpt_net/data/locale/locale.pl.ini +1 -4
  26. pygpt_net/data/locale/locale.uk.ini +1 -0
  27. pygpt_net/data/locale/locale.zh.ini +1 -0
  28. pygpt_net/data/locale/plugin.mcp.en.ini +4 -4
  29. pygpt_net/data/locale/plugin.osm.en.ini +35 -0
  30. pygpt_net/data/locale/plugin.wolfram.en.ini +24 -0
  31. pygpt_net/icons.qrc +2 -0
  32. pygpt_net/icons_rc.py +232 -147
  33. pygpt_net/js_rc.py +10490 -10432
  34. pygpt_net/plugin/base/worker.py +7 -1
  35. pygpt_net/plugin/osm/__init__.py +12 -0
  36. pygpt_net/plugin/osm/config.py +267 -0
  37. pygpt_net/plugin/osm/plugin.py +87 -0
  38. pygpt_net/plugin/osm/worker.py +719 -0
  39. pygpt_net/plugin/wolfram/__init__.py +12 -0
  40. pygpt_net/plugin/wolfram/config.py +214 -0
  41. pygpt_net/plugin/wolfram/plugin.py +115 -0
  42. pygpt_net/plugin/wolfram/worker.py +551 -0
  43. pygpt_net/provider/api/anthropic/tools.py +4 -2
  44. pygpt_net/provider/api/google/__init__.py +3 -2
  45. pygpt_net/provider/api/google/video.py +0 -0
  46. pygpt_net/provider/api/openai/agents/experts.py +1 -1
  47. pygpt_net/provider/api/openai/agents/remote_tools.py +14 -4
  48. pygpt_net/provider/api/openai/chat.py +7 -2
  49. pygpt_net/provider/api/openai/remote_tools.py +5 -2
  50. pygpt_net/provider/api/x_ai/remote.py +6 -1
  51. pygpt_net/provider/core/config/patch.py +8 -1
  52. pygpt_net/provider/llms/anthropic.py +29 -1
  53. pygpt_net/provider/llms/google.py +30 -1
  54. pygpt_net/provider/llms/open_router.py +3 -1
  55. pygpt_net/provider/llms/x_ai.py +21 -1
  56. pygpt_net/ui/layout/chat/output.py +7 -2
  57. {pygpt_net-2.6.52.dist-info → pygpt_net-2.6.54.dist-info}/METADATA +37 -2
  58. {pygpt_net-2.6.52.dist-info → pygpt_net-2.6.54.dist-info}/RECORD +60 -47
  59. {pygpt_net-2.6.52.dist-info → pygpt_net-2.6.54.dist-info}/LICENSE +0 -0
  60. {pygpt_net-2.6.52.dist-info → pygpt_net-2.6.54.dist-info}/WHEEL +0 -0
  61. {pygpt_net-2.6.52.dist-info → pygpt_net-2.6.54.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.07.30 00:00:00 #
9
+ # Updated Date: 2025.09.17 05:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -87,10 +87,11 @@ class RemoteTools:
87
87
  "file_search": False,
88
88
  "computer_use": False,
89
89
  }
90
+ enabled_global = self.window.controller.chat.remote_tools.enabled # get global config
90
91
 
91
92
  # from global config if not expert call
92
93
  if not is_expert_call:
93
- enabled["web_search"] = self.window.core.config.get("remote_tools.web_search", False)
94
+ enabled["web_search"] = enabled_global(model, "web_search") # <-- from global config
94
95
  enabled["image"] = self.window.core.config.get("remote_tools.image", False)
95
96
  enabled["code_interpreter"] = self.window.core.config.get("remote_tools.code_interpreter", False)
96
97
  enabled["mcp"] = self.window.core.config.get("remote_tools.mcp", False)
@@ -101,6 +102,8 @@ class RemoteTools:
101
102
  if preset:
102
103
  if preset.remote_tools:
103
104
  tools_list = [preset_remote_tool.strip() for preset_remote_tool in preset.remote_tools.split(",") if preset_remote_tool.strip()]
105
+ if "web_search" not in tools_list:
106
+ enabled["web_search"] = enabled_global(model, "web_search") # <-- from global config
104
107
  for item in tools_list:
105
108
  if item in enabled:
106
109
  enabled[item] = True
@@ -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.17 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from __future__ import annotations
@@ -57,11 +57,16 @@ class Remote:
57
57
  :return: Dict with 'sdk' and 'http' keys
58
58
  """
59
59
  cfg = self.window.core.config
60
+ is_web = self.window.controller.chat.remote_tools.enabled(model, "web_search") # get global config
60
61
 
61
62
  mode = str(cfg.get("remote_tools.xai.mode") or "auto").lower()
62
63
  if mode not in ("auto", "on", "off"):
63
64
  mode = "auto"
64
65
 
66
+ if mode == "off":
67
+ if is_web:
68
+ mode = "on" # override off if global web_search enabled
69
+
65
70
  # sources toggles
66
71
  s_web = bool(cfg.get("remote_tools.xai.sources.web", True))
67
72
  s_x = bool(cfg.get("remote_tools.xai.sources.x", True))
@@ -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.16 11:00:00 #
9
+ # Updated Date: 2025.09.17 05:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -104,6 +104,13 @@ class Patch:
104
104
  patch_css('style.dark.css', True)
105
105
  updated = True
106
106
 
107
+ # < 2.6.53
108
+ if old < parse_version("2.6.53"):
109
+ print("Migrating config from < 2.6.53...")
110
+ if "remote_tools.global.web_search" not in data:
111
+ data["remote_tools.global.web_search"] = True
112
+ updated = True
113
+
107
114
  # update file
108
115
  migrated = False
109
116
  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.09.15 01:00:00 #
9
+ # Updated Date: 2025.09.17 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import List, Dict, Optional
@@ -78,6 +78,34 @@ class AnthropicLLM(BaseLLM):
78
78
  if "api_key" not in args or args["api_key"] == "":
79
79
  args["api_key"] = window.core.config.get("api_key_anthropic", "")
80
80
 
81
+ # ---------------------------------------------
82
+ # Remote server tools (e.g., web_search_20250305)
83
+ # We forward provider-native server tools via Anthropic "tools" param.
84
+ # This keeps behavior identical to the native SDK configuration.
85
+ # ---------------------------------------------
86
+ try:
87
+ remote_tools = window.core.api.anthropic.tools.build_remote_tools(model=model) or []
88
+ except Exception as e:
89
+ # Do not break if config builder throws; just skip tools
90
+ window.core.debug.log(e)
91
+ remote_tools = []
92
+
93
+ if remote_tools:
94
+ # Merge with any user-supplied 'tools' (avoid duplicates by (type, name))
95
+ existing = args.get("tools") or []
96
+ if isinstance(existing, list):
97
+ def _key(d: dict) -> str:
98
+ return f"{d.get('type')}::{d.get('name')}"
99
+ index = {_key(t): True for t in existing if isinstance(t, dict)}
100
+ for t in remote_tools:
101
+ k = _key(t) if isinstance(t, dict) else None
102
+ if k and k not in index:
103
+ existing.append(t)
104
+ args["tools"] = existing
105
+ else:
106
+ # Defensive: if 'tools' was something unexpected, overwrite safely
107
+ args["tools"] = list(remote_tools)
108
+
81
109
  return AnthropicWithProxy(**args, proxy=proxy)
82
110
 
83
111
  def get_embeddings_model(
@@ -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.15 01:00:00 #
9
+ # Updated Date: 2025.09.17 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict
@@ -59,6 +59,35 @@ class GoogleLLM(BaseLLM):
59
59
 
60
60
  window.core.api.google.setup_env() # setup VertexAI if configured
61
61
  args = self.inject_llamaindex_http_clients(args, window.core.config)
62
+
63
+ # -----------------------------------------------------------
64
+ # Remote built-in tools for Google GenAI via LlamaIndex:
65
+ # - Google Search grounding (Tool(google_search=GoogleSearch()))
66
+ # - Code Execution (Tool(code_execution=ToolCodeExecution()))
67
+ # - Url Context (Tool(url_context=UrlContext)) on 2.x+
68
+ # We reuse native builder and forward tools into LlamaIndex.
69
+ # If 1 tool -> use 'built_in_tool', if >1 -> pack into generation_config.tools
70
+ # -----------------------------------------------------------
71
+ built_tools = []
72
+ try:
73
+ built_tools = window.core.api.google.build_remote_tools(model=model) or []
74
+ except Exception as e:
75
+ window.core.debug.log(e)
76
+
77
+ if built_tools:
78
+ # Only attach if user didn't already pass their own config
79
+ if "built_in_tool" not in args and "generation_config" not in args:
80
+ if len(built_tools) == 1:
81
+ args["built_in_tool"] = built_tools[0]
82
+ else:
83
+ # If multiple tools are enabled, provide them via generation_config.tools
84
+ try:
85
+ args["generation_config"] = gtypes.GenerateContentConfig(tools=built_tools)
86
+ except Exception as e:
87
+ # Fallback to the first tool if GenerateContentConfig cannot be constructed
88
+ window.core.debug.log(e)
89
+ args["built_in_tool"] = built_tools[0]
90
+
62
91
  return GoogleGenAI(**args)
63
92
 
64
93
  def get_embeddings_model(
@@ -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.15 01:00:00 #
9
+ # Updated Date: 2025.09.17 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, Dict, List
@@ -82,6 +82,8 @@ class OpenRouterLLM(BaseLLM):
82
82
  if "is_function_calling_model" not in args:
83
83
  args["is_function_calling_model"] = model.tool_calls
84
84
  args = self.inject_llamaindex_http_clients(args, window.core.config)
85
+ if model:
86
+ args["model"] = window.core.models.get_openrouter_model(model)
85
87
  return OpenAILike(**args)
86
88
 
87
89
  def get_models(
@@ -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.15 01:00:00 #
9
+ # Updated Date: 2025.09.17 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict
@@ -89,6 +89,26 @@ class xAILLM(BaseLLM):
89
89
  if "is_function_calling_model" not in args:
90
90
  args["is_function_calling_model"] = model.tool_calls
91
91
  args = self.inject_llamaindex_http_clients(args, window.core.config)
92
+
93
+ # -----------------------------------------------------------
94
+ # xAI Live Search via search_parameters (Chat Completions)
95
+ # LlamaIndex OpenAILike supports 'additional_kwargs' passed to request body.
96
+ # -----------------------------------------------------------
97
+ try:
98
+ xai_remote = window.core.api.xai.remote.build(model=model) or {}
99
+ except Exception as e:
100
+ window.core.debug.log(e)
101
+ xai_remote = {}
102
+
103
+ search_http = xai_remote.get("http")
104
+ if search_http:
105
+ add_kwargs = dict(args.get("additional_kwargs") or {})
106
+ extra_body = dict(add_kwargs.get("extra_body") or {})
107
+ # Do not overwrite if user already set search_parameters manually
108
+ extra_body.setdefault("search_parameters", search_http)
109
+ add_kwargs["extra_body"] = extra_body
110
+ args["additional_kwargs"] = add_kwargs
111
+
92
112
  return OpenAILike(**args)
93
113
 
94
114
  def llama_multimodal(
@@ -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.24 23:00:00 #
9
+ # Updated Date: 2025.09.17 07:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
@@ -72,7 +72,7 @@ class Output:
72
72
 
73
73
  nodes['icon.audio.output'] = IconLabel(":/icons/volume.svg", window=self.window)
74
74
  nodes['icon.audio.output'].setToolTip(trans("icon.audio.output"))
75
- nodes['icon.audio.output'].clicked.connect(lambda: ctrl.plugins.toggle('audio_output'))
75
+ nodes['icon.audio.output'].clicked.connect(lambda: ctrl.plugins.toggle_audio_output()) # special case for AUDIO mode
76
76
 
77
77
  nodes['icon.audio.input'] = IconLabel(":/icons/mic.svg", window=self.window)
78
78
  nodes['icon.audio.input'].setToolTip(trans("icon.audio.input"))
@@ -86,6 +86,10 @@ class Output:
86
86
  nodes['icon.indexer'].setToolTip("Indexer")
87
87
  nodes['icon.indexer'].clicked.connect(lambda: tools.get("indexer").toggle())
88
88
 
89
+ nodes['icon.remote_tool.web'] = IconLabel(":/icons/web_on.svg", window=self.window)
90
+ nodes['icon.remote_tool.web'].setToolTip(trans("icon.remote_tool.web"))
91
+ nodes['icon.remote_tool.web'].clicked.connect(lambda: ctrl.chat.remote_tools.toggle('web_search'))
92
+
89
93
  min_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
90
94
 
91
95
  nodes['chat.label'] = ChatStatusLabel("")
@@ -135,6 +139,7 @@ class Output:
135
139
  nodes['anim.loading'].hide()
136
140
 
137
141
  right_bar_layout = QHBoxLayout()
142
+ right_bar_layout.addWidget(nodes['icon.remote_tool.web'])
138
143
  right_bar_layout.addWidget(nodes['icon.video.capture'])
139
144
  right_bar_layout.addWidget(nodes['icon.audio.input'])
140
145
  right_bar_layout.addWidget(nodes['icon.audio.output'])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pygpt-net
3
- Version: 2.6.52
3
+ Version: 2.6.54
4
4
  Summary: Desktop AI Assistant powered by: OpenAI GPT-5, GPT-4, o1, o3, Gemini, Claude, Grok, DeepSeek, and other models supported by Llama Index, and Ollama. Chatbot, agents, completion, image generation, vision analysis, speech-to-text, plugins, MCP, internet access, file handling, command execution and more.
5
5
  License: MIT
6
6
  Keywords: ai,api,api key,app,assistant,bielik,chat,chatbot,chatgpt,claude,dall-e,deepseek,desktop,gemini,gpt,gpt-3.5,gpt-4,gpt-4-vision,gpt-4o,gpt-5,gpt-oss,gpt3.5,gpt4,grok,langchain,llama-index,llama3,mistral,o1,o3,ollama,openai,presets,py-gpt,py_gpt,pygpt,pyside,qt,text completion,tts,ui,vision,whisper
@@ -119,7 +119,7 @@ Description-Content-Type: text/markdown
119
119
 
120
120
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
121
121
 
122
- Release: **2.6.52** | build: **2025-09-17** | Python: **>=3.10, <3.14**
122
+ Release: **2.6.54** | build: **2025-09-18** | Python: **>=3.10, <3.14**
123
123
 
124
124
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
125
125
  >
@@ -1450,6 +1450,8 @@ The following plugins are currently available, and model can use them instantly:
1450
1450
 
1451
1451
  - `Mouse and Keyboard` - provides the ability to control the mouse and keyboard by the model.
1452
1452
 
1453
+ - `OpenStreetMap` - Search, geocode, plan routes, and generate static maps using OpenStreetMap services (Nominatim, OSRM, staticmap).
1454
+
1453
1455
  - `Real Time` - automatically appends the current date and time to the system prompt, informing the model about current time.
1454
1456
 
1455
1457
  - `Serial port / USB` - plugin provides commands for reading and sending data to USB ports.
@@ -1474,6 +1476,8 @@ The following plugins are currently available, and model can use them instantly:
1474
1476
 
1475
1477
  - `Wikipedia` - Search Wikipedia for information.
1476
1478
 
1479
+ - `Wolfram Alpha` - Compute and solve with Wolfram Alpha: short answers, full JSON pods, math (solve, derivatives, integrals), unit conversions, matrix operations, and plots.
1480
+
1477
1481
  - `X/Twitter` - Interact with tweets and users, manage bookmarks and media, perform likes, retweets, and more.
1478
1482
 
1479
1483
 
@@ -1795,6 +1799,20 @@ Plugin capabilities include:
1795
1799
 
1796
1800
  Documentation: https://pygpt.readthedocs.io/en/latest/plugins.html#mouse-and-keyboard
1797
1801
 
1802
+ ## OpenStreetMap
1803
+
1804
+ Provides everyday mapping utilities using OpenStreetMap services:
1805
+
1806
+ - Forward and reverse geocoding via Nominatim
1807
+ - Search with optional near/bbox filters
1808
+ - Routing via OSRM (driving, walking, cycling)
1809
+ - Generate openstreetmap.org URL (center/zoom or bbox; optional marker)
1810
+ - Utility helpers: open an OSM website URL centered on a point; download a single XYZ tile
1811
+
1812
+ Images are saved under `data/openstreetmap/` in the user data directory.
1813
+
1814
+ Documentation: https://pygpt.readthedocs.io/en/latest/plugins.html#openstreetmap
1815
+
1798
1816
  ## Real Time
1799
1817
 
1800
1818
  This plugin automatically adds the current date and time to each system prompt you send.
@@ -1918,6 +1936,12 @@ The Wikipedia plugin allows for comprehensive interactions with Wikipedia, inclu
1918
1936
 
1919
1937
  Documentation: https://pygpt.readthedocs.io/en/latest/plugins.html#wikipedia
1920
1938
 
1939
+ ## Wolfram Alpha
1940
+
1941
+ Provides computational knowledge via Wolfram Alpha: short answers, full JSON pods, numeric and symbolic math (solve, derivatives, integrals), unit conversions, matrix operations, and plots rendered as images. Images are saved under `data/wolframalpha/` in the user data directory.
1942
+
1943
+ Documentation: https://pygpt.readthedocs.io/en/latest/plugins.html#wolfram-alpha
1944
+
1921
1945
  ## X/Twitter
1922
1946
 
1923
1947
  The X/Twitter plugin integrates with the X platform, allowing for comprehensive interactions such as tweeting, retweeting, liking, media uploads, and more. This plugin requires OAuth2 authentication and offers various configuration options to manage API interactions effectively.
@@ -3622,6 +3646,17 @@ may consume additional tokens that are not displayed in the main window.
3622
3646
 
3623
3647
  ## Recent changes:
3624
3648
 
3649
+ **2.6.54 (2025-09-18)**
3650
+
3651
+ - Added: Remote tools (like web search) are now also available in the Chat with Files and Agents (LlamaIndex) modes.
3652
+ - Added: Two new plugins: Wolfram Alpha and OpenStreetMap.
3653
+ - Fixed: Enabled local file-like schemes in links/images in the markdown-it parser.
3654
+
3655
+ **2.6.53 (2025-09-17)**
3656
+
3657
+ - Added: An icon to enable/disable the web search remote tool in the icon bar, along with remote web search functionality in OpenRouter (#135).
3658
+ - Added: The ability to mute audio in real-time mode via the audio icon.
3659
+
3625
3660
  **2.6.52 (2025-09-17)**
3626
3661
 
3627
3662
  - Added MCP plugin: Provides access to remote tools via the Model Context Protocol (MCP), including stdio, SSE, and Streamable HTTP transports, with per-server allow/deny filtering, Authorization header support, and a tools cache.