Skip to content

feat(chat-ao): add CMA bridge controller subclass - #811

Open
anfibiacreativa wants to merge 1 commit into
feat/chat-ao-controller-decouplefrom
feat/chat-ao-cma-subclass
Open

anfibiacreativa wants to merge 1 commit into
feat/chat-ao-controller-decouplefrom
feat/chat-ao-cma-subclass

Conversation

@anfibiacreativa

Copy link
Copy Markdown
Member

│ Stacked on PR 1 (feat/chat-ao-controller-decouple). Base this PR on that branch; rebase onto main once PR 1 merges.

Summary

  • Add CmaChatController extends BaseChatController — the CMA bridge path now has its own controller instead of sharing the AO-direct one.
  • Route the bridge socket with activationKey + x-site on one AUTH frame, map bridge auth rejections to tester-facing copy, route the skills catalog to the bridge, and
    resume the last session per-site on reload.
  • chat-ao.js selects the subclass from the ew.altHarness flag once config resolves.
  • 10 new CMA tests; 326 chat-ao tests pass total.

Why

Completes the controller decoupling started in PR 1. With a dedicated CMA subclass, bridge-path behavior (resume, auth-error copy, skills routing) can evolve without
any risk to the CX Coworker path, and vice-versa. It also absorbs the long-lived ewoncma branch's CMA client work onto current main and folds in the reload-resume
change (superseding feat/chat-ao-resume-main).

What Changed

  • cma-chat-controller.js (new) — CmaChatController extends Base:
    • _connectionInfo: routes to CMA_BRIDGE_WS_BASE; the AUTH frame carries both x-site (S12 per-site session scoping) and activationKey (bridge auth/routing).
    • friendlyBackendError: maps the bridge's terse auth rejections to tester-facing copy (S15), surfaced only during an active turn.
    • _fetchSkills: routes the catalog to the bridge via the activation key.
    • Reload-resume: a per-site sessionStorage pointer (nx2:cma-episode:/); loadEpisodes reconnects to it (the bridge replays history on attach),
      _onSessionReady persists it, _onSessionError drops a rejected/stale pointer and starts fresh, startNewEpisode clears it.
  • base-chat-controller.js — _attach/reattachIfIdle and a default attach-only warmSession move to Base (both harnesses use them via chat-ao.js); Coworker keeps its REST
    warm override.
  • chat-ao.js — controller creation deferred until ew.altHarness is known, then new (altHarness ? CmaChatController : CoworkerChatController)(...); the activation key is
    passed through. onUpdate handling extracted to _onControllerUpdate.
  • utils/skills.js — fetchSkills routes to the bridge REST plane (+ explicit x-user-id) when an activation key is present; the AO path is byte-unchanged.
  • ao-constants.js — CMA bridge WS/HTTP bases.

Test Plan

  • test/nx2/blocks/chat-ao/** — 326 tests pass (316 existing + 10 new CMA-subclass tests).
  • ESLint clean; secrets scan clean over the branch diff.
  • On an ew.altHarness site: send a message, reload the page — the conversation resumes (bridge replays). Start a new session, reload — no stale resume.
  • Bad/missing activation key surfaces the friendly copy, not an internal error.
  • Skills slash-menu populates from the bridge on the alt harness.
  • Regression: a non-alt-harness (CX Coworker) site behaves exactly as before.

Risks / Follow-ups

  • Risk: low-moderate — the AO/Coworker path is unchanged and fully covered; the new behavior is isolated to the CMA subclass and its own tests. The one cross-cutting
    change is deferring controller creation to after the flag resolves (no component-mount test depends on the old eager timing).
  • Follow-up: the alt-harness +menu customizations were ewoncma-specific against a different menu structure and don't map cleanly to current main; port separately if
    still wanted.
  • Follow-up: land the stop-indicator (feat/chat-ao-stop-indicator) into BaseChatController.
  • Retires ewoncma as a long-lived branch once merged.

Test URLs:

Second step of decoupling the chat controller (see
docs/chat-ao-controller-decoupling.md): the CMA bridge path now has its own
subclass instead of sharing the AO-direct controller.

- cma-chat-controller.js: CmaChatController extends Base. Routes the socket to
  the bridge (CMA_BRIDGE_WS_BASE) with activationKey + x-site on one AUTH frame,
  maps bridge auth rejections to tester-facing copy, routes the skills catalog
  to the bridge, and resumes the last session for the site on reload via a
  per-site sessionStorage pointer (the bridge replays history on attach).
- base: _attach/reattachIfIdle and a default attach-only warmSession move to
  Base (both harnesses use them); Coworker keeps the REST warm override.
- chat-ao.js: selects CmaChatController vs CoworkerChatController from the
  ew.altHarness flag once config resolves, passing the activation key.
- skills.js: fetchSkills routes to the bridge REST plane (+ x-user-id) when an
  activation key is present; AO path unchanged.
- ao-constants.js: CMA bridge WS/HTTP bases.
- 10 CMA-subclass tests; 326 chat-ao tests pass total.

Folds in the resume-on-reload work (supersedes feat/chat-ao-resume-main) and
absorbs the ewoncma CMA client features onto current main.
@anfibiacreativa
anfibiacreativa added this pull request to stack #812 October 3, 2026 07:43
@aem-code-sync

aem-code-sync Bot commented Oct 3, 2026

Copy link
Copy Markdown

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

This branch was successfully deployed

1 active deployment
feat/chat-ao-cma-subclass — 059552a4 Deployed Oct 3, 2026 by aem-code-sync[bot]
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