Compare commits

...
Author SHA1 Message Date
centdix 588575d943 Merge remote-tracking branch 'origin/main' into add-get-documentation-global-chat
# Conflicts:
#	ai_evals/cases/global.yaml
#	frontend/src/lib/components/copilot/chat/global/core.test.ts
2026-06-09 23:58:28 +02:00
centdixandClaude Opus 4.8 8391dba248 test(ai_evals): add get_documentation vs get_instructions boundary cases
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 17:10:21 +02:00
centdixandClaude Opus 4.8 2a05424c32 feat: add get_documentation tool to global mode ai chat
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 16:31:56 +02:00
3 changed files with 96 additions and 0 deletions
+92
View File
@@ -870,3 +870,95 @@
judgeChecklist:
- fetches the logs for the requested job id
- explains the failure from the returned logs (connection refused to the upstream API)
# --- get_documentation vs get_instructions boundary ---
# get_documentation answers Windmill product questions (features, concepts,
# how-tos) from the docs; get_instructions returns authoring guidance for
# writing a specific item type. These cases guard against the two being
# confused in either direction. They make no draft, so the global judge (which
# only sees the drafts artifact) would score them empty -> skipJudge, validate
# purely on tool use.
- id: global-test29-doc-resource-vs-variable-concept
prompt: |-
What's the difference between a resource and a variable in Windmill,
and when should I use each?
runtime:
maxTurns: 6
validate:
draftCountExactly: 0
toolExpect:
requiredToolsUsed:
- get_documentation
forbiddenToolsUsed:
# The word "resource" must not trigger get_instructions(subject: resource):
# this is a conceptual question, not a request to author a resource.
- get_instructions
- write_resource
- write_variable
- deploy_workspace_item
- delete_workspace_item
skipJudge: true
judgeChecklist:
- looks up the answer in the Windmill documentation rather than authoring instructions
- explains the conceptual difference between resources and variables
- does not create a resource, a variable, or any other draft
- does not treat the word "resource" as a request to author a resource
- id: global-test30-doc-feature-explanation
prompt: |-
How does Windmill decide which worker runs a job?
# Deliberately a pure platform-mechanics question (worker groups / tags /
# queues) with no authoring surface, so forbidding get_instructions is fair.
# An authoring-adjacent feature question (e.g. per-step retries) legitimately
# pulls get_instructions on some models, which would be a false negative here.
runtime:
maxTurns: 6
validate:
draftCountExactly: 0
toolExpect:
requiredToolsUsed:
- get_documentation
forbiddenToolsUsed:
- get_instructions
- write_script
- write_flow
- write_app
- deploy_workspace_item
- delete_workspace_item
skipJudge: true
judgeChecklist:
- consults the Windmill documentation to explain how jobs are dispatched to workers
- answers the conceptual question without writing or editing any item
- does not call get_instructions, since the user is not authoring anything
- id: global-test31-authoring-uses-instructions-not-doc
prompt: |-
Create a draft Bun script at `f/evals/global/celsius_to_fahrenheit`.
It should take a number `celsius` and return the value converted to Fahrenheit.
Leave it as an AI draft only; do not deploy or save it.
runtime:
maxTurns: 8
validate:
draftCountExactly: 1
requiredDrafts:
- type: script
path: f/evals/global/celsius_to_fahrenheit
language: bun
valueIncludes:
- celsius
toolExpect:
requiredToolsUsed:
- get_instructions
- write_script
forbiddenToolsUsed:
# Authoring a self-contained script needs authoring guidance, not a
# product-docs lookup -> get_documentation must not be used here.
- get_documentation
- deploy_workspace_item
- delete_workspace_item
judgeChecklist:
- creates a Bun script draft at f/evals/global/celsius_to_fahrenheit
- the script accepts a numeric celsius input and returns the Fahrenheit conversion
- uses authoring guidance (get_instructions) rather than a product-docs lookup
- the result stays as an AI draft and is not deployed or saved to the workspace
@@ -271,6 +271,7 @@ describe('global AI tools', () => {
expect(names).toContain('test_run_script')
expect(names).toContain('test_run_flow')
expect(names).toContain('test_run_step')
expect(names).toContain('get_documentation')
expect(names).toContain('get_job_logs')
expect(names).toContain('list_runs')
})
@@ -74,6 +74,7 @@ import {
} from '../shared'
import type { ContextElement } from '../context'
import { getDatatableTools } from '../datatableTools'
import { getDocumentationTool } from '../navigator/core'
import { UserDraft, type UserDraftMeta } from '$lib/userDraft.svelte'
import { emptySchema } from '$lib/utils'
import { inferArgs } from '$lib/infer'
@@ -630,6 +631,7 @@ Rules:
- Variable values are never readable. For secrets, create a secret variable and reference it from resources as "$var:path/to/variable".
- Use search_resource_types before write_resource.
- Use get_instructions before writing scripts, flows, resources, or apps. For scripts, pass the target language.
- Use get_documentation to look up Windmill product documentation (features, concepts, how-tos) when the user asks how something works or you need authoritative platform knowledge. This is distinct from get_instructions, which returns authoring guidance for writing a specific item type.
- After creating or editing a script or flow draft, run test_run_script, test_run_flow, or test_run_step with representative args before reporting that it works. These tools prefer local drafts, so testing does not require deployment.
- Use list_runs to find recent runs (optionally filtered by path, creator, label, or status), then get_job_logs with a returned id to inspect a specific run's logs — without starting a new test run.
- When a required decision is ambiguous, use askUserQuestion with two to ten clear proposed answer strings instead of guessing. The user can also type a custom answer when none of the proposed answers fit.
@@ -1469,6 +1471,7 @@ export const globalTools: Tool<{}>[] = [
}
},
createSearchHubScriptsTool(false),
getDocumentationTool,
{
def: createToolDef(
askUserQuestionSchema,