Persist completed run elapsed time
This commit is contained in:
+54
-20
@@ -3799,34 +3799,68 @@ def _annotate_last_assistant_elapsed(
|
||||
session_id: str,
|
||||
elapsed_ms: int,
|
||||
) -> None:
|
||||
path = _session_json_path(directory, session_id)
|
||||
try:
|
||||
data = json.loads(path.read_text(encoding='utf-8'))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
stored = load_agent_session(session_id, directory=directory)
|
||||
except (
|
||||
FileNotFoundError,
|
||||
OSError,
|
||||
json.JSONDecodeError,
|
||||
KeyError,
|
||||
TypeError,
|
||||
ValueError,
|
||||
):
|
||||
return
|
||||
messages = data.get('messages')
|
||||
display_messages = data.get('display_messages')
|
||||
if not isinstance(display_messages, list):
|
||||
display_messages = messages
|
||||
if not isinstance(messages, list) and not isinstance(display_messages, list):
|
||||
|
||||
messages, messages_changed = _annotate_last_assistant_in_messages(
|
||||
stored.messages,
|
||||
elapsed_ms,
|
||||
)
|
||||
display_messages: tuple[dict[str, Any], ...] = ()
|
||||
display_changed = False
|
||||
if stored.display_messages:
|
||||
display_messages, display_changed = _annotate_last_assistant_in_messages(
|
||||
stored.display_messages,
|
||||
elapsed_ms,
|
||||
)
|
||||
|
||||
if not messages_changed and not display_changed:
|
||||
return
|
||||
for message_list in (messages, display_messages):
|
||||
if not isinstance(message_list, list):
|
||||
continue
|
||||
for message in reversed(message_list):
|
||||
if not isinstance(message, dict) or message.get('role') != 'assistant':
|
||||
|
||||
save_agent_session(
|
||||
replace(
|
||||
stored,
|
||||
messages=messages if messages_changed else stored.messages,
|
||||
display_messages=(
|
||||
display_messages
|
||||
if display_changed
|
||||
else stored.display_messages
|
||||
),
|
||||
),
|
||||
directory=directory,
|
||||
)
|
||||
|
||||
|
||||
def _annotate_last_assistant_in_messages(
|
||||
messages: tuple[dict[str, Any], ...] | tuple[Any, ...],
|
||||
elapsed_ms: int,
|
||||
) -> tuple[tuple[dict[str, Any], ...], bool]:
|
||||
updated = [dict(message) for message in messages if isinstance(message, dict)]
|
||||
for index in range(len(updated) - 1, -1, -1):
|
||||
message = updated[index]
|
||||
if message.get('role') != 'assistant':
|
||||
continue
|
||||
metadata = message.get('metadata')
|
||||
if not isinstance(metadata, dict):
|
||||
metadata = {}
|
||||
message['metadata'] = metadata
|
||||
else:
|
||||
metadata = dict(metadata)
|
||||
if metadata.get('elapsed_ms') == elapsed_ms:
|
||||
return tuple(updated), False
|
||||
metadata['elapsed_ms'] = elapsed_ms
|
||||
break
|
||||
try:
|
||||
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8')
|
||||
except OSError:
|
||||
return
|
||||
return
|
||||
message['metadata'] = metadata
|
||||
updated[index] = message
|
||||
return tuple(updated), True
|
||||
return tuple(updated), False
|
||||
|
||||
|
||||
def _read_session_title(directory: Path, session_id: str | None) -> str | None:
|
||||
|
||||
@@ -148,7 +148,7 @@ export function ThreadListSidebar({
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton size="lg">
|
||||
<div className="aui-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<div className="aui-sidebar-header-icon-wrapper flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-accent text-sidebar-foreground">
|
||||
<BotIcon className="aui-sidebar-header-icon size-4" />
|
||||
</div>
|
||||
<div className="aui-sidebar-header-heading mr-6 flex flex-col gap-0.5 leading-none">
|
||||
@@ -647,7 +647,7 @@ function AccountMenu({
|
||||
{compact ? (
|
||||
<button
|
||||
type="button"
|
||||
className="flex size-8 items-center justify-center rounded-full bg-sidebar-primary text-sidebar-primary-foreground transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
||||
className="flex size-8 items-center justify-center rounded-full bg-sidebar-accent text-sidebar-foreground transition-colors hover:bg-sidebar-accent/80 hover:text-sidebar-accent-foreground"
|
||||
aria-label="账号与统计"
|
||||
title={account.username}
|
||||
>
|
||||
@@ -660,7 +660,7 @@ function AccountMenu({
|
||||
type="button"
|
||||
className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left transition-colors hover:bg-sidebar-accent"
|
||||
>
|
||||
<div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-sidebar-accent text-sidebar-foreground">
|
||||
<UserIcon className="size-4" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
|
||||
Reference in New Issue
Block a user