Skip to content

Commit ab8e9a6

Browse files
authored
fix(core): Reduce planner workflow bias and fix data-table task routing (no-changelog) (#28299)
1 parent 320a4b2 commit ab8e9a6

File tree

7 files changed

+46
-12
lines changed

7 files changed

+46
-12
lines changed

packages/@n8n/instance-ai/src/agent/system-prompt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ You have access to workflow, execution, and credential tools plus a specialized
170170
171171
2. **Multi-step work** (2+ tasks with dependencies — e.g. data table setup + multiple workflows, or parallel builds + consolidation): call \`plan\` immediately — do NOT ask the user questions first. The planner sub-agent discovers credentials, data tables, and best practices, and will ask the user targeted questions itself if needed — it has far better context about what to ask than you do. Only pass \`guidance\` when the conversation is ambiguous about which approach to take — one sentence, not a rewrite. When \`plan\` returns, tasks are already dispatched. Never use \`create-tasks\` for initial planning.
172172
173-
3. **Replanning after failure** (\`<planned-task-follow-up type="replan">\` arrived): call \`create-tasks\` directly — you already have the task context from the failed plan and do not need discovery again.
173+
3. **Replanning after failure** (\`<planned-task-follow-up type="replan">\` arrived): inspect the failure details and remaining work. If only one simple task remains (e.g. a single data table operation or credential setup), handle it directly with the appropriate tool (\`manage-data-tables-with-agent\`, \`delegate\`, \`build-workflow-with-agent\`). Only call \`create-tasks\` when multiple tasks with dependencies still need scheduling.
174174
175175
Use \`update-tasks\` only for lightweight visible checklists that do not need scheduler-driven execution.
176176
@@ -279,7 +279,7 @@ When \`<running-tasks>\` context is present, use it only to reference active tas
279279
280280
When \`<planned-task-follow-up type="synthesize">\` is present, all planned tasks completed successfully. Read the task outcomes and write the final user-facing completion message. Do not create another plan.
281281
282-
When \`<planned-task-follow-up type="replan">\` is present, a planned task failed. Inspect the failure details and either call \`create-tasks\` with a revised remaining task list, or explain the blocker to the user if replanning is not appropriate.
282+
When \`<planned-task-follow-up type="replan">\` is present, a planned task failed. Inspect the failure details and the remaining work. If only one task remains, handle it directly with the appropriate tool rather than creating a new plan. Only call \`create-tasks\` when multiple dependent tasks still need scheduling. If replanning is not appropriate, explain the blocker to the user.
283283
284284
If the user sends a correction while a build is running, call \`correct-background-task\` with the task ID and correction.
285285

packages/@n8n/instance-ai/src/tools/best-practices/guides/data-persistence.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,5 +190,16 @@ Data Tables and other storage nodes return 0 items when:
190190
- A filter/lookup query matches nothing
191191
192192
This silently breaks the downstream chain — all nodes after the empty result are skipped. Always set \`alwaysOutputData: true\` on data-fetching nodes (operation: 'get') when downstream nodes depend on their output.
193+
194+
## Standalone Data Table Operations
195+
196+
Data tables are not only storage for workflows — they can also be managed as standalone resources:
197+
198+
- **Table creation and schema design**: Create tables with specific columns for data organization, even without an associated workflow.
199+
- **Seed data**: Populate tables with initial or sample data as a standalone operation.
200+
- **Schema management**: Add, rename, or remove columns on existing tables.
201+
- **Data cleanup**: Delete rows or entire tables that are no longer needed.
202+
203+
When the user's request is purely about table CRUD (creating tables, inserting rows, modifying schemas, deleting tables) with no automation triggers or schedules, these should be handled as direct data table operations — not wrapped in a workflow.
193204
`;
194205
}

packages/@n8n/instance-ai/src/tools/orchestration/add-plan-item.tool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function createAddPlanItemTool(
6464
description:
6565
'Add a single plan item (data table, workflow, research, or delegate task). ' +
6666
'Call once per item as you design it — each call makes the item visible to the user immediately. ' +
67-
'Emit data tables FIRST, then workflows that depend on them. ' +
67+
'Emit data tables FIRST. Add workflow items only if the request requires automation. ' +
6868
'Set summary and assumptions on your first call.',
6969
inputSchema: addPlanItemInputSchema,
7070
outputSchema: z.object({ result: z.string() }),

packages/@n8n/instance-ai/src/tools/orchestration/blueprint-accumulator.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,27 @@ type BlueprintItem =
4545

4646
/** Format a data table schema as a compact string for builder context. */
4747
export function formatTableSchema(dt: BlueprintDataTableItem): string {
48+
if (!dt.columns || dt.columns.length === 0) return `Table '${dt.name}'`;
4849
const cols = dt.columns.map((c) => `${c.name} (${c.type})`).join(', ');
4950
return `Table '${dt.name}': ${cols}`;
5051
}
5152

5253
function dataTableItemToTask(dt: BlueprintDataTableItem): PlannedTaskInput {
53-
const columnList = dt.columns.map((c) => `${c.name} (${c.type})`).join(', ');
54+
if (dt.columns && dt.columns.length > 0) {
55+
const columnList = dt.columns.map((c) => `${c.name} (${c.type})`).join(', ');
56+
return {
57+
id: dt.id,
58+
title: `Create '${dt.name}' data table`,
59+
kind: 'manage-data-tables',
60+
spec: `Create a data table named '${dt.name}'. Purpose: ${dt.purpose}\nColumns: ${columnList}`,
61+
deps: dt.dependsOn,
62+
};
63+
}
5464
return {
5565
id: dt.id,
56-
title: `Create '${dt.name}' data table`,
66+
title: dt.name,
5767
kind: 'manage-data-tables',
58-
spec: `Create a data table named '${dt.name}'. Purpose: ${dt.purpose}\nColumns: ${columnList}`,
68+
spec: dt.purpose,
5969
deps: dt.dependsOn,
6070
};
6171
}

packages/@n8n/instance-ai/src/tools/orchestration/blueprint.schema.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@ export const blueprintWorkflowItemSchema = z.object({
2525

2626
export const blueprintDataTableItemSchema = z.object({
2727
id: z.string().describe('Stable ID — preserved as task ID'),
28-
name: z.string().describe('Table name'),
29-
purpose: z.string().describe('1 sentence: what this table stores'),
28+
name: z.string().describe('Table name or short task label'),
29+
purpose: z.string().describe('What to do: create with schema, delete, modify, or seed data'),
3030
columns: z
3131
.array(
3232
z.object({
3333
name: z.string(),
3434
type: z.enum(['string', 'number', 'boolean', 'date']),
3535
}),
3636
)
37-
.describe('Column definitions — name and type only'),
37+
.optional()
38+
.describe('Column definitions for table creation — omit for delete/modify operations'),
3839
dependsOn: z.array(z.string()).default([]),
3940
});
4041

packages/@n8n/instance-ai/src/tools/orchestration/data-table-agent.prompt.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ Do NOT produce visible output until the final summary. All reasoning happens int
2929
## Destructive Operations
3030
3131
\`delete-data-table\` and \`delete-data-table-rows\` will trigger a confirmation prompt to the user. The user must approve before the action executes. Do not ask the user to confirm via text — the tool handles it.
32+
33+
## Seed Data
34+
35+
When the task spec includes sample or seed rows to insert, create the table first, then insert the rows using \`insert-data-table-rows\`. Match column names exactly to the schema you just created.
36+
37+
## Scope
38+
39+
Only perform the operations explicitly assigned to you. Your task spec describes exactly what to create, modify, or delete — do nothing beyond that. If the spec mentions context about what other tasks will do (e.g. subsequent steps in a larger plan), ignore those — they are handled separately.
3240
`;

packages/@n8n/instance-ai/src/tools/orchestration/plan-agent-prompt.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ You receive the recent conversation between the user and the orchestrator. Read
2424
- Skip searches for nodes you already know exist (webhooks, schedule triggers, data tables, code, set, filter, etc.)
2525
2626
3. **Build incrementally** — call \`add-plan-item\` for each item:
27-
- Emit data tables FIRST, then workflows that depend on them
27+
- Emit data tables FIRST. If the request also requires automation, add workflow items that depend on them. A plan may consist entirely of data-table items.
2828
- Set \`summary\` and \`assumptions\` on your first call
2929
- Each call makes the item visible to the user immediately
30-
- \`purpose\`: Write a rich, user-focused description of what the workflow does and why. Include key requirements and behaviors from the user's request. 3-5 sentences. Do NOT include node names, parameters, or implementation details — the builder handles that.
30+
- \`purpose\`: Write a rich, user-focused description of what this item delivers and why. Include key requirements and behaviors from the user's request. 3-5 sentences. Do NOT include node names, parameters, or implementation details — the builder handles that.
3131
- \`triggerDescription\`: a few words (e.g. "Webhook POST", "Schedule daily")
3232
- \`dependsOn\`: **CRITICAL** — set dependencies correctly. Data tables before workflows that use them. Workflows that produce data before workflows that consume it. Independent workflows should NOT depend on each other.
3333
- \`columns\`: name and type only — no descriptions
@@ -45,5 +45,9 @@ You receive the recent conversation between the user and the orchestrator. Read
4545
- **Always call \`submit-plan\` after your last \`add-plan-item\`.** Never end without submitting.
4646
- **On rejection, be surgical.** Only change what the user asked for. Do NOT re-add items that are already correct.
4747
- **Dependencies are mandatory.** Every workflow MUST list the data table IDs it reads from or writes to in \`dependsOn\`. If workflow C needs data produced by workflows A and B, it must depend on A and B.
48-
- **No duplicate items.** Each piece of work appears exactly once. Use \`workflow\` kind for workflows, \`data-table\` kind for tables. Only use \`delegate\` kind for tasks that don't fit the other categories.
48+
- **No duplicate items.** Each piece of work appears exactly once. Use \`workflow\` kind for workflows, \`data-table\` kind for ALL data table operations (create, delete, modify, seed). Only use \`delegate\` kind for tasks that don't fit the other categories — never use \`delegate\` for data table operations.
49+
- **Data-table-only plans are valid.** If the request is purely about creating, populating, modifying, or deleting data tables — with no automation triggers, schedules, or integrations — use only \`data-table\` kind items. Do NOT wrap table operations in a \`workflow\` or \`delegate\` item.
50+
- **\`data-table\` kind supports any table operation.** For creation, include \`columns\`. For deletion, modification, or other operations, omit \`columns\` and describe the operation in \`purpose\`.
51+
- **Include seed data instructions in the \`purpose\` field.** When the user wants sample or initial rows, describe them in the data table item's \`purpose\` (e.g. "Seed with 3 rows: ..."). The data-table agent handles insertion.
52+
- **Each item's \`purpose\` must only describe what THAT item does.** Do not reference actions handled by other plan items. Each task is executed by an independent agent that only sees its own spec — cross-task context causes agents to perform work outside their scope.
4953
- Never fabricate node names — if unsure whether a node exists, search first.`;

0 commit comments

Comments
 (0)