feat(metadata-instance-editor): support for cascade extraction#4616
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
WalkthroughThis PR refactors the metadata instance editor to support custom AI extract agent management by introducing utility helpers for agent ID parsing, new component layers for agent-managed and editable instances, and routing logic that conditionally renders the appropriate UI based on cascade policy type. ChangesCustom AI Extract Agent Management in Metadata Editor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.4.16)src/features/metadata-instance-editor/CustomExtractAgentInstanceBody.jsFile contains syntax errors that prevent linting: Line 14: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 22: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 47: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax. src/features/metadata-instance-editor/EditableInstanceBody.jsFile contains syntax errors that prevent linting: Line 5: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 15: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 22: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 87: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax. src/features/metadata-instance-editor/Instance.jsFile contains syntax errors that prevent linting: Line 10: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 20: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 29: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 49: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 72: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 85: optional parameters are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 85: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 91: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 91: Type an ... [truncated 6347 characters] ... ript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 576: return type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 577: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 582: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 583: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 619: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 629: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/features/metadata-instance-editor/__tests__/CustomExtractAgentInstanceBody.test.js (1)
36-41: ⚡ Quick winAlign the test assertion with the stated “title and description” behavior.
This test currently verifies only the description. Please also assert the notice title (or rename the test) so heading regressions are caught.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/metadata-instance-editor/__tests__/CustomExtractAgentInstanceBody.test.js` around lines 36 - 41, The test "renders the custom extract agent notice with title and description" only asserts NOTICE_DESCRIPTION; update it to also assert the notice title is rendered (or rename the test). Locate the test function (test(...) with renderComponent({ isEditing: true })) and add an assertion for the title—e.g. assert presence of NOTICE_TITLE or use screen.getByRole('heading', { name: NOTICE_TITLE })—and keep the existing assertion that CASCADE_NOTICE is not present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/metadata-instance-editor/CustomExtractAgentInstanceBody.js`:
- Around line 55-59: The ActionableInlineNotice currently only renders the
description; update the component usage in CustomExtractAgentInstanceBody so
that in edit mode it also receives a title prop: pass
title={formatMessage(messages.customExtractAgentNoticeTitle)} (using the
existing formatMessage and messages.customExtractAgentNoticeTitle) when the
editor is in edit mode, ensuring the notice shows “Managed by a Box AI extract
agent” above the description; keep the existing icon, iconAriaLabel and text
props unchanged and only add the title prop for edit-mode rendering.
In `@src/features/metadata-instance-editor/metadataUtil.js`:
- Around line 53-57: isCustomExtractAgentPolicy currently calls
agent.startsWith(...) which can throw if
cascadePolicy.cascadePolicyConfiguration.agent exists but is not a string;
modify isCustomExtractAgentPolicy to guard that agent is a string before calling
startsWith (e.g., check typeof agent === "string" or coerce safely) and keep the
existing conditions on cascadePolicy?.cascadePolicyType ===
CASCADE_POLICY_TYPE_AI_EXTRACT and CUSTOM_EXTRACT_AGENT_CONFIGURATION_PREFIX so
malformed/non-string agent values do not cause render-time crashes.
---
Nitpick comments:
In
`@src/features/metadata-instance-editor/__tests__/CustomExtractAgentInstanceBody.test.js`:
- Around line 36-41: The test "renders the custom extract agent notice with
title and description" only asserts NOTICE_DESCRIPTION; update it to also assert
the notice title is rendered (or rename the test). Locate the test function
(test(...) with renderComponent({ isEditing: true })) and add an assertion for
the title—e.g. assert presence of NOTICE_TITLE or use
screen.getByRole('heading', { name: NOTICE_TITLE })—and keep the existing
assertion that CASCADE_NOTICE is not present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b0239e2f-78a1-47be-8ed5-b08886b8ef0c
⛔ Files ignored due to path filters (2)
i18n/en-US.propertiesis excluded by!i18n/**src/features/metadata-instance-editor/__tests__/__snapshots__/Instance.test.js.snapis excluded by!**/*.snap
📒 Files selected for processing (18)
src/features/metadata-instance-editor/CustomExtractAgentInstanceBody.jssrc/features/metadata-instance-editor/CustomExtractAgentInstanceBody.scsssrc/features/metadata-instance-editor/EditableInstanceBody.jssrc/features/metadata-instance-editor/Instance.jssrc/features/metadata-instance-editor/InstanceCard.jssrc/features/metadata-instance-editor/Instances.jssrc/features/metadata-instance-editor/MetadataInstanceEditor.jssrc/features/metadata-instance-editor/__tests__/CustomExtractAgentInstanceBody.test.jssrc/features/metadata-instance-editor/__tests__/EditableInstanceBody.test.jssrc/features/metadata-instance-editor/__tests__/Instance.test.jssrc/features/metadata-instance-editor/__tests__/InstanceCard.test.jssrc/features/metadata-instance-editor/__tests__/Instances.test.jssrc/features/metadata-instance-editor/__tests__/MetadataInstanceEditor.test.jssrc/features/metadata-instance-editor/__tests__/__fixtures__/metadataInstances.jssrc/features/metadata-instance-editor/__tests__/metadataUtil.test.jssrc/features/metadata-instance-editor/constants.jssrc/features/metadata-instance-editor/messages.jssrc/features/metadata-instance-editor/metadataUtil.js
Merge Queue Status
This pull request spent 19 seconds in the queue, including 3 seconds running CI. Required conditions to merge
|
Description
Product scope
When a metadata instance on a folder is managed by a Box AI extract agent (i.e. its
cascadePolicy.cascadePolicyType === ai_extract), the values for that instance are populated and kept in sync by the agent. Editing those values inline in the metadata sidebar would put the form's local state out of sync with what the agent will produce on the next cascade run, so this PR removes the inline-edit affordance for those instances and points users to the right place to make changes — the agent itself.Resulting UX for an extract-managed instance:
ActionableInlineNotice(lock icon) titled "Managed by a Box AI extract agent" with body copy explaining that the instance can't be edited here, plus a primary "Manage agent" button. Clicking it invokes a newonManageExtractAgent(agentId)callback, where the numeric agent id is extracted from the cascade policy'sagentconfiguration value. The host app (EUA) wires this up to navigate to the agent management surface.For all non-extract-managed instances the existing behavior is preserved exactly — same form, same cascade-policy controls, same save/remove footer, same confirm-remove dialog.
Selected approach
Instance.jshad grown into a ~700-line class component that owned both the editor state machine and the entire view tree (collapsible chrome, cascade policy, form, footer, confirm dialog). Rather than add a third rendering branch into that file, this PR splits the presentational layer into three focused components and keepsInstanceas the stateful orchestrator:InstanceCard.jsEditableInstanceBody.jsCascadePolicy+TemplatedInstance/CustomInstance+Footer+ confirm-remove dialog. Pure presentational — every handler and flag is passed in as a prop.ExtractManagedInstanceBody.jscascadePolicyType === ai_extract. Renders the read-only view when collapsed and theActionableInlineNotice+ "Manage agent" button when editing.Instance.jsnow:isEditing,isCascadingEnabled,cascadePolicyConfiguration, etc.) and all the change handlers (onSave,onFieldChange,onCascadeToggle,onAIAgentSelect, …) — unchanged behavior;isExtractManaged = cascadePolicy?.cascadePolicyType === CASCADE_POLICY_TYPE_AI_EXTRACT);InstanceCardand the body to one of the two new components.The new
onManageExtractAgentcallback is added as an optional prop and threadedMetadataInstanceEditor → Instances → Instance → ExtractManagedInstanceBody. When it's not provided (or noagentIdis on the cascade policy), the "Manage agent" button is simply not rendered, so existing consumers are unaffected.Why this split rather than inlining the new branch in
Instance:Instanceno longer mixes "what to show when" with "how to lay out a card / form / notice"; each new file is small, props-only, and unit-testable in isolation (see the new test files).ExtractManagedInstanceBody), which makes future tweaks to that UX — copy, additional CTAs, telemetry tags — a single-file change.connect, no lifecycle), so they avoid the snapshot churn that touchingInstanceitself causes; the bulk of the snapshot diff in this PR comes fromInstance.test.jsre-rendering through the new component tree rather than from semantic changes.What's included
Source
Instance.js— refactor: extract chrome + body, addisExtractManagedbranch, accept newonManageExtractAgentprop.InstanceCard.js— new presentational card.EditableInstanceBody.js— new presentational editable body.ExtractManagedInstanceBody.js+.scss— new presentational managed body.Instances.js,MetadataInstanceEditor.js— forward the new optionalonManageExtractAgentprop.messages.js— 4 new i18n strings (extractManagedTitle,extractManagedDescription,extractManagedManageAgent,extractManagedNoticeIconAriaLabel).i18n/en-US.properties— generated.Tests
EditableInstanceBody.test.js,ExtractManagedInstanceBody.test.js,InstanceCard.test.js, plus a shared__fixtures__/metadataInstances.js.Instance.test.js,Instances.test.js,MetadataInstanceEditor.test.jsto cover the new prop pass-through and the extract-managed branching (view + edit).Instance.test.js.snap— large diff, but purely structural (rendering goes throughInstanceCard/EditableInstanceBodywrappers now).All 650 tests pass; coverage on the touched module is 100% statements / ~85% branches for the new files.
How to test
Semantic release type
PR title:
feat(metadata-instance-editor): support cascade extractionfeat— New feature (extract-agent-managed metadata instances)Summary by CodeRabbit
Release Notes
New Features
Refactor