diff --git a/packages/@n8n/instance-ai/skills/intent-recognition/SKILL.md b/packages/@n8n/instance-ai/skills/intent-recognition/SKILL.md index a317794e301..286d96327e6 100644 --- a/packages/@n8n/instance-ai/skills/intent-recognition/SKILL.md +++ b/packages/@n8n/instance-ai/skills/intent-recognition/SKILL.md @@ -102,6 +102,16 @@ be a direct agent tool or a workflow tool: reusable, manually callable, or usable outside the agent. Build the workflow first, pass it to `build-agent` via `workflowContext`, and set `embeds_other: true`. +- Create required **data tables** via `data-table-manager` → `data-tables` + before `build-agent` when the agent will store or query tabular data — the + builder cannot create tables. +- Before the first `build-agent` call, create every prerequisite the builder + cannot: required data tables and any workflow tools the agent will invoke. + Pass built workflows in `workflowContext` and list every prerequisite + name/schema in `message`. Then let the builder gather remaining agent-specific + requirements (model, credentials, integrations). +- If a `builderReply` lists missing workflows or tables, create them and call + `build-agent` again — never ask the user to create them manually. Count the nodes required inside one tool invocation, not the total number of tools on the agent. For example, looking up and inserting Data Table rows are diff --git a/packages/@n8n/instance-ai/src/skills/__tests__/runtime-skills.test.ts b/packages/@n8n/instance-ai/src/skills/__tests__/runtime-skills.test.ts index e495643e5fd..9cf5b3e8cf5 100644 --- a/packages/@n8n/instance-ai/src/skills/__tests__/runtime-skills.test.ts +++ b/packages/@n8n/instance-ai/src/skills/__tests__/runtime-skills.test.ts @@ -185,6 +185,18 @@ describe('Instance AI runtime skills', () => { ).toHaveLength(1); }); + it('requires agent prerequisites before build-agent and retries when the builder reports missing assets', () => { + const skill = readFileSync( + join(INSTANCE_AI_SKILLS_DIR, 'intent-recognition', 'SKILL.md'), + 'utf-8', + ); + + expect(skill).toContain('Before the first `build-agent` call, create every prerequisite'); + expect(skill).toContain('builder cannot create tables'); + expect(skill).toContain('If a `builderReply` lists missing workflows or tables'); + expect(skill).toContain('never ask the user to create them manually'); + }); + it('loads the bundled Computer Use credential setup skill', async () => { const source = loadInstanceAiRuntimeSkillSource(); const skill = source.registry.skills.find( diff --git a/packages/cli/src/modules/agents/__tests__/instance-ai-builder-delegate.adapter.test.ts b/packages/cli/src/modules/agents/__tests__/instance-ai-builder-delegate.adapter.test.ts index d08394d9c53..79d78aa0a3e 100644 --- a/packages/cli/src/modules/agents/__tests__/instance-ai-builder-delegate.adapter.test.ts +++ b/packages/cli/src/modules/agents/__tests__/instance-ai-builder-delegate.adapter.test.ts @@ -483,3 +483,15 @@ describe('InstanceAiBuilderDelegateAdapterService', () => { }); }); }); + +describe('INSTANCE_AI_BUILDER_ADDENDUM', () => { + it('tells the builder the orchestrator can create workflows and data tables', () => { + expect(INSTANCE_AI_BUILDER_ADDENDUM).toContain( + 'The Instance AI orchestrator can create workflows and data tables', + ); + expect(INSTANCE_AI_BUILDER_ADDENDUM).toContain('never ask the user to create them manually'); + expect(INSTANCE_AI_BUILDER_ADDENDUM).toContain( + 'the orchestrator will provision them and call you again', + ); + }); +}); diff --git a/packages/cli/src/modules/agents/builder/__tests__/agents-builder-model-recommendations.test.ts b/packages/cli/src/modules/agents/builder/__tests__/agents-builder-model-recommendations.test.ts index e5887b08422..3cde222947b 100644 --- a/packages/cli/src/modules/agents/builder/__tests__/agents-builder-model-recommendations.test.ts +++ b/packages/cli/src/modules/agents/builder/__tests__/agents-builder-model-recommendations.test.ts @@ -1,7 +1,7 @@ import type { ProviderCatalog } from '@n8n/agents'; import { buildModelRecommendationsSection } from '../agents-builder-model-recommendations'; -import { buildBuilderPrompt } from '../agents-builder-prompts'; +import { PREREQUISITES_SECTION, buildBuilderPrompt } from '../agents-builder-prompts'; import { getBuilderRuntimeSkills } from '../skills'; const catalog: ProviderCatalog = { @@ -110,6 +110,12 @@ describe('builder model recommendations', () => { const prompt = buildPrompt(null); expect(prompt).toContain('## Config Mutation Guidance'); + expect(prompt).toContain('## Prerequisites you cannot create'); + expect(PREREQUISITES_SECTION).toContain('cannot create n8n workflows or data tables'); + expect(PREREQUISITES_SECTION).toContain('Do not ask the user to create them in this chat'); + expect(prompt.indexOf('## Prerequisites you cannot create')).toBeLessThan( + prompt.indexOf('## When To Build vs When To Converse'), + ); expect(prompt).toContain('## LLM Selection Guidance'); expect(prompt).toContain('## Memory Guidance'); expect(prompt).toContain('## Tool Guidance'); diff --git a/packages/cli/src/modules/agents/builder/agents-builder-prompts.ts b/packages/cli/src/modules/agents/builder/agents-builder-prompts.ts index 2caf355e740..de1bfd53f36 100644 --- a/packages/cli/src/modules/agents/builder/agents-builder-prompts.ts +++ b/packages/cli/src/modules/agents/builder/agents-builder-prompts.ts @@ -12,6 +12,13 @@ The target agent is the AI agent you are configuring for the user. Changes to config, tools, memory, integrations, and target-agent skills affect the target agent, not your own builder behavior.`; +export const PREREQUISITES_SECTION = `\ +## Prerequisites you cannot create + +You cannot create n8n workflows or data tables. Attach existing workflows only via \`list_workflows\` and \`{ "type": "workflow", "workflow": "" }\`. + +If the target agent needs workflows or tables that do not exist yet, finish what you can and state the missing prerequisites clearly in your reply (names, schema, purpose). Do not ask the user to create them in this chat.`; + export function getConversationModeSection(agentPreviewPath: string): string { return `\ ## When To Build vs When To Converse @@ -279,6 +286,7 @@ export function buildBuilderPrompt(ctx: BuilderPromptContext): string { const sections = [ 'You are an expert agent builder. You help users create and configure AI agents by writing raw JSON configuration and building custom tools.', TARGET_AGENT_SECTION, + PREREQUISITES_SECTION, getConversationModeSection(agentPreviewPath), getConfigMutationPrompt(), getLlmSelectionPrompt(modelRecommendationsSection), diff --git a/packages/cli/src/modules/agents/instance-ai-builder-delegate.adapter.ts b/packages/cli/src/modules/agents/instance-ai-builder-delegate.adapter.ts index 79e6085bda3..3b1ba1a74d2 100644 --- a/packages/cli/src/modules/agents/instance-ai-builder-delegate.adapter.ts +++ b/packages/cli/src/modules/agents/instance-ai-builder-delegate.adapter.ts @@ -26,7 +26,9 @@ You are running as a sub-agent inside n8n's instance AI chat; the user sees your Preview links work in this chat. When the target agent is ready to try — after a successful build, or when the user asks to test/chat/preview — include a markdown Preview link using the exact relative path from "When To Build vs When To Converse" (form: \`[Preview]()\`). Do not invent absolute URLs. Do not omit the link and describe the path in plain text instead. -You can publish and unpublish the target agent with \`publish_agent\` and \`unpublish_agent\`. Never tell the user to open the agent editor and click Publish.`; +You can publish and unpublish the target agent with \`publish_agent\` and \`unpublish_agent\`. Never tell the user to open the agent editor and click Publish. + +The Instance AI orchestrator can create workflows and data tables — never ask the user to create them manually. State missing prerequisites in your reply; the orchestrator will provision them and call you again.`; function isTextDeltaChunk( chunk: StreamChunk,