Skip to content

Add conversational Assistant panel to /query#12

Merged
kosminus merged 1 commit into
mainfrom
feat/assistant-chat-panel
Jun 5, 2026
Merged

Add conversational Assistant panel to /query#12
kosminus merged 1 commit into
mainfrom
feat/assistant-chat-panel

Conversation

@kosminus

@kosminus kosminus commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a conversational Assistant panel on the /query page. Editors ask data questions and grow the semantic layer in plain language; the assistant only drafts — every write rides the existing REST + auto-embed endpoints, so authorization stays unchanged. MCP remains external-only.

One stateless POST /query/assistant turn runs a single structured-JSON LLM call that classifies intent and extracts a draft (no tool-calling loop, no provider changes, no chat-session table — history is passed from the client).

Intents

Intent Action Confirmed write
question sql_preview (reuses generate_sql_only) POST /query/execute-sql
glossary glossary_draft POST /connections/{id}/glossary
metric metric_draft POST /connections/{id}/metrics
dictionary dictionary_draft POST /columns/{column_id}/dictionary (per entry)
knowledge knowledge_draft POST /connections/{id}/knowledge
chat plain message

All draft intents are editor-gated (ctx.has_role(ROLE_EDITOR)); viewers get questions only. Dictionary resolves (table_name, column_name) → column_id server-side against the schema cache and supports multiple value mappings per column, downgrading to a clear chat message when the column isn't found.

Design notes

  • Mounted under /query (body connection_id, get_org_context) mirroring the existing query endpoints — inherits the /query/* rate limiter for free; the service's get_connection enforces read-authz.
  • Agent returns a generic AssistantDecision{intent, message, payload}; per-intent normalizers validate/shape the payload and downgrade to chat when unusable.
  • Frontend: AssistantPanel renders colour-coded, editable confirmation cards that POST to the existing create endpoints and invalidate the relevant query caches. QueryResultView extracted from QueryPage for reuse.

Test plan

  • Backend: 131 passed (33 new assistant tests — agent normalizers per intent, downgrade-on-unusable-payload, service branching incl. dictionary column resolution + viewer-blocked-before-resolution). ruff clean.
  • Frontend: tsc --noEmit clean, ESLint clean, npm run build succeeds.
  • Manual: try "What is total ECL by stage?", "Add a glossary term: NPL means loans where stage = 3", "Define a metric: ECL coverage ratio = sum(ecl)/sum(exposure)", "In the stage column, 1=performing, 2=underperforming, 3=non-performing", "Remember this about IFRS 9: …".

Plan / as-built notes in docs/assistant-plan.md.

🤖 Generated with Claude Code

A chat panel where editors ask data questions and grow the semantic layer in
plain language. One stateless POST /query/assistant turn runs a single
structured-JSON LLM call that classifies intent and extracts a draft; the
assistant only drafts — every write rides the existing REST + auto-embed
endpoints, so authorization is unchanged.

Intents: question -> sql_preview (reuses generate_sql_only), and editor-gated
glossary/metric/dictionary/knowledge drafts. Dictionary resolves
(table_name, column_name) -> column_id server-side and supports multiple value
mappings per column. Viewers get questions only.

Frontend: AssistantPanel renders per-intent confirmation cards that POST to the
existing create endpoints and invalidate the relevant query caches; QueryResultView
extracted from QueryPage for reuse. MCP stays external-only.

Tests: 33 unit tests (agent normalizers + downgrade, service branching incl.
dictionary column resolution). Full backend suite green (131); frontend tsc +
eslint + build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kosminus kosminus merged commit d6f4f05 into main Jun 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant