Skip to content

feat(composer): move Conversation Mode to the composer, delete the drawer - #1079

Merged
philmerrell merged 1 commit into
developfrom
feature/composer-mode-drop-drawer
Sep 13, 2026
Merged

philmerrell merged 1 commit into
developfrom
feature/composer-mode-drop-drawer

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

Step 5 of docs/specs/customize-surface.md. The settings drawer and its icon are gone. −2293 / +461.

⚠️ The plan was wrong about Conversation Modes

The spec had Modes retired in step 6 as "a strictly weaker Agent", on the premise they were dormant (untouched since PR #411). They are not. Measured against the prod account:

Enabled modes in prod 1 — Guided Learning (Socratic tutoring)
Sessions using it 81
July / Aug / Sept 1 / 20 / 60 — and September is 12 days old

Deleting the drawer as written would have removed a growing, pedagogically-meaningful feature outright.

This is the second time "git history says dormant" has misled on this epic — step 3's thinking param was the inverse, declared in curated-models.ts and absent from the deployed records. Check the data in the environment that matters.

Where Mode went

Skills and Tools left for Customize because they're global. Mode couldn't follow: it applies to this conversation, and putting it on a global page would recreate the exact scope lie this epic exists to fix.

So it went the other way — into the composer, beside the model and effort controls. Those three are the same question: how should this conversation run. The old passive chip (which could display an active mode but never select one) is replaced by a picker that does both, with "None" carrying the chip's dismiss role. It renders nothing until an admin authors a mode, so most deployments see no new control.

That also reframes step 6 as reconsider, not execute: retiring Modes is hard to justify against growing use, and the migration isn't clean — a Mode applies to the conversation you're in; an Agent is a separate thing you start a chat with.

⚠️ Latent bug found while verifying, fixed here

The session page hydrates the active mode twice on load — provisionally (before session metadata arrives) and then for real. The provisional call claimed the session id, so the clobber guard in hydrateFromSession rejected the real hydration.

Not cosmetic: chat-request.service sends selected_prompt_id from activePromptId(), so after any reload the mode silently stopped being applied to every later turn while the stored preference still said it was on. On prod that's every Guided Learning user who reloaded mid-conversation.

The provisional call now passes claim: false. A deliberate "None" still claims, so stale metadata can't undo it — that edge has its own test. Fixed here rather than deferred because this change promotes the control to a first-class affordance; shipping it more prominently while knowing it silently drops would be worse than leaving it alone.

Open question, resolved

No composer pointer to Customize. The sidenav entry is the path — always visible, one click, the same shape Claude uses. Adding one would have reintroduced an icon to replace the one this removes.

Verification

  • ng test — 2805 passed; 14 new (8 picker, 6 hydration regression including the "None isn't clobbered" edge).
  • tsc --noEmit clean.
  • Browser-verified against a real backend: no settings icon, no drawer, picker silent with zero modes. Then seeded a temporary mode in dev and exercised the whole path — trigger shows "Mode" → select → named + accented + correct aria-label → "None" returns it → selection persists to session preferences ({"selectedPromptId":"zz-picker-test"}) → survives a reload (the bug above, before and after). Test record deleted and local .env restored afterwards; dev is back to zero modes.

Note DYNAMODB_SYSTEM_PROMPTS_TABLE_NAME is unset in the local .env, so the repository disables itself and returns [] silently — worth adding to .env.example, not done here.

🤖 Generated with Claude Code

…awer

Step 5 of docs/specs/customize-surface.md. The settings drawer and its icon
are gone; everything it held now lives where it belongs.

Skills and Tools left for Customize in step 1 because they are global. Mode
could not follow them: it applies to THIS conversation, and putting it on a
global page would have recreated the exact scope lie this epic exists to fix.
So it went the other way, into the composer beside the model and effort
controls — those three are the same question, how should this conversation
run. The old passive chip, which could display an active mode but never
select one, is replaced by a picker that does both.

⚠️ The plan said retire Modes in step 6 as "a strictly weaker Agent", on the
premise they were dormant. The premise was wrong. Prod carries one enabled
mode — Guided Learning, a Socratic tutoring prompt — and use is accelerating:
1 session in July, 20 in August, 60 in the first 12 days of September.
Deleting the drawer without this would have removed it outright.

⚠️ Fixes a latent bug found while verifying the picker. The session page
hydrates the active mode twice on load: provisionally, before metadata
arrives, then for real. The provisional call claimed the session id, so the
clobber guard rejected the real hydration. Because chat-request sends
selected_prompt_id from activePromptId(), the mode silently stopped being
applied to every turn after a reload while the stored preference still said
it was on. The provisional call now passes claim:false; a deliberate "None"
still claims, so stale metadata cannot undo it.

Fixed here rather than deferred because this change promotes the control to a
first-class composer affordance, and shipping it more prominently while
knowing it silently drops would be worse than leaving it alone.

No composer pointer to Customize: the sidenav entry is the path, which is
what the removed icon's replacement would otherwise have been.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@philmerrell
philmerrell merged commit b8898c0 into develop Sep 13, 2026
6 checks passed
@philmerrell
philmerrell deleted the feature/composer-mode-drop-drawer branch September 13, 2026 02:46
raoakkineni pushed a commit to AuraWorx/auraxai-agentcore-public-stack that referenced this pull request Sep 22, 2026
Clicking a tool in Customize → Tools now drills into
`/customize/tools/:toolId`, which carries what a browse card cannot:
the full description, an MCP server's tools one by one with their own
switches, the prompts and resources the server exposes, and the catalog
facts behind it.

Step 5 (Boise-State-Development#1079) deleted the composer drawer, so between that merge and
this page there is no per-sub-tool surface anywhere in the app — a user
who wants 3 of Canvas's 48 tools has nowhere to say so. This closes that.

The page descends from the drawer's `ToolDetailComponent` but is a new
component, not a port, for the reason the Customize list is not a port of
the drawer's list: the drawer was conversation-scoped
(`isToolShownEnabled()`, writes through the Agent lock) and this surface
is global (`tool.isEnabled`, `respectAgentLock: false`). Reusing it would
reopen the agent-lock seam the spec exists to close.

The drawer's tab strip did not come along. Tabs existed because the pane
was 320px; on a page, Tools / Prompts / Resources / About are stacked
sections, so find-in-page reaches all of them. The problem tabs were
solving — a 48-tool server — is solved directly: above eight sub-tools
the list grows a filter box.

Prompts and resources stay a read of the stored capability snapshot
rather than a live probe (probing opens an MCP session per server, and a
3LO server needs a consent token the browser does not hold), and stay
read-only (acting needs `prompts/get` / `resources/read`, which this
surface has no endpoint for). The snapshot is fetched only for
`mcp_external` tools — nothing else has a server that could be asked.

Colored text uses `text-primary-accessible dark:text-primary-accessible-dark`.
The numbered ramp fails WCAG AA here: with the brand primary at #0033a0,
`dark:text-primary-400` measures 2.59:1 against the dark page background,
where the accessible alias measures 4.52:1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
raoakkineni pushed a commit to AuraWorx/auraxai-agentcore-public-stack that referenced this pull request Sep 22, 2026
`dark:text-primary-400` resolves to #1e53c1, which fails WCAG AA in dark
mode. The repo already generates `--color-primary-accessible-dark`
(#437cee) for exactly this, and src/branding/README.md §7 documents the
pairing: `text-primary-accessible dark:text-primary-accessible-dark`.

Swaps the 6 remaining legacy occurrences across 4 files. Measured with
getComputedStyle against each site's real composited backdrop, in both
themes (light is unaffected: all 6 sit at 10.6:1 on white, except the KB
tint at 6.7:1).

                                     before   after   threshold
  agent-form +Add (text)              2.23     3.90     4.5  ⚠
  agent-form Show details (text)      2.23     3.90     4.5  ⚠
  create-training-job check (icon)    2.59     4.53     3.0  ok
  knowledge-base sparkles (icon)      2.48     4.31     3.0  ok
  mode-picker check (icon)            2.14     3.74     3.0  ok

⚠ The two agent-form buttons are the only real *text* of the six, and
they sit on a `dark:bg-gray-800/80` card rather than the page background.
The token is generated by findAccessibleLightnessDelta against the
resolved dark *surface* (gray-900, #101828), where it clears AA at
4.53:1. On the lighter card it lands at 3.90:1 — better than the 2.23:1
it replaces, and past AA-large, but still short of AA for text-xs/5.
Flagged rather than silently accepted: the fix belongs in the generator
(a card-surface variant), not in a one-off override here, since every
accessible-dark text on a gray-800 card has the same ~0.6 shortfall.

The four icon sites all clear the 3:1 non-text bar; three of them are
aria-hidden decorative anyway, with state carried by aria-checked.

The 5 other occurrences named in the original sweep are already gone:
71a8901 (Boise-State-Development#1079) deleted the model-settings drawer and the chat-input
attachment button along with it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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