pygpt-net 2.4.28__py3-none-any.whl → 2.4.34__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 (168) hide show
  1. CHANGELOG.md +40 -0
  2. README.md +62 -5
  3. pygpt_net/CHANGELOG.txt +40 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/access/__init__.py +5 -5
  6. pygpt_net/controller/access/control.py +3 -2
  7. pygpt_net/controller/attachment.py +67 -1
  8. pygpt_net/controller/audio/__init__.py +34 -6
  9. pygpt_net/controller/chat/__init__.py +3 -1
  10. pygpt_net/controller/chat/attachment.py +239 -37
  11. pygpt_net/controller/chat/audio.py +99 -0
  12. pygpt_net/controller/chat/input.py +10 -3
  13. pygpt_net/controller/chat/output.py +4 -1
  14. pygpt_net/controller/chat/text.py +10 -5
  15. pygpt_net/controller/dialogs/confirm.py +17 -1
  16. pygpt_net/controller/kernel/reply.py +5 -8
  17. pygpt_net/controller/lang/custom.py +3 -1
  18. pygpt_net/controller/mode.py +2 -1
  19. pygpt_net/controller/presets/editor.py +11 -2
  20. pygpt_net/core/access/voice.py +2 -2
  21. pygpt_net/core/agents/legacy.py +3 -1
  22. pygpt_net/core/attachments/__init__.py +11 -7
  23. pygpt_net/core/attachments/context.py +226 -44
  24. pygpt_net/core/{audio.py → audio/__init__.py} +1 -1
  25. pygpt_net/core/audio/context.py +34 -0
  26. pygpt_net/core/bridge/context.py +29 -1
  27. pygpt_net/core/bridge/worker.py +16 -1
  28. pygpt_net/core/ctx/__init__.py +4 -1
  29. pygpt_net/core/db/__init__.py +4 -2
  30. pygpt_net/core/debug/attachments.py +3 -1
  31. pygpt_net/core/debug/context.py +5 -1
  32. pygpt_net/core/debug/presets.py +3 -1
  33. pygpt_net/core/docker/__init__.py +170 -16
  34. pygpt_net/core/docker/builder.py +6 -2
  35. pygpt_net/core/events/event.py +3 -1
  36. pygpt_net/core/experts/__init__.py +24 -6
  37. pygpt_net/core/idx/chat.py +55 -4
  38. pygpt_net/core/idx/indexing.py +123 -15
  39. pygpt_net/core/modes.py +3 -1
  40. pygpt_net/core/presets.py +13 -2
  41. pygpt_net/core/render/markdown/pid.py +2 -1
  42. pygpt_net/core/render/plain/pid.py +2 -1
  43. pygpt_net/core/render/web/body.py +34 -12
  44. pygpt_net/core/render/web/pid.py +2 -1
  45. pygpt_net/core/render/web/renderer.py +12 -3
  46. pygpt_net/core/tokens.py +4 -2
  47. pygpt_net/core/types/mode.py +2 -1
  48. pygpt_net/data/config/config.json +7 -4
  49. pygpt_net/data/config/models.json +191 -6
  50. pygpt_net/data/config/modes.json +11 -5
  51. pygpt_net/data/config/presets/current.audio.json +34 -0
  52. pygpt_net/data/config/settings.json +15 -1
  53. pygpt_net/data/css/web.css +70 -0
  54. pygpt_net/data/css/web.dark.css +4 -1
  55. pygpt_net/data/css/web.light.css +1 -1
  56. pygpt_net/data/locale/locale.de.ini +33 -20
  57. pygpt_net/data/locale/locale.en.ini +73 -58
  58. pygpt_net/data/locale/locale.es.ini +33 -20
  59. pygpt_net/data/locale/locale.fr.ini +35 -22
  60. pygpt_net/data/locale/locale.it.ini +33 -20
  61. pygpt_net/data/locale/locale.pl.ini +36 -23
  62. pygpt_net/data/locale/locale.uk.ini +33 -20
  63. pygpt_net/data/locale/locale.zh.ini +40 -27
  64. pygpt_net/data/locale/plugin.cmd_code_interpreter.de.ini +6 -0
  65. pygpt_net/data/locale/plugin.cmd_code_interpreter.en.ini +15 -7
  66. pygpt_net/data/locale/plugin.cmd_code_interpreter.es.ini +6 -0
  67. pygpt_net/data/locale/plugin.cmd_code_interpreter.fr.ini +6 -0
  68. pygpt_net/data/locale/plugin.cmd_code_interpreter.it.ini +6 -0
  69. pygpt_net/data/locale/plugin.cmd_code_interpreter.pl.ini +6 -0
  70. pygpt_net/data/locale/plugin.cmd_code_interpreter.uk.ini +6 -0
  71. pygpt_net/data/locale/plugin.cmd_code_interpreter.zh.ini +6 -0
  72. pygpt_net/data/locale/plugin.cmd_files.de.ini +4 -4
  73. pygpt_net/data/locale/plugin.cmd_files.en.ini +4 -4
  74. pygpt_net/data/locale/plugin.cmd_files.es.ini +4 -4
  75. pygpt_net/data/locale/plugin.cmd_files.fr.ini +4 -4
  76. pygpt_net/data/locale/plugin.cmd_files.it.ini +4 -4
  77. pygpt_net/data/locale/plugin.cmd_files.pl.ini +4 -4
  78. pygpt_net/data/locale/plugin.cmd_files.uk.ini +4 -4
  79. pygpt_net/data/locale/plugin.cmd_files.zh.ini +4 -4
  80. pygpt_net/data/locale/plugin.cmd_system.de.ini +6 -6
  81. pygpt_net/data/locale/plugin.cmd_system.en.ini +12 -6
  82. pygpt_net/data/locale/plugin.cmd_system.es.ini +6 -6
  83. pygpt_net/data/locale/plugin.cmd_system.fr.ini +6 -6
  84. pygpt_net/data/locale/plugin.cmd_system.it.ini +6 -6
  85. pygpt_net/data/locale/plugin.cmd_system.pl.ini +6 -6
  86. pygpt_net/data/locale/plugin.cmd_system.uk.ini +6 -6
  87. pygpt_net/data/locale/plugin.cmd_system.zh.ini +6 -6
  88. pygpt_net/data/locale/plugin.cmd_web.de.ini +5 -5
  89. pygpt_net/data/locale/plugin.cmd_web.en.ini +5 -5
  90. pygpt_net/data/locale/plugin.cmd_web.es.ini +5 -5
  91. pygpt_net/data/locale/plugin.cmd_web.fr.ini +5 -5
  92. pygpt_net/data/locale/plugin.cmd_web.it.ini +5 -5
  93. pygpt_net/data/locale/plugin.cmd_web.pl.ini +5 -5
  94. pygpt_net/data/locale/plugin.cmd_web.uk.ini +5 -5
  95. pygpt_net/data/locale/plugin.cmd_web.zh.ini +5 -5
  96. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +12 -12
  97. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +12 -12
  98. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +12 -12
  99. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +12 -12
  100. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +12 -12
  101. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +12 -12
  102. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +12 -12
  103. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +12 -12
  104. pygpt_net/item/attachment.py +9 -1
  105. pygpt_net/item/ctx.py +9 -1
  106. pygpt_net/item/preset.py +5 -1
  107. pygpt_net/launcher.py +3 -1
  108. pygpt_net/migrations/Version20241126170000.py +28 -0
  109. pygpt_net/migrations/__init__.py +3 -1
  110. pygpt_net/plugin/audio_input/__init__.py +11 -1
  111. pygpt_net/plugin/audio_input/worker.py +9 -1
  112. pygpt_net/plugin/audio_output/__init__.py +37 -7
  113. pygpt_net/plugin/audio_output/worker.py +38 -41
  114. pygpt_net/plugin/cmd_code_interpreter/__init__.py +51 -35
  115. pygpt_net/plugin/cmd_code_interpreter/builder.py +16 -4
  116. pygpt_net/plugin/cmd_code_interpreter/config.py +98 -39
  117. pygpt_net/plugin/cmd_code_interpreter/docker.py +4 -0
  118. pygpt_net/plugin/cmd_code_interpreter/ipython/__init__.py +13 -0
  119. pygpt_net/plugin/cmd_code_interpreter/{ipython.py → ipython/docker_kernel.py} +10 -3
  120. pygpt_net/plugin/cmd_code_interpreter/ipython/local_kernel.py +220 -0
  121. pygpt_net/plugin/cmd_code_interpreter/runner.py +5 -5
  122. pygpt_net/plugin/cmd_mouse_control/__init__.py +4 -2
  123. pygpt_net/plugin/cmd_system/config.py +50 -0
  124. pygpt_net/plugin/cmd_system/docker.py +4 -0
  125. pygpt_net/plugin/idx_llama_index/__init__.py +23 -1
  126. pygpt_net/plugin/idx_llama_index/worker.py +10 -0
  127. pygpt_net/plugin/openai_dalle/__init__.py +3 -1
  128. pygpt_net/plugin/openai_vision/__init__.py +3 -1
  129. pygpt_net/provider/core/attachment/json_file.py +4 -1
  130. pygpt_net/provider/core/config/patch.py +25 -0
  131. pygpt_net/provider/core/ctx/db_sqlite/storage.py +14 -4
  132. pygpt_net/provider/core/ctx/db_sqlite/utils.py +19 -2
  133. pygpt_net/provider/core/model/patch.py +7 -1
  134. pygpt_net/provider/core/preset/json_file.py +5 -1
  135. pygpt_net/provider/gpt/__init__.py +14 -2
  136. pygpt_net/provider/gpt/audio.py +63 -0
  137. pygpt_net/provider/gpt/chat.py +76 -44
  138. pygpt_net/provider/gpt/utils.py +27 -0
  139. pygpt_net/provider/gpt/vision.py +37 -15
  140. pygpt_net/provider/loaders/base.py +10 -1
  141. pygpt_net/provider/loaders/web_yt.py +19 -1
  142. pygpt_net/tools/code_interpreter/__init__.py +1 -0
  143. pygpt_net/tools/image_viewer/ui/dialogs.py +3 -1
  144. pygpt_net/ui/dialog/preset.py +3 -1
  145. pygpt_net/ui/dialog/url.py +29 -0
  146. pygpt_net/ui/dialogs.py +5 -1
  147. pygpt_net/ui/layout/chat/attachments.py +42 -6
  148. pygpt_net/ui/layout/chat/attachments_ctx.py +14 -4
  149. pygpt_net/ui/layout/chat/attachments_uploaded.py +8 -4
  150. pygpt_net/ui/layout/toolbox/agent.py +8 -7
  151. pygpt_net/ui/layout/toolbox/agent_llama.py +5 -4
  152. pygpt_net/ui/layout/toolbox/prompt.py +8 -6
  153. pygpt_net/ui/menu/tools.py +17 -11
  154. pygpt_net/ui/widget/anims/toggles.py +167 -0
  155. pygpt_net/ui/widget/dialog/url.py +59 -0
  156. pygpt_net/ui/widget/element/group.py +2 -1
  157. pygpt_net/ui/widget/lists/attachment.py +22 -17
  158. pygpt_net/ui/widget/lists/attachment_ctx.py +65 -3
  159. pygpt_net/ui/widget/option/checkbox.py +69 -5
  160. pygpt_net/ui/widget/option/cmd.py +4 -5
  161. pygpt_net/ui/widget/option/toggle.py +62 -0
  162. pygpt_net/ui/widget/option/toggle_label.py +79 -0
  163. pygpt_net/ui/widget/textarea/url.py +43 -0
  164. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/METADATA +65 -7
  165. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/RECORD +168 -154
  166. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/LICENSE +0 -0
  167. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/WHEEL +0 -0
  168. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,220 @@
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: 2024.11.25 02:00:00 #
10
+ # ================================================== #
11
+
12
+ import re
13
+ from jupyter_client import KernelManager
14
+
15
+ class LocalKernel:
16
+ def __init__(self, plugin = None):
17
+ self.plugin = plugin
18
+ self.client = None
19
+ self.manager = None
20
+ self.initialized = False
21
+ self.signals = None
22
+
23
+ def restart_kernel(self) -> bool:
24
+ """
25
+ Restart the IPython kernel.
26
+
27
+ :return: True if successful.
28
+ """
29
+ if self.initialized:
30
+ self.manager.stop_channels()
31
+ self.manager.restart_kernel(now=True)
32
+ self.manager = self.manager.client()
33
+ self.manager.start_channels()
34
+ self.log("IPython kernel restarted.")
35
+ else:
36
+ self.init()
37
+ self.log("IPython kernel started.")
38
+ return True
39
+
40
+ def shutdown_kernel(self):
41
+ """Shutdown the IPython kernel."""
42
+ self.manager.stop_channels()
43
+ self.manager.shutdown_kernel()
44
+
45
+ def init(self, force: bool = False):
46
+ """
47
+ Initialize the IPython kernel client.
48
+
49
+ :param force: Force reinitialization.
50
+ """
51
+ if self.initialized and not force:
52
+ return
53
+ self.manager = KernelManager()
54
+ self.manager.start_kernel()
55
+ self.client = self.manager.client()
56
+ self.client.start_channels()
57
+ self.client.wait_for_ready()
58
+ self.log("Connected to local IPython kernel.")
59
+ self.initialized = True
60
+ self.log("IPython kernel is ready.")
61
+
62
+ def process_message(self, msg: dict) -> str:
63
+ """
64
+ Process the message from the IPython kernel.
65
+
66
+ :param msg: Message from the IPython kernel.
67
+ :return: Processed message.
68
+ """
69
+ msg_type = msg['msg_type']
70
+ content = msg['content']
71
+ if msg_type == 'stream':
72
+ # standard output and error
73
+ return content['text']
74
+ elif msg_type == 'display_data':
75
+ # display data
76
+ data = content['data']
77
+ if 'text/plain' in data:
78
+ return data['text/plain']
79
+ elif msg_type == 'execute_result':
80
+ # execution result
81
+ data = content['data']
82
+ if 'text/plain' in data:
83
+ return data['text/plain']
84
+ elif msg_type == 'error':
85
+ # execution errors
86
+ return "Error executing code:" + "\n".join(content['traceback'])
87
+ return ""
88
+
89
+ def end(self, all: bool = False):
90
+ """
91
+ Stop the IPython kernel.
92
+
93
+ :param all: Stop the container as well.
94
+ """
95
+ self.client.stop_channels() # stop the client
96
+ self.manager.shutdown_kernel()
97
+
98
+ def execute(self, code: str, current: bool = False) -> str:
99
+ """
100
+ Execute the code in the IPython kernel.
101
+
102
+ :param code: Python code to execute.
103
+ :param current: Use the current kernel.
104
+ :return: Output from the kernel.
105
+ """
106
+ self.init()
107
+ if not current:
108
+ self.restart_kernel()
109
+
110
+ self.log("Executing code: " + str(code)[:100] + "...")
111
+
112
+ msg_id = self.client.execute(code)
113
+ output = ""
114
+ while True:
115
+ try:
116
+ msg = self.client.get_iopub_msg(timeout=1)
117
+ except:
118
+ continue
119
+
120
+ if msg['parent_header'].get('msg_id') != msg_id:
121
+ continue
122
+
123
+ chunk = str(self.process_message(msg))
124
+ if chunk.strip() != "":
125
+ output += chunk
126
+ self.send_output(chunk)
127
+
128
+ if (msg['msg_type'] == 'status' and
129
+ msg['content']['execution_state'] == 'idle'):
130
+ break
131
+
132
+ return self.remove_ansi(output).strip()
133
+
134
+ def send_output(self, output: str):
135
+ """
136
+ Send the output to the output.
137
+
138
+ :param output: Output.
139
+ :return: Output.
140
+ """
141
+ if self.signals is not None:
142
+ self.signals.ipython_output.emit(output)
143
+
144
+ def remove_ansi_more(self, text):
145
+ """
146
+ Clean the text from ANSI escape sequences, carriage returns, and progress bars.
147
+
148
+ :param text: Text to clean.
149
+ :return: Cleaned text.
150
+ """
151
+ # Remove ANSI escape sequences
152
+ ansi_escape = re.compile(r'''
153
+ \x1B # ESC
154
+ (?: # Start of sequence
155
+ [@-Z\\-_] # ESC [@ to ESC _ (7-bit C1 Control codes)
156
+ | # or
157
+ \[ # ESC[
158
+ [0-?]* # Parameter bytes
159
+ [ -/]* # Intermediate bytes
160
+ [@-~] # Final byte
161
+ )
162
+ ''', re.VERBOSE)
163
+ text = ansi_escape.sub('', text)
164
+
165
+ # Split text into lines
166
+ lines = text.split('\n')
167
+
168
+ cleaned_lines = []
169
+ for line in lines:
170
+ # Handle carriage returns - keep only the text after the last '\r'
171
+ if '\r' in line:
172
+ line = line.split('\r')[-1]
173
+ # Optionally, remove progress bar lines by detecting lines containing box-drawing characters
174
+ # Skip the line if it contains box-drawing characters
175
+ if re.search(r'[\u2500-\u257F]', line):
176
+ continue # Skip this line
177
+ # Append the cleaned line
178
+ cleaned_lines.append(line)
179
+ # Reconstruct the text
180
+ text = '\n'.join(cleaned_lines)
181
+ return text
182
+
183
+ def remove_ansi(self, text) -> str:
184
+ """
185
+ Clean the text from ANSI escape sequences.
186
+
187
+ :param text: Text to clean.
188
+ :return: Cleaned text.
189
+ """
190
+ ansi_escape = re.compile(
191
+ r'''
192
+ \x1B # ESC
193
+ (?: # 7-bit C1 Fe
194
+ [@-Z\\-_]
195
+ | # or 8-bit C1 Fe
196
+ \[
197
+ [0-?]* # Parameter bytes
198
+ [ -/]* # Intermediate bytes
199
+ [@-~] # Final byte
200
+ )
201
+ ''',
202
+ re.VERBOSE
203
+ )
204
+ return ansi_escape.sub('', text)
205
+
206
+ def attach_signals(self, signals):
207
+ """
208
+ Attach signals
209
+
210
+ :param signals: signals
211
+ """
212
+ self.signals = signals
213
+
214
+ def log(self, msg):
215
+ """
216
+ Log the message.
217
+
218
+ :param msg: Message to log.
219
+ """
220
+ print(msg)
@@ -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 22:00:00 #
9
+ # Updated Date: 2024.11.26 04:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os.path
@@ -140,7 +140,7 @@ class Runner:
140
140
 
141
141
  # append to ctx
142
142
  ctx.files = paths
143
- ctx.images = images_list
143
+ ctx.images = self.plugin.window.core.filesystem.make_local_list(list(images_list))
144
144
  return paths
145
145
 
146
146
  def handle_result_ipython(self, ctx: CtxItem, response) -> str:
@@ -416,7 +416,7 @@ class Runner:
416
416
  self.log("Connecting to IPython interpreter...", sandbox=True)
417
417
  try:
418
418
  self.log("Please wait...", sandbox=True)
419
- result = self.plugin.ipython.execute(data, current=False)
419
+ result = self.plugin.get_interpreter().execute(data, current=False)
420
420
  result = self.handle_result_ipython(ctx, result)
421
421
  except Exception as e:
422
422
  self.error(e)
@@ -461,7 +461,7 @@ class Runner:
461
461
  self.log("Connecting to IPython interpreter...", sandbox=True)
462
462
  try:
463
463
  self.log("Please wait...", sandbox=True)
464
- result = self.plugin.ipython.execute(data, current=True)
464
+ result = self.plugin.get_interpreter().execute(data, current=True)
465
465
  result = self.handle_result_ipython(ctx, result)
466
466
  except Exception as e:
467
467
  self.error(e)
@@ -489,7 +489,7 @@ class Runner:
489
489
  self.log("Connecting to IPython interpreter...", sandbox=True)
490
490
  try:
491
491
  self.log("Restarting IPython kernel...", sandbox=True)
492
- response = self.plugin.ipython.restart_kernel()
492
+ response = self.plugin.get_interpreter().restart_kernel()
493
493
  except Exception as e:
494
494
  self.error(e)
495
495
  response = False
@@ -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.24 04:00:00 #
9
+ # Updated Date: 2024.11.26 04:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Slot, QTimer
@@ -141,7 +141,9 @@ class Plugin(BasePlugin):
141
141
  self.window.controller.attachment.clear_silent()
142
142
  path = self.window.controller.painter.capture.screenshot(attach_cursor=True,
143
143
  silent=True) # attach screenshot
144
- ctx.images.append(path)
144
+
145
+ img_path = self.window.core.filesystem.make_local(path)
146
+ ctx.images.append(img_path)
145
147
  #ctx.images_before.append(path)
146
148
 
147
149
  context = BridgeContext()
@@ -29,6 +29,26 @@ class Config(BaseConfig):
29
29
  dockerfile += '\n\n'
30
30
  dockerfile += '# Data directory, bound as a volume to the local \'data/\' directory'
31
31
  dockerfile += '\nWORKDIR /data'
32
+
33
+ volumes_keys = {
34
+ "enabled": "bool",
35
+ "docker": "text",
36
+ "host": "text",
37
+ }
38
+ volumes_items = [
39
+ {
40
+ "enabled": True,
41
+ "docker": "/data",
42
+ "host": "{workdir}",
43
+ },
44
+ ]
45
+ ports_keys = {
46
+ "enabled": "bool",
47
+ "docker": "text",
48
+ "host": "int",
49
+ }
50
+ ports_items = []
51
+
32
52
  plugin.add_option(
33
53
  "sandbox_docker",
34
54
  type="bool",
@@ -61,6 +81,36 @@ class Config(BaseConfig):
61
81
  label="Docker container name",
62
82
  tab="sandbox",
63
83
  )
84
+ plugin.add_option(
85
+ "docker_entrypoint",
86
+ type="text",
87
+ value='tail -f /dev/null',
88
+ label="Docker run command",
89
+ tab="sandbox",
90
+ advanced=True,
91
+ )
92
+ plugin.add_option(
93
+ "docker_volumes",
94
+ type="dict",
95
+ value=volumes_items,
96
+ label="Docker volumes",
97
+ description="Docker volumes mapping",
98
+ tooltip="Docker volumes mapping",
99
+ keys=volumes_keys,
100
+ tab="sandbox",
101
+ advanced=True,
102
+ )
103
+ plugin.add_option(
104
+ "docker_ports",
105
+ type="dict",
106
+ value=ports_items,
107
+ label="Docker ports",
108
+ description="Docker ports mapping",
109
+ tooltip="Docker ports mapping",
110
+ keys=ports_keys,
111
+ tab="sandbox",
112
+ advanced=True,
113
+ )
64
114
  plugin.add_option(
65
115
  "auto_cwd",
66
116
  type="bool",
@@ -26,6 +26,10 @@ class Docker(BaseDocker):
26
26
  """Run image build"""
27
27
  self.builder.build_image()
28
28
 
29
+ def build_and_restart(self):
30
+ """Run image build and restart container"""
31
+ self.builder.build_image(restart=True)
32
+
29
33
  def get_dockerfile(self) -> str:
30
34
  """
31
35
  Get the Dockerfile
@@ -71,7 +71,7 @@ class Plugin(BasePlugin):
71
71
  if "mode" in data:
72
72
  self.mode = data['mode']
73
73
 
74
- elif name == Event.POST_PROMPT:
74
+ elif name == Event.POST_PROMPT_ASYNC:
75
75
  if self.mode in self.ignored_modes: # ignore
76
76
  return
77
77
 
@@ -167,6 +167,22 @@ class Plugin(BasePlugin):
167
167
  prepared_question = response
168
168
  return prepared_question
169
169
 
170
+ def get_from_retrieval(self, query: str) -> str:
171
+ """
172
+ Get response from retrieval
173
+
174
+ :param query: query
175
+ :return: response
176
+ """
177
+ idx = self.get_option_value("idx")
178
+ indexes = idx.split(",")
179
+ response = ""
180
+ for index in indexes:
181
+ response = self.window.core.idx.chat.query_retrieval(query, index)
182
+ if response is not None and response != "":
183
+ break
184
+ print(response)
185
+ return response
170
186
 
171
187
  def on_post_prompt(self, prompt: str, ctx: CtxItem) -> str:
172
188
  """
@@ -188,6 +204,12 @@ class Plugin(BasePlugin):
188
204
 
189
205
  self.log("Querying Llama-index for: " + question)
190
206
 
207
+ # at first, try to get from retrieval
208
+ response = self.get_from_retrieval(question)
209
+ if response is not None and response != "":
210
+ self.log("Found using retrieval...")
211
+ return prompt + "\nADDITIONAL CONTEXT: " + response
212
+
191
213
  response, doc_ids, metas = self.query(question)
192
214
  if response is None or len(response) == 0:
193
215
  self.log("No additional context. Aborting.")
@@ -69,6 +69,16 @@ class Worker(BaseWorker):
69
69
  """
70
70
  question = self.get_param(item, "query")
71
71
  self.status("Please wait... querying: {}...".format(question))
72
+ # at first, try to get from retrieval
73
+ response = self.plugin.get_from_retrieval(question)
74
+ if response is not None and response != "":
75
+ self.log("Found using retrieval...")
76
+ context = "ADDITIONAL CONTEXT (response from DB):\n--------------------------------\n" + response
77
+ extra = {
78
+ "context": context,
79
+ }
80
+ return self.make_response(item, response, extra=extra)
81
+
72
82
  content, doc_ids, metas = self.plugin.query(question) # send question to Llama-index
73
83
  result = content
74
84
  context = "ADDITIONAL CONTEXT (response from DB):\n--------------------------------\n" + content
@@ -6,13 +6,14 @@
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: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.types import (
13
13
  MODE_AGENT,
14
14
  MODE_AGENT_LLAMA,
15
15
  MODE_ASSISTANT,
16
+ MODE_AUDIO,
16
17
  MODE_CHAT,
17
18
  MODE_LANGCHAIN,
18
19
  MODE_LLAMA_INDEX,
@@ -44,6 +45,7 @@ class Plugin(BasePlugin):
44
45
  MODE_LLAMA_INDEX,
45
46
  MODE_ASSISTANT,
46
47
  MODE_AGENT,
48
+ MODE_AUDIO,
47
49
  ]
48
50
  self.allowed_cmds = [
49
51
  "image",
@@ -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: 2024.11.24 04:00:00 #
9
+ # Updated Date: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.types import (
13
13
  MODE_AGENT,
14
14
  MODE_AGENT_LLAMA,
15
+ MODE_AUDIO,
15
16
  MODE_LANGCHAIN,
16
17
  MODE_LLAMA_INDEX,
17
18
  MODE_VISION,
@@ -59,6 +60,7 @@ class Plugin(BasePlugin):
59
60
  MODE_AGENT_LLAMA,
60
61
  MODE_LLAMA_INDEX,
61
62
  MODE_LANGCHAIN,
63
+ MODE_AUDIO,
62
64
  ]
63
65
  self.worker = None
64
66
  self.config = Config(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: 2023.12.31 04:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -143,6 +143,7 @@ class JsonFileProvider(BaseProvider):
143
143
  'remote': attachment.remote,
144
144
  'send': attachment.send,
145
145
  'vector_store_ids': attachment.vector_store_ids,
146
+ 'type': attachment.type,
146
147
  }
147
148
 
148
149
  @staticmethod
@@ -165,6 +166,8 @@ class JsonFileProvider(BaseProvider):
165
166
  attachment.send = data['send']
166
167
  if 'vector_store_ids' in data:
167
168
  attachment.vector_store_ids = data['vector_store_ids']
169
+ if 'type' in data:
170
+ attachment.type = data['type']
168
171
 
169
172
  def dump(self, item: AttachmentItem) -> str:
170
173
  """
@@ -1692,6 +1692,31 @@ class Patch:
1692
1692
  'ctx.attachment.img')
1693
1693
  updated = True
1694
1694
 
1695
+ # < 2.4.29
1696
+ if old < parse_version("2.4.29"):
1697
+ print("Migrating config from < 2.4.29...")
1698
+ if 'cmd_code_interpreter' in data['plugins'] \
1699
+ and 'ipython_dockerfile' in data['plugins']['cmd_code_interpreter']:
1700
+ # remove
1701
+ del data['plugins']['cmd_code_interpreter']['ipython_dockerfile']
1702
+ updated = True
1703
+
1704
+ # < 2.4.31
1705
+ if old < parse_version("2.4.31"):
1706
+ print("Migrating config from < 2.4.31...")
1707
+ if 'attachments_auto_index' not in data:
1708
+ data["attachments_auto_index"] = self.window.core.config.get_base(
1709
+ 'attachments_auto_index')
1710
+ updated = True
1711
+
1712
+ # < 2.4.34
1713
+ if old < parse_version("2.4.34"):
1714
+ print("Migrating config from < 2.4.34...")
1715
+ if 'ctx.attachment.query.model' not in data:
1716
+ data["ctx.attachment.query.model"] = self.window.core.config.get_base(
1717
+ 'ctx.attachment.query.model')
1718
+ updated = True
1719
+
1695
1720
  # update file
1696
1721
  migrated = False
1697
1722
  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: 2024.11.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from datetime import datetime
@@ -718,7 +718,9 @@ class Storage:
718
718
  output_tokens,
719
719
  total_tokens,
720
720
  is_internal,
721
- docs_json
721
+ docs_json,
722
+ audio_id,
723
+ audio_expires_ts
722
724
  )
723
725
  VALUES
724
726
  (
@@ -749,7 +751,9 @@ class Storage:
749
751
  :output_tokens,
750
752
  :total_tokens,
751
753
  :is_internal,
752
- :docs_json
754
+ :docs_json,
755
+ :audio_id,
756
+ :audio_expires_ts
753
757
  )
754
758
  """).bindparams(
755
759
  meta_id=int(meta.id),
@@ -780,6 +784,8 @@ class Storage:
780
784
  total_tokens=int(item.total_tokens or 0),
781
785
  is_internal=int(item.internal),
782
786
  docs_json=pack_item_value(item.doc_ids),
787
+ audio_id=item.audio_id,
788
+ audio_expires_ts=int(item.audio_expires_ts or 0)
783
789
  )
784
790
  with db.begin() as conn:
785
791
  result = conn.execute(stmt)
@@ -822,7 +828,9 @@ class Storage:
822
828
  output_tokens = :output_tokens,
823
829
  total_tokens = :total_tokens,
824
830
  is_internal = :is_internal,
825
- docs_json = :docs_json
831
+ docs_json = :docs_json,
832
+ audio_id = :audio_id,
833
+ audio_expires_ts = :audio_expires_ts
826
834
  WHERE id = :id
827
835
  """).bindparams(
828
836
  id=item.id,
@@ -852,6 +860,8 @@ class Storage:
852
860
  total_tokens=int(item.total_tokens or 0),
853
861
  is_internal=int(item.internal or 0),
854
862
  docs_json=pack_item_value(item.doc_ids),
863
+ audio_id=item.audio_id,
864
+ audio_expires_ts=int(item.audio_expires_ts or 0)
855
865
  )
856
866
  with db.begin() as conn:
857
867
  conn.execute(stmt)
@@ -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.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -158,11 +158,28 @@ def unpack_item(item: CtxItem, row: dict) -> CtxItem:
158
158
  item.total_tokens = unpack_var(row['total_tokens'], 'int')
159
159
  item.internal = unpack_var(row['is_internal'], 'bool')
160
160
  item.doc_ids = unpack_item_value(row['docs_json'])
161
-
161
+ item.audio_id = row['audio_id']
162
+ item.audio_expires_ts = row['audio_expires_ts']
163
+
164
+ # set defaults
165
+ if item.cmds is None:
166
+ item.cmds = []
167
+ if item.results is None:
168
+ item.results = []
169
+ if item.urls is None:
170
+ item.urls = []
171
+ if item.images is None:
172
+ item.images = []
173
+ if item.files is None:
174
+ item.files = []
175
+ if item.attachments is None:
176
+ item.attachments = []
162
177
  if item.additional_ctx is None:
163
178
  item.additional_ctx = []
164
179
  if item.doc_ids is None:
165
180
  item.doc_ids = []
181
+ if item.extra is None:
182
+ item.extra = {}
166
183
  return item
167
184
 
168
185
 
@@ -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.15 00:00:00 #
9
+ # Updated Date: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from packaging.version import parse as parse_version, Version
@@ -308,6 +308,12 @@ class Patch:
308
308
  model.mode.append("agent_llama")
309
309
  updated = True
310
310
 
311
+ # < 2.4.34 <--- add gpt-4o-audio-preview, gpt-4o-2024-11-20
312
+ if old < parse_version("2.4.34"):
313
+ print("Migrating models from < 2.4.34...")
314
+ # add missing gpt-4o-audio-preview, gpt-4o-2024-11-20
315
+ updated = True
316
+
311
317
  # update file
312
318
  if updated:
313
319
  data = dict(sorted(data.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: 2024.11.21 20:00:00 #
9
+ # Updated Date: 2024.11.26 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -18,6 +18,7 @@ from pygpt_net.core.types import (
18
18
  MODE_AGENT,
19
19
  MODE_AGENT_LLAMA,
20
20
  MODE_ASSISTANT,
21
+ MODE_AUDIO,
21
22
  MODE_CHAT,
22
23
  MODE_COMPLETION,
23
24
  MODE_EXPERT,
@@ -193,6 +194,7 @@ class JsonFileProvider(BaseProvider):
193
194
  MODE_AGENT: item.agent,
194
195
  MODE_AGENT_LLAMA: item.agent_llama,
195
196
  MODE_EXPERT: item.expert,
197
+ MODE_AUDIO: item.audio,
196
198
  'temperature': item.temperature,
197
199
  'filename': item.filename,
198
200
  'model': item.model,
@@ -232,6 +234,8 @@ class JsonFileProvider(BaseProvider):
232
234
  item.agent_llama = data[MODE_AGENT_LLAMA]
233
235
  if MODE_EXPERT in data:
234
236
  item.expert = data[MODE_EXPERT]
237
+ if MODE_AUDIO in data:
238
+ item.audio = data[MODE_AUDIO]
235
239
 
236
240
  if 'uuid' in data:
237
241
  item.uuid = data['uuid']