Skip to content

Add user-serving agent support with OAuth configuration to agent creation wizard#9888

Open
ranuka-laksika wants to merge 1 commit intowso2:masterfrom
ranuka-laksika:agent-application-creation-rebased
Open

Add user-serving agent support with OAuth configuration to agent creation wizard#9888
ranuka-laksika wants to merge 1 commit intowso2:masterfrom
ranuka-laksika:agent-application-creation-rebased

Conversation

@ranuka-laksika
Copy link

Enhanced the agent creation wizard to support user-serving agents with
configurable OAuth/OIDC authentication flows. The wizard now handles both
Interactive (authorization code) and Background (CIBA) agent types with
appropriate OAuth configuration.

Changes

  1. Agent Model & API Enhancements
  • Added AgentType enum with INTERACTIVE and BACKGROUND values
  • Extended AgentSchema interface with new properties:
    • IsUserServingAgent: Flag to identify user-serving agents
    • AgentType: Interactive or Background agent type
    • CallbackUrl: OAuth callback URL for Interactive agents
    • CibaAuthReqExpiryTime: Authentication request expiry time for background
      agents
    • NotificationChannels: Notification channels for CIBA flow (email, SMS)
  • Implemented updateAgentApplicationConfiguration() API function to configure
    OAuth settings post-creation
  1. Wizard UI Redesign
  • Migrated from basic Modal to ModalWithSidePanel component for improved UX
  • Added dynamic form with conditional fields based on agent type selection:
    • User-serving agent checkbox: Enables OAuth configuration options
    • Agent type selection: Radio buttons for Intreractive/Background
    • Interactive agents: Callback URL field with validation
    • Background agents: CIBA expiry time and notification channel checkboxes
  • Implemented success screen displaying:
    • Agent ID (copyable)
    • Agent Secret (copyable, masked)
    • OAuth Client ID (copyable, shown only for user-serving agents)
  • Added contextual help panel with dynamic content based on user selections
  1. OAuth Configuration Flow

When creating a user-serving agent, the wizard now:

  1. Creates the agent via SCIM API
  2. Updates the auto-generated application's OIDC configuration:
    - Interactive: Sets authorization_code and refresh_token grants, configures
    callback URL
    - Background: Sets urn:openid:params:grant-type:ciba grant, configures CIBA
    settings
  3. Retrieves and displays the OAuth Client ID
  4. Gracefully handles OAuth configuration failures (shows warning but doesn't fail
    entire operation)

Here is the Agent Creation Wizard :-

Screenshot 2026-03-16 at 13 09 03 For User Serving Agents(Allow users to log into the agent) :- image

For Interactive Agents (User should be interact with agent always within that time period like chatbot, AI Assistant):-

image

For Background Agents(Agent run in Background hence this no need the user interaction always but at some point)

image

Final Result for User Serving Agents:-

Screenshot 2026-03-16 at 13 10 13

Final Result Wizard for Non User Serving Agents:-

Screenshot 2026-03-16 at 13 10 27

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

This pull request introduces support for Agent applications—a new application template type within the system. Changes include a multi-step agent creation wizard with conditional form fields based on agent type, API endpoints for updating agent OAuth/OIDC configuration, new data models and enums for agent type classification, application template configuration, and comprehensive internationalization support.

Changes

Cohort / File(s) Summary
Agent API & Models
features/admin.agents.v1/api/agents.ts, features/admin.agents.v1/models/agents.ts
Introduced AgentType enum (INTERACTIVE, BACKGROUND), extended AgentSchema with optional agent-specific properties (IsUserServingAgent, AgentType, CallbackUrl, CibaAuthReqExpiryTime, NotificationChannels), and added updateAgentApplicationConfiguration() API function with UpdateAgentApplicationConfigInterface to conditionally update OIDC inbound protocol settings based on agent type.
Agent Wizard UI
features/admin.agents.v1/components/wizards/add-agent-wizard.tsx, features/admin.agents.v1/components/wizards/add-agent-wizard.scss, features/admin.agents.v1/pages/agents.tsx
Replaced simple modal with full ModalWithSidePanel wizard featuring extensive form validation, conditional fields for agent type selection, callback URL/CIBA expiry/notification channels, post-creation success screen, and updated callback flow. Added SCSS styling for wizard layout and field containers. Modified parent page to handle wizard lifecycle via handleAddAgentWizardClose callback and AgentCreationResultInterface.
Agent Application Template Configuration
features/admin.applications.v1/data/application-templates/application-templates-config.ts, features/admin.applications.v1/data/application-templates/templates/agent-application/agent-application.json, features/admin.applications.v1/models/application.ts, features/admin.applications.v1/components/forms/inbound-oidc-form.tsx
Added AGENT_APPLICATION constant to ApplicationTemplateIdTypes enum, created agent application template JSON with OAuth2/OIDC configuration including authorization code, refresh token, and CIBA grant types, integrated template into application templates registry, and enabled "Client Authentication" section visibility for agent templates in OIDC form.
Extension Layer Configuration
features/admin.extensions.v1/application-templates/templates/agent-application/agent-application.json, features/admin.extensions.v1/configs/application.tsx, features/admin.extensions.v1/configs/models/application.ts
Added agent application template definition at extension layer with identical OIDC configuration, extended tab/role eligibility checks to include AGENT_APPLICATION template type, updated danger zone and delete button visibility to hide for agent applications, added "agent-application" grant type mapping, added agent: boolean flag to application config model and templates configuration.
Internationalization
modules/i18n/src/models/namespaces/agents-ns.ts, modules/i18n/src/translations/en-US/portals/agents.ts
Extended AgentsNS interface and English translation with comprehensive wizard property containing field labels/placeholders/validation messages, alert definitions for creation success/failure/client ID fetch/config update errors, button labels, success screen messaging with credential field display, and help documentation for each agent configuration option.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Changeset Required ❌ Error Pull request modifies files in features/ and modules/ directories without a changeset file in .changeset/ Create a new changeset file in .changeset/ directory following pattern .md documenting changed packages and version updates.
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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding user-serving agent support with OAuth configuration to the agent creation wizard.
Description check ✅ Passed The description provides comprehensive details including purpose, changes made, UI/UX improvements, and OAuth configuration flow with visual examples, though some checklist items are incomplete.
✨ 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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (6)
features/admin.extensions.v1/configs/application.tsx (1)

441-445: Consider using enum constant instead of string literal.

Other template checks in this file use ApplicationTemplateIdTypes.AGENT_APPLICATION (lines 234, 281, 387, 404), but this mapping uses the string literal "agent-application". For consistency and type safety, consider using the enum.

♻️ Suggested change
-        [ "agent-application" ]: [
+        [ ApplicationTemplateIdTypes.AGENT_APPLICATION ]: [
             ApplicationManagementConstants.AUTHORIZATION_CODE_GRANT,
             ApplicationManagementConstants.REFRESH_TOKEN_GRANT,
             ApplicationManagementConstants.CIBA_GRANT
         ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.extensions.v1/configs/application.tsx` around lines 441 - 445,
Replace the string literal "agent-application" in the grant mapping with the
enum constant ApplicationTemplateIdTypes.AGENT_APPLICATION to match other usages
and improve type safety; locate the mapping that defines the grant array (the
entry currently keyed by "agent-application") and swap the key to
ApplicationTemplateIdTypes.AGENT_APPLICATION so it aligns with the other entries
that reference ApplicationTemplateIdTypes (e.g., where APPLICATION_TEMPLATE
constants are used on lines near uses of
ApplicationTemplateIdTypes.AGENT_APPLICATION).
features/admin.agents.v1/api/agents.ts (2)

240-242: Potential issue: delete may not work if property is read-only or non-configurable.

Using delete on cibaAuthenticationRequest should work here since updatedOidcConfig is a shallow copy. However, consider setting it to undefined for clearer intent, which also works with JSON serialization (the property will be omitted).

♻️ Alternative approach
             if (updatedOidcConfig.cibaAuthenticationRequest) {
-                delete updatedOidcConfig.cibaAuthenticationRequest;
+                updatedOidcConfig.cibaAuthenticationRequest = undefined;
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.agents.v1/api/agents.ts` around lines 240 - 242, Replace the
delete operation on updatedOidcConfig.cibaAuthenticationRequest with explicitly
setting the property to undefined to avoid issues with
non-configurable/read-only properties and to ensure JSON serialization omits it;
locate the code that checks if (updatedOidcConfig.cibaAuthenticationRequest) and
change the removal step to updatedOidcConfig.cibaAuthenticationRequest =
undefined so intent is clearer and safe across environments.

269-278: Simplify async/await usage for consistency.

The function uses async/await throughout but switches to .then()/.catch() for the final PUT request. This can be simplified for consistency.

♻️ Suggested refactor
-        return httpClient(putRequestConfig)
-            .then((response: AxiosResponse) => {
-                return Promise.resolve(response);
-            })
-            .catch((error: AxiosError) => {
-                return Promise.reject(error);
-            });
-    } catch (error) {
-        return Promise.reject(error);
-    }
+        return await httpClient(putRequestConfig);
+    } catch (error: unknown) {
+        throw error;
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.agents.v1/api/agents.ts` around lines 269 - 278, The final PUT
call is using .then()/.catch() inside an async function; replace it with an
awaited call to httpClient(putRequestConfig) and directly return the
AxiosResponse to match the rest of the async/await style and let the surrounding
try/catch handle errors; locate the httpClient call that uses putRequestConfig
(and references AxiosResponse/AxiosError) and remove the
Promise.resolve/Promise.reject wrappers so the function simply awaits the client
and returns the result.
features/admin.agents.v1/components/wizards/add-agent-wizard.tsx (2)

191-196: Race condition: creationResult may be stale when handleClose is called.

handleClose resets creationResult to null on line 193 before calling onClose(creationResult) on line 195. Due to React's asynchronous state updates, creationResult in the closure still holds the previous value, so this works. However, the code order is confusing. Consider passing the result before resetting state.

♻️ Clearer ordering
     const handleClose = (): void => {
+        const result: AgentCreationResultInterface | null = creationResult;
         setIsShowingSuccessScreen(false);
         setCreationResult(null);
         setSubmittedValues(null);
-        onClose(creationResult);
+        onClose(result);
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.agents.v1/components/wizards/add-agent-wizard.tsx` around
lines 191 - 196, The handleClose function can pass a stale or confusing
creationResult because state resets happen after calling onClose; capture the
current creationResult into a local variable (e.g., const result =
creationResult) and call onClose(result) before calling
setIsShowingSuccessScreen(false), setCreationResult(null), and
setSubmittedValues(null); alternatively, call onClose with creationResult first
and then reset state—update the handleClose implementation (references:
handleClose, creationResult, onClose, setIsShowingSuccessScreen,
setCreationResult, setSubmittedValues) to ensure the result passed to onClose is
the intended current value.

525-534: Consider using form ref instead of DOM query for submit.

Using document.getElementById and manual event dispatch is fragile (relies on string ID matching). Consider using a form ref or react-final-form's form API for more robust form submission.

♻️ Suggested refactor using form ref
+import React, { FunctionComponent, ReactElement, useRef, useState } from "react";
+
+    const formRef: React.RefObject<HTMLFormElement> = useRef<HTMLFormElement>(null);
+
     // In the form element:
-    <form id="addAgentForm" onSubmit={ handleSubmit }>
+    <form ref={ formRef } onSubmit={ handleSubmit }>
     
     // In the button onClick:
-    onClick={ () => {
-        document
-            .getElementById("addAgentForm")
-            .dispatchEvent(
-                new Event("submit", {
-                    bubbles: true,
-                    cancelable: true
-                })
-            );
-    } }
+    onClick={ () => formRef.current?.requestSubmit() }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@features/admin.agents.v1/components/wizards/add-agent-wizard.tsx` around
lines 525 - 534, The current onClick handler uses
document.getElementById("addAgentForm") and dispatchEvent to submit the form
which is fragile; update the button's onClick to use a React ref (e.g., create a
formRef and attach it to the <form id="addAgentForm">) or, if using
react-final-form, call the form API (e.g., form.submit()) directly instead of
querying the DOM; replace the manual Event dispatch in the onClick closure with
formRef.current.requestSubmit() or form.submit() to make submission type-safe
and refactor any references to the string ID ("addAgentForm") accordingly.
features/admin.applications.v1/data/application-templates/templates/agent-application/agent-application.json (1)

48-52: Consider removing unused hybridFlowResponseType configuration.

The template sets hybridFlowResponseType: "code_idtoken" but doesn't include the implicit grant type required for hybrid flow. Since the agent flow uses only authorization_code, refresh_token, or ciba (configured post-creation via updateAgentApplicationConfiguration), this setting appears unused and may cause confusion.

🧹 Suggested cleanup
                 "refreshToken": {
                     "expiryInSeconds": 86400,
                     "renewRefreshToken": true
-                },
-                "hybridFlowResponseType": "code_idtoken"
+                }

Also applies to: 62-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@features/admin.applications.v1/data/application-templates/templates/agent-application/agent-application.json`
around lines 48 - 52, The template includes a hybridFlowResponseType
("code_idtoken") that is unused because grantTypes in agent-application.json
only list "authorization_code", "refresh_token", and
"urn:openid:params:grant-type:ciba"; remove the hybridFlowResponseType property
from the agent-application.json template (and any duplicate instance at line 62)
to avoid confusion, or if hybrid flow is intended, add "implicit" to the
grantTypes and ensure updateAgentApplicationConfiguration aligns with that
choice; locate the key hybridFlowResponseType and either delete it or update
grantTypes accordingly (see updateAgentApplicationConfiguration and the
grantTypes array for context).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@features/admin.agents.v1/components/wizards/add-agent-wizard.tsx`:
- Around line 140-155: The catch block conflates failures from
updateAgentApplicationConfiguration and getInboundProtocolConfig and always
dispatches the configUpdateFailed alert; split the operations or add a separate
try/catch around getInboundProtocolConfig so failures fetching the OAuth client
ID dispatch the clientIdFetchFailed alert (while
updateAgentApplicationConfiguration failures still dispatch configUpdateFailed).
Specifically, keep the existing try for updateAgentApplicationConfiguration and,
after that succeeds, call getInboundProtocolConfig inside its own try/catch that
sets result.oauthClientId on success and dispatches addAlert with the
clientIdFetchFailed message on failure, referencing result.oauthClientId,
getInboundProtocolConfig, updateAgentApplicationConfiguration, addAlert,
clientIdFetchFailed and configUpdateFailed.

---

Nitpick comments:
In `@features/admin.agents.v1/api/agents.ts`:
- Around line 240-242: Replace the delete operation on
updatedOidcConfig.cibaAuthenticationRequest with explicitly setting the property
to undefined to avoid issues with non-configurable/read-only properties and to
ensure JSON serialization omits it; locate the code that checks if
(updatedOidcConfig.cibaAuthenticationRequest) and change the removal step to
updatedOidcConfig.cibaAuthenticationRequest = undefined so intent is clearer and
safe across environments.
- Around line 269-278: The final PUT call is using .then()/.catch() inside an
async function; replace it with an awaited call to httpClient(putRequestConfig)
and directly return the AxiosResponse to match the rest of the async/await style
and let the surrounding try/catch handle errors; locate the httpClient call that
uses putRequestConfig (and references AxiosResponse/AxiosError) and remove the
Promise.resolve/Promise.reject wrappers so the function simply awaits the client
and returns the result.

In `@features/admin.agents.v1/components/wizards/add-agent-wizard.tsx`:
- Around line 191-196: The handleClose function can pass a stale or confusing
creationResult because state resets happen after calling onClose; capture the
current creationResult into a local variable (e.g., const result =
creationResult) and call onClose(result) before calling
setIsShowingSuccessScreen(false), setCreationResult(null), and
setSubmittedValues(null); alternatively, call onClose with creationResult first
and then reset state—update the handleClose implementation (references:
handleClose, creationResult, onClose, setIsShowingSuccessScreen,
setCreationResult, setSubmittedValues) to ensure the result passed to onClose is
the intended current value.
- Around line 525-534: The current onClick handler uses
document.getElementById("addAgentForm") and dispatchEvent to submit the form
which is fragile; update the button's onClick to use a React ref (e.g., create a
formRef and attach it to the <form id="addAgentForm">) or, if using
react-final-form, call the form API (e.g., form.submit()) directly instead of
querying the DOM; replace the manual Event dispatch in the onClick closure with
formRef.current.requestSubmit() or form.submit() to make submission type-safe
and refactor any references to the string ID ("addAgentForm") accordingly.

In
`@features/admin.applications.v1/data/application-templates/templates/agent-application/agent-application.json`:
- Around line 48-52: The template includes a hybridFlowResponseType
("code_idtoken") that is unused because grantTypes in agent-application.json
only list "authorization_code", "refresh_token", and
"urn:openid:params:grant-type:ciba"; remove the hybridFlowResponseType property
from the agent-application.json template (and any duplicate instance at line 62)
to avoid confusion, or if hybrid flow is intended, add "implicit" to the
grantTypes and ensure updateAgentApplicationConfiguration aligns with that
choice; locate the key hybridFlowResponseType and either delete it or update
grantTypes accordingly (see updateAgentApplicationConfiguration and the
grantTypes array for context).

In `@features/admin.extensions.v1/configs/application.tsx`:
- Around line 441-445: Replace the string literal "agent-application" in the
grant mapping with the enum constant
ApplicationTemplateIdTypes.AGENT_APPLICATION to match other usages and improve
type safety; locate the mapping that defines the grant array (the entry
currently keyed by "agent-application") and swap the key to
ApplicationTemplateIdTypes.AGENT_APPLICATION so it aligns with the other entries
that reference ApplicationTemplateIdTypes (e.g., where APPLICATION_TEMPLATE
constants are used on lines near uses of
ApplicationTemplateIdTypes.AGENT_APPLICATION).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: ec0674d6-7bfd-42db-9e71-7e72fbbfed17

📥 Commits

Reviewing files that changed from the base of the PR and between bf50817 and 550e921.

📒 Files selected for processing (14)
  • features/admin.agents.v1/api/agents.ts
  • features/admin.agents.v1/components/wizards/add-agent-wizard.scss
  • features/admin.agents.v1/components/wizards/add-agent-wizard.tsx
  • features/admin.agents.v1/models/agents.ts
  • features/admin.agents.v1/pages/agents.tsx
  • features/admin.applications.v1/components/forms/inbound-oidc-form.tsx
  • features/admin.applications.v1/data/application-templates/application-templates-config.ts
  • features/admin.applications.v1/data/application-templates/templates/agent-application/agent-application.json
  • features/admin.applications.v1/models/application.ts
  • features/admin.extensions.v1/application-templates/templates/agent-application/agent-application.json
  • features/admin.extensions.v1/configs/application.tsx
  • features/admin.extensions.v1/configs/models/application.ts
  • modules/i18n/src/models/namespaces/agents-ns.ts
  • modules/i18n/src/translations/en-US/portals/agents.ts

@codecov
Copy link

codecov bot commented Mar 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.01%. Comparing base (58dfc3b) to head (550e921).
⚠️ Report is 8 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9888   +/-   ##
=======================================
  Coverage   56.01%   56.01%           
=======================================
  Files          42       42           
  Lines        1023     1023           
  Branches      231      231           
=======================================
  Hits          573      573           
  Misses        450      450           
Flag Coverage Δ
@wso2is/core 56.01% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

1 participant