pygpt-net 2.6.20__py3-none-any.whl → 2.6.21__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 (89) hide show
  1. pygpt_net/CHANGELOG.txt +9 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/controller/agent/agent.py +130 -2
  4. pygpt_net/controller/agent/experts.py +93 -96
  5. pygpt_net/controller/agent/llama.py +2 -1
  6. pygpt_net/controller/assistant/assistant.py +18 -1
  7. pygpt_net/controller/attachment/attachment.py +17 -1
  8. pygpt_net/controller/camera/camera.py +15 -7
  9. pygpt_net/controller/chat/chat.py +2 -2
  10. pygpt_net/controller/chat/common.py +50 -33
  11. pygpt_net/controller/chat/image.py +67 -77
  12. pygpt_net/controller/chat/input.py +94 -166
  13. pygpt_net/controller/chat/output.py +83 -140
  14. pygpt_net/controller/chat/response.py +83 -102
  15. pygpt_net/controller/chat/text.py +116 -149
  16. pygpt_net/controller/ctx/common.py +2 -1
  17. pygpt_net/controller/ctx/ctx.py +86 -6
  18. pygpt_net/controller/files/files.py +13 -1
  19. pygpt_net/controller/idx/idx.py +26 -2
  20. pygpt_net/controller/kernel/reply.py +53 -66
  21. pygpt_net/controller/kernel/stack.py +16 -16
  22. pygpt_net/controller/model/importer.py +2 -1
  23. pygpt_net/controller/model/model.py +62 -3
  24. pygpt_net/controller/settings/editor.py +4 -4
  25. pygpt_net/controller/ui/ui.py +16 -2
  26. pygpt_net/core/agents/observer/evaluation.py +3 -3
  27. pygpt_net/core/agents/provider.py +25 -3
  28. pygpt_net/core/agents/runner.py +4 -1
  29. pygpt_net/core/agents/runners/llama_workflow.py +19 -7
  30. pygpt_net/core/agents/runners/loop.py +3 -1
  31. pygpt_net/core/agents/runners/openai_workflow.py +17 -3
  32. pygpt_net/core/agents/tools.py +4 -1
  33. pygpt_net/core/bridge/context.py +34 -37
  34. pygpt_net/core/ctx/ctx.py +1 -1
  35. pygpt_net/core/db/database.py +2 -2
  36. pygpt_net/core/debug/debug.py +12 -1
  37. pygpt_net/core/dispatcher/dispatcher.py +24 -1
  38. pygpt_net/core/events/app.py +7 -7
  39. pygpt_net/core/events/control.py +26 -26
  40. pygpt_net/core/events/event.py +6 -3
  41. pygpt_net/core/events/kernel.py +2 -2
  42. pygpt_net/core/events/render.py +13 -13
  43. pygpt_net/core/experts/experts.py +76 -82
  44. pygpt_net/core/experts/worker.py +12 -12
  45. pygpt_net/core/models/models.py +5 -1
  46. pygpt_net/core/models/ollama.py +14 -5
  47. pygpt_net/core/render/web/helpers.py +2 -2
  48. pygpt_net/core/render/web/renderer.py +4 -4
  49. pygpt_net/core/types/__init__.py +2 -1
  50. pygpt_net/core/types/agent.py +4 -4
  51. pygpt_net/core/types/base.py +19 -0
  52. pygpt_net/core/types/console.py +6 -6
  53. pygpt_net/core/types/mode.py +8 -8
  54. pygpt_net/core/types/multimodal.py +3 -3
  55. pygpt_net/core/types/openai.py +2 -1
  56. pygpt_net/data/config/config.json +4 -4
  57. pygpt_net/data/config/models.json +19 -3
  58. pygpt_net/data/config/settings.json +14 -14
  59. pygpt_net/data/locale/locale.en.ini +2 -2
  60. pygpt_net/item/ctx.py +256 -240
  61. pygpt_net/item/model.py +59 -116
  62. pygpt_net/item/preset.py +122 -105
  63. pygpt_net/provider/agents/llama_index/workflow/planner.py +3 -3
  64. pygpt_net/provider/agents/openai/agent.py +4 -12
  65. pygpt_net/provider/agents/openai/agent_b2b.py +10 -15
  66. pygpt_net/provider/agents/openai/agent_planner.py +4 -4
  67. pygpt_net/provider/agents/openai/agent_with_experts.py +3 -7
  68. pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +4 -8
  69. pygpt_net/provider/agents/openai/agent_with_feedback.py +4 -8
  70. pygpt_net/provider/agents/openai/bot_researcher.py +2 -18
  71. pygpt_net/provider/agents/openai/bots/__init__.py +0 -0
  72. pygpt_net/provider/agents/openai/bots/research_bot/__init__.py +0 -0
  73. pygpt_net/provider/agents/openai/bots/research_bot/agents/__init__.py +0 -0
  74. pygpt_net/provider/agents/openai/bots/research_bot/agents/planner_agent.py +1 -1
  75. pygpt_net/provider/agents/openai/bots/research_bot/agents/search_agent.py +1 -0
  76. pygpt_net/provider/agents/openai/bots/research_bot/agents/writer_agent.py +1 -1
  77. pygpt_net/provider/agents/openai/bots/research_bot/manager.py +1 -10
  78. pygpt_net/provider/agents/openai/evolve.py +5 -9
  79. pygpt_net/provider/agents/openai/supervisor.py +4 -8
  80. pygpt_net/provider/core/config/patch.py +10 -3
  81. pygpt_net/provider/core/ctx/db_sqlite/utils.py +43 -43
  82. pygpt_net/provider/core/model/patch.py +11 -1
  83. pygpt_net/provider/core/preset/json_file.py +47 -49
  84. pygpt_net/provider/gpt/agents/experts.py +2 -2
  85. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.21.dist-info}/METADATA +13 -6
  86. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.21.dist-info}/RECORD +86 -85
  87. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.21.dist-info}/LICENSE +0 -0
  88. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.21.dist-info}/WHEEL +0 -0
  89. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.21.dist-info}/entry_points.txt +0 -0
pygpt_net/item/ctx.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.24 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -18,81 +18,80 @@ from typing import Optional
18
18
 
19
19
  class CtxItem:
20
20
 
21
- def __init__(self, mode=None):
21
+ def __init__(self, mode: Optional[str] = None):
22
22
  """
23
23
  Context item
24
24
 
25
- :param mode: Mode (completion, chat, img, vision, langchain, assistant, llama_index, agent, expert)
25
+ :param mode: Mode
26
26
  """
27
- self.id = None
28
- self.meta = None # CtxMeta object
29
- self.meta_id = None
30
- self.external_id = None
31
- self.stream = None
27
+ self.additional_ctx = []
28
+ self.agent_call = False # prevents plugin reply if True
29
+ self.agent_final_response = ""
30
+ self.async_disabled = False # async disabled
31
+ self.attachments = []
32
+ self.attachments_before = []
33
+ self.audio_expires_ts = 0
34
+ self.audio_id = None
35
+ self.audio_output = None
36
+ self.bag = None
32
37
  self.cmds = []
33
38
  self.cmds_before = []
34
- self.results = []
35
- self.urls = []
36
- self.urls_before = []
37
- self.images = []
38
- self.images_before = []
39
+ self.current = False
40
+ self.doc_ids = [] # document ids
41
+ self.external_id = None
42
+ self.extra = {}
43
+ self.extra_ctx = None
39
44
  self.files = []
40
45
  self.files_before = []
41
- self.attachments = []
42
- self.attachments_before = []
43
- self.additional_ctx = []
44
- self.reply = False
46
+ self.first = False
47
+ self.force_call = False # force call even if command is not present
48
+ self.hidden = False # hidden context
49
+ self.hidden_input = None
50
+ self.hidden_output = None
51
+ self.id = None
52
+ self.idx = 0
53
+ self.images = []
54
+ self.images_before = []
55
+ self.index_meta = {} # llama-index metadata ctx used
45
56
  self.input = None
46
- self.output = None
47
- self.mode = mode
48
- self.model = None
49
- self.thread = None
50
- self.msg_id = None
51
- self.run_id = None
52
57
  self.input_name = None
53
- self.output_name = None
54
58
  self.input_timestamp = None
55
- self.output_timestamp = None
56
- self.hidden_input = None
57
- self.hidden_output = None
58
59
  self.input_tokens = 0
59
- self.output_tokens = 0
60
- self.total_tokens = 0
61
- self.extra = {}
62
- self.extra_ctx = None
63
- self.current = False
64
60
  self.internal = False
65
- self.is_vision = False
66
61
  self.is_audio = False
67
- self.idx = 0
68
- self.first = False
62
+ self.is_vision = False
69
63
  self.live = False # True if is current flow (not loaded from DB)
70
- self.agent_call = False # prevents plugin reply if True
71
- self.agent_final_response = ""
72
- self.use_agent_final_response = False # use agent final response
73
- self.stream_agent_output = True # stream agent output in real-time
74
- self.tool_calls = [] # API tool calls
75
- self.index_meta = {} # llama-index metadata ctx used
76
- self.doc_ids = [] # document ids
64
+ self.live_output = ""
65
+ self.meta = None # CtxMeta object
66
+ self.meta_id = None
67
+ self.model = None
68
+ self.mode = mode
69
+ self.msg_id = None
70
+ self.output = None
71
+ self.output_name = None
72
+ self.output_timestamp = None
73
+ self.output_tokens = 0
74
+ self.partial = False # not final output, used in cycle next ctx, force wait for final output, do not eval, etc
75
+ self.pid = 0
77
76
  self.prev_ctx = None # previous context (reply output)
77
+ self.reply = False
78
+ self.response = None # response object
79
+ self.results = []
80
+ self.run_id = None
78
81
  self.stopped = False # run stopped
79
- self.sub_calls = 0 # sub calls count
82
+ self.stream = None
83
+ self.stream_agent_output = True # stream agent output in real-time
80
84
  self.sub_call = False # is sub call
85
+ self.sub_calls = 0 # sub calls count
81
86
  self.sub_reply = False # sub call reply
82
87
  self.sub_tool_call = False # sub tool call
83
- self.hidden = False # hidden context
88
+ self.thread = None
89
+ self.tool_calls = [] # API tool calls
90
+ self.total_tokens = 0
91
+ self.urls = []
92
+ self.urls_before = []
93
+ self.use_agent_final_response = False # use agent final response
84
94
  self.use_responses_api = False # use responses API format
85
- self.pid = 0
86
- self.audio_id = None
87
- self.audio_output = None
88
- self.audio_expires_ts = 0
89
- self.response = None # response object
90
- self.async_disabled = False # async disabled
91
- self.bag = None
92
- self.live_output = ""
93
- self.force_call = False # force call even if command is not present
94
- self.partial = False # not final output, used in cycle next ctx, force wait for final output, do not eval, etc
95
-
96
95
 
97
96
  @property
98
97
  def final_input(self) -> Optional[str]:
@@ -127,23 +126,23 @@ class CtxItem:
127
126
  self.urls_before = []
128
127
 
129
128
  def from_previous(self):
130
- """Copy data from previous context reply to current context"""
129
+ """Copy data from previous context item"""
131
130
  p = self.prev_ctx
132
131
  if not p:
133
132
  return
134
133
  dp = copy.deepcopy
135
- if p.urls or p.urls_before:
136
- src = p.urls_before if p.urls_before else p.urls
137
- if src:
138
- self.urls = dp(src)
139
- if p.images or p.images_before:
140
- src = p.images_before if p.images_before else p.images
134
+ for name in ("urls", "images", "files", "attachments"):
135
+ src = getattr(p, f"{name}_before", None) or getattr(p, name, None)
141
136
  if src:
142
- self.images = dp(src)
143
- if p.files_before:
144
- self.files = dp(p.files_before)
145
- if p.attachments_before:
146
- self.attachments = dp(p.attachments_before)
137
+ setattr(self, name, dp(src))
138
+
139
+ def is_empty(self) -> bool:
140
+ """
141
+ Check if context item is empty
142
+
143
+ :return: True if context item is empty
144
+ """
145
+ return not self.final_output and not self.stream and not self.live_output
147
146
 
148
147
  def has_commands(self) -> bool:
149
148
  """
@@ -175,7 +174,7 @@ class CtxItem:
175
174
  self.index_meta = meta
176
175
  self.doc_ids.append(meta)
177
176
 
178
- def set_input(self, input: str | None, name: str = None):
177
+ def set_input(self, input: Optional[str], name: Optional[str] = None):
179
178
  """
180
179
  Set input
181
180
 
@@ -186,7 +185,7 @@ class CtxItem:
186
185
  self.input_name = name
187
186
  self.input_timestamp = int(time.time())
188
187
 
189
- def set_output(self, output: str | None, name: str = None):
188
+ def set_output(self, output: Optional[str], name: Optional[str] = None):
190
189
  """
191
190
  Set output
192
191
 
@@ -216,7 +215,12 @@ class CtxItem:
216
215
  self.output_tokens = output_tokens
217
216
  self.total_tokens = input_tokens + output_tokens
218
217
 
219
- def get_pid(self):
218
+ def get_pid(self) -> int:
219
+ """
220
+ Get context item PID (process ID)
221
+
222
+ :return: int
223
+ """
220
224
  return 0
221
225
 
222
226
  def to_dict(self, dump: bool = False, format: bool = False) -> dict:
@@ -228,72 +232,71 @@ class CtxItem:
228
232
  :return: dict
229
233
  """
230
234
  data = {
231
- "id": self.id,
232
- "meta_id": self.meta_id,
233
- "idx": self.idx,
234
- "first": self.first,
235
- "live": self.live,
236
- "hidden": False,
237
- "internal": self.internal,
238
- "external_id": self.external_id,
239
- # "stream": self.stream, # <-- do not dump stream response object
240
- "reply": self.reply,
241
- "current": self.current,
242
- "stopped": self.stopped,
243
- "is_audio": self.is_audio,
244
- "is_vision": self.is_vision,
245
235
  "agent_call": self.agent_call,
246
- "tool_calls": self.tool_calls,
247
- "index_meta": self.index_meta,
236
+ "attachments": self.attachments,
237
+ "attachments_before": self.attachments_before,
238
+ "audio_expires_ts": self.audio_expires_ts,
239
+ "audio_id": self.audio_id,
240
+ "cmds": self.cmds,
241
+ "cmds_before": self.cmds_before,
242
+ "current": self.current,
248
243
  "doc_ids": self.doc_ids,
249
- "sub_calls": 0,
250
- "sub_call": False,
251
- "sub_reply": False,
252
- "sub_tool_call": False,
244
+ "external_id": self.external_id,
253
245
  "extra": self.extra,
254
246
  "extra_ctx": self.extra_ctx,
255
- "cmds": self.cmds,
256
- "cmds_before": self.cmds_before,
257
- "results": self.results,
258
- "urls": self.urls,
259
- "urls_before": self.urls_before,
260
- "images": self.images,
261
- "images_before": self.images_before,
262
247
  "files": self.files,
263
248
  "files_before": self.files_before,
264
- "attachments": self.attachments,
265
- "attachments_before": self.attachments_before,
266
- "pid": self.pid,
249
+ "first": self.first,
250
+ "force_call": self.force_call,
251
+ "hidden": False,
252
+ "hidden_input": self.hidden_input,
253
+ "hidden_output": self.hidden_output,
254
+ "id": self.id,
255
+ "idx": self.idx,
256
+ "images": self.images,
257
+ "images_before": self.images_before,
258
+ "index_meta": self.index_meta,
259
+ "input": self.input,
260
+ "input_name": self.input_name,
261
+ "input_timestamp": self.input_timestamp,
262
+ "input_tokens": self.input_tokens,
263
+ "internal": self.internal,
264
+ "is_audio": self.is_audio,
265
+ "is_vision": self.is_vision,
266
+ "live": self.live,
267
+ "meta": self.meta.to_dict() if type(self.meta) == CtxMeta else self.meta,
268
+ "meta_id": self.meta_id,
267
269
  "mode": self.mode,
268
270
  "model": self.model,
269
- "thread": self.thread,
270
271
  "msg_id": self.msg_id,
271
- "run_id": self.run_id,
272
- "audio_id": self.audio_id,
273
- "audio_expires_ts": self.audio_expires_ts,
274
- "input": self.input,
275
272
  "output": self.output,
276
- 'hidden_input': self.hidden_input,
277
- 'hidden_output': self.hidden_output,
278
- "input_name": self.input_name,
279
273
  "output_name": self.output_name,
280
- "input_timestamp": self.input_timestamp,
281
274
  "output_timestamp": self.output_timestamp,
282
- "input_tokens": self.input_tokens,
283
275
  "output_tokens": self.output_tokens,
276
+ "pid": self.pid,
277
+ "reply": self.reply,
278
+ "results": self.results,
279
+ "run_id": self.run_id,
280
+ "stopped": self.stopped,
281
+ "sub_call": False,
282
+ "sub_calls": 0,
283
+ "sub_reply": False,
284
+ "sub_tool_call": False,
285
+ "thread": self.thread,
286
+ "tool_calls": self.tool_calls,
284
287
  "total_tokens": self.total_tokens,
285
- "force_call": self.force_call,
286
- "meta": self.meta.to_dict() if type(self.meta) == CtxMeta else self.meta,
288
+ "urls": self.urls,
289
+ "urls_before": self.urls_before,
287
290
  }
288
291
  if dump:
289
- data["live_output"] = self.live_output
290
292
  data["hidden"] = self.hidden
293
+ data["live_output"] = self.live_output
291
294
  data["sub_calls"] = self.sub_calls
292
295
  data["sub_call"] = self.sub_call
293
296
  data["sub_reply"] = self.sub_reply
294
297
  data["sub_tool_call"] = self.sub_tool_call
295
298
 
296
- return data
299
+ return dict(sorted(data.items(), key=lambda item: item[0])) # sort by keys
297
300
 
298
301
  def to_debug(self):
299
302
  """
@@ -310,56 +313,56 @@ class CtxItem:
310
313
  :param data: dict
311
314
  """
312
315
  g = data.get
313
- self.id = g("id", None)
314
- self.meta = g("meta", None)
315
- self.meta_id = g("meta_id", None)
316
- self.external_id = g("external_id", None)
317
- self.stream = g("stream", None)
316
+ self.agent_call = g("agent_call", False)
317
+ self.attachments = g("attachments", [])
318
+ self.attachments_before = g("attachments_before", [])
319
+ self.audio_expires_ts = g("audio_expires_ts", None)
320
+ self.audio_id = g("audio_id", None)
318
321
  self.cmds = g("cmds", [])
319
- self.results = g("results", [])
320
- self.urls = g("urls", [])
321
- self.urls_before = g("urls_before", [])
322
- self.images = g("images", [])
323
- self.images_before = g("images_before", [])
322
+ self.current = g("current", False)
323
+ self.doc_ids = g("doc_ids", [])
324
+ self.external_id = g("external_id", None)
325
+ self.extra = g("extra", None)
326
+ self.extra_ctx = g("extra_ctx", False)
324
327
  self.files = g("files", [])
325
328
  self.files_before = g("files_before", [])
326
- self.attachments = g("attachments", [])
327
- self.attachments_before = g("attachments_before", [])
328
- self.reply = g("reply", False)
329
+ self.first = g("first", False)
330
+ self.hidden = g("hidden", False)
331
+ self.hidden_input = g("hidden_input", None)
332
+ self.hidden_output = g("hidden_output", None)
333
+ self.id = g("id", None)
334
+ self.idx = g("idx", 0)
335
+ self.images = g("images", [])
336
+ self.images_before = g("images_before", [])
337
+ self.index_meta = g("index_meta", {})
329
338
  self.input = g("input", None)
330
- self.output = g("output", None)
331
- self.mode = g("mode", None)
332
- self.model = g("model", None)
333
- self.thread = g("thread", None)
334
- self.msg_id = g("msg_id", None)
335
- self.run_id = g("run_id", None)
336
- self.audio_id = g("audio_id", None)
337
- self.audio_expires_ts = g("audio_expires_ts", None)
338
339
  self.input_name = g("input_name", None)
339
- self.output_name = g("output_name", None)
340
340
  self.input_timestamp = g("input_timestamp", None)
341
- self.output_timestamp = g("output_timestamp", None)
342
- self.hidden_input = g("hidden_input", None)
343
- self.hidden_output = g("hidden_output", None)
344
341
  self.input_tokens = g("input_tokens", 0)
345
- self.output_tokens = g("output_tokens", 0)
346
- self.total_tokens = g("total_tokens", 0)
347
- self.extra = g("extra", None)
348
- self.extra_ctx = g("extra_ctx", False)
349
- self.current = g("current", False)
350
342
  self.internal = g("internal", False)
351
343
  self.is_vision = g("is_vision", False)
352
- self.idx = g("idx", 0)
353
- self.first = g("first", False)
354
- self.agent_call = g("agent_call", False)
355
- self.tool_calls = g("tool_calls", [])
356
- self.index_meta = g("index_meta", {})
357
- self.doc_ids = g("doc_ids", [])
358
- self.sub_calls = g("sub_calls", 0)
344
+ self.meta = g("meta", None)
345
+ self.meta_id = g("meta_id", None)
346
+ self.model = g("model", None)
347
+ self.mode = g("mode", None)
348
+ self.msg_id = g("msg_id", None)
349
+ self.output = g("output", None)
350
+ self.output_name = g("output_name", None)
351
+ self.output_timestamp = g("output_timestamp", None)
352
+ self.output_tokens = g("output_tokens", 0)
353
+ self.results = g("results", [])
354
+ self.reply = g("reply", False)
355
+ self.run_id = g("run_id", None)
356
+ self.stream = g("stream", None)
359
357
  self.sub_call = g("sub_call", False)
358
+ self.sub_calls = g("sub_calls", 0)
360
359
  self.sub_reply = g("sub_reply", False)
361
360
  self.sub_tool_call = g("sub_tool_call", False)
362
- self.hidden = g("hidden", False)
361
+ self.thread = g("thread", None)
362
+ self.tool_calls = g("tool_calls", [])
363
+ self.total_tokens = g("total_tokens", 0)
364
+ self.urls = g("urls", [])
365
+ self.urls_before = g("urls_before", [])
363
366
 
364
367
 
365
368
  def dump(self, dump: bool = True) -> str:
@@ -391,42 +394,42 @@ class CtxItem:
391
394
 
392
395
  class CtxMeta:
393
396
 
394
- def __init__(self, id=None):
397
+ def __init__(self, id: Optional[int] = None):
395
398
  """
396
399
  Context meta data
397
400
 
398
401
  :param id: Context ID
399
402
  """
400
- self.id = id
401
- self.external_id = None
402
- self.uuid = None
403
- self.name = None
404
- self.date = datetime.datetime.now().strftime("%Y-%m-%d")
403
+ self.additional_ctx = [] # additional context data
404
+ self.archived = False
405
+ self.assistant = None
405
406
  self.created = int(time.time())
406
- self.updated = int(time.time())
407
+ self.date = datetime.datetime.now().strftime("%Y-%m-%d")
408
+ self.deleted = False
409
+ self.external_id = None
410
+ self.extra = None
411
+ self.group = None # parent group
412
+ self.group_id = None
413
+ self.id = id
414
+ self.important = False
407
415
  self.indexed = None
408
- self.mode = None
409
- self.model = None
416
+ self.indexes = {} # indexes data
417
+ self.initialized = False
418
+ self.label = 0 # label color
410
419
  self.last_mode = None
411
420
  self.last_model = None
412
- self.thread = None
413
- self.assistant = None
421
+ self.model = None
422
+ self.mode = None
423
+ self.name = None
424
+ self.owner_uuid = None
425
+ self.parent_id = None
414
426
  self.preset = None
427
+ self.root_id = None
415
428
  self.run = None
416
429
  self.status = None
417
- self.extra = None
418
- self.initialized = False
419
- self.deleted = False
420
- self.important = False
421
- self.archived = False
422
- self.label = 0 # label color
423
- self.indexes = {} # indexes data
424
- self.additional_ctx = [] # additional context data
425
- self.group = None # parent group
426
- self.group_id = None
427
- self.root_id = None
428
- self.parent_id = None
429
- self.owner_uuid = None
430
+ self.thread = None
431
+ self.updated = int(time.time())
432
+ self.uuid = None
430
433
 
431
434
  def has_additional_ctx(self) -> bool:
432
435
  """
@@ -490,35 +493,35 @@ class CtxMeta:
490
493
  :return: dict
491
494
  """
492
495
  data = {
493
- "id": self.id,
494
- "external_id": self.external_id,
495
- "uuid": self.uuid,
496
- "name": self.name,
497
- "date": self.date,
496
+ "additional_ctx": self.additional_ctx,
497
+ "archived": self.archived,
498
+ "assistant": self.assistant,
498
499
  "created": self.created,
499
- "updated": self.updated,
500
+ "date": self.date,
501
+ "deleted": self.deleted,
502
+ "external_id": self.external_id,
503
+ "extra": self.extra,
504
+ "group_id": self.group_id,
505
+ "id": self.id,
506
+ "important": self.important,
500
507
  "indexed": self.indexed,
501
- "mode": self.mode,
502
- "model": self.model,
508
+ "indexes": self.indexes,
509
+ "initialized": self.initialized,
510
+ "label": self.label,
503
511
  "last_mode": self.last_mode,
504
512
  "last_model": self.last_model,
505
- "thread": self.thread,
506
- "assistant": self.assistant,
513
+ "mode": self.mode,
514
+ "model": self.model,
515
+ "name": self.name,
516
+ "owner_uuid": self.owner_uuid,
517
+ "parent_id": self.parent_id,
507
518
  "preset": self.preset,
519
+ "root_id": self.root_id,
508
520
  "run": self.run,
509
521
  "status": self.status,
510
- "extra": self.extra,
511
- "initialized": self.initialized,
512
- "deleted": self.deleted,
513
- "important": self.important,
514
- "archived": self.archived,
515
- "label": self.label,
516
- "indexes": self.indexes,
517
- "additional_ctx": self.additional_ctx,
518
- "group_id": self.group_id,
519
- "root_id": self.root_id,
520
- "parent_id": self.parent_id,
521
- "owner_uuid": self.owner_uuid,
522
+ "thread": self.thread,
523
+ "updated": self.updated,
524
+ "uuid": self.uuid,
522
525
  }
523
526
  if self.group:
524
527
  data["__group__"] = self.group.to_dict()
@@ -531,37 +534,42 @@ class CtxMeta:
531
534
  :param data: dict
532
535
  """
533
536
  g = data.get
534
- self.id = g("id", None)
535
- self.external_id = g("external_id", None)
536
- self.uuid = g("uuid", None)
537
- self.name = g("name", None)
538
- self.date = g("date", None)
537
+ self.additional_ctx = g("additional_ctx", [])
538
+ self.archived = g("archived", False)
539
+ self.assistant = g("assistant", None)
539
540
  self.created = g("created", None)
540
- self.updated = g("updated", None)
541
+ self.date = g("date", None)
542
+ self.deleted = g("deleted", False)
543
+ self.external_id = g("external_id", None)
544
+ self.extra = g("extra", None)
545
+ self.group_id = g("group_id", None)
546
+ self.id = g("id", None)
547
+ self.important = g("important", False)
541
548
  self.indexed = g("indexed", None)
542
- self.mode = g("mode", None)
543
- self.model = g("model", None)
549
+ self.indexes = g("indexes", {})
550
+ self.initialized = g("initialized", False)
551
+ self.label = g("label", 0)
544
552
  self.last_mode = g("last_mode", None)
545
553
  self.last_model = g("last_model", None)
546
- self.thread = g("thread", None)
547
- self.assistant = g("assistant", None)
554
+ self.mode = g("mode", None)
555
+ self.model = g("model", None)
556
+ self.name = g("name", None)
557
+ self.owner_uuid = g("owner_uuid", None)
558
+ self.parent_id = g("parent_id", None)
548
559
  self.preset = g("preset", None)
560
+ self.root_id = g("root_id", None)
549
561
  self.run = g("run", None)
550
562
  self.status = g("status", None)
551
- self.extra = g("extra", None)
552
- self.initialized = g("initialized", False)
553
- self.deleted = g("deleted", False)
554
- self.important = g("important", False)
555
- self.archived = g("archived", False)
556
- self.label = g("label", 0)
557
- self.indexes = g("indexes", {})
558
- self.additional_ctx = g("additional_ctx", [])
559
- self.group_id = g("group_id", None)
560
- self.root_id = g("root_id", None)
561
- self.parent_id = g("parent_id", None)
562
- self.owner_uuid = g("owner_uuid", None)
563
+ self.thread = g("thread", None)
564
+ self.updated = g("updated", None)
565
+ self.uuid = g("uuid", None)
563
566
 
564
- def get_pid(self):
567
+ def get_pid(self) -> int:
568
+ """
569
+ Get context item PID (process ID)
570
+
571
+ :return: int
572
+ """
565
573
  return 0
566
574
 
567
575
  def dump(self) -> str:
@@ -576,27 +584,31 @@ class CtxMeta:
576
584
  pass
577
585
  return ""
578
586
 
579
- def __str__(self):
580
- """To string"""
587
+ def __str__(self) -> str:
588
+ """
589
+ To string
590
+
591
+ :return: JSON string
592
+ """
581
593
  return self.dump()
582
594
 
583
595
  class CtxGroup:
584
596
 
585
- def __init__(self, id=None, name=None):
597
+ def __init__(self, id: Optional[int] = None, name: Optional[str] = None):
586
598
  """
587
599
  Context group
588
600
 
589
601
  :param id: Group ID
590
602
  :param name: Group name
591
603
  """
604
+ self.additional_ctx = []
605
+ self.count = 0
606
+ self.created = int(time.time())
592
607
  self.id = id
593
- self.uuid = None
594
- self.name = name
595
608
  self.items = []
596
- self.created = int(time.time())
609
+ self.name = name
597
610
  self.updated = int(time.time())
598
- self.additional_ctx = []
599
- self.count = 0
611
+ self.uuid = None
600
612
 
601
613
  def has_additional_ctx(self) -> bool:
602
614
  """
@@ -637,14 +649,14 @@ class CtxGroup:
637
649
  :return: dict
638
650
  """
639
651
  return {
640
- "id": self.id,
641
- "uuid": self.uuid,
642
- "name": self.name,
643
- "items": self.items,
644
652
  "additional_ctx": self.additional_ctx,
653
+ "count": self.count,
645
654
  "created": self.created,
655
+ "id": self.id,
656
+ "items": self.items,
657
+ "name": self.name,
646
658
  "updated": self.updated,
647
- "count": self.count,
659
+ "uuid": self.uuid,
648
660
  }
649
661
 
650
662
  def from_dict(self, data: dict):
@@ -654,13 +666,13 @@ class CtxGroup:
654
666
  :param data: dict
655
667
  """
656
668
  g = data.get
669
+ self.count = g("count", 0)
670
+ self.created = g("created", None)
657
671
  self.id = g("id", None)
658
- self.uuid = g("uuid", None)
659
- self.name = g("name", None)
660
672
  self.items = g("items", [])
661
- self.created = g("created", None)
673
+ self.name = g("name", None)
662
674
  self.updated = g("updated", None)
663
- self.count = g("count", 0)
675
+ self.uuid = g("uuid", None)
664
676
 
665
677
  def dump(self) -> str:
666
678
  """
@@ -674,6 +686,10 @@ class CtxGroup:
674
686
  pass
675
687
  return ""
676
688
 
677
- def __str__(self):
678
- """To string"""
689
+ def __str__(self) -> str:
690
+ """
691
+ To string
692
+
693
+ :return: JSON string
694
+ """
679
695
  return self.dump()