diff --git a/claude_code_log/factories/meta_factory.py b/claude_code_log/factories/meta_factory.py index 3e9b7d85..0275889a 100644 --- a/claude_code_log/factories/meta_factory.py +++ b/claude_code_log/factories/meta_factory.py @@ -4,7 +4,7 @@ that is shared across all message types. """ -from ..models import BaseTranscriptEntry, MessageMeta +from ..models import AssistantTranscriptEntry, BaseTranscriptEntry, MessageMeta def create_meta(transcript: BaseTranscriptEntry) -> MessageMeta: @@ -33,4 +33,10 @@ def create_meta(transcript: BaseTranscriptEntry) -> MessageMeta: cwd=transcript.cwd, git_branch=transcript.gitBranch, team_name=getattr(transcript, "teamName", None), + # The model id lives on the assistant message body, not the base entry. + model=( + transcript.message.model + if isinstance(transcript, AssistantTranscriptEntry) + else None + ), ) diff --git a/claude_code_log/html/renderer.py b/claude_code_log/html/renderer.py index 6e7df37f..7911508e 100644 --- a/claude_code_log/html/renderer.py +++ b/claude_code_log/html/renderer.py @@ -1032,7 +1032,11 @@ def title_TaskInput(self, input: TaskInput, message: TemplateMessage) -> str: if input.run_in_background else "" ) - suffix = async_hint + self._agent_depth_badge(message) + suffix = ( + async_hint + + self._agent_depth_badge(message) + + self._agent_model_badge(message) + ) if input.description and input.subagent_type: escaped_desc = escape_html(input.description) return ( @@ -1069,6 +1073,21 @@ def _agent_depth_badge(self, message: TemplateMessage) -> str: f"Depth {spawned_depth}" ) + def _agent_model_badge(self, message: TemplateMessage) -> str: + """Model badge for a spawn card (#246): the model the spawned + sub-agent ran on, stamped on the always-visible Task/Agent launch + card by ``_surface_agent_models`` (``display_model``). Shown for + every spawn depth β unlike the depth badge, it isn't suppressed at + depth 1, since the top-level Explore/Task spawn is the common case a + reader wants to see. Empty when no model was resolved (e.g. an + interrupted spawn whose sub-agent produced no assistant turn).""" + if not message.display_model: + return "" + return ( + f" " + f"{escape_html(message.display_model)}" + ) + def _async_id_suffix( self, minted_id: Optional[str], diff --git a/claude_code_log/html/templates/components/message_styles.css b/claude_code_log/html/templates/components/message_styles.css index a4565678..b538347f 100644 --- a/claude_code_log/html/templates/components/message_styles.css +++ b/claude_code_log/html/templates/components/message_styles.css @@ -278,6 +278,13 @@ color: #888; } +/* Model id surfaced on sub-agent message headers (issue #246) */ +.message-model { + font-size: 0.75em; + font-family: var(--font-mono, 'SFMono-Regular', Consolas, monospace); + color: var(--text-secondary, #888); +} + /* Paired message styling */ .message.pair_first { margin-bottom: 0; diff --git a/claude_code_log/html/templates/transcript.html b/claude_code_log/html/templates/transcript.html index 2cca16a7..0fdd6b22 100644 --- a/claude_code_log/html/templates/transcript.html +++ b/claude_code_log/html/templates/transcript.html @@ -129,7 +129,7 @@
#cccc333]
+ π§ Task Coverage analysis (Explore) [async #cccc333] claude-opus-4-7