pygpt-net 2.6.1__py3-none-any.whl → 2.6.2__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 +4 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +15 -1
  4. pygpt_net/controller/chat/response.py +5 -3
  5. pygpt_net/controller/chat/stream.py +40 -2
  6. pygpt_net/controller/plugins/plugins.py +25 -0
  7. pygpt_net/controller/presets/editor.py +33 -88
  8. pygpt_net/controller/presets/experts.py +20 -1
  9. pygpt_net/controller/presets/presets.py +2 -2
  10. pygpt_net/controller/ui/mode.py +17 -66
  11. pygpt_net/core/agents/runner.py +15 -7
  12. pygpt_net/core/experts/experts.py +3 -3
  13. pygpt_net/data/config/config.json +3 -3
  14. pygpt_net/data/config/models.json +3 -3
  15. pygpt_net/data/locale/locale.de.ini +2 -0
  16. pygpt_net/data/locale/locale.en.ini +2 -0
  17. pygpt_net/data/locale/locale.es.ini +2 -0
  18. pygpt_net/data/locale/locale.fr.ini +2 -0
  19. pygpt_net/data/locale/locale.it.ini +2 -0
  20. pygpt_net/data/locale/locale.pl.ini +3 -1
  21. pygpt_net/data/locale/locale.uk.ini +2 -0
  22. pygpt_net/data/locale/locale.zh.ini +2 -0
  23. pygpt_net/plugin/base/plugin.py +35 -3
  24. pygpt_net/plugin/bitbucket/__init__.py +12 -0
  25. pygpt_net/plugin/bitbucket/config.py +267 -0
  26. pygpt_net/plugin/bitbucket/plugin.py +125 -0
  27. pygpt_net/plugin/bitbucket/worker.py +569 -0
  28. pygpt_net/plugin/facebook/__init__.py +12 -0
  29. pygpt_net/plugin/facebook/config.py +359 -0
  30. pygpt_net/plugin/facebook/plugin.py +114 -0
  31. pygpt_net/plugin/facebook/worker.py +698 -0
  32. pygpt_net/plugin/github/__init__.py +12 -0
  33. pygpt_net/plugin/github/config.py +441 -0
  34. pygpt_net/plugin/github/plugin.py +124 -0
  35. pygpt_net/plugin/github/worker.py +674 -0
  36. pygpt_net/plugin/google/__init__.py +12 -0
  37. pygpt_net/plugin/google/config.py +367 -0
  38. pygpt_net/plugin/google/plugin.py +126 -0
  39. pygpt_net/plugin/google/worker.py +826 -0
  40. pygpt_net/plugin/slack/__init__.py +12 -0
  41. pygpt_net/plugin/slack/config.py +349 -0
  42. pygpt_net/plugin/slack/plugin.py +116 -0
  43. pygpt_net/plugin/slack/worker.py +639 -0
  44. pygpt_net/plugin/telegram/__init__.py +12 -0
  45. pygpt_net/plugin/telegram/config.py +308 -0
  46. pygpt_net/plugin/telegram/plugin.py +118 -0
  47. pygpt_net/plugin/telegram/worker.py +563 -0
  48. pygpt_net/plugin/twitter/__init__.py +12 -0
  49. pygpt_net/plugin/twitter/config.py +491 -0
  50. pygpt_net/plugin/twitter/plugin.py +126 -0
  51. pygpt_net/plugin/twitter/worker.py +837 -0
  52. pygpt_net/provider/agents/llama_index/legacy/openai_assistant.py +35 -3
  53. pygpt_net/ui/base/config_dialog.py +4 -0
  54. pygpt_net/ui/dialog/preset.py +34 -77
  55. pygpt_net/ui/layout/toolbox/presets.py +2 -2
  56. pygpt_net/ui/main.py +3 -1
  57. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.2.dist-info}/METADATA +145 -2
  58. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.2.dist-info}/RECORD +61 -33
  59. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.2.dist-info}/LICENSE +0 -0
  60. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.2.dist-info}/WHEEL +0 -0
  61. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,359 @@
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.08.14 00:00:00 #
10
+ # ================================================== #
11
+
12
+ from pygpt_net.plugin.base.config import BaseConfig, BasePlugin
13
+
14
+
15
+ class Config(BaseConfig):
16
+ def __init__(self, plugin: BasePlugin = None, *args, **kwargs):
17
+ super(Config, self).__init__(plugin)
18
+ self.plugin = plugin
19
+
20
+ def from_defaults(self, plugin: BasePlugin = None):
21
+ # Endpoints / HTTP
22
+ plugin.add_option(
23
+ "graph_version",
24
+ type="text",
25
+ value="v21.0",
26
+ label="Graph API version",
27
+ description="API version (e.g. v21.0).",
28
+ )
29
+ plugin.add_option(
30
+ "api_base",
31
+ type="text",
32
+ value="https://graph.facebook.com",
33
+ label="API base",
34
+ description="Base API host (Graph API). Version is appended automatically.",
35
+ )
36
+ plugin.add_option(
37
+ "authorize_base",
38
+ type="text",
39
+ value="https://www.facebook.com",
40
+ label="Authorize base",
41
+ description="Base for OAuth authorize (Login dialog). Version is appended automatically.",
42
+ )
43
+ plugin.add_option(
44
+ "http_timeout",
45
+ type="int",
46
+ value=30,
47
+ label="HTTP timeout (s)",
48
+ description="Requests timeout in seconds.",
49
+ )
50
+
51
+ # OAuth2 (PKCE)
52
+ plugin.add_option(
53
+ "oauth2_client_id",
54
+ type="text",
55
+ value="",
56
+ label="App ID (client_id)",
57
+ description="Facebook App ID.",
58
+ secret=False,
59
+ )
60
+ plugin.add_option(
61
+ "oauth2_client_secret",
62
+ type="text",
63
+ value="",
64
+ label="App Secret (optional)",
65
+ description="Needed for long-lived token exchange and if not using PKCE.",
66
+ secret=True,
67
+ )
68
+ plugin.add_option(
69
+ "oauth2_confidential",
70
+ type="bool",
71
+ value=False,
72
+ label="Confidential client (use client_secret on exchange)",
73
+ description="If enabled, code exchange includes client_secret instead of code_verifier.",
74
+ )
75
+ plugin.add_option(
76
+ "oauth2_redirect_uri",
77
+ type="text",
78
+ value="http://127.0.0.1:8732/callback",
79
+ label="Redirect URI",
80
+ description="Must exactly match one of the Valid OAuth Redirect URIs in your Meta App.",
81
+ )
82
+ plugin.add_option(
83
+ "oauth2_scopes",
84
+ type="text",
85
+ value="public_profile pages_show_list pages_read_engagement pages_manage_posts pages_read_user_content openid",
86
+ label="Scopes",
87
+ description="Space-separated permissions for Authorization Code (PKCE).",
88
+ )
89
+ plugin.add_option(
90
+ "oauth2_code_verifier",
91
+ type="text",
92
+ value="",
93
+ label="(auto) code_verifier",
94
+ description="Generated by fb_oauth_begin.",
95
+ secret=True,
96
+ )
97
+ plugin.add_option(
98
+ "oauth2_state",
99
+ type="text",
100
+ value="",
101
+ label="(auto) state",
102
+ description="Generated by fb_oauth_begin.",
103
+ secret=True,
104
+ )
105
+ plugin.add_option(
106
+ "oauth2_nonce",
107
+ type="text",
108
+ value="",
109
+ label="(auto) nonce",
110
+ description="Generated by fb_oauth_begin (OIDC).",
111
+ secret=True,
112
+ )
113
+ plugin.add_option(
114
+ "oauth2_access_token",
115
+ type="textarea",
116
+ value="",
117
+ label="(auto) User access token",
118
+ description="Stored user access token.",
119
+ secret=True,
120
+ )
121
+ plugin.add_option(
122
+ "oauth2_expires_at",
123
+ type="text",
124
+ value="0",
125
+ label="(auto) Expires at (unix)",
126
+ description="Auto-calculated expiry time.",
127
+ secret=False,
128
+ )
129
+
130
+ # Convenience cache
131
+ plugin.add_option(
132
+ "user_id",
133
+ type="text",
134
+ value="",
135
+ label="(auto) User ID",
136
+ description="Cached after fb_me or oauth exchange.",
137
+ )
138
+ plugin.add_option(
139
+ "user_name",
140
+ type="text",
141
+ value="",
142
+ label="(auto) User name",
143
+ description="Cached after fb_me or oauth exchange.",
144
+ )
145
+ plugin.add_option(
146
+ "fb_page_id",
147
+ type="text",
148
+ value="",
149
+ label="(auto) Default Page ID",
150
+ description="Chosen by fb_page_set_default.",
151
+ )
152
+ plugin.add_option(
153
+ "fb_page_name",
154
+ type="text",
155
+ value="",
156
+ label="(auto) Default Page name",
157
+ description="Chosen by fb_page_set_default.",
158
+ )
159
+ plugin.add_option(
160
+ "fb_page_access_token",
161
+ type="textarea",
162
+ value="",
163
+ label="(auto) Default Page access token",
164
+ description="Cached via fb_page_set_default or on demand.",
165
+ secret=True,
166
+ )
167
+
168
+ # OAuth UX
169
+ plugin.add_option(
170
+ "oauth_auto_begin",
171
+ type="bool",
172
+ value=True,
173
+ label="Auto-start OAuth when required",
174
+ description="If a command needs user token, begin PKCE flow automatically.",
175
+ )
176
+ plugin.add_option(
177
+ "oauth_open_browser",
178
+ type="bool",
179
+ value=True,
180
+ label="Open browser automatically",
181
+ description="Open authorize URL in default browser.",
182
+ )
183
+ plugin.add_option(
184
+ "oauth_local_server",
185
+ type="bool",
186
+ value=True,
187
+ label="Use local server for OAuth",
188
+ description="Start local HTTP server to capture redirect.",
189
+ )
190
+ plugin.add_option(
191
+ "oauth_local_timeout",
192
+ type="int",
193
+ value=180,
194
+ label="OAuth local timeout (s)",
195
+ description="How long to wait for redirect with code.",
196
+ )
197
+ plugin.add_option(
198
+ "oauth_success_html",
199
+ type="textarea",
200
+ value="<html><body><h3>Authorization complete. You can close this window.</h3></body></html>",
201
+ label="Success HTML",
202
+ description="HTML shown on local callback success.",
203
+ )
204
+ plugin.add_option(
205
+ "oauth_fail_html",
206
+ type="textarea",
207
+ value="<html><body><h3>Authorization failed.</h3></body></html>",
208
+ label="Fail HTML",
209
+ description="HTML shown on local callback error.",
210
+ )
211
+ plugin.add_option(
212
+ "oauth_local_port",
213
+ type="int",
214
+ value=8732,
215
+ label="OAuth local port (0=auto)",
216
+ description="Local HTTP port for callback; use >1024. Must be allowed in App.",
217
+ )
218
+ plugin.add_option(
219
+ "oauth_allow_port_fallback",
220
+ type="bool",
221
+ value=True,
222
+ label="Allow fallback port if busy",
223
+ description="If preferred port is busy/forbidden, pick a free local port.",
224
+ )
225
+
226
+ # ---------------- Commands ----------------
227
+
228
+ # Auth
229
+ plugin.add_cmd(
230
+ "fb_oauth_begin",
231
+ instruction="Begin OAuth2 (PKCE) flow (returns authorize URL).",
232
+ params=[
233
+ {"name": "scopes", "type": "str", "required": False, "description": "Override permissions (space-separated)"},
234
+ {"name": "state", "type": "str", "required": False, "description": "Optional CSRF state"},
235
+ ],
236
+ enabled=True,
237
+ description="Auth: begin OAuth2",
238
+ tab="auth",
239
+ )
240
+ plugin.add_cmd(
241
+ "fb_oauth_exchange",
242
+ instruction="Exchange authorization code for user access token.",
243
+ params=[
244
+ {"name": "code", "type": "str", "required": True, "description": "Authorization code"},
245
+ {"name": "state", "type": "str", "required": False, "description": "State (if used)"},
246
+ ],
247
+ enabled=True,
248
+ description="Auth: exchange code",
249
+ tab="auth",
250
+ )
251
+ plugin.add_cmd(
252
+ "fb_token_extend",
253
+ instruction="Exchange short-lived user token for long-lived token (requires app secret).",
254
+ params=[],
255
+ enabled=True,
256
+ description="Auth: extend user token",
257
+ tab="auth",
258
+ )
259
+
260
+ # Me
261
+ plugin.add_cmd(
262
+ "fb_me",
263
+ instruction="Get authorized user profile.",
264
+ params=[
265
+ {"name": "fields", "type": "str", "required": False, "description": "Default: id,name"},
266
+ ],
267
+ enabled=True,
268
+ description="Users: me",
269
+ tab="users",
270
+ )
271
+
272
+ # Pages
273
+ plugin.add_cmd(
274
+ "fb_pages_list",
275
+ instruction="List Pages I manage (id,name,access_token,tasks).",
276
+ params=[
277
+ {"name": "fields", "type": "str", "required": False, "description": "Default: id,name,access_token,tasks"},
278
+ {"name": "limit", "type": "int", "required": False, "description": "Default 25"},
279
+ {"name": "after", "type": "str", "required": False, "description": "Paging cursor"},
280
+ {"name": "before", "type": "str", "required": False, "description": "Paging cursor"},
281
+ ],
282
+ enabled=True,
283
+ description="Pages: list",
284
+ tab="pages",
285
+ )
286
+ plugin.add_cmd(
287
+ "fb_page_set_default",
288
+ instruction="Set default Page (caches name and access token).",
289
+ params=[
290
+ {"name": "page_id", "type": "str", "required": True, "description": "Page ID"},
291
+ {"name": "fetch_token", "type": "bool", "required": False, "description": "Fetch and cache page access token"},
292
+ ],
293
+ enabled=True,
294
+ description="Pages: set default",
295
+ tab="pages",
296
+ )
297
+
298
+ # Posts
299
+ plugin.add_cmd(
300
+ "fb_page_posts",
301
+ instruction="Get Page feed (posts).",
302
+ params=[
303
+ {"name": "page_id", "type": "str", "required": False, "description": "Defaults to selected page"},
304
+ {"name": "fields", "type": "str", "required": False, "description": "Default: id,message,created_time,permalink_url,is_published"},
305
+ {"name": "limit", "type": "int", "required": False, "description": "Default 25"},
306
+ {"name": "since", "type": "str", "required": False, "description": "Unix or ISO8601"},
307
+ {"name": "until", "type": "str", "required": False, "description": "Unix or ISO8601"},
308
+ {"name": "after", "type": "str", "required": False, "description": "Paging cursor"},
309
+ {"name": "before", "type": "str", "required": False, "description": "Paging cursor"},
310
+ ],
311
+ enabled=True,
312
+ description="Posts: list",
313
+ tab="posts",
314
+ )
315
+ plugin.add_cmd(
316
+ "fb_page_post_create",
317
+ instruction="Publish a Page post (text/link and optional photos).",
318
+ params=[
319
+ {"name": "page_id", "type": "str", "required": False, "description": "Defaults to selected page"},
320
+ {"name": "message", "type": "str", "required": False, "description": "Post text"},
321
+ {"name": "link", "type": "str", "required": False, "description": "URL link"},
322
+ {"name": "published", "type": "bool", "required": False, "description": "Default true"},
323
+ {"name": "scheduled_publish_time", "type": "str", "required": False, "description": "Unix seconds or ISO8601 (requires published=false)"},
324
+ {"name": "media_fbids", "type": "list", "required": False, "description": "Photo IDs uploaded earlier"},
325
+ {"name": "photo_urls", "type": "list", "required": False, "description": "Auto-upload URLs (unpublished then attach)"},
326
+ {"name": "photo_paths", "type": "list", "required": False, "description": "Auto-upload local files (unpublished then attach)"},
327
+ {"name": "targeting", "type": "dict", "required": False, "description": "Audience targeting object"},
328
+ ],
329
+ enabled=True,
330
+ description="Posts: create",
331
+ tab="posts",
332
+ )
333
+ plugin.add_cmd(
334
+ "fb_page_post_delete",
335
+ instruction="Delete a Page post.",
336
+ params=[
337
+ {"name": "post_id", "type": "str", "required": True, "description": "Page post ID (e.g. {pageid}_{postid})"},
338
+ ],
339
+ enabled=True,
340
+ description="Posts: delete",
341
+ tab="posts",
342
+ )
343
+
344
+ # Media
345
+ plugin.add_cmd(
346
+ "fb_page_photo_upload",
347
+ instruction="Upload a photo to Page (local path or URL).",
348
+ params=[
349
+ {"name": "page_id", "type": "str", "required": False, "description": "Defaults to selected page"},
350
+ {"name": "path", "type": "str", "required": False, "description": "Local file path"},
351
+ {"name": "url", "type": "str", "required": False, "description": "Remote image URL"},
352
+ {"name": "caption", "type": "str", "required": False, "description": "Photo caption"},
353
+ {"name": "published", "type": "bool", "required": False, "description": "Default true"},
354
+ {"name": "temporary", "type": "bool", "required": False, "description": "Required for scheduled multi-photo"},
355
+ ],
356
+ enabled=True,
357
+ description="Media: upload photo",
358
+ tab="media",
359
+ )
@@ -0,0 +1,114 @@
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.07.14 00:00:00 #
10
+ # ================================================== #
11
+
12
+ import os
13
+
14
+ from pygpt_net.plugin.base.plugin import BasePlugin
15
+ from pygpt_net.core.events import Event
16
+ from pygpt_net.item.ctx import CtxItem
17
+
18
+ from .config import Config
19
+ from .worker import Worker
20
+
21
+
22
+ class Plugin(BasePlugin):
23
+ def __init__(self, *args, **kwargs):
24
+ super(Plugin, self).__init__(*args, **kwargs)
25
+ self.id = "facebook"
26
+ self.name = "Facebook"
27
+ self.description = "Manage user info, pages, posts, and photos on Facebook pages."
28
+ self.prefix = "API"
29
+ self.order = 100
30
+ self.allowed_cmds = [
31
+ "fb_oauth_begin",
32
+ "fb_oauth_exchange",
33
+ "fb_token_extend",
34
+ "fb_me",
35
+ "fb_pages_list",
36
+ "fb_page_set_default",
37
+ "fb_page_posts",
38
+ "fb_page_post_create",
39
+ "fb_page_post_delete",
40
+ "fb_page_photo_upload"
41
+ ]
42
+ self.use_locale = False
43
+ self.worker = None
44
+ self.config = Config(self)
45
+ self.init_options()
46
+
47
+ def init_options(self):
48
+ """Initialize options"""
49
+ self.config.from_defaults(self)
50
+
51
+ def handle(self, event: Event, *args, **kwargs):
52
+ """
53
+ Handle dispatched event
54
+
55
+ :param event: event object
56
+ :param args: event args
57
+ :param kwargs: event kwargs
58
+ """
59
+ name = event.name
60
+ data = event.data
61
+ ctx = event.ctx
62
+
63
+ if name == Event.CMD_SYNTAX:
64
+ self.cmd_syntax(data)
65
+
66
+ elif name == Event.CMD_EXECUTE:
67
+ self.cmd(
68
+ ctx,
69
+ data['commands'],
70
+ )
71
+
72
+ def cmd_syntax(self, data: dict):
73
+ """
74
+ Event: CMD_SYNTAX
75
+
76
+ :param data: event data dict
77
+ """
78
+ for option in self.allowed_cmds:
79
+ if self.has_cmd(option):
80
+ data['cmd'].append(self.get_cmd(option)) # append command
81
+
82
+ def cmd(self, ctx: CtxItem, cmds: list):
83
+ """
84
+ Event: CMD_EXECUTE
85
+
86
+ :param ctx: CtxItem
87
+ :param cmds: commands dict
88
+ """
89
+ is_cmd = False
90
+ my_commands = []
91
+ for item in cmds:
92
+ if item["cmd"] in self.allowed_cmds:
93
+ my_commands.append(item)
94
+ is_cmd = True
95
+
96
+ if not is_cmd:
97
+ return
98
+
99
+ # set state: busy
100
+ self.cmd_prepare(ctx, my_commands)
101
+
102
+ try:
103
+ worker = Worker()
104
+ worker.from_defaults(self)
105
+ worker.cmds = my_commands
106
+ worker.ctx = ctx
107
+
108
+ if not self.is_async(ctx):
109
+ worker.run()
110
+ return
111
+ worker.run_async()
112
+
113
+ except Exception as e:
114
+ self.error(e)