feat(ai-chat): agent avatar stack — agent front, launcher behind (#300) #304
Open
agent_coder
wants to merge 2 commits from
feat/300-agent-avatar-stack into develop
pull from: feat/300-agent-avatar-stack
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:feat/git-sync
vvzvlad:refactor/294-tool-spec-registry
vvzvlad:feat/scroll-restore-ux
vvzvlad:fix/302-reasoning-parse-when-open
vvzvlad:develop
vvzvlad:feat/184-autonomous-agent-runs
vvzvlad:fix/responsive-tablet-sidebar
vvzvlad:feature/ai-chat-page-change-observability
vvzvlad:feature/offline-sync
vvzvlad:image-inline-center
vvzvlad:fix/283-short-remap-title
vvzvlad:fix/283-slash-layout
vvzvlad:image-inline-row
vvzvlad:feat/276-ai-chat-dock
vvzvlad:fix/269-table-menu-refocus
vvzvlad:docs/dev-stand-guide
vvzvlad:feat/266-scroll-position
vvzvlad:fix/260-collab-docname-slugid
vvzvlad:test/244-phase2-tail
vvzvlad:fix/262-reindex-progress-realtime
vvzvlad:fix/258-changelog-compare-links
vvzvlad:fix/244-dataloss-bugs
vvzvlad:feat/246-spoiler
vvzvlad:feat/221-image-captions
vvzvlad:test/244-part-b
vvzvlad:feat/251-intentional-clear
vvzvlad:fix/embeddings-reindex-progress
vvzvlad:refactor/193-tool-spec-registry
vvzvlad:fix/255-ws-redis-adapter-leak
vvzvlad:fix/252-e2e-open-handles
vvzvlad:feat/229-catalog-yaml
vvzvlad:feat/243-blob-sandbox
vvzvlad:feat/228-inline-footnotes
vvzvlad:fix/qa-ui-bugs-216-218
vvzvlad:feature/agent-roles-catalog
vvzvlad:fix/share-alias-rename
vvzvlad:fix/ai-chat-empty-render
vvzvlad:feat/191-chat-doc-binding
vvzvlad:feat/201-temporary-notes
vvzvlad:feat/198-interrupt-agent
vvzvlad:feat/ai-chat-full-history
vvzvlad:feat/199-ai-generate-title
vvzvlad:feat/205-share-aliases
vvzvlad:batch/issues-189-187-170
vvzvlad:feat/170-mcp-test-button
vvzvlad:feat/189-context-badge
vvzvlad:feat/198-interrupt-agent-send-now
vvzvlad:fix/issues-190-159
vvzvlad:fix/ai-chat-new-chat-during-stream
vvzvlad:fix/ai-chat-stream-perf
vvzvlad:batch/issues-2026-06-25
vvzvlad:feat/ai-chat-persistent-history
vvzvlad:fix/ai-chat-copy-chat-wysiwyg
vvzvlad:fix/ai-stream-reset-resilience
vvzvlad:fix/ai-stream-undici-timeout
vvzvlad:fix/footnote-review-1227-followup
vvzvlad:fix/ai-chat-token-counter-realtime
vvzvlad:docs/manual-qa-test-plan
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
86c1307ed2 |
fix(#300 review): drop stray symlink, re-fetch enriched on comment update, cover history mapping (F1/F2/F3)
F1: remove an accidentally-committed self-referential symlink
packages/mcp/node_modules/node_modules -> an absolute build-machine path (leaked a dev
home path, a pnpm artifact useless in the repo), and add a targeted ignore so it can't
recommit.
F2: the commentUpdated broadcast re-emitted the caller's pre-loaded comment mutated in
place, so the {agent,launcher} stack survived only because the controller happened to
load it with includeCreator:true — the fragile coupling that let the stack vanish on
edit once already. update() now RE-FETCHES the enriched comment before broadcasting,
symmetric with create()/resolveComment() (the row is already persisted), so all three
broadcasts carry the stack regardless of any caller's pre-load. Adds a caller-contract
test asserting all three broadcasts emit agent/launcher for an agent comment and neither
for a non-agent one, spotlighting the update path (non-vacuous vs the old re-emit).
F3: add a direct test of the page-history attachPageHistoryAgent mapping (its distinct
lastUpdatedSource/lastUpdatedAiChatId/lastUpdatedBy column set): role / no-role / MCP /
non-agent, and that the internal agentRole join column is stripped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
0968ea97d2 |
feat(ai-chat): agent avatar stack — agent in front, launcher behind (#300)
For AI-agent-authored content (comments + page history), replace the text AI-AGENT badge with an avatar stack: the agent in front, the human who launched it smaller and behind. This fixes the inverted hierarchy (the action was the agent's; the human just launched it). closes #300. Backend: a single server-authoritative resolver resolveAgentProvenance normalizes to { agent, launcher } from server columns only (createdSource/lastUpdatedSource, aiChatId, creator, chat role) — nothing from request input, so agent identity can't be spoofed. Internal chat -> agent = chat role (name/emoji), launcher = human; external MCP (aiChatId null) -> agent = the agent account, launcher = null; non-agent -> neither. The role join (aiChatId -> ai_chats.role_id -> ai_agent_roles) deliberately does NOT filter enabled/deleted_at, so a later-disabled role still labels historical content (mirrors findById, not findLiveEnabled). Enrichment is applied on BOTH findPageComments (list) AND findById (the create/resolve/update broadcast path), so the stack shows on live comment events and doesn't vanish on resolve/edit. Frontend: new AgentAvatarStack + AgentGlyph (avatarUrl -> role emoji on violet -> IconSparkles on violet), integrated into comment-list-item and history-item where the badge was; the deep-link-to-chat click moved onto the stack. ai-agent-badge removed. Tests: AgentAvatarStack (role/no-role/MCP/click/non-clickable), the provenance resolver + recorder tests proving the role join never filters enabled/deleted, and findById enrichment (guards the live-broadcast regression). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |