feat(core): Add folder exploration to Instance AI - #37865
Conversation
PR review overviewBased on ownership of the 31 changed files in this PR:
|
Bundle ReportChanges will increase total bundle size by 1.23kB (0.0%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: editor-ui-esmAssets Changed:
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Instance AI Discovery Eval ✅Branch: Eval output |
There was a problem hiding this comment.
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
Instance AI Workflow EvalImportant 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 = 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)
Per-test-case results (8)
Workflow checksScored over 24 successful build(s). N/A = check did not apply to that workflow. Error = check could not be measured (e.g. judge timeout).
All workflow checks (3 failing of 35 checks)
|
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>
4076d65 to
44e544e
Compare
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.workflows(action="list")carriesfolder: { id, name, path }.listacceptsfolderPath,folderId, andrecursive. 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.folderResolutionwith 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.projectId.build-workflowacceptsfolderPathfor new workflows. The adapter resolves it before it writes anything. An unresolved folder throwsFolderResolutionErrorand 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 toworkspace(action="move-workflow-to-folder").110_instance_ai_folder_explorationdecides per user.N8N_INSTANCE_AI_FOLDER_EXPLORATION_ENABLED=trueforce-enables. With the flag off, the list and build schemas keep their previous shape.folder_placement.How to test
The feature needs an instance with
feat:folderslicensed and the flag on.N8N_INSTANCE_AI_FOLDER_EXPLORATION_ENABLED=trueand a license that includes folders. For the create case also configure a sandbox (N8N_INSTANCE_AI_SANDBOX_ENABLED=trueplus the sandbox service).Orbit/Ingest,Orbit/Core,Orbit/Ops,Finance/Reports, andEmpty Shelf. Put two workflows inOrbit/Ingest, one inOrbit/Core, one inOrbit/Ops, one inFinance/Reports. Name them so they share no word with their folder. Add a root workflow namedOrbit Status Pageas a decoy.What's in my Orbit folder? Just list the workflows.Expect the members ofOrbitand its subfolders only. The decoy must not appear.Anything left in my Empty Shelf folder?Expect "empty", not "not found".Show me the workflows in my Zeta folder.Expect a "no such folder" answer with the real folders listed and no name filter.ReportsunderOrbit/Core. Send:List everything in the Reports folder.Expect the agent to ask which one and to quote both paths.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 theOrbitfolders, and the final message to name that folder.Unit tests:
pnpm --filter @n8n/instance-ai testandpnpm --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
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)🤖 PR Summary generated by AI
🤖 Generated with Claude Code