frdel commited on
Commit
d912d1e
·
1 Parent(s): d6e60a2
python/api/import_knowledge.py CHANGED
@@ -2,7 +2,7 @@ from python.helpers.api import ApiHandler
2
  from flask import Request, Response
3
 
4
  from python.helpers.file_browser import FileBrowser
5
- from python.helpers import files
6
  import os
7
  from werkzeug.utils import secure_filename
8
 
@@ -12,8 +12,14 @@ class ImportKnowledge(ApiHandler):
12
  if "files[]" not in request.files:
13
  raise Exception("No files part")
14
 
 
 
 
 
 
 
15
  file_list = request.files.getlist("files[]")
16
- KNOWLEDGE_FOLDER = files.get_abs_path("knowledge/custom/main")
17
 
18
  saved_filenames = []
19
 
@@ -23,4 +29,11 @@ class ImportKnowledge(ApiHandler):
23
  file.save(os.path.join(KNOWLEDGE_FOLDER, filename))
24
  saved_filenames.append(filename)
25
 
26
- return {"message": "Knowledge Imported", "filenames": saved_filenames}
 
 
 
 
 
 
 
 
2
  from flask import Request, Response
3
 
4
  from python.helpers.file_browser import FileBrowser
5
+ from python.helpers import files, memory
6
  import os
7
  from werkzeug.utils import secure_filename
8
 
 
12
  if "files[]" not in request.files:
13
  raise Exception("No files part")
14
 
15
+ ctxid = request.form.get("ctxid", "")
16
+ if not ctxid:
17
+ raise Exception("No context id provided")
18
+
19
+ context = self.get_context(ctxid)
20
+
21
  file_list = request.files.getlist("files[]")
22
+ KNOWLEDGE_FOLDER = files.get_abs_path(memory.get_custom_knowledge_subdir_abs(context.agent0),"main")
23
 
24
  saved_filenames = []
25
 
 
29
  file.save(os.path.join(KNOWLEDGE_FOLDER, filename))
30
  saved_filenames.append(filename)
31
 
32
+ #reload memory to re-import knowledge
33
+ await memory.Memory.reload(context.agent0)
34
+ context.log.set_initial_progress()
35
+
36
+ return {
37
+ "message": "Knowledge Imported",
38
+ "filenames": saved_filenames[:5]
39
+ }
python/api/nudge.py CHANGED
@@ -1,8 +1,6 @@
1
  from python.helpers.api import ApiHandler
2
  from flask import Request, Response
3
 
4
- from python.helpers import persist_chat
5
-
6
  class Nudge(ApiHandler):
7
  async def process(self, input: dict, request: Request) -> dict | Response:
8
  ctxid = input.get("ctxid", "")
 
1
  from python.helpers.api import ApiHandler
2
  from flask import Request, Response
3
 
 
 
4
  class Nudge(ApiHandler):
5
  async def process(self, input: dict, request: Request) -> dict | Response:
6
  ctxid = input.get("ctxid", "")
python/api/poll.py CHANGED
@@ -35,5 +35,6 @@ class Poll(ApiHandler):
35
  "log_guid": context.log.guid,
36
  "log_version": len(context.log.updates),
37
  "log_progress": context.log.progress,
 
38
  "paused": context.paused,
39
  }
 
35
  "log_guid": context.log.guid,
36
  "log_version": len(context.log.updates),
37
  "log_progress": context.log.progress,
38
+ "log_progress_active": context.log.progress_active,
39
  "paused": context.paused,
40
  }
python/extensions/message_loop_prompts/_50_recall_memories.py CHANGED
@@ -1,29 +1,36 @@
 
1
  from python.helpers.extension import Extension
2
  from python.helpers.memory import Memory
3
  from agent import LoopData
4
 
 
5
 
6
  class RecallMemories(Extension):
7
 
8
  INTERVAL = 3
9
- HISTORY = 5 # TODO cleanup
10
  RESULTS = 3
11
  THRESHOLD = 0.6
12
 
13
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
14
 
15
- if (
16
- loop_data.iteration % RecallMemories.INTERVAL == 0
17
- ): # every 3 iterations (or the first one) recall memories
18
- await self.search_memories(loop_data=loop_data, **kwargs)
 
 
 
 
 
19
 
20
  async def search_memories(self, loop_data: LoopData, **kwargs):
21
 
22
- #cleanup
23
  extras = loop_data.extras_temporary
24
  if "memories" in extras:
25
  del extras["memories"]
26
-
27
  # try:
28
  # show temp info message
29
  self.agent.context.log.log(
@@ -51,7 +58,9 @@ class RecallMemories(Extension):
51
 
52
  # call util llm to summarize conversation
53
  query = await self.agent.call_utility_llm(
54
- system=system, msg=loop_data.user_message.output_text() if loop_data.user_message else "", callback=log_callback
 
 
55
  )
56
 
57
  # get solutions database
@@ -91,7 +100,7 @@ class RecallMemories(Extension):
91
 
92
  # append to prompt
93
  extras["memories"] = memories_prompt
94
-
95
  # except Exception as e:
96
  # err = errors.format_error(e)
97
  # self.agent.context.log.log(
 
1
+ import asyncio
2
  from python.helpers.extension import Extension
3
  from python.helpers.memory import Memory
4
  from agent import LoopData
5
 
6
+ DATA_NAME_TASK = "_recall_memories_task"
7
 
8
  class RecallMemories(Extension):
9
 
10
  INTERVAL = 3
11
+ HISTORY = 5 # TODO cleanup
12
  RESULTS = 3
13
  THRESHOLD = 0.6
14
 
15
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
16
 
17
+ # every 3 iterations (or the first one) recall memories
18
+ if loop_data.iteration % RecallMemories.INTERVAL == 0:
19
+ task = asyncio.create_task(self.search_memories(loop_data=loop_data, **kwargs))
20
+ else:
21
+ task = None
22
+
23
+ # set to agent to be able to wait for it
24
+ self.agent.set_data(DATA_NAME_TASK, task)
25
+
26
 
27
  async def search_memories(self, loop_data: LoopData, **kwargs):
28
 
29
+ # cleanup
30
  extras = loop_data.extras_temporary
31
  if "memories" in extras:
32
  del extras["memories"]
33
+
34
  # try:
35
  # show temp info message
36
  self.agent.context.log.log(
 
58
 
59
  # call util llm to summarize conversation
60
  query = await self.agent.call_utility_llm(
61
+ system=system,
62
+ msg=loop_data.user_message.output_text() if loop_data.user_message else "",
63
+ callback=log_callback,
64
  )
65
 
66
  # get solutions database
 
100
 
101
  # append to prompt
102
  extras["memories"] = memories_prompt
103
+
104
  # except Exception as e:
105
  # err = errors.format_error(e)
106
  # self.agent.context.log.log(
python/extensions/message_loop_prompts/_51_recall_solutions.py CHANGED
@@ -1,7 +1,9 @@
 
1
  from python.helpers.extension import Extension
2
  from python.helpers.memory import Memory
3
  from agent import LoopData
4
 
 
5
 
6
  class RecallSolutions(Extension):
7
 
@@ -13,10 +15,14 @@ class RecallSolutions(Extension):
13
 
14
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
15
 
16
- if (
17
- loop_data.iteration % RecallSolutions.INTERVAL == 0
18
- ): # every 3 iterations (or the first one) recall solution memories
19
- await self.search_solutions(loop_data=loop_data, **kwargs)
 
 
 
 
20
 
21
  async def search_solutions(self, loop_data: LoopData, **kwargs):
22
 
 
1
+ import asyncio
2
  from python.helpers.extension import Extension
3
  from python.helpers.memory import Memory
4
  from agent import LoopData
5
 
6
+ DATA_NAME_TASK = "_recall_solutions_task"
7
 
8
  class RecallSolutions(Extension):
9
 
 
15
 
16
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
17
 
18
+ # every 3 iterations (or the first one) recall memories
19
+ if loop_data.iteration % RecallSolutions.INTERVAL == 0:
20
+ task = asyncio.create_task(self.search_solutions(loop_data=loop_data, **kwargs))
21
+ else:
22
+ task = None
23
+
24
+ # set to agent to be able to wait for it
25
+ self.agent.set_data(DATA_NAME_TASK, task)
26
 
27
  async def search_solutions(self, loop_data: LoopData, **kwargs):
28
 
python/extensions/message_loop_prompts/_90_organize_history_wait.py CHANGED
@@ -15,7 +15,7 @@ class OrganizeHistoryWait(Extension):
15
  # Check if the task is already done
16
  if task:
17
  if not task.done():
18
- self.log()
19
 
20
  # Wait for the task to complete
21
  await task
@@ -24,11 +24,6 @@ class OrganizeHistoryWait(Extension):
24
  self.agent.set_data(DATA_NAME_TASK, None)
25
  else:
26
  # no task running, start and wait
27
- self.log()
28
  await self.agent.history.compress()
29
 
30
- def log(self):
31
- if not hasattr(self, 'log_item') or not self.log_item:
32
- self.log_item = self.agent.context.log.log(
33
- type="util", heading="Waiting for history to be compressed..."
34
- )
 
15
  # Check if the task is already done
16
  if task:
17
  if not task.done():
18
+ self.agent.context.log.set_progress("Compressing history...")
19
 
20
  # Wait for the task to complete
21
  await task
 
24
  self.agent.set_data(DATA_NAME_TASK, None)
25
  else:
26
  # no task running, start and wait
27
+ self.agent.context.log.set_progress("Compressing history...")
28
  await self.agent.history.compress()
29
 
 
 
 
 
 
python/extensions/message_loop_prompts/_91_recall_wait.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from python.helpers.extension import Extension
2
+ from agent import LoopData
3
+ from python.extensions.message_loop_prompts._50_recall_memories import DATA_NAME_TASK as DATA_NAME_TASK_MEMORIES
4
+ from python.extensions.message_loop_prompts._51_recall_solutions import DATA_NAME_TASK as DATA_NAME_TASK_SOLUTIONS
5
+
6
+
7
+ class RecallWait(Extension):
8
+ async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
9
+
10
+ task = self.agent.get_data(DATA_NAME_TASK_MEMORIES)
11
+ if task and not task.done():
12
+ self.agent.context.log.set_progress("Recalling memories...")
13
+ await task
14
+
15
+ task = self.agent.get_data(DATA_NAME_TASK_SOLUTIONS)
16
+ if task and not task.done():
17
+ self.agent.context.log.set_progress("Recalling solutions...")
18
+ await task
19
+
python/extensions/monologue_end/_90_waiting_for_input_msg.py CHANGED
@@ -6,7 +6,5 @@ class WaitingForInputMsg(Extension):
6
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
7
  # show temp info message
8
  if self.agent.number == 0:
9
- self.agent.context.log.log(
10
- type="util", heading="Waiting for input", temp=True
11
- )
12
 
 
6
  async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
7
  # show temp info message
8
  if self.agent.number == 0:
9
+ self.agent.context.log.set_initial_progress()
 
 
10
 
python/helpers/log.py CHANGED
@@ -5,165 +5,172 @@ import uuid
5
  from collections import OrderedDict # Import OrderedDict
6
 
7
  Type = Literal[
8
- "agent",
9
- "code_exe",
10
- "error",
11
- "hint",
12
- "info",
13
- "progress",
14
- "response",
15
- "tool",
16
- "user",
17
- "util",
18
- "warning",
 
19
  ]
20
 
21
  @dataclass
22
  class LogItem:
23
- log: "Log"
24
- no: int
25
- type: str
26
- heading: str
27
- content: str
28
- temp: bool
29
- kvps: Optional[OrderedDict] = None # Use OrderedDict for kvps
30
- id: Optional[str] = None # Add id field
31
- guid: str = ""
32
-
33
- def __post_init__(self):
34
- self.guid = self.log.guid
35
-
36
- def update(
37
- self,
38
- type: Type | None = None,
39
- heading: str | None = None,
40
- content: str | None = None,
41
- kvps: dict | None = None,
42
- temp: bool | None = None,
43
- **kwargs,
44
- ):
45
- if self.guid == self.log.guid:
46
- self.log.update_item(
47
- self.no,
48
- type=type,
49
- heading=heading,
50
- content=content,
51
- kvps=kvps,
52
- temp=temp,
53
- **kwargs,
54
- )
55
-
56
- def stream(self, heading: str | None = None, content: str | None = None, **kwargs):
57
- if heading is not None:
58
- self.update(heading=self.heading + heading)
59
- if content is not None:
60
- self.update(content=self.content + content)
61
-
62
- for k, v in kwargs.items():
63
- prev = self.kvps.get(k, "") if self.kvps else ""
64
- self.update(**{k: prev + v})
65
-
66
- def output(self):
67
- return {
68
- "no": self.no,
69
- "id": self.id, # Include id in output
70
- "type": self.type,
71
- "heading": self.heading,
72
- "content": self.content,
73
- "temp": self.temp,
74
- "kvps": self.kvps,
75
- }
76
 
77
  class Log:
78
 
79
- def __init__(self):
80
- self.guid: str = str(uuid.uuid4())
81
- self.updates: list[int] = []
82
- self.logs: list[LogItem] = []
83
- self.progress = ""
84
- self.progress_no = 0
85
-
86
- def log(
87
- self,
88
- type: Type,
89
- heading: str | None = None,
90
- content: str | None = None,
91
- kvps: dict | None = None,
92
- temp: bool | None = None,
93
- id: Optional[str] = None, # Add id parameter
94
- ) -> LogItem:
95
- # Use OrderedDict if kvps is provided
96
- if kvps is not None:
97
- kvps = OrderedDict(kvps)
98
- item = LogItem(
99
- log=self,
100
- no=len(self.logs),
101
- type=type,
102
- heading=heading or "",
103
- content=content or "",
104
- kvps=kvps,
105
- temp=temp or False,
106
- id=id, # Pass id to LogItem
107
- )
108
- self.logs.append(item)
109
- self.updates += [item.no]
110
- if heading and item.no >= self.progress_no:
111
- self.progress = heading
112
- self.progress_no = item.no
113
- return item
114
-
115
- def update_item(
116
- self,
117
- no: int,
118
- type: str | None = None,
119
- heading: str | None = None,
120
- content: str | None = None,
121
- kvps: dict | None = None,
122
- temp: bool | None = None,
123
- **kwargs,
124
- ):
125
- item = self.logs[no]
126
- if type is not None:
127
- item.type = type
128
- if heading is not None:
129
- item.heading = heading
130
- if no >= self.progress_no:
131
- self.progress = heading
132
- self.progress_no = no
133
- if content is not None:
134
- item.content = content
135
- if kvps is not None:
136
- item.kvps = OrderedDict(kvps) # Use OrderedDict to keep the order
137
-
138
- if temp is not None:
139
- item.temp = temp
140
-
141
- if kwargs:
142
- if item.kvps is None:
143
- item.kvps = OrderedDict() # Ensure kvps is an OrderedDict
144
- for k, v in kwargs.items():
145
- item.kvps[k] = v
146
-
147
- self.updates += [item.no]
148
-
149
- def output(self, start=None, end=None):
150
- if start is None:
151
- start = 0
152
- if end is None:
153
- end = len(self.updates)
154
-
155
- out = []
156
- seen = set()
157
- for update in self.updates[start:end]:
158
- if update not in seen:
159
- out.append(self.logs[update].output())
160
- seen.add(update)
161
-
162
- return out
163
-
164
- def reset(self):
165
- self.guid = str(uuid.uuid4())
166
- self.updates = []
167
- self.logs = []
168
- self.progress = ""
169
- self.progress_no = 0
 
 
 
 
 
 
 
5
  from collections import OrderedDict # Import OrderedDict
6
 
7
  Type = Literal[
8
+ "agent",
9
+ "code_exe",
10
+ "error",
11
+ "hint",
12
+ "info",
13
+ "progress",
14
+ "response",
15
+ "tool",
16
+ "input",
17
+ "user",
18
+ "util",
19
+ "warning",
20
  ]
21
 
22
  @dataclass
23
  class LogItem:
24
+ log: "Log"
25
+ no: int
26
+ type: str
27
+ heading: str
28
+ content: str
29
+ temp: bool
30
+ kvps: Optional[OrderedDict] = None # Use OrderedDict for kvps
31
+ id: Optional[str] = None # Add id field
32
+ guid: str = ""
33
+
34
+ def __post_init__(self):
35
+ self.guid = self.log.guid
36
+
37
+ def update(
38
+ self,
39
+ type: Type | None = None,
40
+ heading: str | None = None,
41
+ content: str | None = None,
42
+ kvps: dict | None = None,
43
+ temp: bool | None = None,
44
+ **kwargs,
45
+ ):
46
+ if self.guid == self.log.guid:
47
+ self.log.update_item(
48
+ self.no,
49
+ type=type,
50
+ heading=heading,
51
+ content=content,
52
+ kvps=kvps,
53
+ temp=temp,
54
+ **kwargs,
55
+ )
56
+
57
+ def stream(self, heading: str | None = None, content: str | None = None, **kwargs):
58
+ if heading is not None:
59
+ self.update(heading=self.heading + heading)
60
+ if content is not None:
61
+ self.update(content=self.content + content)
62
+
63
+ for k, v in kwargs.items():
64
+ prev = self.kvps.get(k, "") if self.kvps else ""
65
+ self.update(**{k: prev + v})
66
+
67
+ def output(self):
68
+ return {
69
+ "no": self.no,
70
+ "id": self.id, # Include id in output
71
+ "type": self.type,
72
+ "heading": self.heading,
73
+ "content": self.content,
74
+ "temp": self.temp,
75
+ "kvps": self.kvps,
76
+ }
77
 
78
  class Log:
79
 
80
+ def __init__(self):
81
+ self.guid: str = str(uuid.uuid4())
82
+ self.updates: list[int] = []
83
+ self.logs: list[LogItem] = []
84
+ self.set_initial_progress()
85
+
86
+ def log(
87
+ self,
88
+ type: Type,
89
+ heading: str | None = None,
90
+ content: str | None = None,
91
+ kvps: dict | None = None,
92
+ temp: bool | None = None,
93
+ id: Optional[str] = None, # Add id parameter
94
+ ) -> LogItem:
95
+ # Use OrderedDict if kvps is provided
96
+ if kvps is not None:
97
+ kvps = OrderedDict(kvps)
98
+ item = LogItem(
99
+ log=self,
100
+ no=len(self.logs),
101
+ type=type,
102
+ heading=heading or "",
103
+ content=content or "",
104
+ kvps=kvps,
105
+ temp=temp or False,
106
+ id=id, # Pass id to LogItem
107
+ )
108
+ self.logs.append(item)
109
+ self.updates += [item.no]
110
+ if heading and item.no >= self.progress_no:
111
+ self.set_progress(heading, item.no)
112
+ return item
113
+
114
+ def update_item(
115
+ self,
116
+ no: int,
117
+ type: str | None = None,
118
+ heading: str | None = None,
119
+ content: str | None = None,
120
+ kvps: dict | None = None,
121
+ temp: bool | None = None,
122
+ **kwargs,
123
+ ):
124
+ item = self.logs[no]
125
+ if type is not None:
126
+ item.type = type
127
+ if heading is not None:
128
+ item.heading = heading
129
+ if no >= self.progress_no:
130
+ self.set_progress(heading, no)
131
+ if content is not None:
132
+ item.content = content
133
+ if kvps is not None:
134
+ item.kvps = OrderedDict(kvps) # Use OrderedDict to keep the order
135
+
136
+ if temp is not None:
137
+ item.temp = temp
138
+
139
+ if kwargs:
140
+ if item.kvps is None:
141
+ item.kvps = OrderedDict() # Ensure kvps is an OrderedDict
142
+ for k, v in kwargs.items():
143
+ item.kvps[k] = v
144
+
145
+ self.updates += [item.no]
146
+
147
+ def set_progress(self, progress: str, no: int = 0, active: bool = True):
148
+ self.progress = progress
149
+ if not no:
150
+ no = len(self.logs)
151
+ self.progress_no = no
152
+ self.progress_active = active
153
+
154
+ def set_initial_progress(self):
155
+ self.set_progress("Waiting for input", 0, False)
156
+
157
+ def output(self, start=None, end=None):
158
+ if start is None:
159
+ start = 0
160
+ if end is None:
161
+ end = len(self.updates)
162
+
163
+ out = []
164
+ seen = set()
165
+ for update in self.updates[start:end]:
166
+ if update not in seen:
167
+ out.append(self.logs[update].output())
168
+ seen.add(update)
169
+
170
+ return out
171
+
172
+ def reset(self):
173
+ self.guid = str(uuid.uuid4())
174
+ self.updates = []
175
+ self.logs = []
176
+ self.set_initial_progress()
python/helpers/memory.py CHANGED
@@ -72,6 +72,13 @@ class Memory:
72
  memory_subdir=memory_subdir,
73
  )
74
 
 
 
 
 
 
 
 
75
  @staticmethod
76
  def initialize(
77
  log_item: LogItem | None,
@@ -151,6 +158,9 @@ class Memory:
151
  async def preload_knowledge(
152
  self, log_item: LogItem | None, kn_dirs: list[str], memory_subdir: str
153
  ):
 
 
 
154
  # db abs path
155
  db_dir = Memory._abs_db_dir(memory_subdir)
156
 
@@ -351,5 +361,12 @@ class Memory:
351
  def get_timestamp():
352
  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
353
 
 
354
  def get_memory_subdir_abs(agent: Agent) -> str:
355
- return files.get_abs_path("memory", agent.config.memory_subdir or "default")
 
 
 
 
 
 
 
72
  memory_subdir=memory_subdir,
73
  )
74
 
75
+ @staticmethod
76
+ async def reload(agent: Agent):
77
+ memory_subdir = agent.config.memory_subdir or "default"
78
+ if Memory.index.get(memory_subdir):
79
+ del Memory.index[memory_subdir]
80
+ return await Memory.get(agent)
81
+
82
  @staticmethod
83
  def initialize(
84
  log_item: LogItem | None,
 
158
  async def preload_knowledge(
159
  self, log_item: LogItem | None, kn_dirs: list[str], memory_subdir: str
160
  ):
161
+ if log_item:
162
+ log_item.update(heading="Preloading knowledge...")
163
+
164
  # db abs path
165
  db_dir = Memory._abs_db_dir(memory_subdir)
166
 
 
361
  def get_timestamp():
362
  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
363
 
364
+
365
  def get_memory_subdir_abs(agent: Agent) -> str:
366
+ return files.get_abs_path("memory", agent.config.memory_subdir or "default")
367
+
368
+ def get_custom_knowledge_subdir_abs(agent: Agent) -> str:
369
+ for dir in agent.config.knowledge_subdirs:
370
+ if dir != "default":
371
+ return files.get_abs_path("knowledge", dir)
372
+ raise Exception("No custom knowledge subdir set")
python/helpers/persist_chat.py CHANGED
@@ -166,8 +166,7 @@ def _deserialize_agents(
166
  def _deserialize_log(data: dict[str, Any]) -> "Log":
167
  log = Log()
168
  log.guid = data.get("guid", str(uuid.uuid4()))
169
- log.progress = "" # data.get("progress", "")
170
- log.progress_no = data.get("progress_no", 0)
171
 
172
  # Deserialize the list of LogItem objects
173
  i = 0
 
166
  def _deserialize_log(data: dict[str, Any]) -> "Log":
167
  log = Log()
168
  log.guid = data.get("guid", str(uuid.uuid4()))
169
+ log.set_initial_progress()
 
170
 
171
  # Deserialize the list of LogItem objects
172
  i = 0
python/helpers/settings.py CHANGED
@@ -703,7 +703,7 @@ def get_default_settings() -> Settings:
703
  chat_model_temperature=0,
704
  chat_model_kwargs={},
705
  chat_model_ctx_length=8192,
706
- chat_model_ctx_history=0.65,
707
  util_model_provider=ModelProvider.OPENAI.name,
708
  util_model_name="gpt-4o-mini",
709
  util_model_temperature=0,
 
703
  chat_model_temperature=0,
704
  chat_model_kwargs={},
705
  chat_model_ctx_length=8192,
706
+ chat_model_ctx_history=0.7,
707
  util_model_provider=ModelProvider.OPENAI.name,
708
  util_model_name="gpt-4o-mini",
709
  util_model_temperature=0,
webui/index.js CHANGED
@@ -269,6 +269,8 @@ window.loadKnowledge = async function () {
269
  formData.append('files[]', file);
270
  }
271
 
 
 
272
  const response = await fetch('/import_knowledge', {
273
  method: 'POST',
274
  body: formData,
@@ -357,7 +359,7 @@ async function poll() {
357
  afterMessagesUpdate(response.logs)
358
  }
359
 
360
- updateProgress(response.log_progress)
361
 
362
  //set ui model vars from backend
363
  const inputAD = Alpine.$data(inputSection);
@@ -400,11 +402,30 @@ function speakMessages(logs) {
400
  }
401
  }
402
 
403
- function updateProgress(progress) {
404
- const defaultText = "Waiting for input"
405
- if (!progress) progress = defaultText
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
 
407
- if (progress == defaultText) {
408
  removeClassFromElement(progressBar, "shiny-text")
409
  } else {
410
  addClassToElement(progressBar, "shiny-text")
 
269
  formData.append('files[]', file);
270
  }
271
 
272
+ formData.append('ctxid', getContext());
273
+
274
  const response = await fetch('/import_knowledge', {
275
  method: 'POST',
276
  body: formData,
 
359
  afterMessagesUpdate(response.logs)
360
  }
361
 
362
+ updateProgress(response.log_progress, response.log_progress_active)
363
 
364
  //set ui model vars from backend
365
  const inputAD = Alpine.$data(inputSection);
 
402
  }
403
  }
404
 
405
+ function afterMessagesUpdate(logs) {
406
+ if (localStorage.getItem('speech') == 'true') {
407
+ speakMessages(logs)
408
+ }
409
+ }
410
+
411
+ function speakMessages(logs) {
412
+ // log.no, log.type, log.heading, log.content
413
+ for (let i = logs.length - 1; i >= 0; i--) {
414
+ const log = logs[i]
415
+ if (log.type == "response") {
416
+ if (log.no > lastSpokenNo) {
417
+ lastSpokenNo = log.no
418
+ speech.speak(log.content)
419
+ return
420
+ }
421
+ }
422
+ }
423
+ }
424
+
425
+ function updateProgress(progress, active) {
426
+ if (!progress) progress = ""
427
 
428
+ if (!active) {
429
  removeClassFromElement(progressBar, "shiny-text")
430
  } else {
431
  addClassToElement(progressBar, "shiny-text")