Add a batch pull mechanism for native mode workers. Instead of each
worker independently polling the DB, a single poller pulls up to N
jobs in one query and dispatches them via an mpsc channel.
- Add `pull_batch()` in windmill-queue with batch SQL query
- Add `run_native_poller()` loop with semaphore-based backpressure
- Workers consume jobs via `try_recv()` on a shared channel
- Detect native mode from both env and DB worker group config
- Add `ScriptLang::tag_str()` to centralize bunnative→nativets mapping
- Fix `add_batch_jobs` tag assignment to use consistent mapping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a flow has a flow-level `skip_expr` (or `no_flow_overlap`) and the first
module has `skip_if` defined, the flow-level condition returns `UpdateFlow`
before any identity job is created. The `UpdateFlow` path passes `Uuid::nil()`
as `job_id_for_status`, causing `fetch_one` to fail with "no rows returned".
- Change `fetch_one` to `fetch_optional` so a missing row returns false
- Short-circuit the DB query with `stop_early && skip_if_stop_early` so both
skip mechanisms (identity job check and early-stop skip flag) are considered
- Also fixes the logical gap where a module with both `skip_if` and
`stop_after_if` would only check the identity job, ignoring the early-stop
skip signal
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* worker: support AIAgent tools in AI executor
* worker: complete nested AIAgent tool execution path
* worker: inline AIAgent tool schema usage
* fix agent action
* frontend: add AI Agent as tool type in flow builder
Add the ability to insert a nested AI Agent as a tool within another
AI Agent step. Includes type definitions, factory function, graph icon,
insert/event wiring, and a dedicated editor component.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove AiAgentToolEditor, reuse FlowModuleComponent for AI agent tools
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: populate all input transforms for nested AI agent tools
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: avoid missing v2_job_status error for nested AI agent tools
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* sqlx
* nit
* refactor: cleanup nested AI agent tool implementation
- Add max nesting depth guard (5) on parent chain traversal
- Reject 3+ level nesting explicitly with clear error message
- Remove unnecessary flow_step_id tuple scaffolding in tool dispatch
- Consolidate get_value() calls using borrow in first match
- Replace unsafe `as unknown as FlowModule` casts with agentToolToFlowModule()
- Simplify toolKind ternary chain with .includes() lookup
- Fix leftover over-indentation from tuple removal
- Remove duplicate doc comment on is_completed_input_transform
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: pass flow_step_id and flow_job_id overrides to run_agent for nested AI agents
For nested AI agent tools, job.flow_step_id is None and job.parent_job
points to the parent agent instead of the flow. This caused memory
read/write and flow context resolution to silently fail.
handle_ai_agent_job already computes the correct flow_step_id (via
runnable_path fallback) and flow_job_id (via parent chain traversal).
This change threads those values through run_agent and
ToolExecutionContext so all downstream consumers use the correct IDs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* cleaning
* cleaning
* move const
* fix
* refactor: replace defaultToAi boolean with allowedAiTransforms whitelist
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: propagate root_job at push time, remove flow_job_id_override
Instead of threading flow_job_id_override through run_agent and
get_flow_context, propagate root_job and flow_innermost_root_job
when pushing tool jobs so nested AI agents can find the flow
job naturally via the existing job fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: simplify nested AI agent parent chain walk-up
Replace the generic depth-limited loop with a single-level check since
only flow → agent → nested agent tool is supported. Remove
MAX_AGENT_NESTING_DEPTH constant and flatten the module lookup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: reject 3+ level nested AI agent tools before job creation
Check at the parent agent level whether a nested AIAgent tool contains
AIAgent sub-tools. If so, return a fatal error immediately, preventing
the sub-job from being created and avoiding retry loops.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve deadlock in nested AI agent tool execution
Replace channel forwarding with inline DB writes for tool job
completions. Nested agents used bounded(1) channels where a sub-tool's
forwarded result would fill the parent channel, leaving no room for the
agent's own completion — causing a deadlock. Writing directly via
add_completed_job/add_completed_job_error bypasses the channel entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: preserve debouncing settings for flows with preprocessors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Revert "fix: preserve debouncing settings for flows with preprocessors"
This reverts commit 3452c1657c.
* feat: add post-preprocessing debounce for flows with preprocessors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* perf: reuse caller tx for push-time debounce and add stress test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add exhaustive edge case tests for debouncing behavior
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* perf: optimize debouncing to reduce DB round-trips
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: replace legacy debounce compat with error logging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add debounce args accumulation tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add end-to-end test for maybe_apply_debouncing arg accumulation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update sqlx offline query cache
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: make workmux pane commands idempotent for replay
Use git rev-parse --show-toplevel to resolve absolute paths instead of
relative cd, so commands work when replayed from within backend/frontend.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add e2e debounce test script for backend API
Comprehensive end-to-end test covering:
- Deploy & run scripts rapidly (no debounce with different args)
- Redeploy without lock in rapid succession
- Debounce with same args (should consolidate)
- Debounce with different args (should not consolidate)
- Custom debounce key behavior
- Git sync debounce + item aggregation (using glob-style ** path filter)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update ee-repo-ref to 0fede4b1086bc1456be9cc55b203228c979c5c5e
This commit updates the EE repository reference after PR #426 was merged in windmill-ee-private.
Previous ee-repo-ref: b5d333370603a6cc7ef70842354cf3be734241b4
New ee-repo-ref: 0fede4b1086bc1456be9cc55b203228c979c5c5e
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* feat: add .npmrc support for private npm registries
Add a new `npmrc` instance setting that accepts full .npmrc file content
for configuring private npm registries. Works with bun (native .npmrc
support since 1.1.18), deno (native .npmrc support in 2.x), and the npm
proxy (parses default registry + auth token from .npmrc).
Legacy `npm_config_registry` and `bunfig_install_scopes` fields are now
hidden when empty, so new users only see the .npmrc field. Also fixes a
pre-existing race condition where gen_bunfig was called after
start_child_process.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: extract object store code into windmill-object-store crate with filesystem backend
Consolidate all object_store-dependent code from windmill-common into a new
windmill-object-store crate. Add a filesystem-backed object store implementation
using LocalFileSystem for dev/testing without cloud credentials. Includes 30
comprehensive tests covering render_endpoint, lfs_to_object_store_resource,
duckdb_connection_settings, error mapping, and filesystem-backed integration tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
* all
* all
* all
* fix: fix raw_app hardcoded path, add missing ObjectStoreResource import, and add tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: move S3ModeFormat to windmill-types, make windmill-parser-sql optional, restore debug logs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add read_ee_registry<T> helper that returns None and emits a job log
in CE builds when a private registry is configured. Applied to all
language executors: pip, npm/bun, deno, cargo, go, maven, nuget,
powershell, and ruby. Maven settings.xml file write in monitor.rs
is also gated.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: handle $var: and $res: in arrays for transform_json_value
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve $var/$res arrays inside objects in transform_json_value
Replace top_level: bool with depth: u8 to fix the main bug where arrays
nested inside objects were never resolved. The Object arm recursed with
top_level: false, which caused the Array arm guard to reject the value.
With depth <= 2, arrays inside objects (depth 1-2) are now processed.
Also: transform all array elements unconditionally (handles $encrypted:
in worker, reserved $vars, nested structures), and warn on >1000 items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add force_sandboxing global setting and #sandbox bash annotation
Add a new global setting `force_sandboxing` to enable nsjail sandboxing
for all jobs, overriding the DISABLE_NSJAIL environment variable.
Also add a #sandbox annotation for bash scripts to enable sandboxing
on a per-script basis.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: decouple nsjail probing from DISABLE_NSJAIL and apply force_sandboxing to all executors
NSJAIL_AVAILABLE now always probes for the nsjail binary at startup
regardless of the DISABLE_NSJAIL policy flag, fixing #sandbox annotation
and force_sandboxing being unusable in default (DISABLE_NSJAIL=true)
configuration. All language executors now use is_sandboxing_enabled()
instead of checking DISABLE_NSJAIL directly, so force_sandboxing
applies to all job types, not just bash.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: clarify force_sandboxing and DISABLE_NSJAIL relationship
Neither setting overrides the other — sandboxing is enabled when either
force_sandboxing=true OR DISABLE_NSJAIL=false. Updated frontend
description and backend comments to reflect this.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
* all
* revert typo
* all
* all
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add AWS Bedrock session token support in API and worker
* Add Bedrock auth mode integration tests for AI agents
* Split Bedrock integration test env vars for IAM and session creds
* cleaning
* Add masked Bedrock bearer-token debug info logs
* Revert "Add masked Bedrock bearer-token debug info logs"
This reverts commit 6b2fc5e7c2d5b1c6db81f416a4439941a084108c.
* cleaning
* feat(ai): support 1M context window for Anthropic resources
Add `enable_1m_context` boolean field to Anthropic resource configuration.
When enabled (and not using Vertex AI), sends the `anthropic-beta: context-1m-2025-08-07`
header in both the API proxy layer and the AI agent worker layer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ai): add serde alias for enable_1M_context DB field name
The resource_type schema uses `enable_1M_context` (uppercase M) but
serde only matched `enable_1m_context` and `enable1mContext`, causing
the field to always deserialize as false.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
When eval_timeout_quickjs hits the timeout (typically due to slow DB
result retrieval), retry up to 2 more times with a 5s interval between
attempts. Non-timeout errors are returned immediately without retry.
Also extract the eval timeout duration as EVAL_TIMEOUT_MS const (set to
20000ms, up from 10000ms) in windmill-jseval.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Alexander Petric <alpetric@users.noreply.github.com>
* feat: add prompt caching support for Anthropic API
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* exclude vertex
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Add new BENCHMARK_KIND variants (sequentialflow, scriptlogs, concurrencylimit,
concurrencykey, mixed, mixed_no_cc) for targeted performance testing. Fix shared
iteration counting across workers using a global atomic counter. Add job_perms
inserts and queue diagnostics for benchmark mode.
Move db connection setup to dedicated module and drop the initial connection pool
before creating the main one, preventing connection starvation when PostgreSQL
max_connections is low.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve Windows build warnings treated as errors
- Gate UV_PATH import behind #[cfg(unix)] in python_versions.rs
- Remove unused tokio::time::sleep import in worker.rs (use fully qualified path)
- Fix unused `file` variable warnings in ansible_executor.rs on Windows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: add Windows cargo check workflow
Runs cargo check with ee_windows features on push to backend/**
using the blacksmith-16vcpu-windows-2025 runner.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: add cargo check step to Windows build, remove separate check workflow
Add a cargo check step with -D warnings before the full build to fail
fast on any warnings. Remove the separate windows-check.yml workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: parse Python datetime.datetime and datetime.date type annotations correctly
The Python parser only matched ExprKind::Name for type annotations, so
`datetime.datetime` (an Attribute expression) silently fell through to
Typ::Unknown and no datetime picker was shown in the UI.
- Extend parse_expr to resolve `datetime.*` attribute access (alongside
the existing `wmill.*` handling)
- Add Typ::Date variant for `datetime.date` → JSON schema format "date"
- Update python worker to import and convert `date.fromisoformat()`
- Update argSigToJsonSchemaType, AI types, schema validation, and SQL
datatype wasm for the new Date variant
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
* all
* all
* all
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- rquickjs: gated behind `quickjs` feature in windmill-jseval, propagated through windmill-worker/windmill-api, added to oss_core
- windmill-autoscaling: made optional in windmill-api (was unconditional), enabled via enterprise feature
- opentelemetry-proto, prost, hudsucker, rcgen, hyper-http-proxy, hyper-tls, hyper-util: made optional in windmill-worker, enabled via enterprise feature
This significantly reduces compilation time for vanilla `cargo check` without features.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: isolate deno_core into windmill-runtime-nativets subcrate
Remove deno_core from flow eval and isolate nativets V8 runtime into a
dedicated subcrate so deno_core compilation no longer blocks
windmill-worker or windmill-api.
- Create windmill-jseval crate: QuickJS-based JS eval for flow
expressions and batch rerun, extracted from windmill-worker
- Create windmill-runtime-nativets crate: all deno_core/V8 deps and
nativets script execution, with build.rs snapshot generation
- Simplify windmill-worker: remove all deno_* direct deps, empty
build.rs, gate nativets behind optional dep
- Update windmill-api: use windmill-jseval for batch rerun instead of
deno_core, remove deno_core feature entirely
- Add nativets integration tests (nativets_jobs.rs) and parallel
stress test (nativets_stress.rs, 8 workers x 200 jobs)
- Remove dead code: deno flow eval path, USE_QUICKJS env var,
parity tests (replaced with 63 standalone expected-value tests)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback for deno_core isolation
- Deduplicate unsafe_raw() into windmill-common/src/utils.rs (single source)
- Delete orphaned runtime.js and windmill-client.js from windmill-worker/src/
- Fix operator precedence in windmill-jseval with explicit parentheses
- Remove unnecessary return keyword in heap limit callback
- Remove redundant as usize casts
- Remove ~150 lines of commented-out code from runtime.js
- Remove commented-out #[cfg] in build.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* otel ee
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: extract windmill-dep-map crate for parallel api/worker compilation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve WebhookShared type mismatch and missing enterprise propagation
- Make windmill-api webhook_util re-export from windmill-common instead of
duplicating types, fixing Extension<WebhookShared> mismatch between
windmill-store and windmill-api
- Add windmill-api-jobs/enterprise to windmill-trigger enterprise feature
so check_license_key_valid is available when trigger subcrates enable
enterprise on windmill-trigger
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: stop trigger features from unconditionally enabling enterprise
Move enterprise propagation for all trigger subcrates from individual
trigger feature definitions to the enterprise feature itself, so
enterprise is only enabled when explicitly requested.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove unused pub use re-exports and disable CI cargo cache
- Remove unused re-exports from windmill-worker/src/lib.rs:
trigger_dependents_to_recompute_dependencies, handle_job_error,
and unused bun/otel items
- Fix callers to use direct module paths instead
- Add windmill-dep-map as dev-dependency for tests
- Disable cargo cache in backend-check CI (faster from-scratch builds)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore bun re-exports used by tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
* chore: re-enable cargo cache for check_ee_full CI job
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: reuse outer tx for schedule push in commit_completed_job
Instead of calling handle_maybe_scheduled_job(db) which opens its own
connections (peak=3), inline the schedule push using a savepoint on the
outer transaction. Auth is fetched via the tx connection using
fetch_authed_from_permissioned_as_conn, and push_scheduled_job runs
on a savepoint so failures roll back only the push, not the completion.
On push failure: savepoint rolls back, schedule is disabled on the outer
tx, and the zombie return path is preserved if disabling also fails.
Peak connections drop from 3 to 1 (or 2 on cold RunnableSettings cache).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* all
* fix: extract shared try_schedule_next_job to unify schedule push paths
Replace the two diverging schedule-push implementations (inlined in
commit_completed_job and standalone handle_maybe_scheduled_job) with a
single try_schedule_next_job that reuses the caller's transaction via
savepoints. This eliminates extra pool connection usage in the
worker_flow.rs path and ensures consistent retry/error semantics.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add failpoint markers to try_schedule_next_job
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: remove plan.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove inner retry loop from try_schedule_next_job, add caller-level retries
The 10-retry x 5s-sleep loop inside try_schedule_next_job held locks on
v2_job_completed/v2_job_queue for up to ~45s when running inside the
outer commit_completed_job transaction.
Now try_schedule_next_job makes a single attempt and returns errors to
the caller. Non-retryable errors (QuotaExceeded, NotFound) disable the
schedule immediately inside the function. Transient errors are returned
for the caller to retry:
- commit_completed_job path: outer backon retry (10x3s) retries the
entire transaction including the schedule push, so no locks are held
during sleep.
- handle_flow path: new backon retry (10x3s) wraps begin/push/commit
with a fresh transaction per attempt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: clear push_err after successful schedule disable to prevent stuck schedules
When try_schedule_next_job disables the schedule for non-retryable errors
(NotFound, QuotaExceeded), clear the error so the caller commits the tx
(persisting the disable). Previously, the error propagated up, causing the
tx to be dropped and rolling back the disable — leaving the schedule
permanently enabled but broken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add 5s timeout on push_scheduled_job, clean up handle_flow error handling
- Add tokio::time::timeout(5s) around push_scheduled_job inside
try_schedule_next_job to bound worst-case lock holding per attempt
- Remove unreachable QuotaExceeded/NotFound match arms in handle_flow
(these errors are handled internally by try_schedule_next_job)
- Add report_error_to_workspace_handler_or_critical_side_channel in
handle_flow when post-exhaustion schedule disable fails
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: return SchedulePushZombieError when both schedule push and disable fail
When handle_flow cannot push the next scheduled job AND cannot disable the
schedule, return a SchedulePushZombieError so the worker leaves the flow job
in the queue for zombie detection to restart. This prevents stuck schedules
where neither the next tick was pushed nor the schedule was disabled.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* iam
* fix occupancy + log settings change
* ee ref
* ee ref
* sqlx
* chore: update ee-repo-ref to 7f93a13e96c77292ed4b1e63bc1e8ff1e341d283
This commit updates the EE repository reference after PR #408 was merged in windmill-ee-private.
Previous ee-repo-ref: 5b6a4b2f990b7e5bdf6dea14645c787b42a4d9a6
New ee-repo-ref: 7f93a13e96c77292ed4b1e63bc1e8ff1e341d283
Automated by sync-ee-ref workflow.
---------
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* feat: mssql integrated auth (kerberos/ntlm)
* install krb5 headers
* also make it work for windows
---------
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>