unisi 0.3.19__py3-none-any.whl → 0.3.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.
unisi/common.py CHANGED
@@ -120,17 +120,17 @@ class Message:
120
120
 
121
121
  def fill_paths4(self, user):
122
122
  if hasattr(self, 'updates'):
123
- invalid = []
123
+ invisible = []
124
124
  for update in self.updates:
125
125
  data = update["data"]
126
126
  path = user.find_path(data)
127
127
  if path:
128
128
  update['path'] = path
129
129
  else:
130
- invalid.append(update)
131
- user.log(f'Invalid element update {data.name}, type {data.type}.\n\
132
- Such element not on the screen!')
133
- for inv in invalid:
130
+ invisible.append(update)
131
+ user.log(f'Invisible element update {data.name}, type {data.type}.\n\
132
+ Such element not on the screen!', type = 'warning')
133
+ for inv in invisible:
134
134
  self.updates.remove(inv)
135
135
 
136
136
  def contains(self, unit):
unisi/llmrag.py CHANGED
@@ -9,9 +9,50 @@ from langchain_google_genai import (
9
9
  HarmCategory,
10
10
  )
11
11
  from datetime import datetime
12
- import collections, inspect, re, json
12
+ import os, inspect, re, json
13
13
  from typing import get_origin, get_args
14
14
 
15
+ class QueryCache:
16
+ ITEM_SEPARATOR = "§¶†‡◊•→±"
17
+ ENTRY_SEPARATOR = "€£¥¢≠≈∆√"
18
+
19
+ def __init__(self, file_path):
20
+ self.file_path = file_path
21
+ self.cache = {}
22
+ self._load_cache()
23
+
24
+ def _load_cache(self):
25
+ if os.path.exists(self.file_path):
26
+ with open(self.file_path, 'r', encoding='utf-8') as f:
27
+ content = f.read()
28
+ entries = content.split(self.ENTRY_SEPARATOR)
29
+ for entry in entries:
30
+ if not entry.strip():
31
+ continue
32
+ parts = entry.split(self.ITEM_SEPARATOR)
33
+ if len(parts) == 2:
34
+ query, result = parts
35
+ self.cache[query] = result
36
+
37
+ def get(self, query):
38
+ return self.cache.get(query)
39
+
40
+ def set(self, query, result):
41
+ entry_data = f"{query}{self.ITEM_SEPARATOR}{result}"
42
+ prepend_separator = bool(self.cache)
43
+
44
+ try:
45
+ with open(self.file_path, 'a', encoding='utf-8') as f:
46
+ if prepend_separator:
47
+ f.write(self.ENTRY_SEPARATOR)
48
+ f.write(entry_data)
49
+
50
+ self.cache[query] = result
51
+ return True
52
+ except Exception as e:
53
+ print(f"Error caching result: {e}")
54
+ return False
55
+
15
56
  def jstype(type_value):
16
57
  if isinstance(type_value, type):
17
58
  if type_value == int:
@@ -99,8 +140,17 @@ def Q(str_prompt, type_value = str, blank = True, **format_model):
99
140
  format = " dd/mm/yyyy string" if type_value == 'date' else f'a JSON {jtype}' if jtype != 'string' else jtype
100
141
  str_prompt = f"System: You are an intelligent and extremely smart assistant. Output STRONGLY {format}. DO NOT OUTPUT ANY COMMENTARY." + str_prompt
101
142
  async def f():
102
- io = await llm.ainvoke(str_prompt)
103
- js = io.content.strip().strip('`').replace('json', '')
143
+ if Unishare.llm_cache:
144
+ if content := Unishare.llm_cache.get(str_prompt):
145
+ pass
146
+ else:
147
+ io = await llm.ainvoke(str_prompt)
148
+ content = io.content
149
+ Unishare.llm_cache.set(str_prompt, content)
150
+ else:
151
+ io = await llm.ainvoke(str_prompt)
152
+ content = io.content
153
+ js = content.strip().strip('`').replace('json', '')
104
154
  if type_value == str or type_value == 'date':
105
155
  return js
106
156
  try:
@@ -125,7 +175,7 @@ def Q(str_prompt, type_value = str, blank = True, **format_model):
125
175
  raise TypeError(f'Invalid type for {k}: {type(parsed[k])} != {v}')
126
176
  else:
127
177
  if not is_type(parsed, type_value):
128
- raise TypeError(f'Invalid type: {type(parsed)} != {type_value}')
178
+ raise TypeError(f'Invalid type: {type(parsed)} != {type_value}')
129
179
  return parsed
130
180
  return f()
131
181
 
@@ -180,6 +230,9 @@ def setup_llmrag():
180
230
  max_retries=2,
181
231
  # other params...
182
232
  )
233
+
234
+ if hasattr(config, 'llm_cache'):
235
+ Unishare.llm_cache = QueryCache(config.llm_cache)
183
236
 
184
237
  async def get_property(name, context = '', type = str, options = None):
185
238
  if type == str and re.search(r'date', name, re.IGNORECASE):
unisi/reloader.py CHANGED
@@ -26,12 +26,12 @@ else:
26
26
  else:
27
27
  busy = False
28
28
 
29
- def reload(sname):
29
+ def reload(sname, changed_dependency = False):
30
30
  user = User.last_user
31
31
  if user:
32
32
  file = open(f'screens{divpath}{sname}', "r")
33
33
  content = file.read()
34
- if file_content[sname] == content:
34
+ if not changed_dependency and file_content[sname] == content:
35
35
  return
36
36
  file_content[sname] = content
37
37
 
@@ -85,7 +85,9 @@ else:
85
85
  if name.endswith('.py'):
86
86
  user = User.last_user
87
87
 
88
+ changed_dependency = False
88
89
  if user.screen_module and dir not in ['screens','blocks']:
90
+ changed_dependency = True
89
91
  #analyze if dependency exist
90
92
  file = open(user.screen_module.__file__, "r")
91
93
  arr[-1] = arr[-1][:-3]
@@ -105,12 +107,12 @@ else:
105
107
  global request_file
106
108
  request_file = short_path
107
109
  else:
108
- fresh_module = reload(name) if dir == 'screens' else None
110
+ fresh_module = reload(name, changed_dependency) if dir == 'screens' else None
109
111
  module = user.screen_module
110
112
  if module:
111
113
  current = module.__file__
112
114
  if not fresh_module or current != fresh_module.__file__:
113
- reload(current.split(divpath)[-1])
115
+ reload(current.split(divpath)[-1], changed_dependency)
114
116
 
115
117
  def on_deleted(self, event):
116
118
  if not event.is_directory and User.last_user:
unisi/server.py CHANGED
@@ -173,9 +173,10 @@ def start(user_type = User, http_handlers = []):
173
173
 
174
174
  User.type = user_type
175
175
  run_tests(User.init_user())
176
-
177
- server_handlers = [web.get('/ws', websocket_handler), web.static(f'/{config.upload_dir}', upload_dir),
178
- web.get('/{tail:.*}', static_serve), web.post('/', post_handler)] + http_handlers
176
+ #http_handlers has to be the first argument
177
+ server_handlers = http_handlers + [web.get('/ws', websocket_handler),
178
+ web.static(f'/{config.upload_dir}', upload_dir),
179
+ web.get('/{tail:.*}', static_serve), web.post('/', post_handler)]
179
180
 
180
181
  app = web.Application()
181
182
  app.add_routes(server_handlers)
unisi/units.py CHANGED
@@ -111,11 +111,12 @@ class Unit:
111
111
  super().__setattr__(name, value)
112
112
 
113
113
  def mutate(self, obj):
114
- self.__dict__.clear()
115
- for key, value in obj.__dict__.items():
116
- setattr(self, key, value)
117
- if self._mark_changed:
118
- self._mark_changed()
114
+ if self is not obj:
115
+ self.__dict__.clear()
116
+ for key, value in obj.__dict__.items():
117
+ setattr(self, key, value)
118
+ if self._mark_changed:
119
+ self._mark_changed()
119
120
 
120
121
  def accept(self, value):
121
122
  if hasattr(self, 'changed'):
unisi/users.py CHANGED
@@ -229,7 +229,9 @@ class User:
229
229
  match raw:
230
230
  case None:
231
231
  if self.changed_units:
232
- raw = Message(*self.changed_units, user = self)
232
+ raw = Message(*self.changed_units, user = self)
233
+ if not raw.updates:
234
+ raw = None
233
235
  case Message():
234
236
  if self.changed_units:
235
237
  message_units = [x['data'] for x in raw.updates]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unisi
3
- Version: 0.3.19
3
+ Version: 0.3.21
4
4
  Summary: Unified System Interface, GUI and Remote API
5
5
  Author-Email: UNISI Tech <g.dernovoy@gmail.com>
6
6
  License: Apache-2.0
@@ -1,10 +1,10 @@
1
- unisi-0.3.19.dist-info/METADATA,sha256=TRxYSei9SHZzjQcu7HSLB9JalHBt9oBeW1btTtEOGos,27266
2
- unisi-0.3.19.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- unisi-0.3.19.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- unisi-0.3.19.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1
+ unisi-0.3.21.dist-info/METADATA,sha256=zEgUix_OED-fHXOFzfMveGsc49W_X_uRa6V6FW_wMjM,27266
2
+ unisi-0.3.21.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ unisi-0.3.21.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ unisi-0.3.21.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
5
  unisi/__init__.py,sha256=prG4FwJzpNJRX1trto0x_4Bne3kkpEX1dUxcRnIxWVw,301
6
6
  unisi/autotest.py,sha256=qYKwSPEPUEio6koUSu1tc71pDkX-doCQJlyRppaXCtY,8709
7
- unisi/common.py,sha256=S9xioaMH0IRxdpKukTaRdO4oJ7eJWUHJeaGnG7j_xYg,5765
7
+ unisi/common.py,sha256=QHSS-pQDtLZxeZls0eDl8-EmYJZuaRmYO1M9izCly-Y,5791
8
8
  unisi/containers.py,sha256=dmRHogzjIVoc0qu713bOPOPBp2QrN-LEA4Wn3owF0Yg,7223
9
9
  unisi/dbunits.py,sha256=g1h9pjoSwJrJ0Hmph-xv5jE1yfrxJeXGfuSnyVTg3j8,7438
10
10
  unisi/graphs.py,sha256=DTyLUPzi9ErKY6ADXVMXf9-uJskNISZY_xDvsnhMs1Q,6959
@@ -14,14 +14,14 @@ unisi/jsoncomparison/config.py,sha256=LbdLJE1KIebFq_tX7zcERhPvopKhnzcTqMCnS3jN12
14
14
  unisi/jsoncomparison/errors.py,sha256=wqphE1Xn7K6n16uvUhDC45m2BxbsMUhIF2olPbhqf4o,1192
15
15
  unisi/jsoncomparison/ignore.py,sha256=xfF0a_BBEyGdZBoq-ovpCpawgcX8SRwwp7IrGnu1c2w,2634
16
16
  unisi/kdb.py,sha256=K-Lqc3e9hLTwO0i1ilTC6qrwZp90tXjLm7HFb_lM1Os,13621
17
- unisi/llmrag.py,sha256=yzhcqt3DQpS9VQovQJsMbkWAPU3k2si4BwvDqg-HDAw,7570
17
+ unisi/llmrag.py,sha256=Ra462DhayMtcFg-QnF8HdZQGQL3mplzUu7Y9WZTjssM,9413
18
18
  unisi/multimon.py,sha256=YKwCuvMsMfdgOGkJoqiqh_9wywXMeo9bUhHmbAIUeSE,4060
19
19
  unisi/proxy.py,sha256=QMHSSFJtmVZIexIMAsuFNlF5JpnYNG90rkTM3PYJhY4,7750
20
- unisi/reloader.py,sha256=qml-ufoUME7mrWrPMwMo3T8Jsh4e26CBj564cHCB6I0,6749
21
- unisi/server.py,sha256=qKYp_AK6Fi8n_oSoe28pLTYW3h7DNkBxgk9U2xfsP9Y,6577
20
+ unisi/reloader.py,sha256=t7z0NgaeJX52044ue_LxITa99WMuE5Jra9qkMEeGhTg,6941
21
+ unisi/server.py,sha256=owUV_siimohV-PZwMkkIRTnynY0wxpia2la3Vjqy9g8,6658
22
22
  unisi/tables.py,sha256=IBuN9f4AF0SkN9uRPf2WWwdXgAzDnj46y0_C09iC2h4,13809
23
- unisi/units.py,sha256=SCUZAOV0nu9khg6JE0lWwsKjiCVz29hiUCRXyZJffeA,11111
24
- unisi/users.py,sha256=WsgS9Fx0RAbk_3ht4S6u9Z41VdgxdRYtbg9w79PoFfs,16267
23
+ unisi/units.py,sha256=egOpf1I6ckAtBR9Lj2ot-RVyecIVmmuc5Rkwffl3y6A,11159
24
+ unisi/users.py,sha256=PM_87GQRV3KVG9TX4lEZnbmpZDpszPL2smCRUcE3fOY,16349
25
25
  unisi/utils.py,sha256=yNhDKCTjHL1H2Suk9DRQkXAZKYy6nqub-dNSdwPwl9I,2625
26
26
  unisi/voicecom.py,sha256=QzS1gIrBeGLO5dEwiu7KIEdJIIVbPBZFGb5nY632Ws8,16707
27
27
  unisi/web/css/565.f35d8840.css,sha256=DjftW1Df0hiHeuUVRz5kZgW2pmcWPDk73SyyI7A5cfM,3053
@@ -55,4 +55,4 @@ unisi/web/js/sigma.ce21336a.js,sha256=ngST-065XWOdnR_Xn7U6oGNHTL8fyiOEI9V8-BWRvl
55
55
  unisi/web/js/sigma.ce21336a.js.gz,sha256=zv6oToZZFCfmrZ4G4fw0sOncVe8-dyYNWh2v5QLKZp4,51965
56
56
  unisi/web/js/vendor.6a64dcc5.js,sha256=OSNK2nadU2DnSOEYQQcAmelybITOFZXMxnRyaDoT3yU,747104
57
57
  unisi/web/js/vendor.6a64dcc5.js.gz,sha256=nmtqRzQRWaToxgHxI9hfJd3UrUCg2-fd-0Fjc4H4wu8,245827
58
- unisi-0.3.19.dist-info/RECORD,,
58
+ unisi-0.3.21.dist-info/RECORD,,
File without changes