proposal(chat): 侧边栏「N 个 agent」计数不能区分「从未配置」vs「配置了但还在跑」
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
## 背景
2026-08-22 devapp 真实浏览器实测(Gap #6,见 #1806 同批发现):一条线程刚发出消息、run 还在跑的时候,侧边栏一直显示"0 个 agent",和"这条线程从来没有配置过/用过任何 agent"是同一个文案,用户没法区分"还没配置 agent" vs "配置了但 run 还没跑完"。
## 已读代码确认的现状
`N 个 agent` 计数是后端算的,**唯一事实源**在 `apps/api/src/domain/chat/thread-badges.ts`:
- `findSpeakingAgentIds`(`apps/api/src/infrastructure/chat/pg-chat-repository.ts:282-290`):`SELECT DISTINCT agent_id FROM chat_messages WHERE thread_id=$1 AND author_kind='agent' AND agent_id IS NOT NULL`。
- `threadBadgeState.agentCount = new Set(speakingAgentIds).size`(`thread-badges.ts:108-115`)。
语义:只数**已经产出过 agent 消息**的不同 agent。排队中/运行中但尚未写回的 run **不计入**——没有 agent 消息行就不会被这条 DISTINCT 数到。所以"配置了 agent、run 还没跑完"与"从未配置任何 agent"在这个数字上完全无法区分,都是 0。
## 为什么不能在这个 issue 里顺手修
`thread-badges.ts` 文件头注释与行内注释明确写着:
> `⚠ 取自该线程内发过言的不同 agent 数,不是 AI 团队面板的在场数/编制数——那两个数属 F110(AgentPresence),且"在场数是否含跑批中"是 domain.md 待裁决第 4 条,未裁。这里不预支那个裁决。`
对应 `phases/phase-01-run-a-project/contracts/chat/domain.md:338-341`:
> `### 4. 「在场数」是否包含跑批中的 agent(S-06)`
> `...跑批中与空闲不计入」。它连带决定线程卡上的「N 个 agent」是哪个数。UC 没写。`
这是一个**已知、已标注、明确等待人类裁决**的设计缺口(S-06),不是遗漏。把"运行中的 run 也算进 N"塞进这个 issue 里会绕开签核直接定案,属于本项目 AGENTS.md 明令禁止的"设计签核"红线。
## 建议方案(供人类裁决 S-06 时参考,不在本 issue 实现)
至少两个候选:
- **方案 A(最小改动)**:后端另外暴露一个布尔 `hasActiveRun`(线程是否存在非终态 `agent_runs` 行),前端在 `agentCount === 0 && hasActiveRun` 时把文案从"0 个 agent"换成"配置中…"/一个进行中小图标,不改变 `agentCount` 本身的语义(不预支 S-06,只是多给一个独立事实字段)。
- **方案 B(等 S-06 裁决后)**:`agentCount` 本身的定义扩展为"发过言 ∪ 有非终态 run 的 agent 数",需要人类先在 `domain.md` 待裁决第 4 条给出裁决,再改 `thread-badges.ts` 单源计算,涉及契约/UI 文案的连带变更。
## 范围
纯设计/方案记录 issue,不建分支不写代码。等 S-06 裁决落地后再拆实现 issue。
Contributor guide
No contributing guide indexed for this repository
Research direction
Read apps/api/src/domain/chat/thread-badges.ts and apps/api/src/infrastructure/chat/pg-chat-repository.ts to understand the current agentCount source, then review phases/phase-01-run-a-project/contracts/chat/domain.md around S-06. This issue is design-only: done means a human decision is recorded and a separate implementation issue is created.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100