mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-21 16:03:26 +00:00
* feat: dynamic ai agent toolsets, and memory as a step input Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: address review round 1 on dynamic ai agent toolsets Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: tag enabled_tools and drop the memory step input Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: let an mcp server entry be named by the path the roster shows Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep $res: out of the tool names the enabled tools picker offers Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: name an mcp server by its bare path on the one side that can hold it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: count the enabled tool names that matched nothing instead of logging them Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: narrow an agent's roster in one pass, by whole entries Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin that an mcp summary is rejected against a name that is not Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: regenerate the copilot flow schema after the merge Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: shorten the enabled tools list hint Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: take enabled_tools back to a plain list of tool names Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: keep the enabled tools add-menu hint describing the unset field Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: name a websearch tool that carries no summary of its own Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: reserve the name web search is enabled by so no tool can share it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: spell the reserved web search name with a hyphen Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: reserve __wm_web_search as the name web search is enabled by Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: advance ee-repo-ref past the git sync ci check work Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: shorten the enabled tools description the run form shows Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to e4c1b794d6c5e6e390987341b2840587bbb40348 This commit updates the EE repository reference after PR #785 was merged in windmill-ee-private. Previous ee-repo-ref: af668462f0f06b02a5f4e0c22e6156858487a518 New ee-repo-ref: e4c1b794d6c5e6e390987341b2840587bbb40348 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
53 lines
2.3 KiB
TypeScript
53 lines
2.3 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
|
|
// `agentToolUtils` reaches the copilot bundle, and Monaco's CSS with it, through this one import.
|
|
// Only `createAiAgentTool` reads it, and nothing below does.
|
|
vi.mock('../aiProviderStorage', () => ({ loadStoredConfig: () => undefined }))
|
|
|
|
import { getToolNameError, toolEnabledName, WEBSEARCH_ENABLED_NAME } from './agentToolUtils'
|
|
|
|
/**
|
|
* The names this returns are the ones `enabled_tools` holds and `tool_enabled_name` in
|
|
* `ai_executor.rs` matches against, so the two have to agree: a name only one side produces
|
|
* silently drops the tool from every run that narrows.
|
|
*/
|
|
describe('toolEnabledName', () => {
|
|
it('names a flow module tool by the name the model is shown', () => {
|
|
expect(
|
|
toolEnabledName({ id: 'a', summary: 'get_user', value: { tool_type: 'flowmodule' } } as any)
|
|
).toBe('get_user')
|
|
})
|
|
|
|
it('names an MCP server by its bare path, never the summary two servers may share', () => {
|
|
// `$res:` and all is how the roster stores it, but a name carrying that prefix is resolved to
|
|
// the resource itself before the worker sees it, so the list can only hold the bare path.
|
|
expect(
|
|
toolEnabledName({
|
|
id: 'm',
|
|
summary: 'github',
|
|
value: { tool_type: 'mcp', resource_path: '$res:u/admin/gh' }
|
|
} as any)
|
|
).toBe('u/admin/gh')
|
|
})
|
|
|
|
it('names web search by a reserved name, whatever label it carries', () => {
|
|
// It reaches the model as a provider capability rather than a tool, so the editor's label is
|
|
// not a name: something else in the roster could carry it and be switched on with it.
|
|
expect(toolEnabledName({ id: 'w', value: { tool_type: 'websearch' } } as any)).toBe(
|
|
WEBSEARCH_ENABLED_NAME
|
|
)
|
|
expect(
|
|
toolEnabledName({ id: 'w', summary: 'Web Search', value: { tool_type: 'websearch' } } as any)
|
|
).toBe(WEBSEARCH_ENABLED_NAME)
|
|
})
|
|
|
|
it('reserves that name against every other kind', () => {
|
|
// A flow module tool cannot be called it, so enabling a tool never enables web search beside
|
|
// it. Nothing about the name itself stops that — it is an ordinary identifier — so the rule
|
|
// is `getToolNameError` refusing it, as `flow_module_tool_name` does on the worker.
|
|
expect(getToolNameError(WEBSEARCH_ENABLED_NAME)).toBe(
|
|
`'${WEBSEARCH_ENABLED_NAME}' is a reserved name`
|
|
)
|
|
})
|
|
})
|