Skip to content

Feat: Agent Tools Improvements#171

Open
medazizktata25 wants to merge 19 commits intoGuepard-Corp:mainfrom
medazizktata25:feat/tools-handling-and-ui
Open

Feat: Agent Tools Improvements#171
medazizktata25 wants to merge 19 commits intoGuepard-Corp:mainfrom
medazizktata25:feat/tools-handling-and-ui

Conversation

@medazizktata25
Copy link
Contributor

What

  • Tooling UX: make tool outputs (schema, SQL, errors) and suggestions more structured, clickable, and easier to read, especially when multiple datasources are attached.
  • Chat flow: add a real “regenerate last answer” flow that replaces the previous assistant message instead of piling more messages.
  • Datasource navigation: unify how we resolve a datasource/table and open its page (including schema) from badges, tool output, and suggestions.
  • Conversation & scrolling UX: improve long‑conversation handling (load‑more, scroll sticking) and todo/suggestion/task delimiters so big sessions stay usable.

All 8 commits in feat/tools-handling-and-ui are covered below.

How

Chat + transport (04fe786, b1b6e42)

  • Server regenerate flow (apps/server/src/routes/chat.ts):
    • When body.trigger === 'regenerate-message':
      • Load the conversation by slug, fetch its messages, find the last message, and delete it only if it’s an assistant (MessageRole.ASSISTANT).
      • Then run the normal chat resolution so the new response replaces the deleted one.
  • Client transport trigger + slimming (packages/agent-factory-sdk/src/services/default-transport.ts):
    • prepareSendMessagesRequest now:
      • Extracts trigger from the request and forwards it into body when present.
      • Sends only the last user message in body.messages (as before), but now with the trigger included so the backend can differentiate “normal send” vs “regenerate”.

Datasource routing & navigation (04fe786, b1b6e42)

  • Route shape change (apps/web/app/routes.ts):
    • Datasource table route changed from ds/:slug/tables/:id to ds/:slug/tables/:schema/:tableName.
  • Tables list → table detail:
    • apps/web/app/routes/datasource/tables.tsx:
      • handleTableClick now builds /ds/${slug}/tables/${encodeURIComponent(schema ?? 'main')}/${encodeURIComponent(name)} instead of using id.
    • apps/web/app/routes/datasource/table.tsx:
      • Reads schema and tableName params, decodes them, and:
        • Locates the table by (t.schema ?? 'main') === schema && t.name === tableName.
        • Filters columns by table_id === table.id, table === table.name, and (col.schema ?? 'main') === (table.schema ?? 'main').
      • Breadcrumb now shows the resolved table.name and links back to /ds/${slug}/tables.
  • Path builders (apps/web/config/project.navigation.config.tsx):
    • New createDatasourceTableViewPath(slug, schema, tableName) builds ds/:slug/tables/:schema/:tableName with proper encodeURIComponent and a default 'main' schema when empty.
  • Centralized navigation helpers (apps/web/lib/utils/datasource-navigation.ts):
    • DatasourceItemLike (id, optional name, slug) to match UI datasource items.
    • slugify helper to normalize ids/names to a safe key.
    • resolveDatasource(items, idOrSlug, name):
      • Tries exact id, exact slug, slugified name/slug/id, and finally plain name match.
    • openUrlInNewTab(pathOrUrl):
      • If relative, prefixes with window.location.origin, opens in a new tab with noopener,noreferrer.
    • openDatasourceInNewTab(items, idOrSlug, name, getPath):
      • Resolves the datasource and opens getPath(ds.slug) in a new tab if a slug is found.
    • openTableInNewTab(items, datasourceIdOrSlug, datasourceName, schema, tableName, getTablePath):
      • Resolves the datasource and opens getTablePath(slug, schema || 'main', tableName) in a new tab.

Agent UI wiring for datasource/table clicks (04fe786, b1b6e42)

  • Agent UI wrapper → conversation content → message renderer:
    • apps/web/app/routes/project/_components/agent-ui-wrapper.tsx:
      • Imports createDatasourceTableViewPath and the navigation helpers.
      • _handleDatasourceNameClick(idOrSlug, name) delegates to openDatasourceInNewTab.
      • _handleTableNameClick(datasourceIdOrSlug, datasourceName, schema, tableName) delegates to openTableInNewTab.
      • Passes onDatasourceNameClick, onTableNameClick, and getDatasourceTooltip to AgentUI.
    • packages/ui/src/qwery/ai/conversation-content.tsx:
      • ConversationContentProps extended with:
        • onDatasourceNameClick
        • onTableNameClick
        • getDatasourceTooltip
      • For each message, passes these props into MessageRenderer.
    • packages/ui/src/qwery/ai/message-renderer.tsx:
      • MessageRendererProps extended with onTableNameClick.
      • Root element annotated with data-message-id={message.id} to help E2E/debugging.
      • When encountering tool-* parts:
        • Uses ToolWithTaskDelimiter instead of raw ToolPart, passing:
          • parts={message.parts}, partIndex, part, messageId, executionTimeMs, and both datasource click handlers.
      • Memo comparison updated: if any of onDatasourceNameClick, onTableNameClick, or getDatasourceTooltip changes, it re-renders.

GetSchema tool: multi‑datasource merge + error reporting (04fe786, b1b6e42)

  • Implementation (packages/agent-factory-sdk/src/tools/get-schema.ts):
    • DESCRIPTION now clearly states it supports multiple attached datasources and returns a merged schema.
    • Early guard: throws No datasources attached if attachedDatasources is empty.
    • For each attachedDatasource:
      • Looks up the datasource via repositories; captures “datasource not found” as an error entry instead of throwing.
      • Resolves a DatasourceExtension from ExtensionsRegistry, picks a Node runtime driver if available (falls back to first driver).
      • Instantiates driver via getDriverInstance with the datasource config, calls metadata(), and closes driver if it has a close() method.
      • Returns either { datasourceId, datasource, datasourceDisplayName, metadata } or { datasourceId, datasourceDisplayName, error }.
    • Merging:
      • Uses a schemaPrefix(datasource) helper (slugified name/slug/id) to build composite schema keys (e.g. Prod__public).
      • Maintains nextTableId and nextSchemaId counters to assign new ids and avoid collisions between datasources.
      • Aggregates schemas, tables, and columns across successful results into one DatasourceMetadata.
    • Errors:
      • All per‑datasource issues are collected into schemaErrors (with datasourceId, optional datasourceName, and error message) instead of failing the whole tool.
  • Tests (packages/agent-factory-sdk/src/tools/__tests__/get-schema.parallel.test.ts):
    • Parallel test suite exercising:
      • Single and multiple datasource scenarios.
      • Missing datasource, missing driver, and driver error paths.
      • Presence and structure of schemaErrors.

Schema visualizer: merged view, pagination, errors, click‑through (04fe786, c00a83e, 65f3af0)

  • Props & types (packages/ui/src/qwery/ai/schema-visualizer.tsx):
    • New shared types:
      • SchemaViewMode = 'card' | 'list'.
      • SchemaVisualizerDatasourceItem (id, name?, slug?, datasource_provider?).
      • SchemaSchemaError (datasourceId, datasourceName?, error).
    • SchemaVisualizerProps extended with:
      • datasources?: SchemaVisualizerDatasourceItem[]
      • schemaErrors?: SchemaSchemaError[] (from GetSchemaTool)
      • pluginLogoMap?: Map<string, string> | Record<string, string>
      • onDatasourceNameClick? and onTableNameClick? (match Agent UI handlers).
  • Merged schema understanding:
    • schemaNameOnly("Prod__public") → "public".
    • datasourcePrefix("Prod__public") → "Prod".
    • slugifyForPrefix aligns prefixes across ids, slugs, and names.
    • Groups tables into:
      • groupedTables: Record<schemaKey, TableWithColumns[]>.
      • groupsByDatasource: Record<prefix, schemaKey[]>.
      • datasourceOrder: string[] representing the display order of datasource prefixes.
  • Pagination and view modes:
    • Stores per‑schema pageBySchema and viewModeBySchema in local state.
    • Uses SCHEMA_TABLES_PER_PAGE to limit tables per schema section and exposes page up/down using ChevronLeft / ChevronRight.
    • getViewMode(schemaKey) and getPage(schemaKey) give consistent behavior across rerenders.
  • UI/UX tweaks:
    • Uses Database, Table2, ChevronDown, ChevronLeft, ChevronRight, LayoutGrid, List, AlertCircleIcon from lucide-react.
    • Improved empty state:
      • Larger icons, slightly bigger typography, and better spacing, differentiated for variant="minimal" vs "default".
    • Top‑level schema error section:
      • Renders schemaErrors list with an alert style, mapping datasource ids to human names via datasources and pluginLogoMap.
      • Shows errors without hiding the successfully loaded schemas.

Tool error visualization (c00a83e)

  • ToolErrorVisualizer (packages/ui/src/qwery/ai/tool-error-visualizer.tsx):
    • Formatting:
      • Added helpers to format and truncate error details, so large payloads don’t blow up the UI.
      • Conditional rendering of detailed payload sections based on availability and size.
    • Copy:
      • Adds a dedicated “Copy details” action so users can copy error payloads to the clipboard for debugging.
  • Message parts wiring (packages/ui/src/qwery/ai/message-parts.tsx / schema-visualizer.tsx):
    • Integrates the new error visualizer behavior into tool part rendering.
    • Ensures schema visualizer and error visualizer coexist nicely within the same tool output card.

Suggestion pipeline & Streamdown (9112924)

  • Suggestion hooks:
    • use-suggestion-detection:
      • Refactored to use useLayoutEffect to avoid flicker and improve consistency when suggestions depend on rendered DOM.
      • Cleans up state transitions for when suggestions appear/disappear during streaming.
    • use-suggestion-enhancement:
      • Preprocesses suggestions before rendering (dedupe, sanitize, formatting tweaks).
  • Suggestion patterns (packages/ui/src/qwery/ai/utils/suggestion-pattern.ts):
    • Centralizes regexes and pattern logic used to detect suggestions within streamed content (e.g. bullet prompts, code suggestions).
  • Streamdown integration (packages/ui/src/qwery/ai/streamdown-with-suggestions.tsx):
    • Preprocesses suggestions input so the rendered output is cleaner and more predictable.
  • Tests (packages/ui/src/qwery/ai/__tests__/suggestions.workflow.test.tsx):
    • Covers detection, enhancement, and rendering flows end‑to‑end so regressions in suggestion behavior are caught.

Conversation list, load‑more, and layout (84cb935)

  • Conversation list (packages/ui/src/qwery/ai/conversation-list.tsx):
    • Props:
      • Adds renderLoadMoreFooter and onLoadMoreStateChange to give parents control over load‑more UX.
    • Internal state:
      • Tracks visibleCount and isLoadingMore, and computes hasMore = allConversations.length > visibleCount.
    • Load‑more behavior:
      • handleLoadMore increments visibleCount in chunks of 20 (with a short timeout to show loading state).
      • useEffect calls onLoadMoreStateChange with { hasMore, onLoadMore: handleLoadMore, isLoading: isLoadingMore }, unless searching.
    • Default footer:
      • If not searching, hasMore, and no onLoadMoreStateChange handler:
        • Renders a bottom bar with a “Load more” button (data-test="conversation-load-more").
    • Layout:
      • Root container is flex h-full min-h-0 flex-col.
      • Command is min-h-0 flex-1, and CommandList is max-h-none min-h-0 flex-1 overflow-y-auto for robust scrolling in nested layouts.
  • Page wiring (apps/web/app/routes/project/conversation/index.tsx):
    • Uses loadMoreState from ConversationList via onLoadMoreStateChange.
    • Adds a bottom Load more bar when loadMoreState.hasMore is true, with a Button wired to loadMoreState.onLoadMore.

Message rendering, task delimiter, scroll, todo logic (65f3af0, b1b6e42)

  • ToolWithTaskDelimiter + TaskDelimiter:
    • New components:
      • packages/ui/src/qwery/ai/task-delimiter.tsx
      • packages/ui/src/qwery/ai/tool-with-task-delimiter.tsx
    • Behavior:
      • Wrap tool UI parts so that “task” and “result” states are visually separated.
      • Use the surrounding message.parts and partIndex to decide how to group related tool outputs.
  • Message rendering (packages/ui/src/qwery/ai/message-item.tsx, message-parts.tsx, message-renderer.tsx):
    • Integrates ToolWithTaskDelimiter into how tool messages are displayed.
    • Refactors some layout and branching logic to keep todo parts, source parts, and tool parts coherent and easier to scan.
  • Scroll utils + tests:
    • packages/ui/src/qwery/ai/utils/scroll-utils.ts:
      • Refined “stick to bottom” logic with thresholds, respecting when the user has manually scrolled up.
      • Handles auto‑scroll on new messages only when appropriate.
    • packages/ui/src/qwery/ai/virtuoso-message-list.tsx:
      • Wires the updated scroll helpers into the virtualized list.
    • Tests:
      • packages/ui/__tests__/scroll-utils.test.ts covers bottom detection, backscroll, and resize behavior.
  • Todo logic + tests:
    • packages/ui/src/qwery/ai/utils/todo-logic.ts:
      • Encapsulates todo state transitions and filtering used in the agent UI.
    • Tests:
      • packages/ui/__tests__/todo-logic.test.ts
      • packages/ui/__tests__/todo-feedback.test.tsx
      • packages/ui/__tests__/task-delimiter.test.tsx for task delimiter behavior.
  • Agent UI refactor (packages/ui/src/qwery/agent-ui.tsx):
    • Internal restructuring to route more behavior through the new task delimiter, todo logic, and scroll utilities.
    • Overall behavior unchanged beyond the new UX features described above; mainly readability and composition improvements.

CodeBlock & datasource UI polish (8918e41, c3529aa)

  • CodeBlock customization (packages/ui/src/ai-elements/code-block.tsx, tool.tsx):
    • New props:
      • preClassName: override the internal <pre> styling (e.g. backgrounds).
      • wrap: enable soft wrapping and word breaking.
      • scrollbarOnHover: show scrollbars on hover even when disableHover is true.
      • noInternalScroll: disable internal overflow/scroll to let parents manage scrolling.
    • Implementation:
      • preBaseClasses and preOverflowClasses centralize the styling logic.
      • Light and dark variants share the same structural classes; backgrounds conditional on isSQL unless overridden by preClassName.
  • Datasource badge & selector (packages/ui/src/qwery/ai/datasource-badge.tsx, datasource-selector.tsx, user-message-bubble.tsx, sql-query-visualizer.tsx, apps/web/styles/qwery.css):
    • Badge:
      • Adds icons (Layers, ExternalLink) and hover affordances for richer datasource hints.
      • Better visual hierarchy when multiple datasources are involved.
    • Selector:
      • readOnly prop to lock interactions when the datasource context shouldn’t be modified.
      • Styling tweaks and state handling improvements.
    • User message bubble and SQL visualizer:
      • Conditional rendering of badges/selectors based on user interaction and whether relevant datasource context exists.
      • Uses updated styles from qwery.css to keep alignment and hover behavior consistent.

Review Guide

  1. Regeneration & transport
    • apps/server/src/routes/chat.ts
    • packages/agent-factory-sdk/src/services/default-transport.ts
  2. Datasource routing & navigation
    • apps/web/app/routes.ts
    • apps/web/app/routes/datasource/tables.tsx
    • apps/web/app/routes/datasource/table.tsx
    • apps/web/config/project.navigation.config.tsx
    • apps/web/lib/utils/datasource-navigation.ts
  3. Agent UI wiring
    • apps/web/app/routes/project/_components/agent-ui-wrapper.tsx
    • packages/ui/src/qwery/ai/conversation-content.tsx
    • packages/ui/src/qwery/ai/message-renderer.tsx
  4. Tooling: schema & errors
    • packages/agent-factory-sdk/src/tools/get-schema.ts
    • packages/ui/src/qwery/ai/schema-visualizer.tsx
    • packages/ui/src/qwery/ai/tool-error-visualizer.tsx
  5. Suggestions & Streamdown
    • packages/ui/src/qwery/ai/hooks/use-suggestion-detection.ts
    • packages/ui/src/qwery/ai/hooks/use-suggestion-enhancement.ts
    • packages/ui/src/qwery/ai/utils/suggestion-pattern.ts
    • packages/ui/src/qwery/ai/streamdown-with-suggestions.tsx
  6. Conversation list & scroll
    • apps/web/app/routes/project/conversation/index.tsx
    • packages/ui/src/qwery/ai/conversation-list.tsx
    • packages/ui/src/qwery/ai/utils/scroll-utils.ts
    • packages/ui/src/qwery/ai/virtuoso-message-list.tsx
  7. UI polish
    • packages/ui/src/ai-elements/code-block.tsx
    • packages/ui/src/qwery/ai/datasource-badge.tsx
    • packages/ui/src/qwery/ai/datasource-selector.tsx
    • packages/ui/src/qwery/ai/user-message-bubble.tsx
    • apps/web/styles/qwery.css
  8. Tests
    • packages/agent-factory-sdk/src/tools/__tests__/get-schema.parallel.test.ts
    • packages/ui/__tests__/scroll-utils.test.ts
    • packages/ui/__tests__/task-delimiter.test.tsx
    • packages/ui/__tests__/todo-feedback.test.tsx
    • packages/ui/__tests__/todo-logic.test.ts
    • packages/ui/src/qwery/ai/__tests__/suggestions.workflow.test.tsx

Testing

  • Manual testing performed
  • Unit tests added/updated
    • get-schema.parallel.test.ts
    • scroll-utils.test.ts
    • task-delimiter.test.tsx
    • todo-feedback.test.tsx
    • todo-logic.test.ts
    • suggestions.workflow.test.tsx
  • E2E tests added/updated

Documentation

  • Code comments added for complex logic (multi‑datasource schema merging, datasource navigation helpers, schema visualizer grouping/pagination).
  • README or docs updated if needed
  • CHANGELOG.md updated (if applicable)

User Impact

  • Regeneration: users can regenerate the last assistant message cleanly; the previous answer is removed and replaced, instead of stacking.
  • Schema tooling: getSchema now supports multiple attached datasources with a merged, disambiguated schema, and clear per‑datasource error reporting in the UI.
  • Navigation: clicks on datasources/tables in tool output, badges, or selectors reliably open the correct datasource/table view (with schema) in a new tab.
  • Long sessions: conversation lists, scrolling, todos, and tool outputs are more structured and performant, with clear load‑more behavior and better suggestion rendering.
  • Breaking change: datasource table route changed from ds/:slug/tables/:id to ds/:slug/tables/:schema/:tableName; any external deep links must be updated.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Tests pass locally (pnpm test)
  • Lint passes (pnpm lint:fix)
  • Type check passes (pnpm typecheck)
  • This PR can be safely reverted if needed

…igation

- Added functionality to regenerate the last assistant message if the trigger is 'regenerate-message'.
- Updated routing for datasource tables to include schema and table name in the URL.
- Enhanced the agent UI to support opening datasources and tables in new tabs with updated navigation functions.
…opy functionality

- Added functions to format and truncate error details for better readability.
- Implemented a copy button to allow users to copy error details to the clipboard.
- Updated the UI to conditionally display error details and the copy button based on availability.
- Refactored `useSuggestionDetection` to utilize `useLayoutEffect` for improved performance and state management.
- Updated `StreamdownWithSuggestions` to preprocess suggestions for rendering, ensuring cleaner output.
- Introduced new utility functions for preprocessing suggestions to avoid formatting issues.
- Added comprehensive tests for suggestion detection and enhancement workflows to ensure reliability.
…onents

- Added hover effects and improved styling for the DatasourceBadge component.
- Introduced a readOnly prop to the DatasourceSelector for better control over user interactions.
- Updated the UserMessageBubble to conditionally display datasource badges and selectors based on user interactions.
…endering

- Added ToolWithTaskDelimiter component to manage task delimiters for tool parts.
- Updated message rendering to utilize the new ToolWithTaskDelimiter for improved task management.
- Refactored todo logic and scrolling utilities for better task handling and user experience.
…metadata retrieval

- Refactored GetSchemaTool to utilize structured types for success and error results.
- Improved error handling for datasource retrieval and driver instantiation.
- Updated tests to ensure parallel execution and correct schema fetching behavior
…ge export to Markdown, and refactor sidebar components with new hooks and stores.
…nhance tool name generation with message part context.
…s with badges, and prevent input clearing on send.
…lUIPart` and remove unused prompt input controller.
… selection and improve web fetch visualizer tool UI
{(isLoading && initialSuggestions?.length) ||
badgeSuggestions.length > 0 ? (
<div className="flex justify-center">
{isLoading && !badgesFadingOut ? (

Check warning

Code scanning / CodeQL

Useless conditional Warning

This use of variable 'isLoading' always evaluates to false.
{(isLoading && initialSuggestions?.length) ||
badgeSuggestions.length > 0 ? (
<div className="flex justify-center">
{isLoading && !badgesFadingOut ? (

Check warning

Code scanning / CodeQL

Useless conditional Warning

This use of variable 'isLoading' always evaluates to false.
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