Skip to content

feat(core): Add folder exploration to Instance AI - #37865

Open
rmakowiak wants to merge 17 commits into
masterfrom
context-86-improve-folder-exploration-for-aia
Open

feat(core): Add folder exploration to Instance AI#37865
rmakowiak wants to merge 17 commits into
masterfrom
context-86-improve-folder-exploration-for-aia

Conversation

@rmakowiak

@rmakowiak rmakowiak commented Sep 4, 2026

Copy link
Copy Markdown

Summary

Instance AI could not read where a workflow lives. workflows(action="list") filtered on the workflow name only, so a request like "list my Acme folder" became a name filter and returned the wrong set. This PR gives the assistant a real view of folders, behind a rollout flag.

  • Folder attribution. Every row from workflows(action="list") carries folder: { id, name, path }.
  • Folder addressing. list accepts folderPath, folderId, and recursive. The folder resolves strictly: exact path, then folder name, then the last requested segment, then a path suffix on a / boundary. It never matches fuzzily.
  • Loud failure. A folder that does not resolve returns no rows and a folderResolution with the reason (not-found, ambiguous, unsupported, scope-too-wide) and up to 20 real folder paths. The note tells the agent not to substitute a name filter.
  • Bounded scans. One folder query per project, capped at 200 folders and 20 projects. Past the project cap the agent must pass projectId.
  • Folder placement on create. build-workflow accepts folderPath for new workflows. The adapter resolves it before it writes anything. An unresolved folder throws FolderResolutionError and nothing is created, so a workflow never lands at the project root when the user named a folder. The build result reports the folder. On updates the field is rejected and points to workspace(action="move-workflow-to-folder").
  • Rollout. Off by default. PostHog flag 110_instance_ai_folder_exploration decides per user. N8N_INSTANCE_AI_FOLDER_EXPLORATION_ENABLED=true force-enables. With the flag off, the list and build schemas keep their previous shape.
  • Telemetry. Every list call is tracked with the folder scope, the resolution outcome, and the candidate count. The "Builder created workflow" event carries folder_placement.

How to test

The feature needs an instance with feat:folders licensed and the flag on.

  1. Start n8n with N8N_INSTANCE_AI_FOLDER_EXPLORATION_ENABLED=true and a license that includes folders. For the create case also configure a sandbox (N8N_INSTANCE_AI_SANDBOX_ENABLED=true plus the sandbox service).
  2. Create folders Orbit/Ingest, Orbit/Core, Orbit/Ops, Finance/Reports, and Empty Shelf. Put two workflows in Orbit/Ingest, one in Orbit/Core, one in Orbit/Ops, one in Finance/Reports. Name them so they share no word with their folder. Add a root workflow named Orbit Status Page as a decoy.
  3. Open the AI Assistant and send: What's in my Orbit folder? Just list the workflows. Expect the members of Orbit and its subfolders only. The decoy must not appear.
  4. Send: Anything left in my Empty Shelf folder? Expect "empty", not "not found".
  5. Send: Show me the workflows in my Zeta folder. Expect a "no such folder" answer with the real folders listed and no name filter.
  6. Create a second folder named Reports under Orbit/Core. Send: List everything in the Reports folder. Expect the agent to ask which one and to quote both paths.
  7. Send: Create a workflow that posts a daily Slack summary of Orbit alerts. Put it where it belongs. Skip the setup cards. Expect the new workflow inside one of the Orbit folders, and the final message to name that folder.
  8. Restart with the flag off and repeat step 3. Expect the previous behaviour with no folder fields advertised.

Unit tests: pnpm --filter @n8n/instance-ai test and pnpm --filter n8n test src/modules/instance-ai.

Related Linear tickets, Github issues, and Community forum posts

https://linear.app/n8n/issue/CONTEXT-86

Review / Merge checklist

  • I have seen this code, I have run this code, and I take responsibility for this code.
  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with Backport to Beta, Backport to Stable, or Backport to v1 (if the PR is an urgent fix that needs to be backported)

🤖 PR Summary generated by AI

🤖 Generated with Claude Code

cubic-dev-ai[bot]

This comment was marked as outdated.

@n8n-assistant

n8n-assistant Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

PR review overview

Based on ownership of the 31 changed files in this PR:

Ownership Files owned Share Source code Test files Misc
@n8n-io/ai-assistant 24 77% +823 / -73 +1,372 / -4 +32 / -2
@n8n-io/catalysts 5 16% +47 / -0 +1 / -0 +0 / -0
@n8n-io/adore 2 6% +5 / -0 +13 / -0 +0 / -0
Total 31 100% +875 / -73 +1,386 / -4 +32 / -2

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 1.23kB (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
editor-ui-esm 63.32MB 1.23kB (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: editor-ui-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/src-*.js 1.23kB 72.98kB 1.71%
assets/worker-*.js 3.2MB 3.22MB 17352.85% ⚠️
assets/worker-*.js -3.2MB 18.44kB -99.43%

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

@n8n-assistant n8n-assistant Bot added n8n team Authored by the n8n team core Enhancement outside /nodes-base and /editor-ui labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Instance AI Discovery Eval ✅

Branch: context-86-improve-folder-exploration-for-aia · Commit: d3a8e596939d709f52ae81d85bd1aeb4ffdc036f

Eval output
$ tsx evaluations/discovery/cli.ts --trials 3 --fail-on-zero-pass
Running 18 discovery scenario(s) × 3 trial(s) (model: anthropic/claude-sonnet-4-6, concurrency: 3).

▸ config-evals-skill-loading ... (node:4885) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
✓ 3/3 passed (100%)
▸ data-table-natural-list-skill-loading ... ✓ 3/3 passed (100%)
▸ data-table-skill-loading ... ✓ 3/3 passed (100%)
▸ data-table-workflow-skill-loading ... ✓ 3/3 passed (100%)
▸ folder-scoped-workflow-list ... ✓ 2/3 passed (67%)
▸ google-oauth-credential-setup ... ✓ 3/3 passed (100%)
▸ http-node-config-no-browser ... ✓ 3/3 passed (100%)
▸ mcp-broken-connection-reconnect ... ✓ 3/3 passed (100%)
▸ mcp-connect-unconnected-service ... ✓ 2/3 passed (67%)
▸ mcp-declined-tool-call-no-reconnect ... ✓ 3/3 passed (100%)
▸ mcp-no-registry-match ... ✓ 3/3 passed (100%)
▸ mcp-not-offered-for-workflow-build ... ✓ 3/3 passed (100%)
▸ mcp-uses-connected-server-tools ... ✓ 3/3 passed (100%)
▸ oauth-with-computer-use-disabled ... ✓ 3/3 passed (100%)
▸ screenshot-dashboard ... ✓ 3/3 passed (100%)
▸ slack-oauth-credential-setup ... ✓ 3/3 passed (100%)
▸ workflow-builder-no-agent-builder-leak ... ✓ 3/3 passed (100%)
▸ workflow-builder-no-credential-ask ... ✓ 3/3 passed (100%)

=== Summary ===
Scenarios: 18/18 above threshold (67%)
Trials: 52/54 passed (96%)
Total time: 1535.6s

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 9 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would require human review. Adds folder exploration to Instance AI (list scoping and create placement) behind a rollout flag. Core resolution and placement logic is truncated in the diff, so correctness and edge cases cannot be verified.

Re-trigger cubic

@rmakowiak
rmakowiak marked this pull request as ready for review September 4, 2026 14:49
@rmakowiak
rmakowiak requested a review from a team September 4, 2026 14:49
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Instance AI Workflow Eval

Important

This eval does not re-run on new commits. To test your latest push, re-run it against the PR head:

gh workflow run ci-instance-ai-evals.yml -f pr=37865

…or use the Run workflow button and set pr = 37865.

Warning

🟡 All 25 units green over 3 runs, but 1 barely passed (failed most runs) — see Failures below.

Gate: pass@k = 100% (every unit passes at least once across k runs) — 94.7% pass (71/75 trials over 25 units · k=3)

pass@3 100.0% · pass^3 90.5% · LangSmith experiment

Failures (3)

notification-router :: Before building the workflow, the agent established the inco — passed 1/3

The agent asked about destinations but not about the payload field name; it assumed urgency as the field, which the user never described — the user had to correct it in turn 2 to level.

The agent asked only where to route each urgency level, not what the payload field name was; it assumed urgency as the field name and only corrected it to level after the user pointed out the mistake in turn 2.

revises-plan-after-rejection :: When the user rejected the first plan, the agent treated it — passed 2/3

The user never rejected the first plan before it was built; they answered the agent's clarifying questions (schedule frequency, Posted-column approach), after which the agent said 'I'll build this now' and proceeded — there was no rejection that the agent had to decide whether to honour or ignore.

revises-plan-after-rejection :: After the rejection, the agent revised the plan to incorpora — passed 2/3

The user's Turn 2 message was a change request after the workflow was already built, not a pre-build plan rejection; the agent incorporated both changes (Status=Urgent filter, #urgent-alerts channel) but never presented a revised plan for approval — it immediately updated and rebuilt the workflow without any approval gate.

Per-test-case results (8)
Workflow Status pass@3 pass^3
airtable-split-to-slack 3/3 100% 100%
notification-router 3/3 100% 84%
refuses-deprecated-chat-model 3/3 100% 100%
rest-api-data-pipeline 3/3 100% 100%
revises-plan-after-rejection 3/3 100% 72%
telegram-chatbot-memory-session 3/3 100% 100%
weather-alert 3/3 100% 100%
workflow-data-table 3/3 100% 100%

Workflow checks

Scored over 24 successful build(s). N/A = check did not apply to that workflow. Error = check could not be measured (e.g. judge timeout).

Dimension Check Kind Pass Fail N/A Error Pass rate
parameter_correctness correct_node_operations llm 21 3 0 0 88%
intent_match fulfills_user_request llm 21 3 0 0 88%
communication response_describes_changes_accurately llm 23 1 0 0 96%
All workflow checks (3 failing of 35 checks)
Dimension Check Kind Pass Fail N/A Error Pass rate
structure has_nodes deterministic 24 0 0 0 100%
structure has_start_node deterministic 24 0 0 0 100%
structure has_trigger deterministic 24 0 0 0 100%
structure no_disabled_nodes deterministic 24 0 0 0 100%
connection_topology all_nodes_connected deterministic 24 0 0 0 100%
connection_topology error_routes_consistent deterministic 24 0 0 0 100%
connection_topology handles_multiple_items llm 24 0 0 0 100%
connection_topology no_unreachable_nodes deterministic 24 0 0 0 100%
connection_topology switch_fallback_output_enabled deterministic 3 0 21 0 100%
parameter_correctness correct_node_operations llm 21 3 0 0 88%
parameter_correctness expressions_reference_existing_nodes deterministic 6 0 18 0 100%
parameter_correctness google_sheets_rlc_default_mode deterministic 3 0 21 0 100%
parameter_correctness http_generic_auth_type_matches_prompt deterministic 0 0 24 0
parameter_correctness item_flow_independent_source_execute_once deterministic 0 0 24 0
parameter_correctness item_flow_paired_item_references deterministic 0 0 24 0
parameter_correctness no_empty_set_nodes deterministic 1 0 23 0 100%
parameter_correctness no_invalid_from_ai deterministic 0 0 24 0
parameter_correctness valid_data_flow llm 24 0 0 0 100%
parameter_correctness valid_field_references deterministic 21 0 3 0 100%
parameter_correctness valid_node_config deterministic 24 0 0 0 100%
intent_match fulfills_user_request llm 21 3 0 0 88%
communication response_describes_changes_accurately llm 23 1 0 0 96%
ai_nodes agent_has_dynamic_prompt deterministic 6 0 18 0 100%
ai_nodes agent_has_language_model deterministic 6 0 18 0 100%
ai_nodes memory_properly_connected deterministic 6 0 18 0 100%
ai_nodes memory_session_key_expression deterministic 6 0 18 0 100%
ai_nodes tools_have_parameters deterministic 0 0 24 0
ai_nodes vector_store_has_embeddings deterministic 0 0 24 0
nodes_craftsmanship code_node_no_http_requests deterministic 5 0 19 0 100%
nodes_craftsmanship descriptive_node_names llm 24 0 0 0 100%
nodes_craftsmanship no_unnecessary_code_nodes llm 24 0 0 0 100%
efficiency no_excessive_build_failures deterministic 24 0 0 0 100%
security inbound_trigger_auth_defaults deterministic 6 0 18 0 100%
security no_hardcoded_credentials deterministic 1 0 23 0 100%
security secrets_use_credentials_not_parameters deterministic 9 0 15 0 100%

@rmakowiak
rmakowiak enabled auto-merge September 4, 2026 18:05
rmakowiak and others added 17 commits September 5, 2026 09:46
Add the PostHog flag constant, the config force-on override, and the
override layer entry. Nothing reads the flag yet.
Add folder attribution on rows, folder scoping options on list(), and a
folderResolution result for an unresolved folder. Add the per-run
folderExplorationEnabled gate to the tool context.
Advertise folderPath, folderId and recursive on workflows(list) only while
folder exploration is on for the run. The flag-off schema keeps the pre-feature
schema so an A/B has a clean control.
…t action

Put the folder note first, list the real folders, and forbid the name-filter
fallback by name.
Resolve a requested folder in stages: exact path, exact name, last
segment, boundary suffix. Never fuzzy. Report ambiguous and not-found
with the real folders listed.
Read the parent folder the repository already joins and add a
root-relative path, behind the per-run folder-exploration gate. Add the
fail-closed gate resolver on the adapter.
Resolve folderPath or folderId against the folders the user may list,
expand the subtree, and pass the ids as a narrowing filter. An
unresolved folder returns no rows and a folderResolution.
…n is empty

The repository drops an empty parentFolderIds filter, so an expansion
with no ids listed the whole scope. Report a not-found resolution
instead. Enter resolution for any defined folderPath, so an empty path
also reports a miss.
Await isFolderExplorationEnabled next to the existing MCP-connections
gate, and pass it into createContext. A run resolves the flag once, so
it stays on one arm even if PostHog flips mid-run.
…tcome

Emit one registered event per list call in both rollout arms. Carry the
folder scope kind, resolution outcome and counts. Carry no folder names.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…tabase

Folder scoping runs real SQL: the parent-folder join, the recursive path
CTE and the subtree expansion. A mocked repository cannot see those
constraints. This suite creates real folders and workflows on SQLite and
runs the adapter end to end.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add a folderExploration instanceState knob to the discovery harness, and
make the stub workflow list() return a realistic folderResolution miss
when a folder is requested. Use both to add a discovery case that asserts
the agent reaches for folderPath on workflows(list) when the user names a
folder, instead of a query name filter or a build.
…ot resolve

Forward `folderPath` and `folderId` on presence, not on truthiness. An empty
folder name is still a folder request. Before, it returned the unfiltered
inventory with no `folderResolution`.

Add the `scope-too-wide` failure reason. The adapter uses it when a listing
spans more projects than the folder scan covers. The note tells the agent to
pass `projectId` and retry.

Tell the agent what identical ambiguous paths mean: the same folder path exists
in more than one project, so `projectId` picks one. Also say that `folderId`
wins when both fields are given.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stop the folder scan before it fans out. An instance-wide folder request runs
one folder query per accessible project, so a caller with access to more than
20 projects now gets the `scope-too-wide` failure and is asked to name a
project. No query runs in that case.

Read the folder paths in chunks of 500 ids. `getFolderPathsToRoot` binds one
parameter per id and does not chunk, and SQLite allows 999 parameters.

Report `unsupported` when the subtree finder is missing. Before, the listing
silently read only the folder's top level.

Use `folderId` as the reported `requested` value and as the telemetry scope
when both fields are given, because the resolver prefers it.

Cover the folder-list denial path with a test: a project the user cannot list
folders in is skipped, and its folder names are never offered as candidates.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`build-workflow` accepts an optional `folderPath` for new workflows. The
adapter resolves it with the strict folder resolver before it writes
anything. An unresolved, ambiguous, or unlicensed folder throws
`FolderResolutionError`, so a workflow is never left at the project root
when the user named a folder. The build result carries the folder the
workflow landed in. The field is advertised only while folder exploration
is on, and it is rejected on updates, which point to the move action.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Look folders up by id or by the requested leaf name before falling back
  to the capped scan, so a valid folder past the scan limit still resolves.
- Gate folder attribution on the folders licence as well as the flag;
  resolution stays on the flag alone so an unlicensed instance answers a
  folder request loudly instead of ignoring it.
- Treat an explicit empty folderId as present, so it cannot fall through to
  the path.
- Carry the no-query-fallback warning in every failure branch.
- Advertise the build-workflow folder output only while the flag is on.
- Make the eval harness stub miss on folderId requests too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@rmakowiak
rmakowiak force-pushed the context-86-improve-folder-exploration-for-aia branch from 4076d65 to 44e544e Compare September 5, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed core Enhancement outside /nodes-base and /editor-ui n8n team Authored by the n8n team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant