From 7b68f584a7640d2689c321c7e80e302ce75e758b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel=20Moreno?= <1411774+miguelsaddress@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:10:05 +0200 Subject: [PATCH] feat(core): Expose 104_canvas_aia_node_context flag with env override (no-changelog) (#35986) Co-authored-by: Claude Sonnet 5 --- packages/@n8n/api-types/src/index.ts | 1 + .../src/schemas/instance-ai.schema.ts | 7 ++- .../config/src/configs/instance-ai.config.ts | 9 ++++ packages/@n8n/config/test/config.test.ts | 1 + .../cli/src/posthog/__tests__/posthog.test.ts | 52 +++++++++++++++++++ packages/cli/src/posthog/index.ts | 9 ++++ 6 files changed, 77 insertions(+), 2 deletions(-) diff --git a/packages/@n8n/api-types/src/index.ts b/packages/@n8n/api-types/src/index.ts index a68d56e483c..97ce3a0dd2b 100644 --- a/packages/@n8n/api-types/src/index.ts +++ b/packages/@n8n/api-types/src/index.ts @@ -334,6 +334,7 @@ export { CONFIG_EVALUATIONS_ENABLED_VARIANT, INSTANCE_AI_MCP_CONNECTIONS_FLAG, INSTANCE_AI_MCP_CONNECTIONS_ENABLED_VARIANT, + CANVAS_NODE_CONTEXT_FLAG, domainAccessActionSchema, domainAccessMetaSchema, webSearchMetaSchema, diff --git a/packages/@n8n/api-types/src/schemas/instance-ai.schema.ts b/packages/@n8n/api-types/src/schemas/instance-ai.schema.ts index d092e7613d7..2ff6b38192d 100644 --- a/packages/@n8n/api-types/src/schemas/instance-ai.schema.ts +++ b/packages/@n8n/api-types/src/schemas/instance-ai.schema.ts @@ -1,10 +1,10 @@ import { z } from 'zod'; +import type { McpRegistryServerIconResponse } from './mcp-registry.schema'; +import { TimeZoneSchema } from './timezone.schema'; import { AgentJsonConfigSchema } from '../agents/agent-json-config.schema'; import { agentSkillSchema } from '../agents/agent-skill.schema'; import { Z } from '../zod-class'; -import type { McpRegistryServerIconResponse } from './mcp-registry.schema'; -import { TimeZoneSchema } from './timezone.schema'; // --------------------------------------------------------------------------- // Credits @@ -1790,6 +1790,9 @@ export const INSTANCE_AI_MCP_CONNECTIONS_FLAG = '089_instance_ai_mcp_connections export const INSTANCE_AI_MCP_CONNECTIONS_ENABLED_VARIANT = 'variant'; +/** Enables adding selected canvas nodes as chat context in the AI Assistant */ +export const CANVAS_NODE_CONTEXT_FLAG = '104_canvas_aia_node_context'; + /** * Records a credential field that was rewritten (e.g. routed to the eval wire * server) during evaluation. Populated for every AI root the server intercepts; diff --git a/packages/@n8n/config/src/configs/instance-ai.config.ts b/packages/@n8n/config/src/configs/instance-ai.config.ts index 6f539e5ebfe..6ded1f197b0 100644 --- a/packages/@n8n/config/src/configs/instance-ai.config.ts +++ b/packages/@n8n/config/src/configs/instance-ai.config.ts @@ -193,4 +193,13 @@ export class InstanceAiConfig { */ @Env('N8N_INSTANCE_AI_MCP_CONNECTIONS_ENABLED') mcpConnectionsEnabled: boolean = false; + + /** + * Force-enable canvas-selected-nodes chat context in Instance AI. + * Acts as an operator-level override of the PostHog rollout flag + * (`104_canvas_aia_node_context`). Cannot force-disable: setting this to + * `false` falls back to PostHog. + */ + @Env('N8N_INSTANCE_AI_NODE_CONTEXT_ENABLED') + canvasNodeContextEnabled: boolean = false; } diff --git a/packages/@n8n/config/test/config.test.ts b/packages/@n8n/config/test/config.test.ts index fdb4e1470d6..14337b2b95b 100644 --- a/packages/@n8n/config/test/config.test.ts +++ b/packages/@n8n/config/test/config.test.ts @@ -359,6 +359,7 @@ describe('GlobalConfig', () => { thinkingEnabled: true, durableLog: true, mcpConnectionsEnabled: false, + canvasNodeContextEnabled: false, }, queue: { health: { diff --git a/packages/cli/src/posthog/__tests__/posthog.test.ts b/packages/cli/src/posthog/__tests__/posthog.test.ts index 917a4dc8e08..ace8d05c35d 100644 --- a/packages/cli/src/posthog/__tests__/posthog.test.ts +++ b/packages/cli/src/posthog/__tests__/posthog.test.ts @@ -226,6 +226,7 @@ describe('PostHog', () => { globalConfig.evaluation.configEvalsEnabled = false; globalConfig.evaluation.agentEvalsEnabled = false; globalConfig.instanceAi.mcpConnectionsEnabled = false; + globalConfig.instanceAi.canvasNodeContextEnabled = false; }); it('force-enables the eval-collections flag when N8N_EVAL_COLLECTIONS_ENABLED is set', async () => { @@ -312,6 +313,57 @@ describe('PostHog', () => { expect(flags).toEqual({ '101_agent_evals': true }); }); + + it('force-enables the canvas-node-context flag when N8N_INSTANCE_AI_NODE_CONTEXT_ENABLED is set', async () => { + (PostHog.prototype.evaluateFlags as Mock).mockResolvedValue(mockEvaluatedFlags({})); + + globalConfig.instanceAi.canvasNodeContextEnabled = true; + + const ph = new PostHogClient(instanceSettings, globalConfig); + await ph.init(); + + const flags = await ph.getFeatureFlags({ id: userId, createdAt }); + + expect(flags).toMatchObject({ '104_canvas_aia_node_context': true }); + }); + + it('leaves the canvas-node-context flag untouched when the override is off', async () => { + (PostHog.prototype.evaluateFlags as Mock).mockResolvedValue( + mockEvaluatedFlags({ '104_canvas_aia_node_context': true }), + ); + + globalConfig.instanceAi.canvasNodeContextEnabled = false; + + const ph = new PostHogClient(instanceSettings, globalConfig); + await ph.init(); + + const flags = await ph.getFeatureFlags({ id: userId, createdAt }); + + expect(flags).toEqual({ '104_canvas_aia_node_context': true }); + }); + + it('applies all env overrides independently when several are set at once', async () => { + (PostHog.prototype.evaluateFlags as Mock).mockResolvedValue(mockEvaluatedFlags({})); + + globalConfig.evaluation.collectionsEnabled = true; + globalConfig.evaluation.configEvalsEnabled = true; + globalConfig.evaluation.agentEvalsEnabled = true; + globalConfig.instanceAi.mcpConnectionsEnabled = true; + globalConfig.instanceAi.canvasNodeContextEnabled = true; + + const ph = new PostHogClient(instanceSettings, globalConfig); + await ph.init(); + + const flags = await ph.getFeatureFlags({ id: userId, createdAt }); + + expect(flags).toEqual({ + '084_eval_collections': true, + '088_config_evaluations': 'variant', + '101_agent_evals': true, + '089_instance_ai_mcp_connections': 'variant', + '104_canvas_aia_node_context': true, + }); + }); }); }); diff --git a/packages/cli/src/posthog/index.ts b/packages/cli/src/posthog/index.ts index 691ba80c463..e2fd1c18527 100644 --- a/packages/cli/src/posthog/index.ts +++ b/packages/cli/src/posthog/index.ts @@ -1,5 +1,6 @@ import { AGENT_EVALS_FLAG, + CANVAS_NODE_CONTEXT_FLAG, CONFIG_EVALUATIONS_ENABLED_VARIANT, CONFIG_EVALUATIONS_FLAG, EVAL_COLLECTIONS_FLAG, @@ -199,17 +200,25 @@ export class PostHogClient { if (this.globalConfig.evaluation.collectionsEnabled) { overrides[EVAL_COLLECTIONS_FLAG] = true; } + // `088_config_evaluations` is multivariate — the enabled arm is the // `variant` string, not a boolean (`isConfigEvalsEnabled` checks for it). if (this.globalConfig.evaluation.configEvalsEnabled) { overrides[CONFIG_EVALUATIONS_FLAG] = CONFIG_EVALUATIONS_ENABLED_VARIANT; } + if (this.globalConfig.evaluation.agentEvalsEnabled) { overrides[AGENT_EVALS_FLAG] = true; } + if (this.globalConfig.instanceAi.mcpConnectionsEnabled) { overrides[INSTANCE_AI_MCP_CONNECTIONS_FLAG] = INSTANCE_AI_MCP_CONNECTIONS_ENABLED_VARIANT; } + + if (this.globalConfig.instanceAi.canvasNodeContextEnabled) { + overrides[CANVAS_NODE_CONTEXT_FLAG] = true; + } + return Object.keys(overrides).length === 0 ? flags : { ...flags, ...overrides }; } }