Skip to content

feat(custom-widget): add native AI copilot - #42063

Open
tomjose92 wants to merge 9 commits into
releasefrom
feat/custom-widget-native-ai-copilot
Open

feat(custom-widget): add native AI copilot#42063
tomjose92 wants to merge 9 commits into
releasefrom
feat/custom-widget-native-ai-copilot

Conversation

@tomjose92

@tomjose92 tomjose92 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a CE-owned native Custom Widget Copilot backed by the CE Ask AI runtime
  • keep the complete component, parser, context contract, configuration fallback, and tests in src/ce
  • remove the legacy internal.appsmith.com iframe integration now that Ask AI configuration and execution are CE-owned
  • apply complete or partial HTML, Style, and JavaScript responses directly to the Custom Widget editors
  • keep assistant rendering self-contained without introducing new package dependencies or EE-owned files

Architecture and community sync

  • this PR contains no src/ee changes; the CE pre-push architecture guard passes
  • the Custom Widget editor imports the CE implementation intentionally so EE consumes the same code after community sync, without a shadow implementation
  • both standalone CE and EE use the native assistant; configured instances get the conversational editor, while unconfigured instances get administrator guidance

Impact on existing instances

The AI tab remains behind the pre-existing release_custom_widget_ai_builder flag. When enabled, the tab now always renders the native assistant in both CE and EE. Instances with a configured and enabled Ask AI provider get the conversational editor experience; unconfigured instances get administrator guidance. The Custom Widget builder no longer loads or communicates with internal.appsmith.com.

Validation

  • yarn jest src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant --runInBand — 21 tests passed
  • focused ESLint — passed with no warnings or errors
  • yarn tsc --noEmit — passed
  • git diff --check — passed
  • CE pre-commit ESLint and gitleaks hooks — passed
  • CE pre-push architecture guard — passed
  • prior real-browser validation covered full generation, partial Style-only changes, multi-turn pivots, Q&A without mutations, error recovery, persistence, and working previews

Linear issue

https://linear.app/appsmith/issue/APP-15735

Automation

/ok-to-test tags="@tag.All"

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/30942752510
Commit: a20bca5
Cypress dashboard.
Tags: @tag.All
Spec:


Tue, 04 Aug 2026 23:56:15 UTC

Summary by CodeRabbit

  • New Features
    • Added a Custom Widget Builder AI Assistant with prompt suggestions, chat actions, loading and error states, and previews of applied updates.
    • Added guidance for unconfigured assistants, including an AI settings link for administrators.
    • Supports applying AI-generated HTML, CSS, and JavaScript updates directly to widgets.
  • Tests
    • Added comprehensive coverage for assistant interactions, code parsing, update application, and error handling.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The custom widget editor now provides a Redux-backed AI assistant that builds widget context, parses HTML/CSS/JS updates, applies them to the builder, and renders configuration, chat, loading, and error states.

Changes

Custom Widget AI Assistant

Layer / File(s) Summary
Widget context and response parsing
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.ts, app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.test.ts
Builds protected widget context, extracts recognized fenced updates, strips applied code from responses, and tests parsing and fence handling.
Assistant state and chat UI
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx, app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/NotConfigured.tsx, app/client/src/ce/constants/messages.ts
Adds Redux-driven prompting, code application, chat rendering, configuration guidance, loading and error states, applied-file indicators, and chat controls.
Assistant validation and editor migration
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx, app/client/src/pages/Editor/CustomWidgetBuilder/Editor/index.tsx, app/client/src/pages/Editor/CustomWidgetBuilder/constants.ts
Tests assistant behavior, routes the feature-flagged AI tab to AIAssistant, and removes obsolete chatbot constants and URL helpers.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CustomWidgetEditor
  participant AIAssistant
  participant ReduxAIState
  participant CustomWidgetBuilder
  CustomWidgetEditor->>AIAssistant: Open the feature-flagged AI tab
  AIAssistant->>ReduxAIState: Dispatch FETCH_AI_RESPONSE with widget context
  ReduxAIState-->>AIAssistant: Return assistant response
  AIAssistant->>CustomWidgetBuilder: Apply extracted HTML/CSS/JS updates
Loading

Possibly related issues

  • appsmithorg/appsmith-ee#9395 — Covers related CE Ask AI settings and backend work.

Possibly related PRs

Suggested labels: Enhancement

Suggested reviewers: subrata71, sondermanish

Poem

Widget prompts flow through the night,
HTML, CSS, and JS align right.
Redux carries each reply,
Builder updates answer why.
Chat states settle into light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The description links the implementation to Linear issue APP-15735.
Out of Scope Changes check ✅ Passed The changes match the stated objective and remain within CE Custom Widget AI Assistant functionality.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding a native AI copilot for Custom Widget.
Description check ✅ Passed The description explains the implementation, architecture, impact, issue, automation, and validation results in sufficient detail.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/custom-widget-native-ai-copilot

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.

@tomjose92
tomjose92 force-pushed the feat/custom-widget-native-ai-copilot branch from ac96dd8 to 26007de Compare July 29, 2026 07:13
@tomjose92

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tomjose92

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/30431314713.
Workflow: On demand build Docker image and deploy preview.
skip-tests: . env: .
PR: 42063.
recreate: .
base-image-tag: .

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx (1)

50-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Suggested-prompt copy bypasses the localization pattern.

Every other user-facing string in this file goes through createMessage(CUSTOM_WIDGET_AI_ASSISTANT.*), but SUGGESTED_PROMPTS labels/prompts are hardcoded English literals.

🤖 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
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`
around lines 50 - 58, Update SUGGESTED_PROMPTS so each user-facing label and
prompt uses the file’s existing createMessage(CUSTOM_WIDGET_AI_ASSISTANT.*)
localization pattern, adding or reusing the corresponding message keys as needed
while preserving the current suggested prompt content.
🤖 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 `@app/client/src/ce/constants/messages.ts`:
- Around line 2748-2749: Update EMPTY_STATE_MESSAGE to describe applying
complete or partial updates to the HTML, Style, and JavaScript editors,
replacing “replaces” with wording that reflects partial changes and correcting
the “Javascript” spelling.

In
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`:
- Around line 500-504: Remove the redundant role-based ternary in the message
rendering block and render message.content once through UserMessageContent,
preserving the current output for both user and assistant messages.

In
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.ts`:
- Around line 28-60: Update buildWidgetAIContext to sanitize srcDoc.html,
srcDoc.css, and srcDoc.js before interpolation so no literal triple-backtick
sequence can appear in the returned context. Add a focused escaping helper that
neutralizes each ``` sequence while preserving the widget source content, and
retain the existing "(empty)" fallback behavior for missing or empty files.

---

Nitpick comments:
In
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`:
- Around line 50-58: Update SUGGESTED_PROMPTS so each user-facing label and
prompt uses the file’s existing createMessage(CUSTOM_WIDGET_AI_ASSISTANT.*)
localization pattern, adding or reusing the corresponding message keys as needed
while preserving the current suggested prompt content.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f2cfac13-b4b9-4642-8f50-6d953c2f4218

📥 Commits

Reviewing files that changed from the base of the PR and between 665fbf1 and 26007de.

📒 Files selected for processing (9)
  • app/client/src/ce/constants/messages.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/NotConfigured.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.test.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.ts
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/index.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/constants.ts
💤 Files with no reviewable changes (2)
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/constants.ts

Comment thread app/client/src/ce/constants/messages.ts Outdated
Comment thread app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx Outdated
@tomjose92

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tomjose92 tomjose92 added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Jul 29, 2026
@tomjose92
tomjose92 marked this pull request as ready for review July 29, 2026 08:22
@tomjose92
tomjose92 requested a review from a team as a code owner July 29, 2026 08:22
@tomjose92

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/30435818962.
Workflow: On demand build Docker image and deploy preview.
skip-tests: . env: .
PR: 42063.
recreate: .
base-image-tag: .

@github-actions

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-42063.dp.appsmith.com

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx (1)

35-44: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Security Misconfiguration (CWE-346): Origin Validation Error

Reachability: External
● Entry
  app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx:577
  ChatBot
│
▼
● Sink
  app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx

Pin the iframe origin for both directions.

postMessage sends the full widget source with "*", while event.source alone does not verify the iframe’s current origin. If the iframe is navigated or compromised, that page could read the source and send arbitrary html_code, css_code, or js_code updates. Derive the expected origin from CUSTOM_WIDGET_AI_BOT_URL and use it as targetOrigin; also require event.origin to match before processing messages.

Also applies to: 54-58

🤖 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 `@app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx`
around lines 35 - 44, Pin the iframe messaging origin in the ChatBot component:
derive the expected origin from CUSTOM_WIDGET_AI_BOT_URL, pass it as
targetOrigin in the ref.current.contentWindow.postMessage call, and require
incoming message events to match event.origin as well as the expected iframe
source before applying html_code, css_code, or js_code updates.
🤖 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.

Outside diff comments:
In `@app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx`:
- Around line 35-44: Pin the iframe messaging origin in the ChatBot component:
derive the expected origin from CUSTOM_WIDGET_AI_BOT_URL, pass it as
targetOrigin in the ref.current.contentWindow.postMessage call, and require
incoming message events to match event.origin as well as the expected iframe
source before applying html_code, css_code, or js_code updates.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 39efe00d-89bc-4414-a60e-7ecaa768329a

📥 Commits

Reviewing files that changed from the base of the PR and between 718d037 and dd6ff96.

📒 Files selected for processing (3)
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx

@github-actions

Copy link
Copy Markdown

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 1, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

@tomjose92 tomjose92 added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Jul 29, 2026

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

Actionable comments posted: 1

🤖 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 `@app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx`:
- Around line 12-23: The ChatBotProps definition currently makes required legacy
copilot inputs optional through Partial. Update ChatBotProps to keep only
uncompiledSrcDoc optional while requiring propId, parentEntityId, update, and
widgetId, preserving the existing ChatBot destructuring and behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 85720d9e-ac4b-466b-a083-edea5149ddf6

📥 Commits

Reviewing files that changed from the base of the PR and between dd6ff96 and a5138b7.

📒 Files selected for processing (2)
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx

Comment thread app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx Outdated
@tomjose92

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

salevine added a commit that referenced this pull request Aug 4, 2026
## Description

**TL;DR** — Ask AI (AI-assisted code editing in the JS/query editors,
plus an admin page to configure the AI provider) currently exists only
in the enterprise edition. Nothing about it is actually
enterprise-specific, so this brings it to CE. The code is ported from
`appsmith-ee/release` unchanged where it already lives in `ce` packages,
and moved from `src/ee` into `src/ce` where it does not.

### Background

Ask AI was originally built for CE on `feat/enable-ai` (PR #41590). That
PR was handed over for review in March, went quiet, and was closed by
the stale bot on 2026-04-03 without ever being merged. The feature
instead shipped in the enterprise repo as `appsmith-ee#8845`, and CE
received only inert stubs via #41692 —
`ce/selectors/aiAssistantSelectors.ts` and friends returning `null` /
`false` / `[]`.

That split was not driven by any technical requirement:

- `ee/selectors/aiAssistantSelectors.ts` contains **no license or
entitlement check** — it reads `state.aiAssistant` and nothing else.
- Enablement is ordinary organization configuration
(`AIAssistantConfig.isAIAssistantEnabled`), set by an instance admin.
- The feature flag that once gated it was removed wholesale in
`appsmith-ee#9119`.

The enterprise-only placement was a product decision, and this PR
reverses it.

### Why port from EE rather than revive the original branch

`feat/enable-ai` is four months stale and EE has since reworked the
implementation:

| | `feat/enable-ai` | `appsmith-ee/release` |
|---|---|---|
| AI settings storage | flat fields on `OrganizationConfiguration` |
nested `AIAssistantConfig` document |
| Provider dispatch | inline `if` chain | extracted `dispatchToProvider`
|
| Datasource schema enrichment | client-side | server-side
`AiDatasourceSchemaSerializerCE` |
| `/ai-config` endpoints | ~1450 lines inlined into
`OrganizationControllerCE` | dedicated `AIConfigControllerCE` +
`AIConfigServiceCE` |
| `AIReferenceServiceCEImpl` | 239 lines | 107 lines |

Reviving the branch would land a divergent second implementation and
guarantee a conflict with the community sync. Porting EE's current
version starts CE and EE byte-identical on the `ce`-package files. Note
the security commit and the review fixes on top of it deliberately move
CE **ahead** of EE, so the sync is no longer a no-op — see **CE→EE sync:
required resolution** below for the exact steps.

### Architecture

**Server** — follows the existing `controller → ce service →
ce_compatible → ee override` layering, all in `ce` packages:

- `AIConfigControllerCE` / `AIConfigController` for `/ai-config`
(`test-connection`, `fetch-models`, `test-api-key`), each gated on
`MANAGE_ORGANIZATION`
- `AIConfigServiceCE(Impl)`, `AIAssistantServiceCE(Impl)`,
`AIReferenceServiceCE(Impl)` with their `ee` override points and
`AIConfigServiceCECompatible(Impl)`
- `AIAssistantConfig` on `OrganizationConfiguration`, `Migration075`,
and the `AIProvider` / DTO types
- `POST /users/ai-assistant/request` on `UserControllerCE`
- `ai-references/*.md` prompt-reference resources

**Client** — the implementation moves from `src/ee` into `src/ce`, which
is where a CE-owned feature belongs. This is safe because the EE UI
files import nothing EE-only; every import is a package, a shared path,
or an `ee/` alias that resolves through CE's shims. The existing
`src/ee` shims from #41692 are untouched and now re-export real code
instead of stubs, and the exported symbol surface of every relocated
file is unchanged. The AI reducer and saga are registered in
`ce/reducers` and `ce/sagas` rather than their `ee` counterparts, and
the admin AI settings page is registered for superusers.

**This PR adds no `src/ee` files**, because the CE pre-push architecture
guard rejects them. Four CE-owned modules therefore have no `ee` shim to
import through — `aiAssistantReducer`, `AIAssistantSagas`, `GPT/shared`,
and the admin AI config — so they are imported from `ce/` directly, each
with a documented `eslint-disable` for `no-restricted-imports`. That is
the same accommodation the native Custom Widget copilot uses in #42063.
If EE would rather route these through `ee/` shims, those shims belong
in a companion EE PR.

Adds `react-markdown` and `remark-gfm`, used by the assistant's response
renderer.

### Impact on existing instances

Inert by default. `AIAssistantConfig` is absent until an admin
configures a provider, `isAIAssistantEnabled` defaults to false, and
`Migration075` only adds the field. With nothing configured, the Ask AI
affordances stay hidden exactly as they do today — no feature flag is
involved, matching how EE ships it since #9119.

### Security fixes included

A nine-reviewer council on the ported code surfaced four defects. All
four are inherited byte-identical from EE and are therefore **live in EE
production today**; because EE's `AIConfigServiceImpl` delegates every
method to the CE class and `AIAssistantServiceImpl` overrides nothing,
fixing them here carries them into EE through the sync rather than
needing a parallel EE change.

1. **SSRF, two call sites.** `callLocalLLMAPI` built a raw `WebClient`,
bypassing `WebClientUtils` and substituting a check that tested only
`isLinkLocalAddress` on the first resolved address — missing loopback,
and racy. `callAzureOpenAIAPI` chained `.clientConnector(...)` *after*
`WebClientUtils.builder()`, which replaces the connector carrying the
DNS-aware resolver; it read as protected and was not. Both now build
through `WebClientUtils.builder(httpClient)`.
2. **`getAIConfig` authorization.** It was the only one of five service
methods without `MANAGE_ORGANIZATION`, disclosing `localLlmUrl`,
`azureOpenaiEndpoint` and the deployment name to any authenticated user,
on every session. Managers still get the full configuration; everyone
else gets enablement, provider, and credential-presence booleans —
exactly what the client consumes.
3. **API keys stored in cleartext.** The `@Encrypted` annotations never
applied — the traversal only descends into `AppsmithDomain` types, and
the write is a sparse `updateById` so the encrypting lifecycle listener
never fires. `AIConfigSecretsCE` now encrypts and decrypts at the few
write/read points, and `Migration076` encrypts existing values in place,
idempotently.
4. **Admin key field corrupted credentials.** A stored key loaded into
the input as the literal `••••••••` with a save guard comparing against
that mask, so typing without clearing persisted `••••••••sk-…` behind a
success toast.

**Behaviour change worth calling out:** a local-LLM URL pointing at
loopback is now refused. In the single-container CE deployment
`127.0.0.1` is Mongo, Redis and RTS rather than the operator's Ollama —
which is the reason to refuse it. A local model on another host or
container stays reachable by hostname or private IP. This also makes the
runtime path agree with `/ai-config/test-connection`, which already went
through `WebClientUtils`.

### Follow-ups (tracked, not addressed here)

1. **Unmetered LLM spend** — `/users/ai-assistant/request` has no rate
limit or per-user quota; on an open-signup CE instance any account can
drain the admin's provider billing.
2. **OpenAI provider lacks guards the others have** — no
empty/max-length prompt validation and no `max_tokens`.
3. **`/users/ai-assistant/request` maps every failure to 400**,
including upstream timeouts, which hurts monitoring.
4. **A measured 0.5–1.0 s reactive-thread stall** in
`AiDatasourceSchemaSerializerCE.extractReferencedTableNames` at the
DTO's own size ceilings.
5. **Dead code carried from EE** — `AIWindow` and the in-editor
`AISidePanel` have no importer, and `ce/utils/aiSchemaSerializer.ts` has
no consumer but its own test.
6. **Test coverage** — `AIConfigSecretsCE` and `Migration076` both route
through `EncryptionHelper`, whose static initialiser needs
`APPSMITH_ENCRYPTION_PASSWORD`/`SALT`. Those are set for the
integration-test and Docker CI jobs but not for `server-unit-tests`, so
this coverage belongs in the integration suite.

A follow-up in `appsmith-ee` should reduce EE's `src/ee` Ask AI files to
re-export shims and drop its `ee/reducers` + `ee/sagas` registration, so
EE consumes this CE implementation instead of shadowing it.

https://linear.app/appsmith/issue/APP-15737

Supersedes the original, stale-closed CE attempt in #41590.

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/30836147916>
> Commit: deab697
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=30836147916&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Mon, 03 Aug 2026 18:47:45 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [x] Yes
- [ ] No

Ask AI becoming available in the community edition is a user-facing
change worth announcing.



## CE→EE sync: required resolution

**This section is load-bearing. The sync of this PR is not a no-op, and
two of its failure modes arrive through *clean* merges — no conflict
marker will surface them.** Whoever runs the sync should follow this,
and it is the condition the architecture review set for unblocking.

Of the changed files that also exist in EE, **18 differ from EE's
copy**. Most are the deliberate hardening in the security commit, which
moves CE ahead of EE on purpose. Five are add/add conflicts
(`ce/sagas/AIAssistantSagas.ts`, `ce/pages/AdminSettings/config/ai.tsx`,
`pages/AdminSettings/AI/index.tsx`, `AIAssistantServiceCEImpl.java`,
`AIConfigServiceCEImpl.java`).

> **These steps are for the sync itself. None of them can be pre-landed
in EE as a separate PR — verified against `appsmith-ee/origin/release`
(`0aff44fa56`, "Sync community release"):**
>
> - **The saga.** EE's `ce/sagas/index.tsx` does **not** register the AI
saga yet — only `ee/sagas/index.tsx` does. Removing EE's registration
*before* the CE change syncs would leave zero registrations and take Ask
AI out of EE entirely. It is only safe once CE's registration has
arrived.
> - **The enum.** EE's `ASK_AI_ORG_CONFIG_UPDATED` /
`ASK_AI_ORG_TEST_RUN` are referenced by `AIConfigServiceCEImpl` (lines
172-173, 236) and its test. Deleting them ahead of the sync breaks EE's
compile. This is a conflict *resolution*, not a change that exists
independently.
>
> So this is work for whoever runs the sync, in the same merge — not a
companion PR that can land first.

### 1. Remove EE's now-duplicate saga registration

CE now registers the AI saga itself, and that CE file merges **cleanly**
into EE — so EE ends up registering it twice:

| EE file | What to do |
|---|---|
| `app/client/src/ee/sagas/index.tsx` | **Remove** the
`aiAssistantSagas` import (from `ee/sagas/AIAssistantSagas`, a shim that
re-exports `ce/sagas/AIAssistantSagas`) and its entry in the saga array
— CE's registration now covers EE |

Left as-is, EE runs the *same* watcher generator twice, so every Ask AI
action fires duplicate requests to the provider — double latency and
double spend.

This one genuinely needs an EE change: EE builds `sagasArr` as
`[...CE_Sagas, …, aiAssistantSagas]`, appending its own entry *after*
spreading CE's list, so CE cannot deduplicate it from its side.

**The duplicate admin category no longer needs an EE change.**
`ConfigFactory.register` is CE-owned and was a raw push into three
collections (`categories`, `settings`, `savableCategories` — only
`settingsMap` was keyed and therefore safe). It is now idempotent, so a
category registered from both `ce/` and `ee/` collapses to one entry on
its own. EE's `ConfigFactory.register(AIConfig)` can stay exactly as it
is.

### 2. Resolve the five add/add conflicts toward CE, wholesale

`Migration076EncryptAIAssistantApiKeys` merges cleanly and will encrypt
EE's stored keys on first boot. EE's current `AIAssistantServiceCEImpl`
/ `AIConfigServiceCEImpl` read those keys **without**
`AIConfigSecretsCE.decrypt`. If either file is resolved toward EE's
copy, **EE sends ciphertext as its `Authorization` header and Ask AI
breaks in EE**.

`pages/AdminSettings/AI/index.tsx` must also move together with
`AIConfigServiceCEImpl` — the client's `hasStoredX` model depends on the
server's `has*` response shape and the manager-only full config.

### 3. Collapse the duplicated analytics enum

`AnalyticsEvents.java`: CE adds `ASK_AI_ORG_CONFIG_UPDATED` /
`ASK_AI_ORG_TEST_RUN` at the enum tail (lines 106/109); EE already has
both at lines 140/143. Naive resolution produces duplicate enum
constants and **fails to compile**. Keep one pair.

### Correction to an earlier claim in this description

An earlier revision said porting from EE keeps the two editions
"byte-identical on the `ce`-package files, so the sync stays a no-op".
That was true of the initial port and is **no longer true**: the
security commit, and the review fixes on top of it, deliberately move CE
ahead. The byte-identity argument still holds for the ~40 untouched
ported files and for the reason to port rather than revive
`feat/enable-ai`, but the sync itself needs the three steps above.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Ask AI assistance for JavaScript, SQL, GraphQL, and JSON
editing.
* Added resizable chat panels with conversation history, editor context,
Markdown responses, quick actions, and keyboard shortcuts.
* Added a global AI assistant panel with context-aware prompts and
schema support.
* Added administrator settings for Claude, OpenAI, Azure OpenAI, and
local Ollama-compatible providers.
* Added connection, credential, and model testing with secure credential
handling and request safeguards.
* **Documentation**
* Added reference guides for JavaScript, SQL, GraphQL, and common
troubleshooting scenarios.
* **Tests**
  * Added coverage for schema handling and AI configuration workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tomjose92
tomjose92 force-pushed the feat/custom-widget-native-ai-copilot branch from 8657a4f to 0f66b7c Compare August 4, 2026 18:20
@tomjose92

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tomjose92

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/30939032401.
Workflow: On demand build Docker image and deploy preview.
skip-tests: . env: .
PR: 42063.
recreate: .
base-image-tag: .

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx (1)

282-288: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Remove the stale CE stub note.

app/client/src/ce/selectors/aiAssistantSelectors.ts defines getAIMessages(state: DefaultRootState): AIMessage[] and returns state.aiAssistant.messages, while EE re-exports the CE selector. This comment is inaccurate and can mislead future maintenance; update or remove it.

🤖 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
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`
around lines 282 - 288, Remove the stale CE selector stub comment immediately
above the messages assignment in the AI assistant component. Keep the
getAIMessages selector usage and AIMessage[] cast unchanged.

Source: Coding guidelines

🤖 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
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx`:
- Around line 148-195: Update applyCodeUpdatesFromAssistant and its surrounding
widget flow to associate each assistant response with the active widget, then
prevent bulkUpdate when the response recipient differs from the current
widgetId. Extend the test coverage to deliver a response through the widget flow
and verify that cross-widget responses are ignored while matching-widget
responses still apply.

In
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`:
- Around line 68-72: Update APPLIED_FILE_LABELS to use localized message keys
resolved through createMessage rather than hardcoded English text, ensuring the
HTML, Style, and JavaScript chip labels are localized. Use “JavaScript” with the
correct capitalization for the JavaScript label and keep the existing label
lookup behavior intact.
- Around line 202-215: Replace the native styled.button used by
SuggestedPromptChip with the appropriate ADS Button variant, and replace
PromptTextArea with the ADS multiline/textarea control. Add a stable accessible
label or aria-label to the textarea, moving any necessary styling to its
wrapper/container while preserving the existing prompt interaction and
appearance.
- Around line 373-386: Bind each AI request and response to the originating
widget and request identity: update
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx
lines 373-386 to include both identifiers in fetchAIResponse, propagate them
through the success payload, reducer, and AIMessage handling around lines
317-361, and guard bulkUpdate so it runs only when the response matches the
current builder context. Add a regression test in
app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx
lines 148-195 covering a delayed response after the widget context changes.

---

Nitpick comments:
In
`@app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx`:
- Around line 282-288: Remove the stale CE selector stub comment immediately
above the messages assignment in the AI assistant component. Keep the
getAIMessages selector usage and AIMessage[] cast unchanged.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2ae096e7-eab7-4065-b8a0-fbafd83bf9f0

📥 Commits

Reviewing files that changed from the base of the PR and between 8657a4f and 8d31b25.

📒 Files selected for processing (9)
  • app/client/src/ce/constants/messages.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/NotConfigured.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.test.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.test.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.ts
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/index.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/constants.ts
💤 Files with no reviewable changes (2)
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/ChatBot/ChatBot.tsx
  • app/client/src/pages/Editor/CustomWidgetBuilder/constants.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • app/client/src/ce/constants/messages.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.test.ts
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/NotConfigured.tsx
  • app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/utils.ts
  • app/client/src/pages/Editor/CustomWidgetBuilder/Editor/index.tsx

Comment thread app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx Outdated
Comment thread app/client/src/ce/pages/Editor/CustomWidgetBuilder/Editor/AIAssistant/index.tsx Outdated
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-42063.dp.appsmith.com

The builder's AI tab sends mode "custom_widget", which intentionally has
no bundled reference document. Document that contract at the fallback
branch it relies on. Also ensures deploy previews build the server from
source instead of reusing the prebuilt cache jar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tomjose92

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/30942324881.
Workflow: On demand build Docker image and deploy preview.
skip-tests: . env: .
PR: 42063.
recreate: .
base-image-tag: .

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-42063.dp.appsmith.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Required label for CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant