Skip to content

agent-sessions: agent-kind 过滤把整段 CSV 当单值精确匹配,选中后列表清空 #105

Description

@vaderyang

Goal

修正 Agent Sessions 页面的 "Agent kind" 过滤。下拉框是多选,前端把选中项以 CSV(如 claude-cli,codex-cli)发给 /api/agent-sessions,但后端 query_sessionsagent_kind = '<整段 CSV>'精确等值匹配,导致选中后匹配不到任何行、列表清空。改为把该值当 CSV 拆分后用 IN (...) 匹配(任一命中即返回)。

Why now

用户报告:在 Agent Sessions 选中 agent kind 后,所有 session 都不显示了。

复现

  1. Agent Sessions 页,打开 "Agent kind" 下拉(多选 FilterDropdown)。
  2. 选中 2 个及以上 kind。
  3. 列表变空("No sessions found"),尽管当前时间窗内这些 kind 都有 session。

根因

  • 前端契约就是 CSV:console/src/hooks/use-agent-sessions.ts 注释写明 /** CSV of agent kinds, e.g. "claude-cli,codex-cli" */console/src/pages/agent-sessions.tsx 用多选下拉 + agentKindFilter.join(",")
  • 后端 server/h-storage-duckdb/src/sessions.rs:31-32 把整段 CSV 当单值精确匹配:
    if let Some(ak) = &query.agent_kind {
        where_parts.push(format!("agent_kind = '{}'", ak.replace('\'', "''")));
    }
    即生成 WHERE agent_kind = 'claude-cli,codex-cli' —— 没有任何行的 agent_kind 恰好等于这串 CSV,故返回 0 行。
  • 对照正确实现:turns 端点 server/h-api/src/routes/agent_turns.rs:86parse_csv(&params.agent_kind) 把 CSV 拆成 Vec 再做 any-match。sessions 端点漏了这步拆分。

In scope

  • query_sessionsagent_kind 按 CSV 解释:逗号拆分、trim、过滤空串后生成 agent_kind IN (...),沿用现有 '' 转义防注入。空选时不加该谓词。

Out of scope (explicit)

  • 不改 SessionListQuery.agent_kind 的类型(保持 Option<String>,按 CSV 解释)。把它重构成 Vec<String> 以与 turns 端点风格统一是可选后续项,会横跨 h-storage / h-api / h-storage-duckdb 多个 crate,本 issue 不做。
  • 不动前端。
  • 不动其它过滤维度(source_id、时间窗等)。

Acceptance criteria

  • 选中单个 kind 仍只返回该 kind 的 session(无回归)。
  • 选中 2 个 kind 返回两者的并集(而非空)。
  • server/h-storage-duckdb/src/sessions.rs 新增确定性单元测试:插入 ≥2 种 agent_kind 的 turns,断言 agent_kind = "a,b" 返回 a、b 两类 session,agent_kind = "a" 仅返回 a。
  • cargo test -p h-storage-duckdb 通过,cargo clippy 无新增告警。

Suggested approach

只改 server/h-storage-duckdb/src/sessions.rs 的 Step-1 WHERE 构造(约 31-32 行):把单个等值谓词替换为「对 query.agent_kind 逗号拆分 → trim → 过滤空串 → 各值用现有 replace('\'', "''") 转义 → agent_kind IN (...)」。可参考 server/h-storage-duckdb/src/distincts.rstest_query_distinct_agent_kinds_filters_by_turn_window 的 turn fixture 来写测试。

Files / crates touched

  • server/h-storage-duckdb/src/sessions.rs(实现 + 单元测试)—— 单 crate。

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:assessTrigger AI triageagent:trywiwi auto-implement queuebugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions