Skip to content

Surface conversation tags in the conversation panel (origin/owner attribution for API- and automation-born conversations) #1925

Description

@harish-chandramowli

Problem

Self-hosted Canvas conversations can be born from many surfaces besides the browser: Slack automations, GitHub triggers, cron automations, or arbitrary API clients hitting the agent-server directly. In the conversation panel today there is no way to tell where a conversation came from or which automation/user it belongs to — API-born conversations all look alike.

The server half of a solution already exists: agent-server stores tags: Record<str, str> on every conversation (settable at creation and via PATCH /api/conversations/{id}), and the Canvas frontend already normalizes them (normalizeTags in agent-server-conversation-service.api.ts). But the UI only ever consumes the single reserved acpserver tag; every other tag is invisible.

Proposal

Surface conversation tags in the conversation panel:

  1. Show non-reserved tags as small chips on the conversation card (e.g. origin: slack, owner: alice). Reserved/internal keys (acpserver) stay hidden.
  2. Match tags in the existing "Filter conversations" text filter, so typing slack or owner:alice narrows the list.
  3. (Possible follow-up, out of scope here) an "Organize → By tag" grouping mode alongside the existing By workspace / By repository modes.

No new server concepts, no schema changes — this is purely making already-stored, already-fetched metadata visible.

Motivating use case

We run a self-hosted Canvas + agent-server for a small team. A glue service births conversations from Slack threads and from an automated PR-review pipeline, over the agent-server REST API. We stamp tags like origin=slack, origin=review, owner=<engineer> at creation — but nobody can see them in the UI, so review runs, Slack runs, and browser runs are indistinguishable in the panel. With chips + filter, any team member could instantly see "started from Slack by alice" or filter to just review conversations — using data the server already returns.

This is adjacent to the created_by_user_id field that exists for Cloud conversations, but deliberately narrower: tags are already a self-hosted, API-writable concept, so no auth/identity machinery is implied.

Implementation sketch

  • Expose the already-normalized tags map on AppConversation (it's currently dropped after acpserver extraction in agent-server-adapter.ts).
  • Render filtered chips in the conversation card footer next to the existing repo/model metadata, behind the existing hover-metadata setting.
  • Extend the filter predicate in conversation-panel.tsx to match key, value, and key:value forms.

I have a working branch for 1–2 and am happy to open a PR if this direction is acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions