mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-19 08:03:16 +00:00
style: lean tool-call rendering and tighter ai chat spacing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
53da8ac148
commit
e32fe4b6ca
@@ -422,13 +422,13 @@
|
||||
{#if showTypingIndicator}
|
||||
<div
|
||||
class={twMerge(
|
||||
'sticky z-10 mt-0.5 ml-2 self-start pointer-events-none',
|
||||
'sticky z-10 -mt-10 ml-2 self-start pointer-events-none',
|
||||
showFlowPendingActionControls ? 'bottom-14' : 'bottom-2'
|
||||
)}
|
||||
>
|
||||
{#if waitingForUserAction}
|
||||
<span
|
||||
class="inline-flex items-center gap-1.5 text-2xs text-accent"
|
||||
class="inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-surface/80 backdrop-blur text-2xs text-accent"
|
||||
aria-label="Waiting for your input"
|
||||
>
|
||||
<Hourglass class="w-3 h-3 hourglass-flip" />
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<div
|
||||
class={twMerge(
|
||||
'mb-2 min-w-0',
|
||||
message.role === 'tool' && 'mb-1',
|
||||
message.role === 'user' && messageIndex > 0 && 'mt-4 mb-6',
|
||||
isLast && '!mb-12',
|
||||
message.role !== 'user' ? 'cursor-default' : 'cursor-pointer'
|
||||
@@ -74,7 +75,7 @@
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class={twMerge('text-sm py-1 px-2', message.role === 'tool' && 'text-primary')}>
|
||||
<div class={twMerge('text-sm py-1 px-2', message.role === 'tool' && 'text-primary py-0')}>
|
||||
{#if message.role === 'assistant'}
|
||||
<div class="px-[1px]"><AssistantMessage {message} /></div>
|
||||
{:else if message.role === 'tool'}
|
||||
|
||||
@@ -104,14 +104,14 @@
|
||||
</script>
|
||||
|
||||
{#if showWhileLoading || (!loading && hasContent) || streaming}
|
||||
<div class="space-y-2">
|
||||
<div class="space-y-2 group">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-2xs">
|
||||
<span class="text-2xs text-hint">
|
||||
{title}:
|
||||
</span>
|
||||
{#if showCopy && hasContent && !streaming}
|
||||
<button
|
||||
class="p-1 rounded hover:bg-surface-secondary text-primary hover:text-secondary transition-colors"
|
||||
class="p-1 rounded hover:bg-surface-secondary text-primary hover:text-secondary transition-opacity duration-200 opacity-0 group-hover:opacity-100 focus-visible:opacity-100"
|
||||
onclick={copyToClipboard}
|
||||
title="Copy {title.toLowerCase()}"
|
||||
>
|
||||
@@ -125,26 +125,20 @@
|
||||
</div>
|
||||
|
||||
{#if loading && !streaming && !hasContent}
|
||||
<div
|
||||
class="bg-surface-secondary border border-gray-200 dark:border-gray-700 rounded p-3 flex items-center gap-2 text-primary"
|
||||
>
|
||||
<div class="flex items-center gap-2 text-primary">
|
||||
<Loader2 class="w-3 h-3 animate-spin" />
|
||||
<span class="text-2xs">Executing...</span>
|
||||
</div>
|
||||
{:else if error}
|
||||
<div
|
||||
class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded p-3 overflow-x-auto max-h-28 overflow-y-auto"
|
||||
>
|
||||
<div class="overflow-x-auto max-h-28 overflow-y-auto">
|
||||
<pre class="text-2xs text-red-700 dark:text-red-300 whitespace-pre-wrap">{error}</pre>
|
||||
</div>
|
||||
{:else if hasContent}
|
||||
<div
|
||||
class="bg-surface-secondary border border-gray-200 dark:border-gray-700 rounded overflow-hidden relative"
|
||||
>
|
||||
<div class="relative">
|
||||
<div
|
||||
bind:this={scrollEl}
|
||||
onscroll={updateCanScrollDown}
|
||||
class="p-3 overflow-x-auto max-h-28 overflow-y-auto"
|
||||
class="overflow-x-auto max-h-28 overflow-y-auto"
|
||||
>
|
||||
<pre class="text-2xs text-primary whitespace-pre-wrap"
|
||||
>{formatJson($state.snapshot(content))}</pre
|
||||
@@ -152,16 +146,12 @@
|
||||
</div>
|
||||
{#if showFade && canScrollDown}
|
||||
<div
|
||||
class="absolute bottom-0 left-0 right-0 h-16 pointer-events-none bg-gradient-to-t from-surface-secondary via-surface-secondary/70 via-surface-secondary/40 to-transparent"
|
||||
class="absolute bottom-0 left-0 right-0 h-16 pointer-events-none bg-gradient-to-t from-surface via-surface/70 via-surface/40 to-transparent"
|
||||
></div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="bg-surface-secondary border border-gray-200 dark:border-gray-700 rounded p-3 text-center"
|
||||
>
|
||||
<span class="text-2xs text-primary">No {title.toLowerCase()} yet</span>
|
||||
</div>
|
||||
<span class="text-2xs text-tertiary">No {title.toLowerCase()} yet</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Loader2, ChevronDown, ChevronRight, XCircle, Play } from 'lucide-svelte'
|
||||
import { Loader2, ChevronRight, XCircle, Play } from 'lucide-svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { getAiChatManager } from './aiChatManagerContext'
|
||||
|
||||
const aiChatManager = getAiChatManager()
|
||||
import { isActiveUserQuestion, type ToolDisplayMessage } from './shared'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { slide } from 'svelte/transition'
|
||||
import ToolContentDisplay from './ToolContentDisplay.svelte'
|
||||
import ToolMessageActions from './ToolMessageActions.svelte'
|
||||
import AskUserQuestionDisplay from './AskUserQuestionDisplay.svelte'
|
||||
@@ -48,42 +49,41 @@
|
||||
{#if activeUserQuestion}
|
||||
<AskUserQuestionDisplay toolCallId={message.tool_call_id} userQuestion={activeUserQuestion} />
|
||||
{:else}
|
||||
<div class="bg-surface border border-border-light rounded-md overflow-hidden font-mono text-xs">
|
||||
<div class="font-mono text-xs">
|
||||
<!-- Collapsible Header -->
|
||||
<button
|
||||
class={twMerge(
|
||||
'w-full p-2 bg-surface-secondary/30 hover:bg-surface-hover transition-colors flex items-center justify-between text-left',
|
||||
isExpanded ? 'border-b border-border-light' : '',
|
||||
'py-0.5 my-0.5 rounded-md hover:bg-surface-hover transition-colors inline-flex items-center text-left',
|
||||
message.needsConfirmation ? 'opacity-80' : ''
|
||||
)}
|
||||
onclick={() => (isExpanded = !isExpanded)}
|
||||
disabled={!message.showDetails && !message.isStreamingArguments}
|
||||
>
|
||||
<div class="flex items-center gap-2 flex-1">
|
||||
{#if message.showDetails || message.isStreamingArguments}
|
||||
{#if isExpanded}
|
||||
<ChevronDown class="w-3 h-3 text-secondary" />
|
||||
{:else}
|
||||
<ChevronRight class="w-3 h-3 text-secondary" />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
{#if message.isLoading && !message.needsConfirmation}
|
||||
<Loader2 class="w-3.5 h-3.5 animate-spin text-blue-500" />
|
||||
{:else if message.error}
|
||||
<span class="text-red-500">✗</span>
|
||||
{:else if !message.isLoading && !message.error}
|
||||
<span class="text-green-500">✓</span>
|
||||
{/if}
|
||||
<span class="text-primary font-medium text-2xs">
|
||||
{message.content}
|
||||
</span>
|
||||
|
||||
{#if message.showDetails || message.isStreamingArguments}
|
||||
<ChevronRight
|
||||
class={twMerge(
|
||||
'w-3 h-3 text-secondary transition-transform duration-150',
|
||||
isExpanded ? 'rotate-90' : ''
|
||||
)}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- Expanded Content -->
|
||||
{#if isExpanded}
|
||||
<div class="p-2 bg-surface space-y-3">
|
||||
<div
|
||||
transition:slide={{ duration: 150 }}
|
||||
class="border border-border-light rounded-md bg-surface p-3 space-y-3"
|
||||
>
|
||||
<!-- Parameters Section - show if we have parameters, or if confirmation is needed (even with empty params) -->
|
||||
{#if hasParameters || message.needsConfirmation}
|
||||
<div class={message.needsConfirmation ? 'opacity-80' : ''}>
|
||||
@@ -99,12 +99,7 @@
|
||||
|
||||
<!-- Confirmation Footer -->
|
||||
{#if message.needsConfirmation}
|
||||
<div
|
||||
class={twMerge(
|
||||
'mt-3 pt-3 flex flex-row items-center justify-end gap-2',
|
||||
hasParameters ? 'border-t border-border-light' : ''
|
||||
)}
|
||||
>
|
||||
<div class="flex flex-row items-center justify-end gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
size="xs"
|
||||
|
||||
Reference in New Issue
Block a user