Commit Graph
22 Commits
Author SHA1 Message Date
hugocasaandClaude Opus 4.8 a368d49bd8 feat(ai-agent): support reasoning effort in AI agent workflow steps (#9886)
* feat(ai-agent): support reasoning effort in AI agent workflow steps

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): round-trip native Anthropic thinking blocks and fix DeepSeek/Mistral reasoning

Address review: native Anthropic now captures the signed thinking block during streaming and replays it before tool_use across iterations (prevents a 400 on multi-turn tool use). DeepSeek 'off' sends thinking:{type:disabled} instead of the rejected reasoning_effort:none, and Mistral drops temperature when reasoning is on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(ai-agent): move reasoning effort into the provider/model selector

Store reasoning_effort on ProviderConfig (next to the model) instead of a separate flow arg, and render the selector inside AIProviderPicker under the model dropdown. Add an explicit 'off' option on models that disable reasoning by omission (e.g. Claude), so reasoning can always be turned off from the UI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(ai-agent): use DropdownV2 for reasoning effort, matching copilot chat

Replace the Select combobox with the same DropdownV2 action-menu the copilot chat reasoning selector uses. Each option carries an action instead of a bound value, so click selection is unambiguous and there is no typeahead/sentinel-value mismatch on the off/default entries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(ai-agent): regenerate system prompts for ProviderConfig.reasoning_effort

Refresh system_prompts/auto-generated and cli skills.gen after adding reasoning_effort to the OpenFlow ProviderConfig schema (check-freshness).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): clear stale reasoning effort on model change; dedup bedrock reasoning folding

Address cubic review: (P1) the reasoning picker now clears the stored effort when the newly selected model doesn't accept it (e.g. carrying 'xhigh' from Opus onto a model that tops out at 'high'), not only when the model can't reason at all. (P3) the proxy's accumulate_reasoning_delta now delegates to the shared bedrock_stream_event_to_reasoning_delta so worker and proxy folding can't drift.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(ai-agent): stream reasoning summary and show a thinking affordance in flow chat

Add StreamingEvent::ReasoningTokenDelta, emitted from every worker reasoning path (Anthropic native thinking deltas, Bedrock, Gemini thought parts, OpenAI-compatible reasoning_content, OpenAI Responses reasoning_summary_text with summary:auto). The flow chat parses it and renders a collapsible 'Thinking' affordance on the assistant message (thinking tokens bill regardless of display, so surfacing the summary is billing-neutral).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): persist streamed reasoning onto the finished chat message

Reasoning isn't stored server-side, so the completion re-poll (which swaps temp messages for the persisted ones) was dropping the streamed thinking summary. Carry it onto the final assistant message so the 'Thought process' affordance survives the run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(ai-agent): match flow-chat thinking box to the copilot chat reasoning UI

Replace the plain <details> thinking affordance with the same bordered, collapsible reasoning box the copilot chat uses (chevron + Brain/spinner + 'Thinking' header, markdown body, expand-while-streaming/collapse-on-answer).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): attribute streamed reasoning per turn by content; drop duplicated comment

Address review: the completion-poll carry-over now matches each temp assistant turn's thinking summary to its persisted message by content, so a multi-turn response (reasoning -> tool call -> final answer) no longer misattributes an earlier turn's thinking to the final answer or drops intermediate turns. Also removes a leftover duplicated comment block above the AIReasoningEffortPicker effect.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): address review round 2 (carry-over edges, off-token validity, aria, test)

cubic round 2: (1) reasoning carry-over now consumes temp turns in order verifying content, so identical/empty-content multi-turn responses attribute thinking correctly and reasoning-only turns aren't dropped; (2) the picker's stale-value check only accepts the off token when the model can actually disable reasoning; (3) add aria-expanded to the Thinking toggle; (4) add a test for the failed tool_result path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): add bottom margin below the flow-chat thinking box

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): don't request OpenAI reasoning summary, matching the copilot chat

OpenAI gates reasoning summaries behind org verification, so requesting summary: auto would 400 for unverified orgs. The copilot chat requests effort only and never asks for a summary; align the worker with it (reasoning: { effort }) and drop the now-unreachable summary-delta parsing. OpenAI reasoning no longer streams a summary in flow chat (consistent with the copilot); Anthropic/Bedrock/Gemini/DeepSeek reasoning display is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): scope reasoning carry-over to newly persisted messages

cubic round 3: matching by content over the full history could attach a new turn's reasoning to an older message with identical text. Restrict eligible targets to the messages just fetched for this response (via afterSeq), so historical turns are never touched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): carry reasoning newest-first instead of gating on the final poll

cubic round 4: gating the carry-over on the final poll's filteredResponse dropped reasoning for messages already fetched by an earlier streaming poll (their id is excluded by afterSeq). Walk persisted newest-first and consume the newest matching pending summary, stopping once summaries run out. This response's turns are always at the end, so they claim their own reasoning (P1) before older history is reached (P2), regardless of which poll persisted them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(ai-agent): drop flow-chat reasoning display, keep backend + effort picker

The chat-side thinking box relied on non-deterministically matching streamed (ephemeral) reasoning back onto persisted messages, which kept spawning edge cases. Remove the flow-chat display entirely (ChatMessage box, FlowChatManager carry-over/threading, parseStreamDeltas reasoning) and keep the sound backend: per-provider reasoning-effort requests, thinking-block round-trips for tool calls, and ReasoningTokenDelta streaming. A display can be built on top later, deterministically (e.g. once the stream carries the persisted message id).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai-agent): include reasoning_effort in default-config compare; document reasoning_token_delta

Codex/Pi nits: isSameAsStoredConfig now compares reasoning_effort so the 'use as personal default' toggle reflects effort-only changes; openflow streaming-events doc lists the reasoning_token_delta event (regenerated auto prompts).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 17:16:07 +02:00
hugocasaandClaude Opus 4.8 d600c7ecfe fix(ai): route Azure Foundry Claude models via Anthropic Messages API (#9908)
* fix(ai): route Azure Foundry Claude models via Anthropic Messages API

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai): keep explicit Azure OpenAI deployment base URLs intact

build_azure_openai_url only appends /openai/v1 for a bare resource root; any base with an explicit path (e.g. .../openai/deployments/<id>) is preserved. Adds a regression test and a unit test for usesAnthropicMessagesApi.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(ai): enable Claude extended thinking on Azure Foundry

Route azure_foundry+Claude through the Anthropic reasoning branch (adaptive thinking + output_config.effort) instead of the gpt/o gate, and recognize claude-sonnet-5. Live-verified: sonnet-5 and opus-4-8 on Foundry accept the low/medium/high/xhigh/max ladder and render summarized thinking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 18:26:12 +02:00
hugocasaandClaude Opus 4.8 d9b080f57f feat(ai): add Azure AI Foundry as a native AI provider (#9879)
* feat(ai): add Azure AI Foundry as a native AI provider

Adds `azure_foundry` as a new AIProvider variant wired through the AI
chat (copilot) and AI agent flow steps. Foundry's chat completions API
is OpenAI-compatible and uses Azure conventions (api-key header, Azure
URL building), so it reuses the existing OpenAI-compatible query builder
and proxy path via the shared `is_azure` helper (renamed from
`is_azure_openai`).

Backend (windmill-ai):
- New `AzureFoundry` enum variant (serde `azure_foundry`)
- `get_base_url` requires a resource base URL (like Azure OpenAI / Custom)
- `is_azure()` covers Azure OpenAI + Foundry (api-key auth, Azure URL)
- Added to OpenAI-compatible proxy support and HttpForward proxy mode
- New proxy URL unit test

Frontend (copilot):
- New provider entry, completion config, model-token handling, streamed
  usage tracking, and reasoning registry (all model-id-gated, so a no-op
  for Foundry's non-OpenAI catalog)
- Treated as a chat-completions provider, not the OpenAI Responses API

OpenAPI:
- `azure_foundry` added to AIProvider (openapi.yaml) and AIProviderKind
  (openflow.openapi.yaml); regenerated CLI guidance

Note: the `azure_foundry` resource type (base_url + optional api_key) is
hub-managed and must be published to the Windmill Hub separately.

Fixes WIN-2122

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ai): add azure_foundry to copilot flow Zod provider enum

The tracked copilot flow schema (openFlowZod.gen.ts and its openFlow.json
source) still carried the old AIProvider enum, so validateFlowModules /
validateSpecialFlowModule rejected AI-generated flow edits that create or
update an aiagent module with provider kind "azure_foundry" before they
could be saved. Add the value to both (preserving the generated single-line
format) and a regression test over the flow-module validation path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(ai): lead provider list with OpenAI, Anthropic, Google AI

Reorder AI_PROVIDERS so the three primary direct providers come first. The
AIProviderPicker renders the first three entries as quick-access buttons, so
these become the defaults (previously OpenAI, Azure OpenAI, Azure Foundry);
Azure OpenAI / Azure Foundry stay adjacent right after. No logic depends on
provider order (only per-provider defaultModels[0] is read).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 23:42:44 +02:00
centdixandClaude Opus 4.8 0cc2257596 fix(ai): emit token usage in gemini proxy streaming translation (#9669)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:57:52 +00:00
centdixandClaude Opus 4.6 82e2197922 chore: remove deprecated enable_1m_context from AI providers (#9580)
* chore: remove deprecated enable_1m_context from AI provider code

1M context is now standard on Anthropic models — the beta header
`anthropic-beta: context-1m-2025-08-07` is no longer needed.

Remove the field from ProviderCredentials and AnthropicQueryBuilder,
and stop injecting the beta header in both the API proxy and worker
query builder paths.

The field is kept (as `_enable_1m_context`) on the ProviderResource
deserialization structs in both windmill-api and windmill-ai so
existing resources with the field still deserialize without error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: drop vestigial _enable_1m_context field from AI resources

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: assert legacy enable_1m_context keys still deserialize

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-15 18:58:19 +02:00
hugocasa aaf05635ce feat: wire chat reasoning effort through gemini and bedrock proxies (#9545)
* feat: map chat reasoning effort to gemini thinkingConfig in ai proxy

* feat: support claude adaptive thinking through the bedrock ai proxy

* feat: per-model gemini effort levels and thought summary display

* fix: exclude claude opus 4.5 from reasoning effort (rejects adaptive)

* fix: render markdown in thinking blocks and unstick reasoning spinner

* feat: model-aware reasoning effort options across ai chat providers

* fix: scope openrouter reasoning off to the underlying model family
2026-06-12 17:24:46 +02:00
centdix d3f5fe1c8c feat: enable native web search in copilot (#9522)
* feat: enable native web search in copilot

* fix: add web search fallback and settings

* test: use frontend uuid helper

* fix: tighten web search fallback

* fix: add web search error hint

* fix: classify web search fallback errors

* fix: avoid web search fallback tool error

* fix: handle anthropic web search enablement errors
2026-06-12 00:18:22 +02:00
Ruben Fiszel 4b06881918 fix(ai): validate token_url for SSRF in OAuth credentials flow (#9385)
get_token_using_oauth resolved the AI OAuth resource's token_url and
POSTed to it without any SSRF validation, while base_url is validated in
get_base_url. A workspace member with resources:write could point
token_url at an internal/metadata address (e.g. 169.254.169.254),
turning the server into an authenticated blind SSRF probe.

Validate the resolved token_url with validate_url_for_ssrf before the
request, gated behind the same ALLOW_PRIVATE_AI_BASE_URLS opt-in as
base_url so private AI deployments keep working consistently for both
URL fields. ALLOW_PRIVATE_AI_BASE_URLS is now pub so windmill-api can
reuse it instead of re-parsing the env var.
2026-05-30 09:33:27 +00:00
centdix 2553fbfe31 feat: add deepseek fim support (#9365) 2026-05-28 16:52:26 +00:00
centdix a7d85a39ff refactor: clean up ai provider proxy logic (#9360)
* refactor: clean up ai provider proxy logic

* docs: remove completed ai refactor plan

* fix: audit failed google global proxy calls
2026-05-28 16:05:04 +00:00
centdix 4be930f585 refactor: unify AI provider credentials (#9317)
* refactor: use provider credentials for worker builders

* refactor: resolve api proxy credentials directly

* fix: lazy load frontend eval modes
2026-05-26 05:51:32 +00:00
centdix c96be0e903 refactor: move bedrock proxy handling to windmill-ai (#9309)
* refactor: move bedrock proxy handling to windmill-ai

* docs: track ai refactor follow-ups
2026-05-25 14:22:10 +00:00
centdix 289549a048 refactor: move google ai proxy handling to windmill-ai (#9260)
* refactor: add ai proxy execution mode

* refactor: move google ai proxy handling

* refactor: share google ai request building
2026-05-20 15:24:07 +00:00
centdix 55dcee2424 refactor: move anthropic proxy building (#9238) 2026-05-19 14:23:31 +00:00
centdix bd32c5f951 refactor: move openai-compatible proxy building (#9133)
* refactor: introduce ai proxy request types

* refactor: move openai-compatible proxy building
2026-05-18 10:24:16 +00:00
Ruben FiszelandClaude Opus 4.7 4e25954722 fix: don't show ALLOW_PRIVATE_AI_BASE_URLS hint for malformed AI base URLs (#9188)
* fix: don't show ALLOW_PRIVATE_AI_BASE_URLS hint for malformed AI base URLs

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

* fix: impl std::error::Error for SsrfValidationError for anyhow callers

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 07:39:47 +00:00
centdix 17cf538a2d refactor: move ai providers to windmill-ai (#9120) 2026-05-12 14:09:31 +00:00
Ruben FiszelandClaude Opus 4.7 01e21c7f91 fix: preserve negative integers in Bedrock tool schema conversion (#9116)
json_to_document cast any i64 to u64 via `as` and wrapped in PosInt.
Negative integers in a tool's JSON schema (e.g. "default": -1,
"minimum": -1) became huge unsigned values like 18446744073709551615,
which Bedrock rejected with `tools.N.custom.input_schema: int too big
to convert`.

Try as_u64 first to preserve full u64 range, fall back to as_i64 for
negatives via NegInt, then as_f64.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 07:00:58 +00:00
centdix 6f7d31e56b refactor: move ai image handling to windmill-ai (#9098) 2026-05-11 14:59:40 +00:00
centdixandwindmill-internal-app[bot] 27acbbf3d5 refactor: move ai sse plumbing to windmill-ai (#9059)
* docs: refine windmill ai refactor plan

* refactor: move ai sse plumbing to windmill-ai

* refactor: remove ai re-export shims

* fix: update ee ai memory ref

* chore: update ee-repo-ref to d3bc7fa85195b46b7a38d43c2f806520bf8b5454

This commit updates the EE repository reference after PR #560 was merged in windmill-ee-private.

Previous ee-repo-ref: ff35bf7cc198e13884b33654e1d6dbd8a8b314d3

New ee-repo-ref: d3bc7fa85195b46b7a38d43c2f806520bf8b5454

Automated by sync-ee-ref workflow.

---------

Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-05-11 10:01:45 +00:00
centdixandClaude Opus 4.5 77d9a53423 fix: strip additionalProperties from google schemas (#8964)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-28 19:59:45 +00:00
centdixandClaude Opus 4.6 26a6d1e4ce refactor: create windmill-ai crate (part 1 — types, traits, base modules) (#8530)
* refactor: create windmill-ai crate and move base AI types from windmill-common

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: move worker AI types to windmill-ai crate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: move QueryBuilder trait and StreamEventSink abstraction to windmill-ai

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add base64 dependency to windmill-ai for bedrock PDF support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add windmill-ai refactor plan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: address PR review — remove dead bedrock feature, add boxed_sink helper, move plan to docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 11:20:27 +00:00