diff --git a/backend/windmill-api/src/inkeep.rs b/backend/windmill-api/src/inkeep.rs index d44f8d2de0..d3a7f1c93a 100644 --- a/backend/windmill-api/src/inkeep.rs +++ b/backend/windmill-api/src/inkeep.rs @@ -63,7 +63,7 @@ pub async fn send_inkeep_request( Err(e) => { error!("Failed to send request to inkeep service: {}", e); ( - StatusCode::BAD_GATEWAY, + StatusCode::INTERNAL_SERVER_ERROR, HeaderMap::new(), Bytes::from(r#"{"error": "Failed to connect to inkeep service"}"#), ) diff --git a/frontend/src/lib/components/chat/GlobalChat.svelte b/frontend/src/lib/components/chat/GlobalChat.svelte index a234a37b74..8ffc0438f1 100644 --- a/frontend/src/lib/components/chat/GlobalChat.svelte +++ b/frontend/src/lib/components/chat/GlobalChat.svelte @@ -98,7 +98,7 @@ : 'bg-gray-100 dark:bg-gray-700 text-primary rounded-bl-sm' )} > -
{msg.content}
+{msg.content}
{/each} @@ -122,9 +122,10 @@ diff --git a/frontend/src/lib/components/chat/core.ts b/frontend/src/lib/components/chat/core.ts index b109ee06f9..96858956f1 100644 --- a/frontend/src/lib/components/chat/core.ts +++ b/frontend/src/lib/components/chat/core.ts @@ -1,4 +1,5 @@ import { get, type Writable } from 'svelte/store' +import { page } from '$app/state' import { getCompletion } from '$lib/components/copilot/lib' import type { ChatCompletionChunk, @@ -20,7 +21,7 @@ You have access to these tools: INSTRUCTIONS: - When users ask about application features or concepts, first use get_documentation internally to retrieve accurate information about how to fulfill the user's request. -- Then immediately use the available tools to guide the user through the application. Do not wait for the user's confirmation before taking action. +- Then check which page you are on using get_current_page_name. Then immediately use the available tools to guide the user through the application. Only wait for the user's confirmation if your are on a flow / script / app creation page. Do not wait for the user's confirmation before taking action on other pages. - Use get_triggerable_components to understand available options, and then trigger the components using trigger_component. Then wait a moment before rescanning the current page, and then continue with the next step. Do this 5 times max. - If you are not able to fulfill the user's request after 5 attempts, redirect the user to the documentation. @@ -98,6 +99,19 @@ const EXECUTE_COMMAND_TOOL: ChatCompletionTool = { } } +const GET_CURRENT_PAGE_NAME_TOOL: ChatCompletionTool = { + type: 'function', + function: { + name: 'get_current_page_name', + description: 'Get the name of the current page the user is on.', + parameters: { + type: 'object', + properties: {}, + required: [] + } + } +} + function getTriggerableComponents(): string { try { // Get components registered in the triggerablesByAI store @@ -121,6 +135,28 @@ function getTriggerableComponents(): string { } } +// Function to get the current page name +function getCurrentPageName(): string { + try { + const currentPage = page.url.pathname + switch (currentPage) { + case '/': + return 'Home Page' + case '/flows/add': + return 'Flow creation page' + case '/scripts/add': + return 'Script creation page' + case '/apps/add': + return 'App creation page' + default: + return 'Non-specific page' + } + } catch (error) { + console.error('Error getting current page name:', error) + return 'Error getting current page name: ' + error.message + } +} + // Function to execute commands on the page function triggerComponent(args: { id: string; value: string }): string { const { id, value } = args @@ -206,6 +242,8 @@ async function processToolCall( } else if (toolCall.function.name === 'get_documentation') { const docResult = await getDocumentation(args) result = docResult || 'No documentation found for this request' + } else if (toolCall.function.name === 'get_current_page_name') { + result = getCurrentPageName() } else { result = `Unknown tool: ${toolCall.function.name}` } @@ -233,7 +271,8 @@ export async function chatRequest( const toolDefs: ChatCompletionTool[] = [ GET_PAGE_HTML_TOOL, EXECUTE_COMMAND_TOOL, - GET_DOCUMENTATION_TOOL + GET_DOCUMENTATION_TOOL, + GET_CURRENT_PAGE_NAME_TOOL ] try { diff --git a/frontend/src/lib/components/common/drawer/Drawer.svelte b/frontend/src/lib/components/common/drawer/Drawer.svelte index c088e00805..5e157b4bda 100644 --- a/frontend/src/lib/components/common/drawer/Drawer.svelte +++ b/frontend/src/lib/components/common/drawer/Drawer.svelte @@ -3,7 +3,7 @@ import { BROWSER } from 'esm-env' import Disposable from './Disposable.svelte' import ConditionalPortal from './ConditionalPortal.svelte' - import { globalChatOpen } from '$lib/stores' + import { globalChatOpen, globalChatSize } from '$lib/stores' export let open = false export let duration = 0.3 @@ -43,7 +43,7 @@ const dispatch = createEventDispatcher() // Calculate adjusted offset based on global chat status - $: adjustedOffset = $globalChatOpen && placement === 'right' ? 200 : 0 + $: adjustedOffset = $globalChatOpen && placement === 'right' ? $globalChatSize : 0 $: style = `--duration: ${duration}s; --size: ${size}; --adjusted-offset: ${adjustedOffset}px;` function scrollLock(open: boolean) { diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index 8a7ff3d8ab..4de9b0ccdd 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -175,6 +175,7 @@ export const triggerablesByAI = writable< >({}) export const globalChatOpen = writable