pygpt-net 2.6.1__py3-none-any.whl → 2.6.6__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 (131) hide show
  1. pygpt_net/CHANGELOG.txt +23 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +20 -1
  4. pygpt_net/config.py +55 -65
  5. pygpt_net/controller/__init__.py +5 -2
  6. pygpt_net/controller/calendar/note.py +101 -126
  7. pygpt_net/controller/chat/chat.py +38 -35
  8. pygpt_net/controller/chat/render.py +154 -214
  9. pygpt_net/controller/chat/response.py +5 -3
  10. pygpt_net/controller/chat/stream.py +92 -27
  11. pygpt_net/controller/config/config.py +39 -42
  12. pygpt_net/controller/config/field/checkbox.py +16 -12
  13. pygpt_net/controller/config/field/checkbox_list.py +36 -31
  14. pygpt_net/controller/config/field/cmd.py +51 -57
  15. pygpt_net/controller/config/field/combo.py +33 -16
  16. pygpt_net/controller/config/field/dictionary.py +48 -55
  17. pygpt_net/controller/config/field/input.py +50 -32
  18. pygpt_net/controller/config/field/slider.py +40 -45
  19. pygpt_net/controller/config/field/textarea.py +20 -6
  20. pygpt_net/controller/config/placeholder.py +110 -231
  21. pygpt_net/controller/ctx/common.py +48 -48
  22. pygpt_net/controller/ctx/ctx.py +91 -132
  23. pygpt_net/controller/lang/mapping.py +57 -95
  24. pygpt_net/controller/lang/plugins.py +64 -55
  25. pygpt_net/controller/lang/settings.py +39 -38
  26. pygpt_net/controller/layout/layout.py +176 -109
  27. pygpt_net/controller/mode/mode.py +88 -85
  28. pygpt_net/controller/model/model.py +73 -73
  29. pygpt_net/controller/plugins/plugins.py +209 -223
  30. pygpt_net/controller/plugins/presets.py +54 -55
  31. pygpt_net/controller/plugins/settings.py +54 -69
  32. pygpt_net/controller/presets/editor.py +33 -88
  33. pygpt_net/controller/presets/experts.py +20 -1
  34. pygpt_net/controller/presets/presets.py +293 -298
  35. pygpt_net/controller/settings/profile.py +16 -4
  36. pygpt_net/controller/theme/theme.py +72 -81
  37. pygpt_net/controller/ui/mode.py +118 -186
  38. pygpt_net/controller/ui/tabs.py +69 -90
  39. pygpt_net/controller/ui/ui.py +47 -56
  40. pygpt_net/controller/ui/vision.py +24 -23
  41. pygpt_net/core/agents/runner.py +15 -7
  42. pygpt_net/core/bridge/bridge.py +5 -5
  43. pygpt_net/core/command/command.py +149 -219
  44. pygpt_net/core/ctx/ctx.py +94 -146
  45. pygpt_net/core/debug/debug.py +48 -58
  46. pygpt_net/core/experts/experts.py +3 -3
  47. pygpt_net/core/models/models.py +74 -112
  48. pygpt_net/core/modes/modes.py +13 -21
  49. pygpt_net/core/plugins/plugins.py +154 -177
  50. pygpt_net/core/presets/presets.py +103 -176
  51. pygpt_net/core/render/web/body.py +217 -215
  52. pygpt_net/core/render/web/renderer.py +330 -474
  53. pygpt_net/core/text/utils.py +28 -44
  54. pygpt_net/core/tokens/tokens.py +104 -203
  55. pygpt_net/data/config/config.json +3 -3
  56. pygpt_net/data/config/models.json +3 -3
  57. pygpt_net/data/locale/locale.de.ini +2 -0
  58. pygpt_net/data/locale/locale.en.ini +2 -0
  59. pygpt_net/data/locale/locale.es.ini +2 -0
  60. pygpt_net/data/locale/locale.fr.ini +2 -0
  61. pygpt_net/data/locale/locale.it.ini +2 -0
  62. pygpt_net/data/locale/locale.pl.ini +3 -1
  63. pygpt_net/data/locale/locale.uk.ini +2 -0
  64. pygpt_net/data/locale/locale.zh.ini +2 -0
  65. pygpt_net/item/ctx.py +141 -139
  66. pygpt_net/plugin/agent/plugin.py +2 -1
  67. pygpt_net/plugin/audio_output/plugin.py +5 -2
  68. pygpt_net/plugin/base/plugin.py +101 -85
  69. pygpt_net/plugin/bitbucket/__init__.py +12 -0
  70. pygpt_net/plugin/bitbucket/config.py +267 -0
  71. pygpt_net/plugin/bitbucket/plugin.py +126 -0
  72. pygpt_net/plugin/bitbucket/worker.py +569 -0
  73. pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
  74. pygpt_net/plugin/cmd_custom/plugin.py +3 -2
  75. pygpt_net/plugin/cmd_files/plugin.py +3 -2
  76. pygpt_net/plugin/cmd_history/plugin.py +3 -2
  77. pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
  78. pygpt_net/plugin/cmd_serial/plugin.py +3 -2
  79. pygpt_net/plugin/cmd_system/plugin.py +3 -6
  80. pygpt_net/plugin/cmd_web/plugin.py +3 -2
  81. pygpt_net/plugin/experts/plugin.py +2 -2
  82. pygpt_net/plugin/facebook/__init__.py +12 -0
  83. pygpt_net/plugin/facebook/config.py +359 -0
  84. pygpt_net/plugin/facebook/plugin.py +113 -0
  85. pygpt_net/plugin/facebook/worker.py +698 -0
  86. pygpt_net/plugin/github/__init__.py +12 -0
  87. pygpt_net/plugin/github/config.py +441 -0
  88. pygpt_net/plugin/github/plugin.py +126 -0
  89. pygpt_net/plugin/github/worker.py +674 -0
  90. pygpt_net/plugin/google/__init__.py +12 -0
  91. pygpt_net/plugin/google/config.py +367 -0
  92. pygpt_net/plugin/google/plugin.py +126 -0
  93. pygpt_net/plugin/google/worker.py +826 -0
  94. pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
  95. pygpt_net/plugin/mailer/plugin.py +3 -5
  96. pygpt_net/plugin/openai_vision/plugin.py +3 -2
  97. pygpt_net/plugin/real_time/plugin.py +52 -60
  98. pygpt_net/plugin/slack/__init__.py +12 -0
  99. pygpt_net/plugin/slack/config.py +349 -0
  100. pygpt_net/plugin/slack/plugin.py +115 -0
  101. pygpt_net/plugin/slack/worker.py +639 -0
  102. pygpt_net/plugin/telegram/__init__.py +12 -0
  103. pygpt_net/plugin/telegram/config.py +308 -0
  104. pygpt_net/plugin/telegram/plugin.py +117 -0
  105. pygpt_net/plugin/telegram/worker.py +563 -0
  106. pygpt_net/plugin/twitter/__init__.py +12 -0
  107. pygpt_net/plugin/twitter/config.py +491 -0
  108. pygpt_net/plugin/twitter/plugin.py +125 -0
  109. pygpt_net/plugin/twitter/worker.py +837 -0
  110. pygpt_net/provider/agents/llama_index/legacy/openai_assistant.py +35 -3
  111. pygpt_net/tools/code_interpreter/tool.py +0 -1
  112. pygpt_net/tools/translator/tool.py +1 -1
  113. pygpt_net/ui/base/config_dialog.py +86 -100
  114. pygpt_net/ui/base/context_menu.py +48 -46
  115. pygpt_net/ui/dialog/preset.py +34 -77
  116. pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
  117. pygpt_net/ui/layout/toolbox/presets.py +41 -41
  118. pygpt_net/ui/main.py +49 -31
  119. pygpt_net/ui/tray.py +61 -60
  120. pygpt_net/ui/widget/calendar/select.py +86 -70
  121. pygpt_net/ui/widget/lists/attachment.py +86 -44
  122. pygpt_net/ui/widget/lists/base_list_combo.py +85 -33
  123. pygpt_net/ui/widget/lists/context.py +135 -188
  124. pygpt_net/ui/widget/lists/preset.py +59 -61
  125. pygpt_net/ui/widget/textarea/web.py +161 -48
  126. pygpt_net/utils.py +8 -1
  127. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/METADATA +164 -2
  128. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/RECORD +131 -103
  129. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/LICENSE +0 -0
  130. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/WHEEL +0 -0
  131. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.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.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Slot, QTimer
@@ -17,7 +17,6 @@ from pygpt_net.core.events import Event, KernelEvent
17
17
  from pygpt_net.item.ctx import CtxItem
18
18
 
19
19
  from .config import Config
20
- from .worker import Worker
21
20
 
22
21
 
23
22
  class Plugin(BasePlugin):
@@ -93,6 +92,8 @@ class Plugin(BasePlugin):
93
92
  :param ctx: CtxItem
94
93
  :param cmds: commands dict
95
94
  """
95
+ from .worker import Worker
96
+
96
97
  is_cmd = False
97
98
  my_commands = []
98
99
  for item in cmds:
@@ -128,6 +129,8 @@ class Plugin(BasePlugin):
128
129
  :param item: command item to execute
129
130
  :return:
130
131
  """
132
+ from .worker import Worker
133
+
131
134
  item["params"]["no_screenshot"] = True # do not take screenshot for single command call
132
135
  worker = Worker()
133
136
  worker.from_defaults(self)
@@ -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: 2024.11.20 03:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.plugin.base.plugin import BasePlugin
@@ -14,7 +14,6 @@ from pygpt_net.core.events import Event
14
14
  from pygpt_net.item.ctx import CtxItem
15
15
 
16
16
  from .config import Config
17
- from .worker import Worker
18
17
 
19
18
 
20
19
  class Plugin(BasePlugin):
@@ -77,6 +76,8 @@ class Plugin(BasePlugin):
77
76
  :param ctx: CtxItem
78
77
  :param cmds: commands dict
79
78
  """
79
+ from .worker import Worker
80
+
80
81
  is_cmd = False
81
82
  my_commands = []
82
83
  for item in cmds:
@@ -6,13 +6,9 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.11.24 06:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import os
13
-
14
- from PySide6.QtCore import Slot
15
-
16
12
  from pygpt_net.plugin.base.plugin import BasePlugin
17
13
  from pygpt_net.core.events import Event
18
14
  from pygpt_net.item.ctx import CtxItem
@@ -21,7 +17,6 @@ from .config import Config
21
17
  from .docker import Docker
22
18
  from .output import Output
23
19
  from .runner import Runner
24
- from .worker import Worker
25
20
 
26
21
  from pygpt_net.utils import trans
27
22
 
@@ -110,6 +105,8 @@ class Plugin(BasePlugin):
110
105
  :param cmds: commands dict
111
106
  :param silent: silent mode
112
107
  """
108
+ from .worker import Worker
109
+
113
110
  is_cmd = False
114
111
  force = False
115
112
  my_commands = []
@@ -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.06.30 02:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import ssl
@@ -19,7 +19,6 @@ from pygpt_net.item.ctx import CtxItem
19
19
 
20
20
  from .config import Config
21
21
  from .websearch import WebSearch
22
- from .worker import Worker
23
22
 
24
23
 
25
24
  class Plugin(BasePlugin):
@@ -347,6 +346,8 @@ class Plugin(BasePlugin):
347
346
  :param ctx: CtxItem
348
347
  :param cmds: commands dict
349
348
  """
349
+ from .worker import Worker
350
+
350
351
  my_commands = []
351
352
  for item in cmds:
352
353
  if item["cmd"] in self.allowed_cmds and self.has_cmd(item["cmd"]):
@@ -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: 2024.11.21 20:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.types import (
@@ -33,7 +33,7 @@ class Plugin(BasePlugin):
33
33
  ]
34
34
  self.order = 9998
35
35
  self.use_locale = True
36
- self.disallowed_modes = [MODE_AGENT, MODE_EXPERT]
36
+ self.disallowed_modes = (MODE_AGENT, MODE_EXPERT)
37
37
  self.config = Config(self)
38
38
  self.init_options()
39
39
 
@@ -0,0 +1,12 @@
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.30 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from .plugin import *
@@ -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,113 @@
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.15 23:00:00 #
10
+ # ================================================== #
11
+
12
+ from pygpt_net.plugin.base.plugin import BasePlugin
13
+ from pygpt_net.core.events import Event
14
+ from pygpt_net.item.ctx import CtxItem
15
+
16
+ from .config import Config
17
+
18
+
19
+ class Plugin(BasePlugin):
20
+ def __init__(self, *args, **kwargs):
21
+ super(Plugin, self).__init__(*args, **kwargs)
22
+ self.id = "facebook"
23
+ self.name = "Facebook"
24
+ self.description = "Manage user info, pages, posts, and photos on Facebook pages."
25
+ self.prefix = "API"
26
+ self.order = 100
27
+ self.allowed_cmds = [
28
+ "fb_oauth_begin",
29
+ "fb_oauth_exchange",
30
+ "fb_token_extend",
31
+ "fb_me",
32
+ "fb_pages_list",
33
+ "fb_page_set_default",
34
+ "fb_page_posts",
35
+ "fb_page_post_create",
36
+ "fb_page_post_delete",
37
+ "fb_page_photo_upload"
38
+ ]
39
+ self.use_locale = False
40
+ self.worker = None
41
+ self.config = Config(self)
42
+ self.init_options()
43
+
44
+ def init_options(self):
45
+ """Initialize options"""
46
+ self.config.from_defaults(self)
47
+
48
+ def handle(self, event: Event, *args, **kwargs):
49
+ """
50
+ Handle dispatched event
51
+
52
+ :param event: event object
53
+ :param args: event args
54
+ :param kwargs: event kwargs
55
+ """
56
+ name = event.name
57
+ data = event.data
58
+ ctx = event.ctx
59
+
60
+ if name == Event.CMD_SYNTAX:
61
+ self.cmd_syntax(data)
62
+
63
+ elif name == Event.CMD_EXECUTE:
64
+ self.cmd(
65
+ ctx,
66
+ data['commands'],
67
+ )
68
+
69
+ def cmd_syntax(self, data: dict):
70
+ """
71
+ Event: CMD_SYNTAX
72
+
73
+ :param data: event data dict
74
+ """
75
+ for option in self.allowed_cmds:
76
+ if self.has_cmd(option):
77
+ data['cmd'].append(self.get_cmd(option)) # append command
78
+
79
+ def cmd(self, ctx: CtxItem, cmds: list):
80
+ """
81
+ Event: CMD_EXECUTE
82
+
83
+ :param ctx: CtxItem
84
+ :param cmds: commands dict
85
+ """
86
+ from .worker import Worker
87
+
88
+ is_cmd = False
89
+ my_commands = []
90
+ for item in cmds:
91
+ if item["cmd"] in self.allowed_cmds:
92
+ my_commands.append(item)
93
+ is_cmd = True
94
+
95
+ if not is_cmd:
96
+ return
97
+
98
+ # set state: busy
99
+ self.cmd_prepare(ctx, my_commands)
100
+
101
+ try:
102
+ worker = Worker()
103
+ worker.from_defaults(self)
104
+ worker.cmds = my_commands
105
+ worker.ctx = ctx
106
+
107
+ if not self.is_async(ctx):
108
+ worker.run()
109
+ return
110
+ worker.run_async()
111
+
112
+ except Exception as e:
113
+ self.error(e)