pygpt-net 2.6.3__py3-none-any.whl → 2.6.5__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 (76) hide show
  1. pygpt_net/CHANGELOG.txt +10 -0
  2. pygpt_net/__init__.py +2 -2
  3. pygpt_net/config.py +55 -65
  4. pygpt_net/controller/__init__.py +5 -2
  5. pygpt_net/controller/chat/chat.py +38 -35
  6. pygpt_net/controller/chat/render.py +144 -217
  7. pygpt_net/controller/chat/stream.py +51 -25
  8. pygpt_net/controller/config/config.py +39 -42
  9. pygpt_net/controller/config/field/checkbox.py +16 -12
  10. pygpt_net/controller/config/field/checkbox_list.py +36 -31
  11. pygpt_net/controller/config/field/cmd.py +51 -57
  12. pygpt_net/controller/config/field/combo.py +33 -16
  13. pygpt_net/controller/config/field/dictionary.py +48 -55
  14. pygpt_net/controller/config/field/input.py +50 -32
  15. pygpt_net/controller/config/field/slider.py +40 -45
  16. pygpt_net/controller/config/field/textarea.py +20 -6
  17. pygpt_net/controller/config/placeholder.py +110 -231
  18. pygpt_net/controller/ctx/common.py +48 -49
  19. pygpt_net/controller/ctx/ctx.py +24 -4
  20. pygpt_net/controller/lang/mapping.py +57 -95
  21. pygpt_net/controller/lang/plugins.py +64 -55
  22. pygpt_net/controller/lang/settings.py +39 -38
  23. pygpt_net/controller/layout/layout.py +11 -2
  24. pygpt_net/controller/plugins/plugins.py +19 -1
  25. pygpt_net/controller/settings/profile.py +16 -4
  26. pygpt_net/controller/ui/mode.py +107 -125
  27. pygpt_net/core/bridge/bridge.py +5 -5
  28. pygpt_net/core/command/command.py +149 -219
  29. pygpt_net/core/ctx/ctx.py +94 -146
  30. pygpt_net/core/debug/debug.py +48 -58
  31. pygpt_net/core/models/models.py +74 -112
  32. pygpt_net/core/modes/modes.py +13 -21
  33. pygpt_net/core/plugins/plugins.py +154 -177
  34. pygpt_net/core/presets/presets.py +103 -176
  35. pygpt_net/core/render/web/body.py +2 -3
  36. pygpt_net/core/render/web/renderer.py +109 -180
  37. pygpt_net/core/text/utils.py +28 -44
  38. pygpt_net/core/tokens/tokens.py +104 -203
  39. pygpt_net/data/config/config.json +3 -3
  40. pygpt_net/data/config/models.json +3 -3
  41. pygpt_net/item/ctx.py +141 -139
  42. pygpt_net/plugin/agent/plugin.py +2 -1
  43. pygpt_net/plugin/audio_output/plugin.py +5 -2
  44. pygpt_net/plugin/base/plugin.py +77 -93
  45. pygpt_net/plugin/bitbucket/plugin.py +3 -2
  46. pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
  47. pygpt_net/plugin/cmd_custom/plugin.py +3 -2
  48. pygpt_net/plugin/cmd_files/plugin.py +3 -2
  49. pygpt_net/plugin/cmd_history/plugin.py +3 -2
  50. pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
  51. pygpt_net/plugin/cmd_serial/plugin.py +3 -2
  52. pygpt_net/plugin/cmd_system/plugin.py +3 -6
  53. pygpt_net/plugin/cmd_web/plugin.py +3 -2
  54. pygpt_net/plugin/experts/plugin.py +2 -2
  55. pygpt_net/plugin/facebook/plugin.py +3 -4
  56. pygpt_net/plugin/github/plugin.py +4 -2
  57. pygpt_net/plugin/google/plugin.py +3 -3
  58. pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
  59. pygpt_net/plugin/mailer/plugin.py +3 -5
  60. pygpt_net/plugin/openai_vision/plugin.py +3 -2
  61. pygpt_net/plugin/real_time/plugin.py +52 -60
  62. pygpt_net/plugin/slack/plugin.py +3 -4
  63. pygpt_net/plugin/telegram/plugin.py +3 -4
  64. pygpt_net/plugin/twitter/plugin.py +3 -4
  65. pygpt_net/tools/code_interpreter/tool.py +0 -1
  66. pygpt_net/tools/translator/tool.py +1 -1
  67. pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
  68. pygpt_net/ui/main.py +33 -29
  69. pygpt_net/ui/tray.py +61 -60
  70. pygpt_net/ui/widget/lists/context.py +2 -2
  71. pygpt_net/ui/widget/textarea/web.py +18 -14
  72. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/METADATA +12 -2
  73. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/RECORD +76 -76
  74. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/LICENSE +0 -0
  75. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/WHEEL +0 -0
  76. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.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.06.29 18:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Dict, Any
@@ -36,24 +36,21 @@ class Cmd:
36
36
  :param key: Option key
37
37
  :param option: Option data
38
38
  """
39
- if "value" not in option or option["value"] is None:
40
- option["value"] = {
41
- "enabled": False,
42
- "instruction": "",
43
- "params": [],
44
- }
45
- if "params" not in option["value"]:
46
- option["value"]["params"] = []
47
- if "enabled" not in option["value"]:
48
- option["value"]["enabled"] = False
49
- if "instruction" not in option["value"]:
50
- option["value"]["instruction"] = ""
51
-
52
- params = list(option["value"]["params"])
53
- self.window.ui.config[parent_id][key].params.items = params # replace model data list
54
- self.window.ui.config[parent_id][key].params.model.updateData(params) # update model data
55
- self.window.ui.config[parent_id][key].enabled.box.setChecked(option["value"]["enabled"])
56
- self.window.ui.config[parent_id][key].instruction.setText(str(option["value"]["instruction"]))
39
+ v = option.get("value")
40
+ if not isinstance(v, dict):
41
+ v = {"enabled": False, "instruction": "", "params": []}
42
+ option["value"] = v
43
+ else:
44
+ v.setdefault("enabled", False)
45
+ v.setdefault("instruction", "")
46
+ v.setdefault("params", [])
47
+
48
+ params = list(v["params"])
49
+ cfg = self.window.ui.config[parent_id][key]
50
+ cfg.params.items = params
51
+ cfg.params.model.updateData(params)
52
+ cfg.enabled.box.setChecked(v["enabled"])
53
+ cfg.instruction.setText(str(v["instruction"]))
57
54
 
58
55
  def apply_row(
59
56
  self,
@@ -70,10 +67,10 @@ class Cmd:
70
67
  :param values: dictionary data values
71
68
  :param idx: row index
72
69
  """
73
- # remove .params suffix
74
70
  if key.endswith(".params"):
75
- key = key.replace(".params", "")
76
- self.window.ui.config[parent_id][key].params.update_item(idx, values["params"])
71
+ key = key[:-7]
72
+ params_cfg = self.window.ui.config[parent_id][key].params
73
+ params_cfg.update_item(idx, values["params"])
77
74
 
78
75
  def get_value(
79
76
  self,
@@ -89,12 +86,12 @@ class Cmd:
89
86
  :param option: Option data
90
87
  :return: list with dictionary values
91
88
  """
92
- data = {
93
- "enabled": self.window.ui.config[parent_id][key].enabled.box.isChecked(),
94
- "instruction": self.window.ui.config[parent_id][key].instruction.toPlainText(),
95
- "params": self.window.ui.config[parent_id][key].params.model.items,
89
+ cfg = self.window.ui.config[parent_id][key]
90
+ return {
91
+ "enabled": cfg.enabled.box.isChecked(),
92
+ "instruction": cfg.instruction.toPlainText(),
93
+ "params": cfg.params.model.items,
96
94
  }
97
- return data
98
95
 
99
96
  def to_options(
100
97
  self,
@@ -108,37 +105,34 @@ class Cmd:
108
105
  :param option: dictionary items option
109
106
  :return: options dict
110
107
  """
111
- # option type: dict
112
- if option["type"] == "dict":
113
- if "keys" not in option:
108
+ ty = option.get("type")
109
+
110
+ if ty == "dict":
111
+ keys_map = option.get("keys")
112
+ if not keys_map:
114
113
  return {}
115
- options = {}
116
- for key in option["keys"]:
117
- item = option["keys"][key]
114
+ opts = {}
115
+ prefix = f"{parent_id}."
116
+ for k, item in keys_map.items():
118
117
  if isinstance(item, str):
119
- item = {
120
- "label": parent_id + '.' + key,
121
- "type": item, # field type is provided as value in this case
122
- }
123
- options[key] = item
124
- if "label" not in options[key]:
125
- options[key]["label"] = key
126
- options[key]["label"] = parent_id + "." + options[key]["label"]
127
- return options
128
-
129
- # option type: cmd
130
- elif option["type"] == "cmd":
131
- if "params_keys" not in option: # keys are stored in "params_keys" in cmd type
118
+ opts[k] = {"label": f"{prefix}{k}", "type": item}
119
+ else:
120
+ opts[k] = item
121
+ if "label" not in item:
122
+ item["label"] = f"{prefix}{k}"
123
+ return opts
124
+
125
+ elif ty == "cmd":
126
+ params_map = option.get("params_keys")
127
+ if not params_map:
132
128
  return {}
133
- options = {}
134
- for key in option["params_keys"]:
135
- item = option["params_keys"][key]
129
+ opts = {}
130
+ prefix = "dictionary.cmd.param."
131
+ for k, item in params_map.items():
136
132
  if isinstance(item, str):
137
- item = {
138
- "label": 'dictionary.cmd.param.' + key,
139
- "type": item, # field type is provided as value in this case
140
- }
141
- options[key] = item
142
- if "label" not in options[key]:
143
- options[key]["label"] = 'dictionary.cmd.param.' + key
144
- return options
133
+ opts[k] = {"label": f"{prefix}{k}", "type": item}
134
+ else:
135
+ opts[k] = item
136
+ if "label" not in item:
137
+ item["label"] = f"{prefix}{k}"
138
+ return opts
@@ -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.29 18:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Any, Dict
@@ -38,12 +38,13 @@ class Combo:
38
38
  if "value" not in option:
39
39
  return
40
40
  value = option["value"]
41
- if "idx" in option: # by idx
42
- self.window.ui.config[parent_id][key].combo.setCurrentIndex(option["idx"])
43
- else: # by value
44
- index = self.window.ui.config[parent_id][key].combo.findData(value)
41
+ combo = self.window.ui.config[parent_id][key].combo
42
+ if "idx" in option:
43
+ combo.setCurrentIndex(option["idx"])
44
+ else:
45
+ index = combo.findData(value)
45
46
  if index != -1:
46
- self.window.ui.config[parent_id][key].combo.setCurrentIndex(index)
47
+ combo.setCurrentIndex(index)
47
48
 
48
49
  def on_update(
49
50
  self,
@@ -62,11 +63,11 @@ class Combo:
62
63
  :param value: Option value
63
64
  :param hooks: Run hooks
64
65
  """
65
- # on update hooks
66
66
  if hooks:
67
- hook_name = "update.{}.{}".format(parent_id, key)
68
- if self.window.ui.has_hook(hook_name):
69
- hook = self.window.ui.get_hook(hook_name)
67
+ ui = self.window.ui
68
+ hook_name = f"update.{parent_id}.{key}"
69
+ if ui.has_hook(hook_name):
70
+ hook = ui.get_hook(hook_name)
70
71
  try:
71
72
  hook(key, value, "combo")
72
73
  except Exception as e:
@@ -88,10 +89,11 @@ class Combo:
88
89
  :param idx: return selected idx, not the value
89
90
  :return: Option text value or selected idx
90
91
  """
92
+ combo = self.window.ui.config[parent_id][key].combo
91
93
  if idx:
92
- return self.window.ui.config[parent_id][key].combo.currentIndex()
94
+ return combo.currentIndex()
93
95
  else:
94
- return self.window.ui.config[parent_id][key].combo.currentData()
96
+ return combo.currentData()
95
97
 
96
98
  def update_list(
97
99
  self,
@@ -106,7 +108,22 @@ class Combo:
106
108
  :param key: Option key
107
109
  :param items: Items dict
108
110
  """
109
- self.window.ui.config[parent_id][key].combo.clear()
110
- for item in items:
111
- self.window.ui.config[parent_id][key].combo.addItem(items[item], item)
112
- self.window.ui.config[parent_id][key].combo.setCurrentIndex(-1)
111
+ combo = self.window.ui.config[parent_id][key].combo
112
+ combo.setUpdatesEnabled(False)
113
+ try:
114
+ need_rebuild = True
115
+ if combo.count() == len(items):
116
+ i = 0
117
+ need_rebuild = False
118
+ for k, v in items.items():
119
+ if combo.itemData(i) != k or combo.itemText(i) != v:
120
+ need_rebuild = True
121
+ break
122
+ i += 1
123
+ if need_rebuild:
124
+ combo.clear()
125
+ for k, v in items.items():
126
+ combo.addItem(v, k)
127
+ combo.setCurrentIndex(-1)
128
+ finally:
129
+ combo.setUpdatesEnabled(True)
@@ -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.29 18:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Dict, Any, List
@@ -37,11 +37,15 @@ class Dictionary:
37
37
  :param key: Option key
38
38
  :param option: Option data
39
39
  """
40
- if "value" not in option or option["value"] is None:
40
+ if option.get("value") is None:
41
41
  option["value"] = []
42
- values = list(option["value"])
43
- self.window.ui.config[parent_id][key].items = values # replace model data list
44
- self.window.ui.config[parent_id][key].model.updateData(values) # update model data
42
+ values = []
43
+ else:
44
+ v = option["value"]
45
+ values = v.copy() if isinstance(v, list) else list(v)
46
+ cfg_item = self.window.ui.config[parent_id][key]
47
+ cfg_item.items = values
48
+ cfg_item.model.updateData(values)
45
49
 
46
50
  def apply_row(
47
51
  self,
@@ -58,9 +62,8 @@ class Dictionary:
58
62
  :param values: dictionary data values
59
63
  :param idx: row index
60
64
  """
61
- # if cmd type, remove .params suffix
62
65
  if key.endswith(".params"):
63
- key = key.replace(".params", "")
66
+ key = key[:-7]
64
67
  self.window.ui.config[parent_id][key].update_item(idx, values)
65
68
 
66
69
  def get_value(
@@ -103,15 +106,13 @@ class Dictionary:
103
106
  )
104
107
  return
105
108
 
106
- # delete item
107
109
  if parent_object is not None:
108
110
  parent_object.delete_item_execute(id)
109
-
110
- # on update hooks
111
111
  if hooks:
112
- hook_name = "update.{}.{}".format(parent_object, id)
113
- if self.window.ui.has_hook(hook_name):
114
- hook = self.window.ui.get_hook(hook_name)
112
+ hook_name = f"update.{parent_object}.{id}"
113
+ ui = self.window.ui
114
+ if ui.has_hook(hook_name):
115
+ hook = ui.get_hook(hook_name)
115
116
  try:
116
117
  hook(id, {}, "dictionary")
117
118
  except Exception as e:
@@ -129,20 +130,21 @@ class Dictionary:
129
130
  :param option: dictionary items option
130
131
  :return: options dict
131
132
  """
132
- if "keys" not in option:
133
+ keys = option.get("keys")
134
+ if not keys:
133
135
  return {}
134
- options = {}
135
- for key in option["keys"]:
136
- item = option["keys"][key]
136
+ options: Dict[str, Any] = {}
137
+ prefix = f"{parent_id}."
138
+ for key, item in keys.items():
137
139
  if isinstance(item, str):
138
140
  item = {
139
- "label": parent_id + '.' + key,
140
- "type": item, # field type is provided as value in this case
141
+ "label": f"{prefix}{key}",
142
+ "type": item,
141
143
  }
144
+ else:
145
+ if "label" not in item:
146
+ item["label"] = f"{prefix}{key}"
142
147
  options[key] = item
143
- if "label" not in options[key]:
144
- options[key]["label"] = key
145
- options[key]["label"] = parent_id + "." + options[key]["label"]
146
148
  return options
147
149
 
148
150
  def append_editor(
@@ -158,15 +160,12 @@ class Dictionary:
158
160
  :param option: Option dict
159
161
  :param data: Option data
160
162
  """
161
- parent_id = "dictionary." + id
163
+ parent_id = f"dictionary.{id}"
162
164
  sub_options = self.to_options(id, option)
163
- for key in sub_options:
164
- sub_option = sub_options[key]
165
- if key in data:
166
- sub_option["value"] = data[key]
167
- else:
168
- sub_option["value"] = ""
169
- self.window.controller.config.apply(
165
+ apply_fn = self.window.controller.config.apply
166
+ for key, sub_option in sub_options.items():
167
+ sub_option["value"] = data.get(key, "")
168
+ apply_fn(
170
169
  parent_id=parent_id,
171
170
  key=key,
172
171
  option=sub_option,
@@ -187,35 +186,29 @@ class Dictionary:
187
186
  :param fields: Fields dict
188
187
  :param hooks: run hooks
189
188
  """
190
- values = {}
191
- dict_id = parent + "." + option_key
192
- dialog_id = "dictionary." + parent + "." + option_key # dictionary parent ID
193
- idx = self.window.ui.dialog["editor." + dialog_id].idx # editing record idx is stored in dialog idx
194
- for key in fields:
195
- value = self.window.controller.config.get_value(
196
- parent_id="dictionary." + dict_id,
189
+ values: Dict[str, Any] = {}
190
+ dict_id = f"{parent}.{option_key}"
191
+ dialog_id = f"dictionary.{dict_id}"
192
+ dialog_key = f"editor.{dialog_id}"
193
+ ui = self.window.ui
194
+ idx = ui.dialog[dialog_key].idx
195
+ get_value_fn = self.window.controller.config.get_value
196
+ fields_parent_id = f"dictionary.{dict_id}"
197
+ for key, field in fields.items():
198
+ values[key] = get_value_fn(
199
+ parent_id=fields_parent_id,
197
200
  key=key,
198
- option=fields[key],
201
+ option=field,
199
202
  )
200
- values[key] = value
201
-
202
- # update values in dictionary item on list in parent
203
- self.apply_row(
204
- parent,
205
- option_key,
206
- values,
207
- idx,
208
- )
209
203
 
210
- # close dialog
211
- self.window.ui.dialog['editor.' + dialog_id].close()
204
+ self.apply_row(parent, option_key, values, idx)
205
+ ui.dialog[dialog_key].close()
212
206
 
213
- # on update hooks
214
207
  if hooks:
215
- hook_name = "update.{}.{}".format(parent, option_key)
216
- if self.window.ui.has_hook(hook_name):
217
- hook = self.window.ui.get_hook(hook_name)
208
+ hook_name = f"update.{parent}.{option_key}"
209
+ if ui.has_hook(hook_name):
210
+ hook = ui.get_hook(hook_name)
218
211
  try:
219
- hook(option_key, [values], "dictionary") # value must be list here
212
+ hook(option_key, [values], "dictionary")
220
213
  except Exception as e:
221
- self.window.core.debug.log(e)
214
+ self.window.core.debug.log(e)
@@ -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.29 18:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Any, Dict, Optional, Union
@@ -36,30 +36,45 @@ class Input:
36
36
  """
37
37
  if "value" not in option:
38
38
  return
39
+
40
+ ui = self.window.ui
41
+ parent = ui.config.get(parent_id)
42
+ if not parent:
43
+ return
44
+ widget = parent.get(key)
45
+ if widget is None:
46
+ return
47
+
39
48
  value = option["value"]
49
+ typ = option.get("type")
40
50
 
41
- # type
42
- if "type" in option and option["type"] == "int":
51
+ if typ == "int":
43
52
  try:
44
53
  value = round(int(value), 0)
45
- except Exception:
54
+ except (ValueError, TypeError):
46
55
  value = 0
47
- elif "type" in option and option["type"] == "float":
56
+ elif typ == "float":
48
57
  try:
49
58
  value = float(value)
50
- except Exception:
59
+ except (ValueError, TypeError):
51
60
  value = 0.0
52
61
 
53
- # min/max
54
- if "type" in option and (option["type"] == "int" or option["type"] == "float"):
55
- if value is not None:
56
- if "min" in option and (option["min"] is not None and value < option["min"]):
57
- value = option["min"]
58
- elif "max" in option and (option["max"] is not None and value > option["max"]):
59
- value = option["max"]
62
+ if typ in ("int", "float") and value is not None:
63
+ minv = option.get("min")
64
+ maxv = option.get("max")
65
+ if minv is not None and value < minv:
66
+ value = minv
67
+ elif maxv is not None and value > maxv:
68
+ value = maxv
60
69
 
61
- if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
62
- self.window.ui.config[parent_id][key].setText("{}".format(value))
70
+ new_text = str(value)
71
+ curr_val = None
72
+ if hasattr(widget, 'text'):
73
+ curr_val = widget.text()
74
+ elif hasattr(widget, 'toPlainText'):
75
+ curr_val = widget.toPlainText()
76
+ if curr_val != new_text:
77
+ widget.setText(new_text)
63
78
 
64
79
  def on_update(
65
80
  self,
@@ -68,7 +83,7 @@ class Input:
68
83
  option: Dict[str, Any],
69
84
  value: Any,
70
85
  hooks: bool = True,
71
- only_hook = False,
86
+ only_hook: bool = False,
72
87
  ):
73
88
  """
74
89
  On update event handler
@@ -84,11 +99,11 @@ class Input:
84
99
  if not only_hook:
85
100
  self.apply(parent_id, key, option)
86
101
 
87
- # on update hooks
88
102
  if hooks:
89
- hook_name = "update.{}.{}".format(parent_id, key)
90
- if self.window.ui.has_hook(hook_name):
91
- hook = self.window.ui.get_hook(hook_name)
103
+ ui = self.window.ui
104
+ hook_name = f"update.{parent_id}.{key}"
105
+ if ui.has_hook(hook_name):
106
+ hook = ui.get_hook(hook_name)
92
107
  try:
93
108
  hook(key, value, "input")
94
109
  except Exception as e:
@@ -108,17 +123,20 @@ class Input:
108
123
  :param option: Option data
109
124
  :return: Value
110
125
  """
111
- value = None
112
- if option["type"] == "int":
126
+ typ = option["type"]
127
+ widget = self.window.ui.config[parent_id][key]
128
+ text = widget.text()
129
+
130
+ if typ == "int":
113
131
  try:
114
- value = int(self.window.ui.config[parent_id][key].text())
115
- except Exception:
116
- value = 0
117
- elif option["type"] == "float":
132
+ return int(text)
133
+ except (ValueError, TypeError):
134
+ return 0
135
+ elif typ == "float":
118
136
  try:
119
- value = float(self.window.ui.config[parent_id][key].text())
120
- except Exception:
121
- value = 0.0
122
- elif option["type"] == "text":
123
- value = self.window.ui.config[parent_id][key].text()
124
- return value
137
+ return float(text)
138
+ except (ValueError, TypeError):
139
+ return 0.0
140
+ elif typ == "text":
141
+ return text
142
+ return None
@@ -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.08 21:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Any, Optional, Dict, Union
@@ -38,61 +38,61 @@ class Slider:
38
38
  """
39
39
  if "value" not in option:
40
40
  return
41
- value = option["value"]
42
- is_integer = False
43
- multiplier = 1
44
41
 
45
- if "type" in option and option["type"] == "int":
46
- is_integer = True
47
- if "multiplier" in option:
48
- multiplier = option["multiplier"]
42
+ ui = self.window.ui
43
+ cfg_parent = ui.config.get(parent_id)
44
+ field = cfg_parent.get(key) if cfg_parent else None
45
+
46
+ is_integer = option.get("type") == "int"
47
+ multiplier = option.get("multiplier", 1)
48
+
49
+ value = option["value"]
49
50
 
50
51
  if type != "slider":
51
52
  if is_integer:
52
53
  try:
53
- value = round(int(value), 0)
54
- except Exception as e:
54
+ value = round(int(float(value)), 0)
55
+ except Exception:
55
56
  value = 0
56
57
  else:
57
58
  try:
58
59
  value = float(value)
59
- except Exception as e:
60
+ except Exception:
60
61
  value = 0.0
61
62
 
62
- if "min" in option and value < option["min"]:
63
- value = option["min"]
64
- elif "max" in option and value > option["max"]:
65
- value = option["max"]
63
+ min_v = option.get("min")
64
+ max_v = option.get("max")
65
+ if min_v is not None and value < min_v:
66
+ value = min_v
67
+ elif max_v is not None and value > max_v:
68
+ value = max_v
66
69
 
67
- # update connected input field
68
- if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
69
- self.window.ui.config[parent_id][key].input.setText(str(value))
70
+ if field:
71
+ field.input.setText(str(value))
70
72
 
71
73
  slider_value = round(float(value) * multiplier, 0)
72
74
 
73
- # from slider
74
75
  if type == "slider":
75
76
  input_value = value / multiplier
76
77
  if is_integer:
77
- input_value = round(int(input_value), 0)
78
- txt = "{}".format(input_value)
79
- self.window.ui.config[parent_id][key].input.setText(txt)
80
-
81
- # from input
78
+ try:
79
+ input_value = round(int(float(input_value)), 0)
80
+ except Exception:
81
+ input_value = 0
82
+ if field:
83
+ field.input.setText(str(input_value))
82
84
  elif type == "input":
83
- if "min" in option and slider_value < option["min"] * multiplier:
84
- slider_value = option["min"] * multiplier
85
- elif "max" in option and slider_value > option["max"] * multiplier:
86
- slider_value = option["max"] * multiplier
87
-
88
- if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
89
- self.window.ui.config[parent_id][key].slider.setValue(slider_value)
90
-
91
- # from value
85
+ min_v = option.get("min")
86
+ max_v = option.get("max")
87
+ if min_v is not None and slider_value < min_v * multiplier:
88
+ slider_value = min_v * multiplier
89
+ elif max_v is not None and slider_value > max_v * multiplier:
90
+ slider_value = max_v * multiplier
91
+ if field:
92
+ field.slider.setValue(slider_value)
92
93
  else:
93
- if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
94
- self.window.ui.config[parent_id][key].input.setText(str(value))
95
- self.window.ui.config[parent_id][key].slider.setValue(slider_value)
94
+ if field:
95
+ field.slider.setValue(slider_value)
96
96
 
97
97
  def on_update(
98
98
  self,
@@ -116,9 +116,8 @@ class Slider:
116
116
  option['value'] = value
117
117
  self.apply(parent_id, key, option, type)
118
118
 
119
- # on update hooks
120
119
  if hooks:
121
- hook_name = "update.{}.{}".format(parent_id, key)
120
+ hook_name = f"update.{parent_id}.{key}"
122
121
  if self.window.ui.has_hook(hook_name):
123
122
  hook = self.window.ui.get_hook(hook_name)
124
123
  try:
@@ -140,14 +139,10 @@ class Slider:
140
139
  :param option: Option data
141
140
  :return: Slider value (int or float)
142
141
  """
143
- is_integer = False
144
- multiplier = 1
145
- if "type" in option and option["type"] == "int":
146
- is_integer = True
147
- if "multiplier" in option:
148
- multiplier = option["multiplier"]
142
+ is_integer = option.get("type") == "int"
143
+ multiplier = option.get("multiplier", 1)
149
144
  value = self.window.ui.config[parent_id][key].slider.value()
150
145
  if is_integer:
151
146
  return round(int(value), 0)
152
147
  else:
153
- return value / multiplier
148
+ return value / multiplier