Files
windmill/frontend/src/lib/components/copilot/chat/ToolPreviewCard.svelte
T
AlexRV12andClaude Opus 5 a6abf2c8a7 feat: run and test scripts from the AI chat through an argument form (#11001)
* fix: disable a dynamic input when its schema field is disabled

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* refactor: extract the run form's argument hygiene into job_args

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: give Tabs an opt-in sliding selection indicator

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* refactor: share the chat's scroll-fade measurement

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: give the chat a run-form contract and incremental job output

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: run and test a script from the chat through an argument form

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: carry a chat run's card and job across saves and reloads

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: render a chat run as a tool call row with its form, logs and result

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: open a pending run form in the sessions preview pane

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* test: benchmark running a deployed script from the chat

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ERed9zo2oJjpSczzMayaNh

* feat: offer a test run's dynamic options from the draft it previews

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: say that a test run's dynselect helper executes on form display

* fix: send a schema default the model omitted when yolo skips the form

* fix: infer a test run's schema when the stored one declares no properties

* docs: tighten the note on the form's mount-time helper job

* fix: apply a nested schema default the bypass posture counts as answered

* fix: apply a declared default to a null value and an optional nested field

* fix: check required fields inside a supplied optional object before bypassing

* fix: read required args as own properties before bypassing the form

* fix: stop the turn from the run form's action row in the preview panel

* refactor: drop the run-form prediction and share its secret minting

* refactor: prefill a proposed secret instead of emptying the field

* docs: correct the comments the run-form prediction left behind

* fix: keep a proposed secret out of the chat's stored messages

* docs: say what a literal secret argument now does

* test: restore the copilotInfo export the aiStore mock omits

* docs: cut the run form's helper-script note to its constraints

* refactor: settle a run form from one entry and fetch a job's logs once

* fix: separate colliding secret paths, gate plan mode, keep polled logs

* fix: mint before the form opens, skip empty fields, show what ran

* revert: mint a run form's secrets at submit, not before it opens

* fix: settle a cancelled run card on the form's arguments, not the proposal

* fix: settle a stopped run form like a cancelled one, and keep an empty secret empty

* fix: snapshot a run's arguments before minting its secrets

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:31:58 +00:00

56 lines
1.7 KiB
Svelte

<script lang="ts">
import { PanelRight } from 'lucide-svelte'
import { Button } from '$lib/components/common'
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
import type { IconType } from '$lib/utils'
import { runToolDisplayAction } from './createdResourceActions.svelte'
import { openItemPreviewAction, type PreviewCardKind } from './shared'
interface Props {
card: { kind: PreviewCardKind; path: string }
/** Opens something other than the item's own preview — the run card opens the call
* it owns, which is a form before it is a run. */
onOpen?: () => void
title?: string
/** The kind icon says what the chip opens. A card that already names its own runnable
* in the row above has said it, and repeating it there reads as a second subject. */
kindIcon?: boolean
}
let { card, onOpen, title, kindIcon = true }: Props = $props()
const kindLabel = $derived(card.kind === 'raw_app' ? 'app' : card.kind)
let opening = $state(false)
async function open() {
if (opening) return
if (onOpen) {
onOpen()
return
}
opening = true
try {
await runToolDisplayAction(openItemPreviewAction(card.kind, card.path))
} finally {
opening = false
}
}
</script>
<Button
variant="default"
unifiedSize="2xs"
disabled={opening}
title={title ?? `Open ${kindLabel} preview: ${card.path}`}
onClick={open}
startIcon={kindIcon
? { icon: RowIcon as unknown as IconType, props: { kind: card.kind, size: 12 } }
: undefined}
endIcon={{ icon: PanelRight }}
wrapperClasses="shrink-0"
>
<!-- The chip renders inside the tool row's font-mono scope; the label is UI text.
(font-main, not font-sans — this Tailwind config only defines main/mono.) -->
<span class="font-main">Preview</span>
</Button>