mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-18 08:03:11 +00:00
feat(ai-chat): wire llms.txt docs lookup tools into global chat mode
Add list_docs_pages/read_docs_page to globalTools and a docs system-prompt section so the workspace assistant can answer product questions from windmill.dev docs and cite canonical URLs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2cbc854577
commit
9e456d053e
@@ -870,3 +870,27 @@
|
||||
judgeChecklist:
|
||||
- fetches the logs for the requested job id
|
||||
- explains the failure from the returned logs (connection refused to the upstream API)
|
||||
|
||||
- id: global-test29-docs-lookup-scheduling
|
||||
prompt: |-
|
||||
How do I schedule a script to run every Monday at 9am in Windmill?
|
||||
runtime:
|
||||
maxTurns: 6
|
||||
validate:
|
||||
draftCountExactly: 0
|
||||
toolExpect:
|
||||
requiredToolsUsed:
|
||||
- list_docs_pages
|
||||
- read_docs_page
|
||||
forbiddenToolsUsed:
|
||||
- deploy_workspace_item
|
||||
- delete_workspace_item
|
||||
- write_script
|
||||
# Answering a product-docs question produces no draft, so the global judge
|
||||
# (which only sees the drafts artifact) would score it empty — validate the
|
||||
# docs-lookup contract via tool use: browse the index first, then read a page.
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- lists the documentation pages before reading one
|
||||
- reads the scheduling documentation page rather than answering from memory
|
||||
- cites the canonical windmill.dev/docs scheduling URL in the answer
|
||||
|
||||
@@ -2020,6 +2020,25 @@ describe('session-only preview tools gating', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('documentation lookup tools', () => {
|
||||
it('exposes list_docs_pages and read_docs_page in both the session and non-session tool sets', () => {
|
||||
// The docs tools are read-only references, not session-preview tools, so
|
||||
// they must be present regardless of `sessionPreview`.
|
||||
for (const sessionPreview of [false, true]) {
|
||||
const names = globalToolsFor({ sessionPreview }).map((t) => t.def.function.name)
|
||||
expect(names).toContain('list_docs_pages')
|
||||
expect(names).toContain('read_docs_page')
|
||||
}
|
||||
})
|
||||
|
||||
it('instructs the model to look up product docs and cite the Source page URL', () => {
|
||||
const content = prepareGlobalSystemMessage().content as string
|
||||
expect(content).toContain('list_docs_pages')
|
||||
expect(content).toContain('read_docs_page')
|
||||
expect(content).toContain('Source page')
|
||||
})
|
||||
})
|
||||
|
||||
describe('prepareGlobalUserMessage', () => {
|
||||
it('injects the active editor reference without contents', () => {
|
||||
__resetUserDraftForTesting()
|
||||
|
||||
@@ -74,6 +74,7 @@ import {
|
||||
} from '../shared'
|
||||
import type { ContextElement } from '../context'
|
||||
import { getDatatableTools } from '../datatableTools'
|
||||
import { listDocsPagesTool, readDocsPageTool } from '../docs/core'
|
||||
import { UserDraft, type UserDraftMeta } from '$lib/userDraft.svelte'
|
||||
import { emptySchema } from '$lib/utils'
|
||||
import { inferArgs } from '$lib/infer'
|
||||
@@ -639,6 +640,12 @@ Rules:
|
||||
: ''
|
||||
}
|
||||
|
||||
Documentation:
|
||||
- To answer questions about Windmill product features, concepts, or syntax, look them up in the official docs with list_docs_pages and read_docs_page rather than relying on memory.
|
||||
- Call list_docs_pages FIRST to see the full index of documentation pages with their titles, URLs and descriptions. Then call read_docs_page on the 1 to 3 most relevant pages. If read_docs_page returns a list of section headings instead of the full page, call it again with the same path and a \`section\` argument to read the relevant section.
|
||||
- Base documentation answers ONLY on what you read. Do not invent features, flags, syntax, or behavior you did not see in the docs.
|
||||
- When you cite a docs page, use the exact "Source page" URL printed at the top of each read_docs_page result — never reconstruct a URL from a link inside the page body. If the docs do not cover the question, say so rather than inventing an answer.
|
||||
|
||||
Flows:
|
||||
- read_workspace_item returns compact flow JSON. Inline script bodies appear as "inline_script.<moduleId>".
|
||||
- Use read_flow_module_code and set_flow_module_code for inline script bodies.
|
||||
@@ -1469,6 +1476,8 @@ export const globalTools: Tool<{}>[] = [
|
||||
}
|
||||
},
|
||||
createSearchHubScriptsTool(false),
|
||||
listDocsPagesTool,
|
||||
readDocsPageTool,
|
||||
{
|
||||
def: createToolDef(
|
||||
askUserQuestionSchema,
|
||||
|
||||
Reference in New Issue
Block a user