diff --git a/frontend/src/lib/components/AskAiButton.svelte b/frontend/src/lib/components/AskAiButton.svelte
index 0ad318e889..80230e923d 100644
--- a/frontend/src/lib/components/AskAiButton.svelte
+++ b/frontend/src/lib/components/AskAiButton.svelte
@@ -11,7 +11,7 @@
const { label, initialInput, onClick: onClickProp }: Props = $props()
- const onClick = () => {
+ export function onClick() {
globalChatOpen.set(true)
if (initialInput) {
globalChatInitialInput.set(initialInput)
diff --git a/frontend/src/lib/components/chat/GlobalChat.svelte b/frontend/src/lib/components/chat/GlobalChat.svelte
index 8a1796be9e..5e1938481f 100644
--- a/frontend/src/lib/components/chat/GlobalChat.svelte
+++ b/frontend/src/lib/components/chat/GlobalChat.svelte
@@ -1,112 +1,26 @@
diff --git a/frontend/src/lib/components/copilot/chat/AIChat.svelte b/frontend/src/lib/components/copilot/chat/AIChat.svelte
index d2fd5a2118..ee8a945f54 100644
--- a/frontend/src/lib/components/copilot/chat/AIChat.svelte
+++ b/frontend/src/lib/components/copilot/chat/AIChat.svelte
@@ -30,15 +30,13 @@
ChatCompletionMessageParam,
ChatCompletionSystemMessageParam
} from 'openai/resources/index.mjs'
-<<<<<<< HEAD
import { chatMode, copilotSessionModel, dbSchemas, workspaceStore } from '$lib/stores'
-=======
import {
navigatorTools,
prepareNavigatorSystemMessage,
prepareNavigatorUserMessage
} from './navigator/core'
->>>>>>> 332040744 (integrate navigator mode)
+ import { globalChatInitialInput } from '$lib/stores'
interface Props {
scriptOptions?: ScriptOptions
flowHelpers?: FlowAIChatHelpers & {
@@ -49,6 +47,9 @@
applyCode?: (code: string) => void
headerLeft?: Snippet
headerRight?: Snippet
+ suggestions?: string[]
+ disabled?: boolean
+ disabledMessage?: string
}
let {
@@ -58,7 +59,10 @@
showDiffMode,
headerLeft,
headerRight,
- navigatorMode = false
+ navigatorMode = false,
+ disabled = false,
+ disabledMessage = '',
+ suggestions = []
}: Props = $props()
let instructions = $state('')
@@ -69,23 +73,14 @@
flow: flowHelpers !== undefined,
navigator: navigatorMode
})
-<<<<<<< HEAD
-
- async function updateMode(currentMode: 'script' | 'flow') {
- if (!allowedModes[currentMode]) {
- chatMode.set(currentMode === 'script' ? 'flow' : 'script')
-=======
- let mode: 'script' | 'flow' | 'navigator' = $state(
- flowHelpers ? 'flow' : scriptOptions ? 'script' : 'navigator'
- )
async function updateMode(currentMode: 'script' | 'flow' | 'navigator') {
if (!allowedModes[currentMode] && Object.keys(allowedModes).length === 1) {
const firstKey = Object.keys(allowedModes)[0]
- mode = firstKey as 'script' | 'flow' | 'navigator'
->>>>>>> 332040744 (integrate navigator mode)
+ chatMode.set(firstKey as 'script' | 'flow' | 'navigator')
}
}
+
$effect(() => {
updateMode(untrack(() => $chatMode))
})
@@ -94,6 +89,14 @@
let abortController: AbortController | undefined = undefined
let messages: ChatCompletionMessageParam[] = $state([])
+ $effect(() => {
+ if ($globalChatInitialInput.length > 0) {
+ instructions = $globalChatInitialInput
+ globalChatInitialInput.set('')
+ sendRequest()
+ }
+ })
+
setContext('AIChatContext', {
loading,
currentReply,
@@ -141,15 +144,11 @@
instructions = ''
const systemMessage =
-<<<<<<< HEAD
- $chatMode === 'script' ? prepareScriptSystemMessage() : prepareFlowSystemMessage()
-=======
- mode === 'script'
+ $chatMode === 'script'
? prepareScriptSystemMessage()
- : mode === 'flow'
+ : $chatMode === 'flow'
? prepareFlowSystemMessage()
: prepareNavigatorSystemMessage()
->>>>>>> 332040744 (integrate navigator mode)
if ($chatMode === 'flow' && !flowHelpers) {
throw new Error('No flow helpers passed')
@@ -402,4 +401,7 @@
!!scriptOptions.lastDeployedCode &&
scriptOptions.lastDeployedCode !== scriptOptions.code}
diffMode={scriptOptions?.diffMode ?? false}
+ {disabled}
+ {disabledMessage}
+ {suggestions}
>
diff --git a/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte b/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
index f47272fc40..7e72e5c995 100644
--- a/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
+++ b/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
@@ -15,6 +15,7 @@
import ProviderModelSelector from './ProviderModelSelector.svelte'
import ChatMode from './ChatMode.svelte'
import { chatMode } from '$lib/stores'
+ import Markdown from 'svelte-exmarkdown'
let {
allowedModes,
@@ -32,7 +33,10 @@
cancel,
askAi = () => {}, // todo: remove default,
headerLeft,
- headerRight
+ headerRight,
+ disabled = false,
+ disabledMessage = '',
+ suggestions = []
}: {
allowedModes: {
script: boolean
@@ -54,6 +58,9 @@
askAi?: (instructions: string, options?: { withCode?: boolean; withDiff?: boolean }) => void
headerLeft?: Snippet
headerRight?: Snippet
+ disabled?: boolean
+ disabledMessage?: string
+ suggestions?: string[]
} = $props()
const { loading, currentReply } = getContext('AIChatContext')
@@ -106,6 +113,11 @@
return -1
}
+ function submitSuggestion(suggestion: string) {
+ instructions = suggestion
+ sendRequest()
+ }
+
const lastUserMessageIndex = $derived(findLastIndex(messages, (m) => m.role === 'user'))
@@ -294,6 +306,7 @@
}
}}
on:updateInstructions={(e) => (instructions = e.detail.value)}
+ {disabled}
/>
{:else}
@@ -309,6 +322,7 @@
rows={3}
placeholder={messages.length === 0 ? 'Ask anything' : 'Ask followup'}
class="resize-none"
+ {disabled}
>
{/if}
@@ -320,10 +334,32 @@
{#if $chatMode === 'script' && hasDiff}
{/if}
-
+ {#if disabled}
+
+
+
+ {:else}
+
+ {/if}
+ {#if suggestions.length > 0 && messages.filter((m) => m.role === 'user').length === 0 && !disabled}
+
+
+ {#each suggestions as suggestion}
+
+ {/each}
+
+
+ {/if}
diff --git a/frontend/src/lib/components/copilot/chat/AssistantMessage.svelte b/frontend/src/lib/components/copilot/chat/AssistantMessage.svelte
index e4ce6f93ac..75b2a4ecb1 100644
--- a/frontend/src/lib/components/copilot/chat/AssistantMessage.svelte
+++ b/frontend/src/lib/components/copilot/chat/AssistantMessage.svelte
@@ -3,6 +3,7 @@
import { gfmPlugin } from 'svelte-exmarkdown/gfm'
import type { DisplayMessage } from './shared'
import CodeDisplay from './script/CodeDisplay.svelte'
+ import LinkRenderer from './LinkRenderer.svelte'
import { setContext } from 'svelte'
export let message: DisplayMessage
@@ -21,7 +22,8 @@
gfmPlugin(),
{
renderer: {
- pre: CodeDisplay
+ pre: CodeDisplay,
+ a: LinkRenderer
}
}
]}
diff --git a/frontend/src/lib/components/copilot/chat/ContextTextarea.svelte b/frontend/src/lib/components/copilot/chat/ContextTextarea.svelte
index 964c843a1c..b4d2f04af9 100644
--- a/frontend/src/lib/components/copilot/chat/ContextTextarea.svelte
+++ b/frontend/src/lib/components/copilot/chat/ContextTextarea.svelte
@@ -8,6 +8,7 @@
export let availableContext: ContextElement[]
export let selectedContext: ContextElement[]
export let isFirstMessage: boolean
+ export let disabled: boolean = false
const dispatch = createEventDispatcher<{
updateInstructions: { value: string }
@@ -319,6 +320,7 @@
style={instructions.length > 0
? 'color: transparent; -webkit-text-fill-color: transparent;'
: ''}
+ {disabled}
>
diff --git a/frontend/src/lib/components/copilot/chat/LinkRenderer.svelte b/frontend/src/lib/components/copilot/chat/LinkRenderer.svelte
new file mode 100644
index 0000000000..87d131e03e
--- /dev/null
+++ b/frontend/src/lib/components/copilot/chat/LinkRenderer.svelte
@@ -0,0 +1,15 @@
+
+
+{#if href}
+
+ {@render children?.()}
+
+{/if}
diff --git a/frontend/src/lib/components/copilot/chat/script/CodeDisplay.svelte b/frontend/src/lib/components/copilot/chat/script/CodeDisplay.svelte
index e2dfb8df32..9ea3f533d7 100644
--- a/frontend/src/lib/components/copilot/chat/script/CodeDisplay.svelte
+++ b/frontend/src/lib/components/copilot/chat/script/CodeDisplay.svelte
@@ -189,7 +189,7 @@
color="dark"
size="xs2"
on:click={() => {
- applyCode(code ?? '')
+ applyCode?.(code ?? '')
}}
>
Apply
diff --git a/frontend/src/lib/components/search/GlobalSearchModal.svelte b/frontend/src/lib/components/search/GlobalSearchModal.svelte
index 355a5fa385..083518f531 100644
--- a/frontend/src/lib/components/search/GlobalSearchModal.svelte
+++ b/frontend/src/lib/components/search/GlobalSearchModal.svelte
@@ -239,6 +239,7 @@
let defaultMenuItemLabels = defaultMenuItems.map((item) => item.label)
let defaultMenuItemAndHiddenLabels = defaultMenuItemsWithHidden.map((item) => item.label)
let switchModeItemLabels = switchModeItems.map((item) => item.label)
+ let askAiButton: AskAiButton | undefined
function fuzzyFilter(filter: string, items: any[], itemsPlainText: string[]) {
if (filter === '') {
@@ -370,6 +371,9 @@
}
}
}
+ if ((itemMap[tab] ?? []).length === 0 && searchTerm.length > 0 && event.key === 'Enter') {
+ askAiButton?.onClick()
+ }
}
}
@@ -617,6 +621,7 @@
{#if (itemMap[tab] ?? []).length === 0 && searchTerm.length > 0}
{