pygpt-net 2.6.19.post1__py3-none-any.whl → 2.6.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pygpt_net/CHANGELOG.txt CHANGED
@@ -1,3 +1,8 @@
1
+ 2.6.20 (2025-08-22)
2
+
3
+ - Added a new plugin: Server (FTP/SSH) - connect to remote servers using FTP, SFTP, and SSH. Execute remote commands, upload, download, and more (beta).
4
+ - Added support for Wayland in Snap/compiled versions.
5
+
1
6
  2.6.19 (2025-08-22)
2
7
 
3
8
  - Fixed: added prevention for summarizing an empty context.
pygpt_net/__init__.py CHANGED
@@ -13,7 +13,7 @@ __author__ = "Marcin Szczygliński"
13
13
  __copyright__ = "Copyright 2025, Marcin Szczygliński"
14
14
  __credits__ = ["Marcin Szczygliński"]
15
15
  __license__ = "MIT"
16
- __version__ = "2.6.19"
16
+ __version__ = "2.6.20"
17
17
  __build__ = "2025-08-22"
18
18
  __maintainer__ = "Marcin Szczygliński"
19
19
  __github__ = "https://github.com/szczyglis-dev/py-gpt"
pygpt_net/app.py CHANGED
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.08.19 07:00:00 #
9
+ # Updated Date: 2025.08.22 10:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -86,6 +86,7 @@ from pygpt_net.plugin.telegram import Plugin as TelegramPlugin
86
86
  from pygpt_net.plugin.slack import Plugin as SlackPlugin
87
87
  from pygpt_net.plugin.github import Plugin as GithubPlugin
88
88
  from pygpt_net.plugin.bitbucket import Plugin as BitbucketPlugin
89
+ from pygpt_net.plugin.server import Plugin as ServerPlugin
89
90
 
90
91
  # agents (Llama-index)
91
92
  # from pygpt_net.provider.agents.llama_index.legacy.openai import OpenAIAgent
@@ -405,6 +406,7 @@ def run(**kwargs):
405
406
  launcher.add_plugin(SlackPlugin())
406
407
  launcher.add_plugin(GithubPlugin())
407
408
  launcher.add_plugin(BitbucketPlugin())
409
+ launcher.add_plugin(ServerPlugin())
408
410
 
409
411
  # register custom plugins
410
412
  plugins = kwargs.get('plugins', None)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.19",
4
- "app.version": "2.6.19",
3
+ "version": "2.6.20",
4
+ "app.version": "2.6.20",
5
5
  "updated_at": "2025-08-22T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.19",
4
- "app.version": "2.6.19",
3
+ "version": "2.6.20",
4
+ "app.version": "2.6.20",
5
5
  "updated_at": "2025-08-22T23:07:35"
6
6
  },
7
7
  "items": {
@@ -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.08.22 10:00:00 #
10
+ # ================================================== #
11
+
12
+ from .plugin import *
@@ -0,0 +1,301 @@
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.22 10: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
+ keys = {
22
+ "enabled": "bool",
23
+ "name": "text",
24
+ "host": "text",
25
+ "login": "text",
26
+ "password": "text",
27
+ "port": "int",
28
+ "desc": "textarea",
29
+ }
30
+ items = [
31
+ {
32
+ "enabled": True,
33
+ "name": "my server",
34
+ "host": "my.server.com",
35
+ "login": "my_login",
36
+ "password": "my_password",
37
+ "port": 22,
38
+ "desc": "This is a test configuration for SSH/SFTP connections. You can add your own servers here.",
39
+ },
40
+ ]
41
+ desc = "Add your server configurations here. The model will not see any credentials, only the server name and port fields."
42
+ plugin.add_option(
43
+ "servers",
44
+ type="dict",
45
+ value=items,
46
+ label="Servers",
47
+ description=desc,
48
+ tooltip=desc,
49
+ keys=keys,
50
+ )
51
+
52
+ # Network / timeouts
53
+ plugin.add_option(
54
+ "net_timeout",
55
+ type="int",
56
+ value=30,
57
+ label="Network timeout (s)",
58
+ description="Network operations timeout.",
59
+ )
60
+
61
+ # SSH / SFTP (system/native and Paramiko)
62
+ plugin.add_option(
63
+ "prefer_system_ssh",
64
+ type="bool",
65
+ value=False,
66
+ label="Prefer system ssh/scp/sftp",
67
+ description="Use native ssh/scp/sftp binaries with system keys.",
68
+ )
69
+ plugin.add_option(
70
+ "ssh_binary",
71
+ type="text",
72
+ value="ssh",
73
+ label="ssh binary",
74
+ description="Path to ssh binary.",
75
+ )
76
+ plugin.add_option(
77
+ "scp_binary",
78
+ type="text",
79
+ value="scp",
80
+ label="scp binary",
81
+ description="Path to scp binary.",
82
+ )
83
+ plugin.add_option(
84
+ "sftp_binary",
85
+ type="text",
86
+ value="sftp",
87
+ label="sftp binary",
88
+ description="Path to sftp binary.",
89
+ )
90
+ plugin.add_option(
91
+ "ssh_options",
92
+ type="text",
93
+ value="",
94
+ label="Extra ssh options",
95
+ description="Extra options appended to ssh/scp (e.g. -o StrictHostKeyChecking=no).",
96
+ )
97
+ plugin.add_option(
98
+ "ssh_auto_add_hostkey",
99
+ type="bool",
100
+ value=True,
101
+ label="Paramiko: Auto add host keys",
102
+ description="Set AutoAddPolicy for Paramiko SSHClient.",
103
+ )
104
+
105
+ # FTP/FTPS
106
+ plugin.add_option(
107
+ "ftp_use_tls_default",
108
+ type="bool",
109
+ value=False,
110
+ label="FTP TLS default",
111
+ description="Use FTP over TLS (explicit) by default.",
112
+ )
113
+ plugin.add_option(
114
+ "ftp_passive_default",
115
+ type="bool",
116
+ value=True,
117
+ label="FTP passive mode",
118
+ description="Default passive mode for FTP.",
119
+ )
120
+
121
+ # Telnet
122
+ plugin.add_option(
123
+ "telnet_login_prompt",
124
+ type="text",
125
+ value="login:",
126
+ label="Telnet: login prompt",
127
+ description="Prompt text expected for username.",
128
+ )
129
+ plugin.add_option(
130
+ "telnet_password_prompt",
131
+ type="text",
132
+ value="Password:",
133
+ label="Telnet: password prompt",
134
+ description="Prompt text expected for password.",
135
+ )
136
+ plugin.add_option(
137
+ "telnet_prompt",
138
+ type="text",
139
+ value="$ ",
140
+ label="Telnet: shell prompt",
141
+ description="Prompt used to delimit command output.",
142
+ )
143
+
144
+ # SMTP
145
+ plugin.add_option(
146
+ "smtp_use_tls_default",
147
+ type="bool",
148
+ value=True,
149
+ label="SMTP STARTTLS default",
150
+ description="Use STARTTLS by default (e.g. port 587).",
151
+ )
152
+ plugin.add_option(
153
+ "smtp_use_ssl_default",
154
+ type="bool",
155
+ value=False,
156
+ label="SMTP SSL default",
157
+ description="Use SMTP over SSL (e.g. port 465).",
158
+ )
159
+ plugin.add_option(
160
+ "smtp_from_default",
161
+ type="text",
162
+ value="",
163
+ label="Default From address",
164
+ description="Used if 'from_addr' not provided in smtp_send.",
165
+ )
166
+
167
+ # ---------------- Commands ----------------
168
+
169
+ # Exec
170
+ plugin.add_cmd(
171
+ "srv_exec",
172
+ instruction="Execute remote shell command (SSH or Telnet).",
173
+ params=[
174
+ {"name": "server", "type": "str", "required": True,
175
+ "description": "Server name/host (from local config)"},
176
+ {"name": "port", "type": "int", "required": True, "description": "Service port (ssh=22, telnet=23)"},
177
+ {"name": "command", "type": "str", "required": True, "description": "Shell command to run"},
178
+ {"name": "cwd", "type": "str", "required": False, "description": "Remote working directory"},
179
+ {"name": "env", "type": "dict", "required": False, "description": "Environment variables dict"},
180
+ ],
181
+ enabled=True,
182
+ description="Server: remote exec",
183
+ tab="server",
184
+ )
185
+
186
+ # List
187
+ plugin.add_cmd(
188
+ "srv_ls",
189
+ instruction="List remote directory (SFTP/FTP over data ports, SSH for 22).",
190
+ params=[
191
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
192
+ {"name": "port", "type": "int", "required": True, "description": "Service port (22/21/990)"},
193
+ {"name": "path", "type": "str", "required": False, "description": "Remote path (default '.')"},
194
+ ],
195
+ enabled=True,
196
+ description="Server: ls",
197
+ tab="server",
198
+ )
199
+
200
+ # Download
201
+ plugin.add_cmd(
202
+ "srv_get",
203
+ instruction="Download remote file to local data dir.",
204
+ params=[
205
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
206
+ {"name": "port", "type": "int", "required": True, "description": "Service port"},
207
+ {"name": "remote_path", "type": "str", "required": True, "description": "Remote file path"},
208
+ {"name": "local_path", "type": "str", "required": False, "description": "Local path (relative=./data)"},
209
+ {"name": "overwrite", "type": "bool", "required": False,
210
+ "description": "Overwrite if exists (default True)"},
211
+ ],
212
+ enabled=True,
213
+ description="Server: download file",
214
+ tab="server",
215
+ )
216
+
217
+ # Upload
218
+ plugin.add_cmd(
219
+ "srv_put",
220
+ instruction="Upload local file to remote.",
221
+ params=[
222
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
223
+ {"name": "port", "type": "int", "required": True, "description": "Service port"},
224
+ {"name": "local_path", "type": "str", "required": True,
225
+ "description": "Local file path (relative=./data)"},
226
+ {"name": "remote_path", "type": "str", "required": False,
227
+ "description": "Remote path (dest file path)"},
228
+ {"name": "make_dirs", "type": "bool", "required": False, "description": "Create dirs (SFTP)"},
229
+ ],
230
+ enabled=True,
231
+ description="Server: upload file",
232
+ tab="server",
233
+ )
234
+
235
+ # Remove
236
+ plugin.add_cmd(
237
+ "srv_rm",
238
+ instruction="Remove remote file or empty dir (non-recursive).",
239
+ params=[
240
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
241
+ {"name": "port", "type": "int", "required": True, "description": "Service port"},
242
+ {"name": "remote_path", "type": "str", "required": True, "description": "Remote file/dir path"},
243
+ ],
244
+ enabled=True,
245
+ description="Server: remove",
246
+ tab="server",
247
+ )
248
+
249
+ # Mkdir
250
+ plugin.add_cmd(
251
+ "srv_mkdir",
252
+ instruction="Create remote directory.",
253
+ params=[
254
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
255
+ {"name": "port", "type": "int", "required": True, "description": "Service port"},
256
+ {"name": "remote_path", "type": "str", "required": True, "description": "Remote directory path"},
257
+ {"name": "exist_ok", "type": "bool", "required": False, "description": "Ignore if exists"},
258
+ ],
259
+ enabled=True,
260
+ description="Server: mkdir",
261
+ tab="server",
262
+ )
263
+
264
+ # Stat
265
+ plugin.add_cmd(
266
+ "srv_stat",
267
+ instruction="Get remote path info (type/size/mtime if available).",
268
+ params=[
269
+ {"name": "server", "type": "str", "required": True, "description": "Server name/host"},
270
+ {"name": "port", "type": "int", "required": True, "description": "Service port"},
271
+ {"name": "remote_path", "type": "str", "required": True, "description": "Remote path"},
272
+ ],
273
+ enabled=True,
274
+ description="Server: stat",
275
+ tab="server",
276
+ )
277
+
278
+ # SMTP
279
+ plugin.add_cmd(
280
+ "smtp_send",
281
+ instruction="Send email via SMTP (uses local server config).",
282
+ params=[
283
+ {"name": "server", "type": "str", "required": True, "description": "SMTP server name/host"},
284
+ {"name": "port", "type": "int", "required": True, "description": "SMTP port (25/465/587)"},
285
+ {"name": "from_addr", "type": "str", "required": False,
286
+ "description": "From address (default from options/login)"},
287
+ {"name": "to", "type": "list", "required": True, "description": "Recipient list"},
288
+ {"name": "cc", "type": "list", "required": False, "description": "CC recipients"},
289
+ {"name": "bcc", "type": "list", "required": False, "description": "BCC recipients"},
290
+ {"name": "subject", "type": "str", "required": False, "description": "Subject"},
291
+ {"name": "body", "type": "str", "required": False, "description": "Body (text or HTML)"},
292
+ {"name": "html", "type": "bool", "required": False, "description": "Body is HTML"},
293
+ {"name": "attachments", "type": "list", "required": False,
294
+ "description": "Local file paths (relative=./data)"},
295
+ {"name": "use_tls", "type": "bool", "required": False, "description": "STARTTLS override"},
296
+ {"name": "use_ssl", "type": "bool", "required": False, "description": "SSL override"},
297
+ ],
298
+ enabled=True,
299
+ description="SMTP: send email",
300
+ tab="smtp",
301
+ )
@@ -0,0 +1,111 @@
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.22 10: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 = "server"
23
+ self.name = "Server (SSH/FTP)"
24
+ self.description = "Connect to remote servers using FTP, SFTP, and SSH. Execute remote commands, upload, download, and more."
25
+ self.prefix = "Remote"
26
+ self.order = 100
27
+ self.allowed_cmds = [
28
+ "srv_exec",
29
+ "srv_ls",
30
+ "srv_get",
31
+ "srv_put",
32
+ "srv_rm",
33
+ "srv_mkdir",
34
+ "srv_stat",
35
+ "smtp_send"
36
+ ]
37
+ self.use_locale = False
38
+ self.worker = None
39
+ self.config = Config(self)
40
+ self.init_options()
41
+
42
+ def init_options(self):
43
+ """Initialize options"""
44
+ self.config.from_defaults(self)
45
+
46
+ def handle(self, event: Event, *args, **kwargs):
47
+ """
48
+ Handle dispatched event
49
+
50
+ :param event: event object
51
+ :param args: event args
52
+ :param kwargs: event kwargs
53
+ """
54
+ name = event.name
55
+ data = event.data
56
+ ctx = event.ctx
57
+
58
+ if name == Event.CMD_SYNTAX:
59
+ self.cmd_syntax(data)
60
+
61
+ elif name == Event.CMD_EXECUTE:
62
+ self.cmd(
63
+ ctx,
64
+ data['commands'],
65
+ )
66
+
67
+ def cmd_syntax(self, data: dict):
68
+ """
69
+ Event: CMD_SYNTAX
70
+
71
+ :param data: event data dict
72
+ """
73
+ for option in self.allowed_cmds:
74
+ if self.has_cmd(option):
75
+ data['cmd'].append(self.get_cmd(option)) # append command
76
+
77
+ def cmd(self, ctx: CtxItem, cmds: list):
78
+ """
79
+ Event: CMD_EXECUTE
80
+
81
+ :param ctx: CtxItem
82
+ :param cmds: commands dict
83
+ """
84
+ from .worker import Worker
85
+
86
+ is_cmd = False
87
+ my_commands = []
88
+ for item in cmds:
89
+ if item["cmd"] in self.allowed_cmds:
90
+ my_commands.append(item)
91
+ is_cmd = True
92
+
93
+ if not is_cmd:
94
+ return
95
+
96
+ # set state: busy
97
+ self.cmd_prepare(ctx, my_commands)
98
+
99
+ try:
100
+ worker = Worker()
101
+ worker.from_defaults(self)
102
+ worker.cmds = my_commands
103
+ worker.ctx = ctx
104
+
105
+ if not self.is_async(ctx):
106
+ worker.run()
107
+ return
108
+ worker.run_async()
109
+
110
+ except Exception as e:
111
+ self.error(e)