Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a13281e
feat: route generate data CTA to developer chat
AdityaHegde Dec 15, 2025
c27d421
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Dec 24, 2025
9461348
Update welcome page
AdityaHegde Dec 24, 2025
4ff5efa
Update the home page
AdityaHegde Dec 24, 2025
d02a46b
Adding generating state
AdityaHegde Dec 29, 2025
33f4c62
Fix tests
AdityaHegde Dec 30, 2025
f3ad88c
Move to a single event emitter implementation
AdityaHegde Dec 30, 2025
6676c27
UI tweaks
AdityaHegde Dec 30, 2025
8cddeb8
UX tweaks
AdityaHegde Jan 5, 2026
c5bb3bb
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Jan 7, 2026
bad17da
Auto navigation to changed file
AdityaHegde Jan 9, 2026
d1c9c51
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Jan 14, 2026
d15d162
Self review
AdityaHegde Jan 14, 2026
7a0cec8
Add back source imported modal
AdityaHegde Jan 15, 2026
ed72d31
Fix tests
AdityaHegde Jan 16, 2026
bd2ce30
PR comments
AdityaHegde Jan 19, 2026
ca561fb
Add navigate tool for the LLM to control the navigation
AdityaHegde Jan 19, 2026
961bac7
Remove the imported modal
AdityaHegde Jan 21, 2026
910de33
Add a generic fallback block
AdityaHegde Jan 27, 2026
2d6ad73
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Jan 27, 2026
ac8b9ac
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Jan 28, 2026
1b13b8b
Fix merge issues
AdityaHegde Jan 28, 2026
2f32d90
Fix lint
AdityaHegde Jan 28, 2026
55873c2
Update icon for navigate tool
AdityaHegde Jan 29, 2026
27c7af4
Merge branch 'main' into feat/generate-data-to-dev-chat
AdityaHegde Jan 29, 2026
afc30b9
PR comments
AdityaHegde Feb 2, 2026
25a5653
Remove button when feature flag is disabled
AdityaHegde Feb 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions runtime/ai/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ func NewRunner(rt *runtime.Runtime, activity *activity.Client) *Runner {
RegisterTool(r, &ListBuckets{Runtime: rt})
RegisterTool(r, &ListBucketObjects{Runtime: rt})

RegisterTool(r, &Navigate{})

return r
}

Expand Down
4 changes: 4 additions & 0 deletions runtime/ai/developer_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func (t *DeveloperAgent) Handler(ctx context.Context, args *DeveloperAgentArgs)
ShowTableName,
QuerySQLName,
DevelopFileName,
NavigateName,
},
MaxIterations: 20,
UnwrapCall: true,
Expand Down Expand Up @@ -160,6 +161,9 @@ This may not relate to the user's task, but for context, the project's default O
{{ if .default_olap_readwrite }} The default OLAP is in readwrite mode, so you can use it in models if you want.
{{ else }} The default OLAP is in read-only mode, so you cannot create models in it. {{ end }}

Call "navigate" tool for the main file created/edited in the conversation. Use kind "file" and pass the written file path.
Prefer dashboard or metrics view files over other files.

Task: {{ .prompt }}
`, data)
}
Expand Down
61 changes: 61 additions & 0 deletions runtime/ai/navigate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package ai

import (
"context"
"errors"
"strings"

"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/rilldata/rill/runtime"
)

const NavigateName = "navigate"

type Navigate struct{}

var _ Tool[*NavigateArgs, *NavigateResult] = (*Navigate)(nil)

type NavigateArgs struct {
Kind string `json:"kind" jsonschema:"The kind of navigation to perform. Supported values: 'file', 'explore', 'canvas'."`
Name string `json:"name" jsonschema:"The name of the item to navigate to."`
}

type NavigateResult struct{}

func (t *Navigate) Spec() *mcp.Tool {
return &mcp.Tool{
Name: NavigateName,
Title: "Navigate UI",
Description: "Navigate to a specific UI element in the Rill UI. Supported kinds: 'file', 'explore', 'canvas'.",
Meta: map[string]any{
"openai/toolInvocation/invoking": "Navigating...",
"openai/toolInvocation/invoked": "Navigated",
},
}
}

func (t *Navigate) CheckAccess(ctx context.Context) (bool, error) {
// Must be allowed to use AI features
s := GetSession(ctx)
if !s.Claims().Can(runtime.UseAI) {
return false, nil
}

// Only allow for rill user agents since it's not functional in MCP contexts.
if !strings.HasPrefix(s.CatalogSession().UserAgent, "rill") {
return false, nil
}
return true, nil
}

func (t *Navigate) Handler(ctx context.Context, args *NavigateArgs) (*NavigateResult, error) {
if args.Kind == "" {
return nil, errors.New("kind is required")
}

if args.Name == "" {
return nil, errors.New("name is required")
}

return &NavigateResult{}, nil
}
11 changes: 10 additions & 1 deletion web-common/src/components/card/CardDescription.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<script lang="ts">
import { cn } from "@rilldata/web-common/lib/shadcn.ts";

export let className: string = "";
</script>

<p
class="text-fg-secondary font-normal text-xs text-center absolute top-[208px]"
class={cn(
"text-fg-secondary font-normal text-xs text-center absolute top-[208px]",
className,
)}
>
<slot />
</p>
11 changes: 8 additions & 3 deletions web-common/src/components/card/CardTitle.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<script lang="ts">
import { cn } from "@rilldata/web-common/lib/shadcn.ts";

export let position: "middle" | "bottom" = "bottom";
export let className: string = "";
</script>

<h3
class="text-fg-secondary font-medium text-sm {position === 'bottom'
? 'absolute top-[180px]'
: ''}"
class={cn(
"text-fg-secondary font-medium text-sm",
position === "bottom" ? "absolute top-[180px]" : "",
className,
)}
>
<slot />
</h3>
41 changes: 41 additions & 0 deletions web-common/src/components/icons/ImportData.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<svg
width="208"
height="64"
viewBox="0 0 208 64"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M88.8172 33.6553C80.237 33.6553 73.2815 31.5991 73.2815 29.0625V35.1861C73.2815 37.7226 80.2371 39.7789 88.8172 39.7789C97.3973 39.7789 104.353 37.7227 104.353 35.1861V29.0625C104.353 31.5991 97.3975 33.6553 88.8172 33.6553Z"
fill="#605FEA"
/>
<path
d="M88.8178 26.195C97.3978 26.195 104.353 24.1389 104.353 21.6024C104.353 19.066 97.3978 17.0098 88.8178 17.0098C80.2379 17.0098 73.2825 19.066 73.2825 21.6024C73.2825 24.1389 80.2379 26.195 88.8178 26.195Z"
fill="#C8C8C8"
/>
<path
d="M88.8172 26.1943C80.237 26.1943 73.2815 24.1381 73.2815 21.6016V27.7252C73.2815 30.2617 80.2371 32.318 88.8172 32.318C97.3973 32.318 104.353 30.2618 104.353 27.7252V21.6016C104.353 24.1381 97.3975 26.1943 88.8172 26.1943Z"
fill="#00B8FF"
/>
<path
d="M88.8178 18.5407C97.3978 18.5407 104.353 16.4846 104.353 13.9481C104.353 11.4117 97.3978 9.35547 88.8178 9.35547C80.2379 9.35547 73.2825 11.4117 73.2825 13.9481C73.2825 16.4846 80.2379 18.5407 88.8178 18.5407Z"
fill="#E4E4E5"
/>
<path
d="M88.8172 18.54C80.237 18.54 73.2815 16.4838 73.2815 13.9473V20.0709C73.2815 22.6074 80.2371 24.6637 88.8172 24.6637C97.3973 24.6637 104.353 22.6075 104.353 20.0709V13.9473C104.353 16.4838 97.3975 18.54 88.8172 18.54Z"
fill="#605FEA"
/>
<path
d="M104.353 20.0674V21.5371C104.353 24.0784 97.3975 26.1298 88.8165 26.1298C80.2355 26.1298 73.28 24.0784 73.28 21.5371V20.0674C73.28 22.6087 80.2357 24.6602 88.8167 24.6602C97.3977 24.6602 104.353 22.6087 104.353 20.0674ZM104.353 27.657V29.1267C104.353 31.668 97.3975 33.7195 88.8165 33.7195C80.2355 33.7195 73.28 31.6681 73.28 29.1267V27.657C73.28 30.1983 80.2357 32.2498 88.8167 32.2498C97.3977 32.2498 104.353 30.1985 104.353 27.657Z"
fill="white"
/>
<path
d="M134.72 35.5072V59.6585C134.72 61.3423 133.358 62.7203 131.658 62.7203H97.3046C95.6206 62.7203 94.2427 61.3423 94.2427 59.6584V30.9144C94.2427 29.2151 95.6206 27.8525 97.3046 27.8525H104.775C105.572 27.8525 106.337 28.1586 106.903 28.7099L109.873 31.588C110.44 32.1391 111.205 32.4453 112.001 32.4453H131.658C133.358 32.4453 134.72 33.8077 134.72 35.5072Z"
fill="#6766FF"
/>
<path d="M134.72 38.7646H94.2427V41.8264H134.72V38.7646Z" fill="#4A49F7" />
<path
d="M100.078 4.30552C111.732 -2.95656 118.175 5.13714 118.175 5.13714L119.194 4.11813C119.68 3.63199 120.511 3.91308 120.599 4.59826L121.7 13.1488C121.765 13.6817 121.308 14.1385 120.775 14.0741L112.219 12.9789C111.533 12.8911 111.252 12.0595 111.738 11.5734L112.751 10.5602C107.949 5.16056 103.024 4.76812 100.336 5.07852C99.8964 5.13125 99.7032 4.53976 100.078 4.30552Z"
fill="#5655FF"
/>
</svg>
3 changes: 1 addition & 2 deletions web-common/src/features/chat/DeveloperChat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import { featureFlags } from "../feature-flags";
import SidebarChat from "./layouts/sidebar/SidebarChat.svelte";
import { chatOpen } from "./layouts/sidebar/sidebar-store";

import { developerChatConfig } from "@rilldata/web-common/features/editor/chat-context.ts";
import { developerChatConfig } from "@rilldata/web-common/features/editor/chat-utils.ts";

const { developerChat } = featureFlags;
</script>
Expand Down
5 changes: 5 additions & 0 deletions web-common/src/features/chat/core/conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
NEW_CONVERSATION_ID,
} from "./utils";
import { EventEmitter } from "@rilldata/web-common/lib/event-emitter.ts";
import { getToolConfig } from "@rilldata/web-common/features/chat/core/messages/tools/tool-registry.ts";

type ConversationEvents = {
"conversation-created": string;
Expand Down Expand Up @@ -318,6 +319,10 @@ export class Conversation {
}

this.addMessageToCache(response.message);
if (response.message.type === MessageType.CALL) {
const config = getToolConfig(response.message.tool);
config?.onResult?.(response.message);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions web-common/src/features/chat/core/messages/Messages.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import UserMessage from "./text/UserMessage.svelte";
import ThinkingBlock from "./thinking/ThinkingBlock.svelte";
import WorkingBlock from "./working/WorkingBlock.svelte";
import GenericBlock from "@rilldata/web-common/features/chat/core/messages/generic/GenericBlock.svelte";

export let conversationManager: ConversationManager;
export let layout: "sidebar" | "fullpage";
Expand Down Expand Up @@ -123,6 +124,8 @@
<ChartBlock {block} {tools} />
{:else if block.type === "file-diff"}
<FileDiffBlock {block} {tools} />
{:else if block.type === "generic-block"}
<GenericBlock {block} {tools} />
{/if}
{/each}
{/if}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from "./thinking/thinking-block";
import { getToolConfig, type ToolConfig } from "./tools/tool-registry";
import { shouldShowWorking, type WorkingBlock } from "./working/working-block";
import type { GenericBlock } from "@rilldata/web-common/features/chat/core/messages/generic/generic-block.ts";

// =============================================================================
// TYPES & TRANSFORMATION
Expand All @@ -25,7 +26,8 @@ export type Block =
| ThinkingBlock
| ChartBlock
| FileDiffBlock
| WorkingBlock;
| WorkingBlock
| GenericBlock;

// Re-export individual block types for convenience
export type {
Expand All @@ -34,6 +36,7 @@ export type {
TextBlock,
ThinkingBlock,
WorkingBlock,
GenericBlock,
};

/**
Expand Down Expand Up @@ -91,6 +94,7 @@ export function transformToBlocks(
if (block) {
blocks.push(block);
}
console.log(block);
break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!--
Renders a file diff block with collapsible tool call header.
Shows the diff visualization with expandable request/response details.
-->
<script lang="ts">
import type { V1Tool } from "../../../../../runtime-client";
import ToolCall from "../tools/ToolCall.svelte";
import type { GenericBlock } from "@rilldata/web-common/features/chat/core/messages/generic/generic-block.ts";

export let block: GenericBlock;
export let tools: V1Tool[] | undefined = undefined;
</script>

<div class="generic-block">
<ToolCall
message={block.message}
resultMessage={block.resultMessage}
{tools}
variant="block"
/>
</div>

<style lang="postcss">
.generic-block {
@apply w-full max-w-full self-start;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { V1Message } from "@rilldata/web-common/runtime-client";

/**
* Generic block that doesnt really have specific rendering.
*/
export type GenericBlock = {
type: "generic-block";
id: string;
message: V1Message;
resultMessage: V1Message;
};

export function createGenericBlock(
message: V1Message,
resultMessage: V1Message | undefined,
): GenericBlock | null {
if (!resultMessage) return null;
return {
type: "generic-block",
id: `generic-block-${message.id}`,
message,
resultMessage,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import {
createFileDiffBlock,
type FileDiffBlock,
} from "../file-diff/file-diff-block";
import { goto } from "$app/navigation";
import { addLeadingSlash } from "@rilldata/web-common/features/entity-management/entity-mappers.ts";
import {
createGenericBlock,
type GenericBlock,
} from "@rilldata/web-common/features/chat/core/messages/generic/generic-block.ts";

// =============================================================================
// RENDER MODES
Expand All @@ -32,7 +38,7 @@ export type ToolRenderMode = "inline" | "block" | "hidden";
// =============================================================================

/** Block types that can be created by tools */
export type ToolBlockType = ChartBlock | FileDiffBlock;
export type ToolBlockType = ChartBlock | FileDiffBlock | GenericBlock;

/**
* Configuration for a tool's rendering behavior.
Expand All @@ -47,6 +53,9 @@ export interface ToolConfig {
callMessage: V1Message,
resultMessage: V1Message | undefined,
) => ToolBlockType | null;

/** Used to process any UI action or side effects from tool calls. */
onResult?: (callMessage: V1Message) => void;
}

/**
Expand Down Expand Up @@ -83,6 +92,12 @@ const TOOL_CONFIGS: Partial<Record<string, ToolConfig>> = {
createBlock: createFileDiffBlock,
},

[ToolName.NAVIGATE]: {
renderMode: "block",
createBlock: createGenericBlock,
onResult: handleNavigateToolCall,
},

// All other tools default to "inline" (shown in thinking blocks)
};

Expand All @@ -105,3 +120,17 @@ export function getToolConfig(toolName: string | undefined): ToolConfig {
export function isHiddenTool(toolName: string | undefined): boolean {
return getToolConfig(toolName).renderMode === "hidden";
}

function handleNavigateToolCall(callMessage: V1Message) {
if (!callMessage.contentData) return;
try {
const content = JSON.parse(callMessage.contentData);
if (!content.kind || !content.name) return;
switch (content.kind) {
case "file":
void goto(`/files${addLeadingSlash(content.name)}`);
}
} catch (err) {
console.error(err);
}
}
3 changes: 3 additions & 0 deletions web-common/src/features/chat/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export const ToolName = {
SEARCH_FILES: "search_files",
READ_FILE: "read_file",
WRITE_FILE: "write_file",

// Common tools
NAVIGATE: "navigate",
} as const;

// =============================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ export const connectorIconMapping = {
snowflake: SnowflakeIcon,
starrocks: StarRocksIcon,
};

export const connectorLabelMapping = {
duckdb: "DuckDB",
clickhouse: "ClickHouse",
};
Loading
Loading