Say what a tool did, not where it ran
An agent event set its label to the SSH profile's name, so the transcript read "homeserver · ls -la" -- naming the machine rather than the thing that was done. Built-in tools set no label at all and fell back to the function name, so a saved memory read "memory_add". The status line said "Running shell_run…" and the approval card had its own hand-written wording. Four places, four answers, nothing checking that any of them agreed. services/tool_labels.py is the one table all of them read now. Bash, Read, Write, List, Web search, Memory saved; an icon each, instead of everything being the sparkle. The precedence is inverted on purpose. Tool events are persisted in Message.tool_calls_json, so every agent row already on disk carries the profile name -- a resolver that preferred the stored value would fix nothing for any transcript that already exists. So a name the table knows resolves from the table, and a name it does not -- a custom HTTP tool, an MCP tool, whose labels are per row and cannot be tabulated -- keeps its own. One rule, both cases correct. The machine moves to `detail`, where "where this ran" belongs. tool_label and tool_icon are Jinja globals because a message bubble is rendered from four handlers, and a fifth thing each of them must remember to pass is a fifth thing one of them will forget. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
52770d7ab1
commit
a58e48fce5
@@ -12,6 +12,7 @@ from lembas import __version__
|
||||
from lembas.config import settings
|
||||
from lembas.db.models import User
|
||||
from lembas.services import metrics as metrics_service
|
||||
from lembas.services import tool_labels
|
||||
from lembas.services.markdown import highlight_tokens
|
||||
from lembas.services.reasoning import format_duration
|
||||
|
||||
@@ -51,6 +52,14 @@ templates.env.filters["stable_hue"] = stable_hue
|
||||
# every one of them would otherwise have to remember to pass it.
|
||||
templates.env.filters["tokens"] = highlight_tokens
|
||||
|
||||
# What a tool call is called and what it looks like. Globals rather than
|
||||
# context values because a message bubble is rendered from four different
|
||||
# handlers -- pages, post_message, regenerate and the SSE follower -- and every
|
||||
# one of them would otherwise have to remember to pass them. That is the exact
|
||||
# trap `audio_service.template_flags` fell into.
|
||||
templates.env.globals["tool_label"] = tool_labels.label_for
|
||||
templates.env.globals["tool_icon"] = tool_labels.icon_for
|
||||
|
||||
|
||||
def resolve_theme(user: User | None) -> str:
|
||||
"""Theme to render with on the server.
|
||||
|
||||
Reference in New Issue
Block a user