Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ def execute(self, loop_data: LoopData = LoopData(), **kwargs):
return

# show full util message
# update_progress="none": this is a post-turn background bookkeeping
# item logged after the final response; it must not take over the
# status bar (monologue_end resets progress to "Waiting for input").
log_item = self.agent.context.log.log(
type="util",
heading="Memorizing new information...",
update_progress="none",
)

# memorize in background
Expand Down Expand Up @@ -73,37 +77,40 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs):

# Add validation and error handling for memories_json
if not memories_json or not isinstance(memories_json, str):
log_item.update(heading="No response from utility model.")
log_item.update(heading="No response from utility model.", finished=True)
return

# Strip any whitespace that might cause issues
memories_json = memories_json.strip()

if not memories_json:
log_item.update(heading="Empty response from utility model.")
log_item.update(heading="Empty response from utility model.", finished=True)
return

try:
memories = DirtyJson.parse_string(memories_json)
except Exception as e:
log_item.update(heading=f"Failed to parse memories response: {str(e)}")
log_item.update(
heading=f"Failed to parse memories response: {str(e)}",
finished=True,
)
return

# Validate that memories is a list or convertible to one
if memories is None:
log_item.update(heading="No valid memories found in response.")
log_item.update(heading="No valid memories found in response.", finished=True)
return

# If memories is not a list, try to make it one
if not isinstance(memories, list):
if isinstance(memories, (str, dict)):
memories = [memories]
else:
log_item.update(heading="Invalid memories format received.")
log_item.update(heading="Invalid memories format received.", finished=True)
return

if not isinstance(memories, list) or len(memories) == 0:
log_item.update(heading="No useful information to memorize.")
log_item.update(heading="No useful information to memorize.", finished=True)
return

raw_memories_count = len(memories)
Expand All @@ -114,6 +121,7 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs):
log_item.update(
heading="No durable information to memorize.",
filtered_memories_count=filtered_memories_count,
finished=True,
)
return

Expand Down Expand Up @@ -216,11 +224,23 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs):
)
if rem:
log_item.stream(result=f"\nReplaced {len(rem)} previous memories.")


# Terminal marker: the background job is done. The Web UI uses the
# finished kvp to close the process group holding this utility
# item; without it the post-turn group never completes and keeps
# rendering as an in-flight "Processing..." phase.
log_item.update(finished=True, update_progress="none")


except Exception as e:
# Mark the utility item finished even on failure so its process
# group does not stay open, and keep the warning off the status
# bar (progress was already reset to "Waiting for input").
log_item.update(finished=True, update_progress="none")
err = errors.format_error(e)
self.agent.context.log.log(
type="warning", heading="Memorize memories extension error", content=err
type="warning",
heading="Memorize memories extension error",
content=err,
update_progress="none",
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ def execute(self, loop_data: LoopData = LoopData(), **kwargs):
return

# show full util message
# update_progress="none": this is a post-turn background bookkeeping
# item logged after the final response; it must not take over the
# status bar (monologue_end resets progress to "Waiting for input").
log_item = self.agent.context.log.log(
type="util",
heading="Memorizing succesful solutions...",
update_progress="none",
)

# memorize in background
Expand Down Expand Up @@ -75,37 +79,40 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs):

# Add validation and error handling for solutions_json
if not solutions_json or not isinstance(solutions_json, str):
log_item.update(heading="No response from utility model.")
log_item.update(heading="No response from utility model.", finished=True)
return

# Strip any whitespace that might cause issues
solutions_json = solutions_json.strip()

if not solutions_json:
log_item.update(heading="Empty response from utility model.")
log_item.update(heading="Empty response from utility model.", finished=True)
return

try:
solutions = DirtyJson.parse_string(solutions_json)
except Exception as e:
log_item.update(heading=f"Failed to parse solutions response: {str(e)}")
log_item.update(
heading=f"Failed to parse solutions response: {str(e)}",
finished=True,
)
return

# Validate that solutions is a list or convertible to one
if solutions is None:
log_item.update(heading="No valid solutions found in response.")
log_item.update(heading="No valid solutions found in response.", finished=True)
return

# If solutions is not a list, try to make it one
if not isinstance(solutions, list):
if isinstance(solutions, (str, dict)):
solutions = [solutions]
else:
log_item.update(heading="Invalid solutions format received.")
log_item.update(heading="Invalid solutions format received.", finished=True)
return

if not isinstance(solutions, list) or len(solutions) == 0:
log_item.update(heading="No successful solutions to memorize.")
log_item.update(heading="No successful solutions to memorize.", finished=True)
return
else:
solutions_txt = "\n\n".join([str(solution) for solution in solutions]).strip()
Expand Down Expand Up @@ -209,9 +216,22 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs):
if rem:
log_item.stream(result=f"\nReplaced {len(rem)} previous solutions.")

# Terminal marker: the background job is done. The Web UI uses the
# finished kvp to close the process group holding this utility
# item; without it the post-turn group never completes and keeps
# rendering as an in-flight "Processing..." phase.
log_item.update(finished=True, update_progress="none")


except Exception as e:
# Mark the utility item finished even on failure so its process
# group does not stay open, and keep the warning off the status
# bar (progress was already reset to "Waiting for input").
log_item.update(finished=True, update_progress="none")
err = errors.format_error(e)
self.agent.context.log.log(
type="warning", heading="Memorize solutions extension error", content=err
type="warning",
heading="Memorize solutions extension error",
content=err,
update_progress="none",
)
Loading