mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 00:03:00 +00:00
fix: keep each mode's provider across output type switches
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fda24bfa1b
commit
323ad63ee5
@@ -4,7 +4,7 @@
|
||||
anonymous usage-stats payload. It answers "does anyone use this, and which variant do they pick"
|
||||
without any identifying data leaving the instance.
|
||||
|
||||
It currently carries 57 registered actions across nineteen features (`ai_session`, `ai_chat`,
|
||||
It currently carries 58 registered actions across nineteen features (`ai_session`, `ai_chat`,
|
||||
`ai_fix`, `ai_agent`, `ai_agent_eval`, `app_sandbox`, `datatable`, `flow_editor`, `flow_run`,
|
||||
`flow_step`, `home`, `run_form`, `debugger`, `trigger`, `command_script`, `hub_script`,
|
||||
`usage_meter`, `sso_groups_claim`, `cloud_trial_offer`). Nearly all of the
|
||||
|
||||
@@ -66,18 +66,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// A kind the mode does not offer cannot run, and switching the output type leaves the old kind
|
||||
// behind. Its resource, model and reasoning effort belong to it, so they go with it rather than
|
||||
// surfacing only as a failed run.
|
||||
// Each mode offers kinds the other does not, so switching the output type swaps the provider: the
|
||||
// one the step held is set aside and comes back with its mode, and a mode not seen yet starts
|
||||
// empty rather than on a kind it cannot run.
|
||||
type PickerMode = 'chat' | 'decision'
|
||||
const heldByMode: Partial<Record<PickerMode, ProviderConfig>> = {}
|
||||
let shownMode: PickerMode = untrack(() => (decision ? 'decision' : 'chat'))
|
||||
$effect(() => {
|
||||
const offered = offeredProviders
|
||||
const mode: PickerMode = decision ? 'decision' : 'chat'
|
||||
untrack(() => {
|
||||
if (value?.kind && !offered.includes(value.kind)) {
|
||||
value.kind = decision ? 'typesafe' : 'openai'
|
||||
value.resource = ''
|
||||
value.model = ''
|
||||
value.reasoning_effort = undefined
|
||||
if (mode === shownMode || !value) return
|
||||
heldByMode[shownMode] = $state.snapshot(value) as ProviderConfig
|
||||
const next = heldByMode[mode] ?? {
|
||||
kind: mode === 'decision' ? 'typesafe' : 'openai',
|
||||
resource: '',
|
||||
model: ''
|
||||
}
|
||||
value.kind = next.kind
|
||||
value.resource = next.resource
|
||||
value.model = next.model
|
||||
value.reasoning_effort = next.reasoning_effort
|
||||
shownMode = mode
|
||||
})
|
||||
})
|
||||
|
||||
@@ -215,22 +224,26 @@
|
||||
<!-- No auto-select: this picker spans every provider type, so a single candidate means "the
|
||||
only AI resource in the workspace" rather than "the only one of the kind this agent uses".
|
||||
Taking it would redefine the agent's provider and drop its model, on open and unasked. -->
|
||||
<ResourcePicker
|
||||
bind:value={
|
||||
() => resourceValueToPath(value?.resource),
|
||||
(v) => {
|
||||
if (value) {
|
||||
value.resource = pathToResourceValue(v) ?? ''
|
||||
<!-- Remounted per mode: the picker empties its value whenever the types it offers change,
|
||||
which would drop the resource the switch above just restored. -->
|
||||
{#key decision}
|
||||
<ResourcePicker
|
||||
bind:value={
|
||||
() => resourceValueToPath(value?.resource),
|
||||
(v) => {
|
||||
if (value) {
|
||||
value.resource = pathToResourceValue(v) ?? ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resourceType={providerResourceTypes}
|
||||
{disabled}
|
||||
{workspace}
|
||||
placeholder="Select an AI provider resource"
|
||||
selectFirst={false}
|
||||
onValueChange={onResourcePicked}
|
||||
/>
|
||||
resourceType={providerResourceTypes}
|
||||
{disabled}
|
||||
{workspace}
|
||||
placeholder="Select an AI provider resource"
|
||||
selectFirst={false}
|
||||
onValueChange={onResourcePicked}
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
if ((mod.value as { type?: string })?.type !== 'aiagent') return all
|
||||
const transforms = (mod.value as { input_transforms?: Record<string, unknown> })
|
||||
?.input_transforms
|
||||
// A step's own agent holds its output type; a linked one takes it from the agent, and until
|
||||
// that has loaded no field is dropped for it.
|
||||
// A step's own agent holds its output type; a linked one takes it from the agent, and reads as
|
||||
// text until that has loaded.
|
||||
const outputTransform = transforms?.output_type as
|
||||
| { type?: string; value?: unknown }
|
||||
| undefined
|
||||
|
||||
Reference in New Issue
Block a user