better chat

This commit is contained in:
centdix
2025-05-30 11:07:43 +02:00
parent 0217a41ffa
commit 1cb8e0d4f2
6 changed files with 52 additions and 11 deletions

View File

@@ -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"}"#),
)

View File

@@ -98,7 +98,7 @@
: 'bg-gray-100 dark:bg-gray-700 text-primary rounded-bl-sm'
)}
>
<p class="whitespace-pre-wrap">{msg.content}</p>
<p class="whitespace-pre-wrap break-words">{msg.content}</p>
</div>
</div>
{/each}
@@ -122,9 +122,10 @@
<Button
on:click={() => submitSuggestion(suggestion)}
size="xs2"
color="gray"
color="blue"
buttonType="button"
disabled={!hasCopilot}
btnClasses="whitespace-normal text-left"
>
{suggestion}
</Button>

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -175,6 +175,7 @@ export const triggerablesByAI = writable<
>({})
export const globalChatOpen = writable<boolean>(false)
export const globalChatInitialInput = writable<string>('')
export const globalChatSize = writable<number>(300)
type SQLBaseSchema = {
[schemaKey: string]: {

View File

@@ -54,7 +54,7 @@
import { base } from '$app/paths'
import { Menubar } from '$lib/components/meltComponents'
import GlobalChat from '$lib/components/chat/GlobalChat.svelte'
import { globalChatOpen } from '$lib/stores'
import { globalChatOpen, globalChatSize } from '$lib/stores'
OpenAPI.WITH_CREDENTIALS = true
let menuOpen = false
@@ -656,8 +656,9 @@
'w-full flex flex-col flex-1 h-full',
devOnly || $userStore?.operator ? '!pl-0' : isCollapsed ? 'md:pl-12' : 'md:pl-40',
'transition-all ease-in-out duration-200',
$globalChatOpen ? 'chat-open pr-[200px]' : ''
$globalChatOpen ? 'chat-open' : ''
)}
style={`padding-right: ${$globalChatOpen ? $globalChatSize : 0}px`}
>
<main class="min-h-screen">
<div class="relative w-full h-full">
@@ -695,7 +696,7 @@
</div>
<!-- Global Chat Panel -->
<div class="fixed-chat-panel" class:open={$globalChatOpen}>
<div class="fixed-chat-panel" class:open={$globalChatOpen} style={`width: ${$globalChatSize}px`}>
<div class="chat-panel-container">
<GlobalChat />
</div>
@@ -707,7 +708,6 @@
top: 0;
right: 0;
height: 100vh;
width: 200px;
transform: translateX(100%);
transition: transform 0.3s ease-in-out;
z-index: 10;