Files
centdix b0ddcf31e4 ci: add path-gated AI agent + ai_evals smoke workflows (#9640)
* ci: add path-gated AI agent integration tests workflow

Runs integration_tests/ai_agent_tests against real LLM providers
(Anthropic/OpenAI/Google) only when AI-agent backend code or the tests
change, since runs make paid LLM calls. Adds a conftest fixture that
skips provider-parametrized cases whose API keys are absent, so CI
exercises only the providers it has secrets for.

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

* ci: add path-gated ai_evals global-mode smoke workflow

Runs the global AI chat eval (global-test1) across one cheap model per
provider (Anthropic/OpenAI/Google/DeepSeek) only when the eval harness or
copilot chat code change, since runs make paid LLM calls. Builds Windmill
CE from source as the AI proxy; global tools/drafts run in the Vitest
bridge. Gates on the deterministic draft pipeline (run succeeded +
produced a draft + used write_script), not the variable LLM judge score.

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

* ci: run AI smokes on PR ready-for-review instead of every push

Switch the pull_request trigger from `synchronize` (every commit) to
`ready_for_review`, with a job guard skipping draft PRs, so the paid LLM
runs only fire when a PR is marked ready to merge (plus push-to-main and
manual dispatch).

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

* fix(ai_evals): lazily load cli mode so non-cli evals skip the cli toolchain

The entrypoint eagerly imported modes/cli, which pulls the wmill CLI
guidance modules and their JSR deps (@cliffy/*). Global/flow/script/app
runs then crashed with "Cannot find module '@cliffy/ansi/colors'" when
the cli workspace deps were not installed. Import createCliModeRunner
dynamically inside runCliBenchmark instead.

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

* test(ai_agent): raise low max_completion_tokens to OpenAI's 16 minimum

OpenAI's /v1/responses rejects max_output_tokens < 16 with a 400, failing
test_low_max_tokens for openai. 16 still exercises a truncated response.

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

* ci: run ai_evals workflow on Node 22 for the frontend undici 8.x dep

The Vitest bridge loads frontend/node_modules/undici@8.x, which requires
Node >=22.19; Node 20 failed with "webidl.util.markAsUncloneable is not a
function" when loading vitest.config.ts.

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

* fix(ai_evals): run frontend evals autonomously + give global-test1 more turns

Frontend evals (flow/script/app/global) ran the production chat prompt, which
assumes an interactive human — so cheaper models burned their turn budget
asking for confirmation, waiting for approval, or presenting a plan, sometimes
hitting maxTurns without producing a draft. Append a shared autonomy note in
baseEvalRunner (the path all frontend modes share, mirroring cli mode): act
directly on clear requests; only ask on genuinely ambiguous ones (preserving
the askUserQuestion cases). Also raise global-test1's maxTurns 8 -> 10 so a
model that over-explores still converges.

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

* ci(ai_evals): watch draft/prompt deps outside copilot/

The global eval runs production frontend code in-process, so the smoke's
behavior depends on files outside frontend/src/lib/components/copilot/**:
the draft model (userDraft.svelte.ts, userDraftDbSyncer.svelte.ts), script
inference (infer.ts), and the chat system prompts ($system_prompts ->
system_prompts/auto-generated). Add them to both push and PR path filters so
a change there actually triggers the smoke that gates on draft production.

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

* fix: skip direct provider tests without credentials

* feat: add ai evals skip judge flag

* fix: simplify ai evals ci gate

* fix: simplify ai evals smoke gate

* fix: handle ai eval workflow triggers

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:41:31 +02:00
..

AI Agents Integration Tests

Integration tests for Windmill AI agents using the preview_flow endpoint.

Quick Start

  1. Create and activate a virtual environment:

    cd integration_tests/ai_agent_tests
    python -m venv .venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    
  2. Install dependencies:

    pip install -r requirements.txt
    
  3. Create .env file with your API keys:

    OPENAI_API_KEY=sk-...
    ANTHROPIC_API_KEY=sk-ant-...
    GOOGLE_AI_API_KEY=...
    OPENROUTER_API_KEY=sk-or-...
    BEDROCK_API_KEY=...
    BEDROCK_IAM_ACCESS_KEY_ID=...
    BEDROCK_IAM_SECRET_ACCESS_KEY=...
    BEDROCK_SESSION_ACCESS_KEY_ID=...
    BEDROCK_SESSION_SECRET_ACCESS_KEY=...
    BEDROCK_SESSION_TOKEN=...  # optional, only for session-token Bedrock test
    AWS_ACCESS_KEY_ID=...      # optional, for env-fallback Bedrock test
    AWS_SECRET_ACCESS_KEY=...  # optional, for env-fallback Bedrock test
    AWS_SESSION_TOKEN=...      # optional, required for env-fallback if AWS_ACCESS_KEY_ID is ASIA...
    BEDROCK_REGION=us-east-1  # optional
    
  4. Run a single test to verify:

    pytest test_basic_completion.py::TestOpenAI::test_openai_completion -v -s
    

Prerequisites

  1. A running Windmill instance (default: http://localhost:8000)
  2. Python 3.10+
  3. API keys for the providers you want to test

How It Works

Provider Setup

The setup_providers fixture automatically creates Windmill variables and resources from your environment variables:

Provider Variable Path Resource Path Resource Type
OpenAI u/admin/openai_api_key u/admin/openai openai
Anthropic u/admin/anthropic_api_key u/admin/anthropic anthropic
Google AI u/admin/google_ai_api_key u/admin/googleai googleai
OpenRouter u/admin/openrouter_api_key u/admin/openrouter openrouter
Bedrock (api key) u/admin/bedrock_api_key u/admin/bedrock aws_bedrock
Bedrock (IAM) u/admin/bedrock_iam_access_key_id, u/admin/bedrock_iam_secret_access_key u/admin/bedrock_iam aws_bedrock
Bedrock (IAM + session) u/admin/bedrock_session_access_key_id, u/admin/bedrock_session_secret_access_key, u/admin/bedrock_session_token u/admin/bedrock_iam_session aws_bedrock
Bedrock (environment fallback) none (uses worker/api AWS env) u/admin/bedrock_env aws_bedrock

Tools

Tools use rawscript with inline content instead of creating actual scripts. This means:

  • No script creation/deployment needed
  • Scripts are embedded directly in the flow definition
  • Faster test execution

Running Tests

All commands assume you're in the integration_tests/ai_agent_tests directory with the venv activated.

Run all AI agent tests

pytest . -v -s

Run only basic completion tests

pytest test_basic_completion.py -v -s

Run only tool calling tests

pytest test_tool_calling.py -v -s

Run tests for a specific provider

# Only Anthropic tests
pytest . -v -s -k "anthropic"

# Only OpenAI tests
pytest . -v -s -k "openai"

Run a single test

# OpenAI basic completion
pytest test_basic_completion.py::TestOpenAI::test_openai_completion -v -s

# Anthropic basic completion
pytest test_basic_completion.py::TestAnthropic::test_anthropic_completion -v -s

# Parametrized test for one provider
pytest test_basic_completion.py::TestBasicCompletion::test_simple_prompt[openai] -v -s

Test Structure

  • conftest.py - Test fixtures and utilities
    • AIAgentTestClient - HTTP client for preview_flow
    • create_ai_agent_flow() - Creates AI agent flow definitions
    • create_rawscript_tool() - Creates inline script tools
    • setup_providers - Sets up variables and resources
  • providers.py - Provider configurations (OpenAI, Anthropic, Google AI, Bedrock, OpenRouter)
  • test_basic_completion.py - Basic AI completion tests
  • test_tool_calling.py - Tool calling tests with inline scripts

Troubleshooting

Tests fail with authentication error

Make sure Windmill is running and you can login with the default credentials:

  • Email: admin@windmill.dev
  • Password: changeme

Tests skip due to missing API keys

Ensure the environment variables are set correctly:

echo $OPENAI_API_KEY

Resource creation fails

If resources already exist with different values, you may need to delete them manually via the Windmill UI or API before running tests again.