Release: dev → main (inspector header redesign + feed bug fixes)#1138
Merged
Conversation
chore: sync dev with main merge commit (fast-forward)
.build-issue__branch already had white-space: nowrap + overflow: hidden + text-overflow: ellipsis + max-width: 100%, but the truncation never fired. Root cause: .build-issue__pr-row had align-items: flex-start inherited from its flex-column parent (.build-issue__footer), which shrinks the row to its content width. max-width: 100% then resolves against that already-oversized parent and does nothing. Fix: add width: 100% to .build-issue__pr-row so the percentage resolves against the card width, not the branch name's intrinsic length.
fix: branch name truncates to card width (not hardcoded length)
… local model name
Three cosmetic/correctness fixes to the llm_iter row in the activity feed:
1. Remove color-coded left borders from all non-error activity rows.
The border-left-color rules by subtype added visual noise without meaning.
Only error rows (border-left: #ef4444) and shell exit-nonzero rows keep a
coloured border because those carry real signal.
2. Drop the 'Iteration N' second line from llm_iter rows.
The step count already establishes position; the iteration number inside a
step is redundant. buildIterSummary now renders a single .af__iter-model
span. Matching SCSS removes the flex-direction: column layout and the
now-unused .af__iter-num selector.
3. Fix 'Local: local' — show the actual Ollama model name.
Two root causes:
a) Backend (llm.py): local_llm_tool_call emitted llm_iter with 'model: model'
(the default parameter 'local') instead of 'model: agent_model or model'
(the resolved settings value, e.g. 'qwen2.5:7b').
b) Frontend (format_utils.ts): parseModelInfo had no handling for Qwen,
Llama, Mistral, Phi, DeepSeek, or Gemma model strings from Ollama.
Now: 'qwen2.5:7b' → { network: 'Local', modelShort: 'Qwen 2.5' } →
display 'Local: Qwen 2.5'. 'local' (fallback) → modelShort '' → display
just 'Local' (no redundant ': local' suffix).
fix: activity feed — remove color borders, drop iteration count, fix local model name
…in Docker Tool rows (tool_invoked, github_tool) now expand on click to show the full parsed arguments inline below the row: - 4-column grid adds a chevron (af__chevron) that rotates 90° when open - Click (or Enter/Space) toggles aria-expanded and the hidden detail panel - af__tool-detail shows each arg as key · value using af__detail-key / af__detail-val; falls back to raw preview if parsing fails - Keyboard-accessible: role=button, tabindex=0 - Light and dark mode styled - 5 new unit tests covering expand, collapse, key-value rendering, and non-expandable row types Also fixes a long-standing Docker gap: vitest.config.ts was never copied into the image (only package.json, tsconfig.json etc. were). Without the config Vitest used default include patterns (**/*.spec.ts) which picked up the Playwright E2E spec and poisoned the jsdom environment for all other tests. Fix: add vitest.config.ts to the Dockerfile COPY step. The config also gains an explicit exclude for agentception/tests/** to prevent future E2E spec pickup regardless of Vitest version changes.
feat: expandable tool call rows in activity feed
- llm_iter rows are suppressed entirely; instead a single .af__model-header element is inserted once at the top of #activity-feed showing the run model (e.g. "Local: Qwen 3.5") so it is not repeated on every step - llm_usage rows are suppressed; their token count is injected directly into the .event-card__tokens placeholder on the current step header, appearing right-aligned on the same line as "STEP N" - Removed per-subtype indentation from tool/file/shell/git_push rows — they are now flush with the rest of the feed since llm_iter is no longer a visual parent - step_context: track _currentStepHeader; export getCurrentStepHeader() - event_card: add empty .event-card__tokens span to step_start cards - SCSS: .af__model-header styles, .event-card__tokens styles, pruned dead llm_iter/llm_usage overrides, updated .af__tool-detail padding - 250 tests passing, zero type errors
feat: model info in feed header; token count on step header; remove tool indent
fix: colon separator in tool summary rows
fix: sans-serif colon separator; 0:00 timestamp instead of 'now'
…e entry - Add humanizeDetailKey() to format_utils with a 40-key label map (n_results→results, cmd_preview→command, old_string→find, etc.) - buildToolDetail uses humanizeDetailKey for all rendered keys - start_line + end_line are collapsed into a single "lines: N–M" entry instead of two separate rows - 260 tests passing, zero type errors
feat: humanize detail panel key names; collapse line range
Backend: - FileReadPayload gains content_preview: NotRequired[str] - read_file_lines emits first 10 lines / 400 chars as content_preview Frontend: - file_read rows are now expandable (click chevron to reveal preview) - buildFileReadDetail renders content_preview in a scrollable <pre> block - Falls back to a "no preview" note for historical events without the field - .af__content-preview SCSS: compact code block, max-height 10rem, scrollable - 263 tests passing, zero mypy errors, zero tsc errors
feat: file content preview in file_read activity events
Backend: - DirListedPayload TypedDict: path, entry_count, entries (newline-delimited) - dir_listed added to ACTIVITY_SUBTYPES - agent_loop: emit dir_listed after successful list_directory with proper isinstance narrowing for JsonValue typing Frontend: - folder SVG icon added to icons.ts - dir_listed: expandable row (folder icon, "N entries" summary) - buildDirListedDetail renders entries as a pre block via af__content-preview (same SCSS reused from file_read content preview) - 267 tests passing, zero mypy errors, zero tsc errors
feat: dir_listed activity event — show list_directory results in inspector
- Increase arg_preview 120→500 chars and text_preview 200→1500 chars so full LLM reply text and complete tool args fit without truncation. - Make llm_reply rows expandable: clicking reveals the full text_preview in a scrollable prose block (af__content-preview--reply). - Suppress the internal `collection` key (Qdrant collection name) from all tool detail panels via HIDDEN_DETAIL_KEYS. - Render old_string/new_string pairs as a colour-coded find/replace diff block (af__diff-block--old / --new) instead of raw key-value lines. - SCSS: add diff block styles with red/green tints for find/replace, and a wrapping prose variant for LLM reply previews. - Tests: 8 new assertions covering llm_reply expand, diff rendering, and collection suppression — 271 tests passing.
feat(feed): llm reply expandable, search humanisation, code diff display
Adds scripts/retrofit_activity_events.py — idempotent back-fill for two event types added after existing runs were recorded: - dir_listed: reconstructs 29 events across 3 runs from tool result rows in agent_messages (entries list stored in raw JSON). - llm_reply text_preview: extends 2 events whose previews were truncated at 200 chars to the new 1 500-char limit using the matching assistant message in agent_messages. Safe to re-run; no-ops when there is nothing left to do. Usage: docker compose exec agentception python3 /app/scripts/retrofit_activity_events.py [--dry-run]
feat(scripts): retrofit historical activity events
dir_listed is a result, not a peer event. Instead of rendering a separate folder-icon row, inject directory entries directly into the detail panel of the preceding list_directory tool_invoked row: - Remove dir_listed from EXPANDABLE_SUBTYPES. - Add injectDirListedIntoPanel(): finds the nearest [data-list-dir-target] panel in the current step container and appends an 'entries' key row + pre block. - Tag list_directory tool_invoked detail panels with data-list-dir-target so the injector can find them. - Route dir_listed events to the injector then return (no standalone row). - Tests: replaced 4 dir_listed-as-row tests with 3 nesting-behaviour tests. 270 tests passing.
feat(feed): nest dir_listed entries inside list_directory row
Same pattern as dir_listed / list_directory: Backend: - Add SearchResultsPayload TypedDict and 'search_results' to ACTIVITY_SUBTYPES. - After search_codebase: emit search_results with deduplicated relative file paths from match objects. - After search_text: emit search_results by parsing rg --heading output to extract file path lines. Frontend: - Tag search_codebase / search_text tool_invoked detail panels with data-search-target. - Route search_results events to injectSearchResultsIntoPanel(), which finds the nearest data-search-target panel and appends a 'files' label + pre block. - No standalone row created — results live inside the search row chevron. - Tests: 4 new assertions; 274 tests passing.
feat(feed): show search result files nested inside search rows
Adds _backfill_search_results() to retrofit_activity_events.py: - Finds runs with search_codebase/search_text tool_invoked events but no search_results activity events. - Reconstructs file lists from agent_messages tool results: structured matches array for search_codebase, rg --heading output parsing for search_text. - Matches invocations to results sequentially (same strategy as dir_listed). Ran live: 61 search_results events inserted across 3 historical runs. Script remains fully idempotent.
feat(scripts): retrofit search_results for historical runs
Three fixes: 1. Injection scope: search the full feed element (not just the current step container) when injecting dir_listed and search_results. This makes injection resilient to step-boundary timing edge cases where the step context changes between the tool_invoked and result events. 2. Label: n_results → 'limit' in ARG_KEY_LABELS. The param is the request cap, not the count of matches found. Showing 'results: 10' implied 10 results were found rather than requested. 3. Retrofit timestamps: search_results events now anchor to invocation.recorded_at + 1 s (not the tool result timestamp) to guarantee they sort strictly after their tool_invoked event. The script purges and re-inserts to fix the previously stored events. 274 tests passing.
Every tool call in the inspector feed now shows its output when expanded: shell_done: stdout_preview (first 30 lines / 2 000 chars) + stderr_preview are added to the shell_done payload and injected into the preceding run_command tool_invoked detail panel (data-shell-output-target). github_result: a new activity event type emitted after every GitHub MCP call carries result_preview (first 30 lines / 2 000 chars of the MCP response text) and is injected into the preceding github_tool detail panel (data-github-result-target). Retrofit inserts lorem-ipsum placeholders for both new event types on historical runs so the UX can be validated immediately. 280 tests passing.
feat: output preview for every tool call (shell + GitHub MCP)
- Compute MD5 fingerprint of app.js at server startup and embed as ?v= query string on all CSS/JS asset URLs so the browser always loads the latest bundle after every npm run build without a manual cache clear. - Add _backfill_missing_shell_done to retrofit script: inserts placeholder shell_done events (with lorem-ipsum stdout_preview) for run_command invocations that have no shell_done event at all (emitted by older code that skipped the event). Matched 3 unmatched invocations and inserted placeholders so the shell-output injection panel receives content.
feat: asset cache-busting + retrofit missing shell_done events
…ind_call_sites All four tools now emit output events on success so the inspector shows real content rather than just the arguments: - read_file_lines → file_read event (content_preview, first 20 lines/1500 chars) - read_symbol → file_read event (symbol body, same limits) - read_window → file_read event (windowed content, same limits) - find_call_sites → search_results event (unique file paths from rg output) Frontend: extend data-file-read-target tagging to read_symbol and read_window panels; add data-search-target to find_call_sites panels. Add humanised labels "Read symbol", "Read window", "Find usages" to TOOL_LABELS so the feed row summary reads naturally.
feat: output preview for read_file_lines, read_symbol, read_window, find_call_sites
…og arch
- Remove icon links from Kanban card; move them to inspector toolbar
- Add transcript and cognitive-arch icon links to the inspector header
- Add inline persona mini-card to inspector panel (HTMX lazy-loaded via
new GET /ui/runs/{run_id}/persona-card endpoint + _persona_card.html)
- Replace raw Timeline section on agent detail page with the same rich
activity-feed SSE stream already used in the inspector panel
- Add agentDetailFeed() Alpine component in build.ts; export from app.ts
- Polish cognitive_arch.html: wrap Prompt Prefix in a collapsible
<details> element; improve hero panel, atom pills, section labels,
skill chips and light-mode friendliness in _agent-detail.scss
- Add agent-feed-section / agent-feed__feed SCSS for the standalone feed
- Add persona-card SCSS in _inspector-layout.scss
…lish feat: inspector + agent pages polish — persona card, activity feed, cog arch
The Timeline section in agent.html was replaced by the SSE-driven activity feed in the previous commit, so get_agent_events_tail, AgentEventRow, _event_detail_text, _event_icon, and processed_events are now unreachable dead code. Remove them all.
fix: remove dead events fetching code from agent detail route
The chain of thought is already surfaced in the rich activity feed (SSE stream) above. The raw Conversation disclosure block — which rendered every user/assistant message as a collapsible pre block — is redundant and visually noisy. - Remove the Conversation <details> section from agent.html - Drop db_messages fetching from get_agent_run_detail in agent_detail() - Remove the messages list build, the "messages" template context key, and the AgentMessageRow import from the main page route - Leave the agent_transcript_partial endpoint untouched (it is a separate HTMX route with its own logic)
fix: remove Conversation section from agent detail page
fix: persona card profile link — same tab, stable hover colour in light mode
Move Presets and Launch buttons before the mode-toggle in the DOM. od-header__title has flex:1 so the right-side cluster is packed against the right edge. With Toggle and Close always the last two items in that cluster, they stay at identical pixel positions regardless of whether Presets/Launch are rendered. No SCSS change needed.
fix: stable org designer toolbar — Toggle and Close never shift position
Place Presets and Launch buttons before the flex:1 title spacer so they expand leftward into the title gap. Everything to the right of the title (initiative, save-as, toggle, close) stays at exactly the same pixel positions in both Live and Design mode — no layout shift whatsoever.
…unch fix: Presets + Launch on left side of org designer toolbar
fix: keep Agent Org anchored far-left in org designer toolbar
Zone A (Issue Identity): restructured toolbar to show a top row with issue number + actions cluster, a prominent title, and a labels + status badge row. Labels are filtered (no phase-* or initiative slugs, max 3) and displayed as chips alongside the colour-coded status badge pushed to the right. Zone B (Execution State): replaced the thin run-meta bar with a dedicated exec strip showing role chip, tier badge (engineer/vp/cto with distinct colours), step count, human-readable run duration (e.g. "ran 8m 23s"), and the branch name. A pulsing dot + "Currently: …" row appears for active runs. Zone C (Agent Attribution): persona card redesigned as a compact horizontal strip — oversized emoji / name + archetype / skill chips / arrow icon link. Data pipeline: extends AgentRun TS interface with steps_completed, spawned_at, last_activity_at, current_step, branch, cognitive_arch (all already carried by RunForIssueRow in the backend). Adds formatRunDuration() helper with live setInterval clock for implementing/reviewing runs. Adds filteredLabels getter using window._buildInitiative to strip noise labels. Removes dead __run-meta, __run-since SCSS. Adds 8 unit tests for formatRunDuration.
feat: redesign inspector header into three information-rich zones
…ranscript
Remove the transcript and cognitive-architecture icon links from the inspector
toolbar — they added visual noise and duplicated the persona card arrow.
The persona card arrow (→) now links to /agents/{run_id} (the agent
transcript page) instead of the cognitive architecture page. Pass run_id to
the _persona_card.html template context so the link can be rendered
server-side. Delete dead __icon-link SCSS block.
fix: remove icon links from toolbar; persona card arrow links to transcript
Switching cards called _closeStream() but never wiped the #activity-feed element, so rows from the previous run bled into the newly selected card (or remained visible when a card with no run was selected). Add clearFeed() to activity_feed.ts — wipes #activity-feed innerHTML and calls resetFeedSession() — then call it from onInspect() and clearInspect() in buildPage(). Add 3 regression tests for clearFeed behaviour.
fix: clear activity feed DOM when switching between inspector cards
All conflicts were between dev's inspector header redesign / feed fixes and main's older versions of the same files. Accepted dev (HEAD) in every case: - build.html: three-zone inspector layout (no icon links) - _inspector-layout.scss: new Zone A/B/C styles (no __icon-link / __run-meta) - _persona_card.html: compact horizontal strip linking to transcript page - build_ui.py: pass run_id to persona card template - build.ts: include clearFeed import - activity_feed.test.ts: include clearFeed regression tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merge conflicts resolved — dev improvements kept over main's older versions.
Inspector Header Redesign (PR #1134)
ran 8m 23s), branch name. Pulsing dot + "Currently: …" row for active runs.AgentRunTS interface withsteps_completed,spawned_at,last_activity_at,current_step,branch,cognitive_arch. AddedformatRunDuration()helper with live clock for active runs.formatRunDuration.Toolbar Simplification (PR #1135)
→arrow links to/agents/{run_id}(agent transcript page).run_idpassed to template server-side.__icon-linkSCSS block.Activity Feed Clear on Card Switch (PR #1136)
clearFeed()toactivity_feed.tsand call it inonInspect()andclearInspect().Conflict resolution
All 6 conflicts were between dev's new inspector code and main's older versions of the same files. Accepted dev (HEAD) in every case. All checks pass: mypy clean, tsc clean, 291 tests pass, bundles build.