Skip to content

🚧 feat: Mycal — in-app AI agent chat (dev preview, do not merge) - #1176

Draft
thelg4 wants to merge 39 commits into
mainfrom
feature/agent-chat-interface
Draft

🚧 feat: Mycal — in-app AI agent chat (dev preview, do not merge)#1176
thelg4 wants to merge 39 commits into
mainfrom
feature/agent-chat-interface

Conversation

@thelg4

@thelg4 thelg4 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Important

Do not merge. This PR exists to spin up a preview/staging build so people can try the feature. Opened as a draft to keep it un-mergeable.

What this is

Mycal: an AI chat panel embedded in the desktop app, backed by the sibling ai-agent service. Always on in local dev builds; in deployed builds it soft-launches behind the hidden Test UI.

Trying it on the preview build

  1. Hold shift+option (alt) and click your avatar (bottom-left) → choose Test UI
  2. The robot icon appears in the header — that's the chat toggle
  3. Go to Settings → Test Settings → enable "Override agent service":
    • Agent service URL: https://dev-ai-agent.remote.it
    • Agent MCP audience: https://mcp.demo.remote.it/mcp
  4. Open the chat, sign in to the agent when prompted, and talk to it

What's in the branch

  • Chat panel — docked column beside the app panels with streaming replies, tool-call display, and write-action approval prompts
  • Agent sign-in — separate Hydra OAuth session (PKCE + dynamic client registration); tears down with app sign-out
  • Org scoping — the chat follows the app's active org (sidebar selector) and sends it with each turn so the agent scopes org queries without hunting; shown as a read-only "Current Org" label
  • Popout window — the chat pops out to its own window (native window in Electron) and hands the conversation back on pop-in/close
  • Test Settings overrides — point the chat at any deployed agent (URL + MCP audience), no env changes
  • UX polish — user-facing unavailable/sign-in states, app-standard styling, themed scrollbars

Known blockers for a real reply

  • The deployed agent's Anthropic API key secret needs re-saving as plaintext + a service redeploy (chat turns currently return an upstream auth error)
  • ai-agent main is missing the tool-discipline prompt changes (stranded on feature/chat-org-scope); a rebuild after that lands improves org-scoped behavior

Comment thread frontend/src/services/agent.ts Fixed
Comment thread frontend/src/services/hydra.ts Fixed
@aws-amplify-us-west-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-1176.d20k671nqqv4kl.amplifyapp.com

@JamieRuderman JamieRuderman changed the title feat: Mycal — in-app AI agent chat (dev preview, do not merge) 🚧 feat: Mycal — in-app AI agent chat (dev preview, do not merge) Aug 5, 2026
thelg4 and others added 27 commits August 10, 2026 15:19
Docked right-column chat talking to the ai-agent service over SSE:
- ChatPanel/ChatMessages/ChatToolCalls/ChatApproval/ChatInput components
- Persisted chat model (transcript, streaming, write-tool confirmations)
- Panel width folds into sidePanelWidth so all panel layouts reflow
- Expand toggle (400px/640px), full-screen overlay below single-panel width
- Vite dev proxy /agent -> :3001 (CSP-safe); VITE_AGENT_URL for deploys
- react-markdown + remark-gfm for assistant replies
- Dev-gated: header robot toggle and panel render only in dev builds
Stage A of agent auth: attach Authorization from a locally stored token
(pasted from the ai-agent dev harness) on chat/confirm/health calls,
surface 401 reauth_required and mid-turn auth failures as a sign-in
notice with a token paste field. The in-app PKCE flow replaces the
paste field as the token writer in a later stage.
Replaces the pasted-token stopgap: a Sign in button self-registers an
OAuth client (Dynamic Client Registration), redirects to the Hydra
login/consent pages, exchanges the code on return (PKCE), and silently
refreshes the 30m access token before each turn. Register/token calls
ride the new dev-only /hydra vite proxy so no CORS setup is needed;
packaged builds need the origin allow-listed or a main-process exchange.
Amplify's OAuth listener consumes and strips ?code/state on page load for
the Cognito flow; the Hydra callback uses the same params on the same
origin, so the agent exchange never ran and sign-in looped. Capture the
params at module-evaluation time (before Amplify configures), claim them
only when this tab started an agent sign-in, and strip the URL
immediately so neither flow double-handles the code.
App sign-out now clears the stored Hydra access/refresh tokens, resets
the chat transcript, and best-effort revokes the refresh token at Hydra
so the otherwise never-expiring refresh chain dies server-side. Local
credentials are cleared synchronously so a sign-out-triggered reload
cannot race the revoke call.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fall back to membership.name in ChatOrgSelect and chat.ts send() when
organization.accounts is unloaded, so org scope never silently
degrades to personal; guard against a whitespace-only name so the
client never sends one the server's non-empty-after-trim validation
would reject. Force-adopt the app's active org on the first syncOrg
after load so orgId (redux-persisted) doesn't survive page reloads,
per the "not persisted" spec decision, while preserving intra-session
divergence across panel close/open.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Matches the ai-agent service's move off mcp.evan.remote.it (older
build without org-scoped list_scripts). The client cache key includes
the audience, so a fresh sign-in re-registers automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AGENT_PROXY_TARGET in frontend/.env points the same-origin /agent proxy
at a deployed agent (e.g. http://dev-ai-agent.remote.it) instead of the
local dev service — the proxy hop keeps CSP satisfied while the ALB is
HTTP-only.
Replaces the dev-facing ':3001' banner: zero-state layout (matching the
sign-in state) when the chat is empty, compact notice above an existing
transcript, and the input disabled while Mycal is unreachable.
The org sidebar (bottom-left avatar stack) is now the single org
selector: the chat mirrors accounts.activeId and shows a read-only
'Current Org' label where the dropdown was. The popout window keeps
the org handed off with its conversation. The request to the agent
is unchanged (org { id, name }, omitted for Personal).
thelg4 added 4 commits August 10, 2026 15:21
Test Settings gains an 'Override agent service' toggle with agent URL
and MCP audience fields (persisted like the existing API overrides).
agentURL() and mcpAudience() resolve per request: the override wins
when enabled (https only — CSP blocks plain http), otherwise dev rides
the vite proxy and builds use VITE_AGENT_URL. Changing the audience
busts the OAuth client cache, so a fresh agent sign-in just works.
MODE === 'development' gates become useChatEnabled(): always on in
local dev, and on in deployed builds when the hidden Test UI is
enabled (shift+option on the avatar menu). Also documents the
dev-ai-agent/demo-audience pairing in Test Settings for staging
testers, whose build default is the beta audience.
The /hydra vite proxy only exists in dev; staging/preview builds 404'd
the agent sign-in's register and token calls. Hydra's public CORS
allows any origin, so builds can hit the issuer directly.
login.dev.remote.it answers CORS preflights without an allow-origin
header, so direct browser calls from deployed previews are blocked.
The /hydra path is served by the vite proxy in dev and an Amplify
rewrite rule on previews.
@thelg4
thelg4 force-pushed the feature/agent-chat-interface branch from 918c246 to 33dd524 Compare August 10, 2026 20:47
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