Skip to content

Add Pluggable Capability to the AI Workspace UI - #3200

Merged
lasanthaS merged 2 commits into
wso2:mainfrom
Induwara04:cloud-plugging
Aug 14, 2026
Merged

Add Pluggable Capability to the AI Workspace UI#3200
lasanthaS merged 2 commits into
wso2:mainfrom
Induwara04:cloud-plugging

Conversation

@Induwara04

@Induwara04 Induwara04 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces a new extension system for the AI Workspace, enabling the platform to support pluggable extensions that can add custom routes and navigation items. The changes include new context providers, updates to the main entry point, and modifications to the sidebar and app shell to surface extensions in the UI.

Issue: https://github.com/wso2-enterprise/apim-saas/issues/2882

Extension system and context:

  • Introduced a new AIWorkspaceExtension type and an ExtensionsProvider context in src/extensions.tsx to manage and provide extension definitions throughout the app.
  • Updated App and AIWorkspace components to accept an extensions prop, propagate it via context, and inject extension routes into the router. [1] [2] [3] [4] [5] [6]

Sidebar and navigation integration:

  • Modified AppSidebar to consume extensions from context and render a new "Cloud" category with navigation links for each registered extension. [1] [2] [3] [4]
  • Enhanced menu item selection logic in appShellMain.tsx to automatically highlight the correct sidebar item for extension routes. [1] [2] [3] [4]

Entry point and exports:

  • Refactored main.tsx to use the new AIWorkspace entrypoint, simplifying the bootstrapping logic and centralizing theme and authentication handling. [1] [2]
  • Updated package.json and index.ts to expose the new extension-related types and entrypoints for external consumption. [1] [2]

These changes collectively make the AI Workspace modular and extensible, allowing new features to be integrated as extensions with minimal changes to the core codebase.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a8eb07fb-3aa3-4cfc-9525-1e38c066b95c

📥 Commits

Reviewing files that changed from the base of the PR and between 7c8be9c and 75ade98.

📒 Files selected for processing (3)
  • portals/ai-workspace/src/AIWorkspace.tsx
  • portals/ai-workspace/src/extensions.tsx
  • portals/ai-workspace/src/main.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • portals/ai-workspace/src/extensions.tsx
  • portals/ai-workspace/src/main.tsx

📝 Walkthrough

Walkthrough

The AI workspace now owns authentication and application setup. It exposes an extension API, registers extension routes, and renders scoped extension links in the application sidebar.

Changes

AI Workspace Extensions

Layer / File(s) Summary
Workspace shell and public entry points
portals/ai-workspace/package.json, portals/ai-workspace/src/AIWorkspace.tsx, portals/ai-workspace/src/main.tsx, portals/ai-workspace/src/extensions.tsx, portals/ai-workspace/src/index.ts
The package exposes runtime and type entry points. AIWorkspace now owns authentication, routing, internationalization, theme setup, loading states, and extension input. The extension context and public exports are available to consumers.
Extension context and route registration
portals/ai-workspace/src/App.tsx
App provides extensions through ExtensionsProvider. Extension elements are registered in organization- and project-scoped route trees with page boundaries.
Extension sidebar navigation
portals/ai-workspace/src/pages/appShell/AppSidebar.tsx, portals/ai-workspace/src/pages/appShell/appShellMain.tsx
The sidebar renders scoped extension links in a Cloud category. AppLayout detects active extension routes before built-in routes and updates when extensions change.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 75ade

The PR adds extension-based routes and navigation to the AI Workspace without any supplied actionable merge-blocking risk; it is merge-ready after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant AIWorkspace
  participant App
  participant ExtensionsProvider
  participant ReactRouter
  participant AppSidebar
  Browser->>AIWorkspace: Render workspace
  AIWorkspace->>App: Render with extensions
  App->>ExtensionsProvider: Provide extension collection
  App->>ReactRouter: Register organization and project routes
  AppSidebar->>ExtensionsProvider: Read extension collection
  AppSidebar->>ReactRouter: Navigate to scoped extension path
  ReactRouter-->>AppSidebar: Match active extension route
Loading

Possibly related PRs

  • wso2/api-platform#3183: Adds a related extension injection system with typed contracts, providers, routing, and navigation integration.

Suggested reviewers: anugayan

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the purpose, goals, approach, and related issue, but omits several required template sections. Add user stories, documentation impact, automation tests, security checks, samples, related PRs, and test environment details.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: adding pluggable capability to the AI Workspace UI.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
portals/ai-workspace/src/App.tsx (2)

282-292: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Validate extension id and path before you build routes.

WorkspaceRoutes trusts the caller-supplied id and path. Two failure modes follow:

  1. Two extensions with the same id produce duplicate React keys here and a duplicate Sidebar.Item id in portals/ai-workspace/src/pages/appShell/AppSidebar.tsx (line 319). The active-item state then highlights both entries.
  2. An extension path that equals a built-in segment (for example settings, insights, projects, proxies) creates two sibling routes with the same pattern. React Router v6 ranks routes by specificity, not by declaration order, so the winner is not defined by the position at Line 609. The built-in page can become unreachable.

Reserve the built-in top-level segments and reject or drop conflicting extensions with a console warning. This is a public plugin API, so the check pays for itself.

♻️ Proposed validation
+const RESERVED_SEGMENTS = new Set([
+  'home', 'projects', 'applications', 'proxies', 'service-provider',
+  'mcp-proxy', 'gateways', 'quick-start', 'insights', 'settings',
+]);
+
 function WorkspaceRoutes({ extensions = [] }: AppProps) {
-  const extensionRoutes = extensions.map((extension) => (
-    <Route key={extension.id} path={extension.path} element={
-      <WithPageBoundary>{extension.element}</WithPageBoundary>
-    } />
-  ));
+  const seen = new Set<string>();
+  const extensionRoutes = extensions
+    .filter((extension) => {
+      const segment = extension.path.replace(/^\/+/, '').split('/')[0];
+      if (RESERVED_SEGMENTS.has(segment)) {
+        console.warn(`Extension "${extension.id}" uses reserved path "${segment}".`);
+        return false;
+      }
+      if (seen.has(extension.id)) {
+        console.warn(`Duplicate extension id "${extension.id}" ignored.`);
+        return false;
+      }
+      seen.add(extension.id);
+      return true;
+    })
+    .map((extension) => (
+      <Route key={extension.id} path={extension.path} element={
+        <WithPageBoundary>{extension.element}</WithPageBoundary>
+      } />
+    ));
🤖 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 `@portals/ai-workspace/src/App.tsx` around lines 282 - 292, Validate extensions
in WorkspaceRoutes before mapping them into Route elements: drop and
console.warn for duplicate extension.id values and for paths that match reserved
built-in top-level segments such as settings, insights, projects, or proxies.
Build extensionRoutes only from the validated extensions so React keys, sidebar
IDs, and route patterns remain unique.

609-609: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Confirm that every extension must mount in both the organization scope and the project scope.

The same extensionRoutes array registers each extension under organizations/:orgSlug and under organizations/:orgSlug/projects/:projectSlug. The extension element receives no indication of the active scope. An extension that is meaningful only at the organization level still gets a project-scoped URL, and AppSidebar.tsx (line 132) links to that URL whenever a project is selected.

If both scopes are intended, document it in the AIWorkspaceExtension type. If not, add a scope?: 'org' | 'project' | 'both' field and filter the routes and the sidebar entries accordingly.

Also applies to: 821-821

🤖 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 `@portals/ai-workspace/src/App.tsx` at line 609, Clarify extension scope in
AIWorkspaceExtension instead of registering every extension in both contexts
unconditionally. Add the scope contract and update extensionRoutes plus
AppSidebar entries to include organization routes, project routes, or both
according to each extension’s scope, preventing organization-only extensions
from appearing under project URLs.
🤖 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.

Nitpick comments:
In `@portals/ai-workspace/src/App.tsx`:
- Around line 282-292: Validate extensions in WorkspaceRoutes before mapping
them into Route elements: drop and console.warn for duplicate extension.id
values and for paths that match reserved built-in top-level segments such as
settings, insights, projects, or proxies. Build extensionRoutes only from the
validated extensions so React keys, sidebar IDs, and route patterns remain
unique.
- Line 609: Clarify extension scope in AIWorkspaceExtension instead of
registering every extension in both contexts unconditionally. Add the scope
contract and update extensionRoutes plus AppSidebar entries to include
organization routes, project routes, or both according to each extension’s
scope, preventing organization-only extensions from appearing under project
URLs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 93ae7bf5-784d-4da2-97da-9ddc2ca4bfcc

📥 Commits

Reviewing files that changed from the base of the PR and between 8bce858 and 7c8be9c.

📒 Files selected for processing (8)
  • portals/ai-workspace/package.json
  • portals/ai-workspace/src/AIWorkspace.tsx
  • portals/ai-workspace/src/App.tsx
  • portals/ai-workspace/src/extensions.tsx
  • portals/ai-workspace/src/index.ts
  • portals/ai-workspace/src/main.tsx
  • portals/ai-workspace/src/pages/appShell/AppSidebar.tsx
  • portals/ai-workspace/src/pages/appShell/appShellMain.tsx

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 11, 2026
Comment thread portals/ai-workspace/src/pages/appShell/AppSidebar.tsx
@lasanthaS
lasanthaS merged commit 9cdb331 into wso2:main Aug 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants