273 Commits

Author SHA1 Message Date
github-actions[bot] 04b445a04d style: auto-fix formatting 2026-07-31 18:58:10 +00:00
Maxim a40427a6f3 docs(reskinnable-demo): state the cardsRef sync trade-off honestly
The previous comment presented the effect-based ref sync as merely avoiding
the react-hooks/refs lint rule. It is a trade-off: the render reads
cardsRef.current, and an effect writes after commit, so a card mutation
landing while the PIN card is open can leave the picker one render behind.
Records why that is accepted and what fixing it properly would require.
2026-07-31 20:55:38 +02:00
Maxim 08e10deb59 Merge branch 'blitz/banking-genui-replay/report' into blitz/reskinnable-demo-port/integration 2026-07-31 20:51:24 +02:00
Maxim 52461637ff feat(reskinnable-demo): port PIN, charges-confirm and note polish to the banking skin
Replays three generative-UI changes from the banking showcase (#6259) into
the reskinnable demo's banking skin:

- setCardPin keys its collapsed render on the tool result and remembers
  answered calls in a module-scope map, so a resolved PIN change survives
  re-render. Drops the [cards] dependency in favour of a ref, which is what
  stopped the tool tearing down mid-flight.
- showCharges becomes human-in-the-loop: it asks before moving the user's
  whole screen, and routes through the skin-scoped base prefix.
- Notes about reported charges are prefixed with a red alert emoji.
2026-07-31 20:49:05 +02:00
Maxim 3a2ea211a0 feat(reskinnable-demo): curate the banking report charts to the final trio
Replays the report chart curation from the banking showcase (#6259, #6263)
into the reskinnable demo's banking skin. The three columns become spend
breakdown, spend over time and largest charges — the last of which answers
"which line items drive the total", a question a three-team aggregate
cannot. Additions carry a policyId so their bars colour by owning team.
2026-07-31 20:46:45 +02:00
Maxim e5b54d81b8 Merge branch 'blitz/banking-genui-replay/seed-policy' into blitz/reskinnable-demo-port/integration 2026-07-31 20:41:01 +02:00
Maxim 83d3bfa31a Merge branch 'blitz/banking-genui-replay/seed-memo' into blitz/reskinnable-demo-port/integration 2026-07-31 20:41:00 +02:00
Maxim 5af07bf489 Merge branch 'blitz/banking-genui-replay/charges-tint' into blitz/reskinnable-demo-port/integration 2026-07-31 20:41:00 +02:00
Maxim 109583caf4 Merge branch 'blitz/banking-genui-replay/prompt' into blitz/reskinnable-demo-port/integration 2026-07-31 20:40:59 +02:00
Maxim 37cf227d8b Merge branch 'blitz/banking-genui-replay/top-charges' into blitz/reskinnable-demo-port/integration 2026-07-31 20:40:59 +02:00
Maxim d9d50139e7 Merge branch 'blitz/banking-genui-replay/pin-card' into blitz/reskinnable-demo-port/integration 2026-07-31 20:40:59 +02:00
Maxim a6c5c93238 feat(reskinnable-demo): tint the charges Sort and Show selects when set
Ports the brand-tint treatment for explicitly-set filter selects from the
banking showcase charges page (#6259) into the reskinnable demo's banking
skin, so an agent-applied filter reads as deliberate.
2026-07-31 20:39:59 +02:00
Maxim ec00c42c50 feat(reskinnable-demo): rebalance seeded policy limits in the banking skin
Ports the seed rebalance from the banking showcase (#6259) into the
reskinnable demo's banking skin so the report's spend-share donut shows a
meaningful split rather than three near-equal slices.
2026-07-31 20:38:50 +02:00
Maxim 9eef856d29 feat(reskinnable-demo): add TopChargesChart to the banking skin
Ports the ranked largest-charges chart from the banking showcase (#6263)
into the reskinnable demo's banking skin. The report-card wiring that
consumes it lands separately.
2026-07-31 20:37:21 +02:00
Maxim 4b4b937599 feat(reskinnable-demo): seed the alert-emoji note convention in the banking skin
Ports the red-alert-emoji instruction from the banking showcase seeded
memories (#6259) into the reskinnable demo's banking skin, so recalled
memory drives the same note formatting.
2026-07-31 20:37:05 +02:00
Maxim a83afc6db8 feat(reskinnable-demo): add prose house-style rules to the banking prompt
Ports the "format prose the same way every time" instruction block from
the banking showcase agent prompt (#6259) into the reskinnable demo's
banking skin, where the prompt lives in agent.ts rather than the route.
2026-07-31 20:36:29 +02:00
Maxim 92756f4a41 feat(reskinnable-demo): add PinChangedCard to the banking skin
Ports the resolved-state PIN card from the banking showcase (#6259) into
the reskinnable demo's banking skin. The consumer wiring lands separately.
2026-07-31 20:36:27 +02:00
Maxim c8fd81a4fe feat(reskinnable-demo): add NavigateConfirmCard to the banking skin
Ports the confirm-before-navigate chat card from the banking showcase
(#6259) into the reskinnable demo's banking skin. The showCharges
human-in-the-loop wiring that consumes it lands separately.
2026-07-31 20:36:02 +02:00
Maxim 916f4b7f24 Merge remote-tracking branch 'origin/main' into blitz/reskinnable-demo-port/integration 2026-07-31 20:31:11 +02:00
Maxim acd8d0715a feat(reskinnable-demo): isolate memory by organization as well as port
Points this app at the stack's second seeded organization
(haus-von-haskell) instead of the one banking uses (casa-de-erlang). Org is
resolved from the authenticated cpk key, and seed.sql already provisions three
orgs for exactly this, so it is a key swap with no backend change.

Ports and orgs isolate on independent axes and the second one matters: ports are
a local convention that copying banking's .env over this one silently undoes,
whereas the org key still holds when someone does. Verified against a freshly
seeded stack — writing under one key is invisible to the other even for an
identical user id, so neither demo can read or delete the other's memories.

Also corrects an inherited claim. banking's .env.example warns that non-seeded
ids 403; measured, they do not — GET/POST /api/memories returns 200/201 for an
unseeded id and for a nonsense one, the scope being created on demand. That
mattered because DEMO_DEFAULT_USER_ID is absent from seed.sql, so the warning
implied the unpinned interactive config it recommends was broken. It is not.
2026-07-31 19:04:05 +02:00
Maxim 3453b228e2 feat(reskinnable-demo): make the resolved Intelligence backend explicit
This app and the sibling banking demo vendor the same durable-memory stack with
identical seeded ids and api key, so which backend a process attached to was
invisible — a `pnpm dev` pointed at the neighbour's live stack shared its memory
buckets silently, and the presenter reset could mutate the other demo's state.
Surface the target so a human notices:

- Runtime route logs the resolved Intelligence API URL once at startup when
  memory is enabled ("[reskinnable-demo] Intelligence: <url>  (memory enabled)").
  Never logs the api key or license token.
- The destructive presenter reset now names its target: it logs a warning with
  the apiUrl and the exact user ids before forgetting, and includes the resolved
  apiUrl in both the success and error response bodies so the caller can see
  which backend was mutated. Behaviour is otherwise unchanged (same ids forgotten,
  same PRESENTER_RESET_ENABLED gate, no confirmation prompt); only observability
  improves. route.test.ts updated to assert the new apiUrl field, still exact.
2026-07-31 17:04:26 +02:00
Maxim 9fe2714d24 fix(reskinnable-demo): shift Intelligence stack host ports by +200 to isolate from banking
reskinnable-demo was cloned from examples/showcases/banking and vendors an
identical Intelligence (durable-memory) docker stack — same seeded ids
(jordan-beamson / morgan-fluxx / northwind-demo-user), same INTELLIGENCE_API_KEY
and org. Both apps identified their backend purely by address, and both pointed
at http://localhost:7050. So with banking's stack already up, a bare `pnpm dev`
here (which, unlike run-demo.sh, checks no port bind) would silently attach to
banking's backend and read/write the SAME memory buckets — worst case, the
presenter reset button forgetting the neighbour demo's memories.

Shift every published host port by +200 (705x/715x -> 725x/727x) in lockstep
across compose, env, scripts, e2e config and tests so attaching to the wrong
stack is impossible by accident:

  app-api        7050 -> 7250
  gateway        7053 -> 7253
  postgres       7156 -> 7256
  redis          7158 -> 7258
  minio API      7160 -> 7260
  minio console  7161 -> 7261
  bundled TEI    7167 -> 7267

The native Metal TEI on :7067 is left shared ON PURPOSE: it holds no demo state
(buckets live in the now-isolated postgres/redis), the same TEI version + model
yields byte-identical embeddings, and run-demo.sh reuses it when healthy rather
than forcing a second ~20x-slower model load. A comment records why.
2026-07-31 17:04:16 +02:00
David McKay de2bc6efc0 feat(banking): rank largest charges instead of repeating the team split
The report's third column was budget-usage bars: the same three team totals the
donut beside it already showed, redrawn with limits added. Two charts, one fact.

It now ranks the largest individual charges, which changes the unit of analysis
from team to transaction. A team aggregate cannot distinguish one $15,000
charge from thirty $500 ones, so this is information the donut genuinely cannot
carry. Bars stay coloured by owning team, so a row still ties back to its slice
without the two charts duplicating each other.

Budget-vs-limit is not lost: it remains the "Over policy limit" KPI above and
the "Needs a decision" rows below.

Invoice-derived line items now carry the policy id of the team they belong to,
so they colour like any other charge. Without it they fell back to a generic
swatch and a Marketing charge did not match Marketing's slice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 13:11:26 -07:00
Maxim 4b8b6572d9 chore(reskinnable-demo): retarget the demo tooling
Points the demo runner, smoke scripts and env template at the skin-scoped
routes and relocated modules, and gives the vendored Intelligence stack its own
compose project name.

That last one matters: cloned from banking, this app inherited the same project
name, so both stacks resolved to one Docker project sharing containers and
named volumes — a compose down in either destroyed the other's memory. The
smoke scripts also still posted to /agent/default/run, which no longer exists
now that agents are keyed per skin; nothing in the toolchain reads those files,
so no build or test could have caught it.
2026-07-30 21:49:02 +02:00
Maxim 1387f32dee docs(reskinnable-demo): document the architecture and add the reskin skill
Describes the app that exists: shell versus skins, the Skin contract field by
field, the client/server boundary that keeps a skin's agent out of the browser
bundle, per-skin server identity, and the theming split. Adds a repo-local
authoring skill that walks someone through creating a skin and registering it
in both registries.

The inherited docs described a single-skin banking demo, which was actively
misleading once a second skin shipped, and carried claims that were false here
— that OGUI can only render inline in the chat (a published-SDK limitation
that does not apply on workspace packages) and that the airline skin omits
every optional contract slot when it ships nine tool labels.
2026-07-30 21:49:02 +02:00
Maxim 12b1ac6b0d test(reskinnable-demo): cover reskinning and retarget the suite
Retargets the e2e suite onto skin-scoped routes and covers the app's headline
feature for the first time: the index redirect, each skin rendering its own
chrome, an unknown skin 404ing, and switching in both directions.

Those assertions check content only a mounted skin can produce. An earlier
draft matched on brand text, which the shell's skin selector renders on every
page for every skin — so it passed against a deliberately broken airline. Each
assertion here was verified by breaking the app and watching it fail.

ogui-routing is marked fixme: it clicks seven suggestion pills, six of which
were dropped from the registered set before this change, so it has been
failing on main unnoticed — nothing runs this suite in CI.
2026-07-30 21:49:02 +02:00
Maxim 4ad47517aa feat(reskinnable-demo): route by skin
/[skin] resolves a skin from the URL and mounts it keyed by its id, so
switching fully remounts into a fresh world; / redirects to the default skin.
The runtime route registers one agent per skin and resolves end-user identity
through that skin's resolver, falling back to the default skin for app-level
routes such as the inspector's memory endpoints.

globals.css now defines only the design-token vocabulary plus a brand-neutral
default set; each skin supplies its own values through a .theme-<id> block, so
a reskin is a pure value swap and the shared chrome styles itself with
semantic utilities.
2026-07-30 21:49:01 +02:00
Maxim 788783bb58 feat(reskinnable-demo): add the airline skin
A second skin — identity, theme, app-shell, three pages, ten presentational
components, frontend tools, a2ui catalog, suggestions and an OGUI design
brief — sharing nothing with banking beyond the contract and a few primitives.

It backs its data with plain client state rather than a REST API and
contributes no identity resolver, so the contract is exercised across both
substrates. A contract that only ever hosted one kind of skin proves much
less than one that spans two.
2026-07-30 21:49:01 +02:00
Maxim 00f95834e5 feat(reskinnable-demo): make banking a self-contained skin
Banking's domain types, in-memory store, seed data, REST backend, components,
gen-UI beats, a2ui catalog, OGUI sandbox, pages, tools and agent now live
entirely under src/skins/banking, and its backend is namespaced to
/api/banking/v1 rather than mounted at the app root.

Every route under it is banking domain — cards, transactions, exceptions,
policies, reports, users, dev/reset — so with a second skin sharing the app,
leaving one skin's whole backend at the root contradicts the premise that
skins are self-contained. Shared UI primitives stay in src/components/ui,
which the shell and both skins import.

Banking contributes its identity through the contract (RuntimeProviders +
useRuntimeProperties) so the CopilotKit provider owns the active member from
its first commit, and a server-safe resolver so Intelligence scopes memory to
the selected persona.
2026-07-30 21:49:01 +02:00
Maxim 651f7dd7aa feat(reskinnable-demo): add the skin-agnostic shell and Skin contract
The shell owns everything independent of which skin is mounted: the Skin
contract, a provider that runs a skin's data hook, split client/server
registries, the chat surface, the a2ui/OGUI canvas region and thread
selection.

The client/server split is deliberate. A skin's agent pulls in
@copilotkit/runtime, which must never reach the browser bundle, so agents are
registered in a separate server-only registry and linked to their skin by a
shared id rather than by being part of the client contract. Skins may also
contribute a server-safe identity resolver there, which is what lets per-user
durable memory be scoped per skin instead of the runtime hard-coding one.
2026-07-30 21:49:01 +02:00
Maxim 3790bbb431 feat(reskinnable-demo): add the app to the workspace
Registers examples/showcases/reskinnable-demo as its own pnpm workspace member
resolving @copilotkit/* via workspace:*, alongside the other showcases.

No dependency differs from the banking showcase this app started as: the
standalone prototype's recharts dep is unused (banking hand-rolls its SVG
charts), and the airline skin's lucide icons all exist in the pinned range.
2026-07-30 21:49:00 +02:00
David McKay 269d49a2c0 feat(banking): generative-UI polish for PIN, charges, report and notes
Five presentation fixes to the Northwind Finance demo, all from running the
beats live.

PIN change now resolves into a card rather than the sentence "New PIN saved."
It shows the card face, brand and last4, a masked new-PIN row and an active
badge. Digits are never rendered: they are never sent to the agent, so the mask
is the honest representation.

Reopening a thread replays setCardPin with status "inProgress" and no result,
so the answered card sat on "Loading..." forever. Other human-in-the-loop tools
here (showCharges) do replay their result, so this is specific to that call.
The outcome is now remembered per tool call id for the session and consulted
ahead of the replayed status. Both this card and the charges card key their
resolved state on the RESULT rather than the status, so an answered call can
never replay with live buttons.

setCardPin also registers once via a ref instead of depending on `cards`:
useFrontendTool re-registers whenever JSON.stringify(deps) changes and
re-registration removes the tool, so the PIN write tore down the very tool that
was servicing it.

showCharges becomes human-in-the-loop. Opening a filtered list is safe, but it
replaces the whole screen, and an agent that does that unasked reads as the
agent being in charge. The confirm card names the sort and filters before the
page changes, and on arrival the Sort and Show controls carry the brand tint
whenever they are non-default, so what the agent set is what lights up.

The Q2 report shows three different chart forms (share-of-total pie, time
series, budget bars) instead of three bar charts, and the seed is rebalanced so
team shares read 42/28/30 instead of 98/2/2 while all three pending charges
still exceed their limits. This drops the income-vs-expenses chart that was
showing $0.00.

Notes about reported charges carry a leading alert emoji so they cannot be
skimmed past. The seeded procedure asks for it and the handler applies it
regardless, because a model is not a reliable emoji emitter.

Finally, prose answers get a house style. The agent was formatting the first
few bullets of a list and then lapsing into plain text, which reads as a
rendering bug rather than a style choice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 11:12:00 -07:00
Maxim 1e575233e6 test(banking): make the memory-recall e2e approval loop actually completable
The approval loop could never pass, independent of the demo's behavior:

  for (let step = 0; step < 4; step++) {
    const approve = page.getByRole("button", { name: /^approve$/i });
    await approve.first().click({ timeout: 30_000 }).catch(...)
  }

Two compounding problems. The recall path emits at most three HITL cards
(openPolicyException -> finalizePolicyException -> approveTransaction) but the
loop demanded four, so the last iteration always waited on a card that never
arrives. And the per-click timeout (30s) equalled the whole test budget
(playwright.config.ts sets no `timeout`, so Playwright's 30s default applied),
so the first miss consumed the entire test and the `.catch()` fallback to the
other APPROVE_LABELS was unreachable dead code.

Now: poll every label for the next visible approve control, treat "no card
left" as flow completion rather than a timeout, keep a runaway guard that is
explicitly not the expected card count, and give the test a budget that can
actually hold one agent turn plus the closing server poll.

Confirmed against a local run (aimock + the docker Intelligence stack): the
agent recalls the procedure, files the EXC-BOARD-APPROVED exception, and
approves the charge, and the "Record a workflow?" card never appears. The
header's "verify on first green run" notes are updated to record what that
run settled and what it did not.

The spec still fails at its closing assertion: PUT /api/v1/transactions/t-3
{status:"approved"} keeps returning 422, i.e. store.hasApprovedException() is
false, so the over-limit gate is never lifted even though the (fixture-scripted)
agent text claims it was. That is pre-existing and out of scope here — this PR
touches no part of the approval path (lib/store, the exceptions/transactions
routes, copilot-context, components/wow are all untouched). Left failing rather
than skipped so it stays visible.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 15:27:08 +02:00
Maxim 0850c5e522 Merge remote-tracking branch 'origin/main' into blitz/glass-inspector/integration
Realigns the inspector/memory work onto the banking demo as it shipped in
#6136 (ChatGPT-style shell, gen-UI beats, durable-memory self-learning) and
#6202 (README refresh).

All six conflicts were the same collision: this branch removes the bespoke
Glass Engine inspector, while #6136 kept and rebuilt around it.

- run-handler.ts: kept both sides (our CopilotKitCoreCatalogComponent and
  main's MAX_FOLLOW_UP_DEPTH landed at the same spot).
- wrapper.tsx / layout.tsx: took main's rewritten provider tree and
  right-hand icon rail, minus the Glass Engine providers, pane, and
  telescope toggle. Also dropped main's `padClass` (it reserved space for
  the Glass pane and referenced a now-removed `glassActive`) and
  `<ProactiveNotice />` (main removed it; the import is already gone).
- memory-tab.tsx, lib/intelligence/memory.ts: confirmed the deletions.
  Their only remaining importers were the bespoke inspector and the
  banking-local /api/memories routes, all removed here. seed-memories.ts
  is unaffected: it POSTs to INTELLIGENCE_API_URL, not the local route.
- README.md: kept our product-inspector section over main's Glass Engine
  availability/activation prose, and documented the Capabilities tab.

Drive-by fixes to comment rot the migration created: user-id.ts and the
copilotkit route doc comments referenced the deleted Memory-panel proxies,
and the README pointed the presenter-reset control at the removed
telescope toggle.

Also replaces a literal NUL byte in capabilityKey() with a unicode escape.
The raw control character made tsc/grep/diff treat run-handler.ts as a
binary file, which hid this very merge's conflict markers from grep.
Behavior is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 21:10:21 +02:00
David McKay b2f4b47a2d docs(banking): refresh the demo README to match what shipped
#6136 changed the demo substantially and left the README describing an older
build. Corrections:

- It documented CopilotPopup; the chat is a left-docked CopilotSidebar rendering
  two columns (thread rail + conversation) with the app's nav rail on the right.
- It called the learned over-limit memory `procedural`; the code writes
  `operational`.
- It said the Glass Engine Memory tab was "top-k semantic recall, not a full
  enumeration". It is now a complete enumeration ("Stored memories (N)"),
  aggregated across the demo's identities, with semantic search as a separate
  box.
- It listed per-run reset as a future follow-up. It ships, gated behind
  PRESENTER_RESET_ENABLED, and also re-seeds memory and returns to the bare root.
- It described showTransactions as a useFrontendTool; it is a useComponent so it
  persists in the transcript.
- The "change my Visa PIN from the team page" example described a navigation
  fallback; PIN entry is now a component in the chat and the agent never sees the
  digits.

Adds what was missing: the eight-pill demo script, the /charges page, the PDF/Q2
multimodal beat, seeded memory (and why the over-limit procedure is deliberately
NOT seeded), the components-not-markdown-tables rule, per-team chart colour, and
the two incompatible helper families in actions.ts that make destructuring `ok`
report a success as a failure.

All three screenshots are replaced — they showed the old right-docked chat, so
they contradicted the first paragraph.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 09:22:11 -07:00
David McKay 66a6af5d3e feat(banking): ChatGPT-style shell, gen-UI beats, and durable-memory self-learning
Turns the Northwind Finance banking demo into a presentable end-to-end demo.
Every beat was driven live and verified against real app state, not just the
agent's own claims.

The demo is eight suggestion pills, in order: show a chart; change a card PIN in
an interactive in-chat component; ask what is on screen; open the 10 most
expensive charges; prep the Q2 report from an attached PDF invoice; summarize
spend using a remembered preference; handle an unrecognized charge using a
remembered procedure; and finally learn a brand-new procedure by watching the
officer clear an over-limit charge. The last three are sequenced deliberately:
already-knows-a-preference, already-knows-a-procedure, learns-a-new-one — and on
a fresh thread the newly learned procedure is recalled and applied to a
different charge unaided.

Shell and UI:
- Chat docks LEFT as two columns (thread rail + conversation) with the app's
  icon rail moved right via flex `order`, so nav still precedes <main> in the
  DOM. The chat surface runs ChatGPT's neutral palette while the app keeps its
  violet identity.
- Tool activity renders as ChatGPT-style expandable lines; internal AG-UI
  plumbing is filtered out of the transcript.
- Tabular data always renders as components, never markdown tables; a one-row
  table is blocked structurally because a single-record table is narration.
- Filed reports are a dashboard (KPI tiles, three charts, decision rows) rather
  than a memo, with one colour per team across every chart and ranked bars in
  place of a donut that collapsed when an invoice pushed one team to 96%.
- PIN entry happens in the chat component; the agent never asks for or receives
  the digits.

Fixes worth review attention:
- Anything a RECALLED procedure can call must be registered globally. Four
  action tools were registered on the cards route, so a saved procedure only
  worked from one page.
- An unanswered human-in-the-loop card poisons the thread: skipping it left an
  unresolved tool call and the next message failed with "Tool result is missing
  for tool call ...". The procedure's closing step no longer gates; approvals
  that move money still do.
- actions.ts has two helper families that are not interchangeable —
  openPolicyException / finalizePolicyException / changeTransactionStatus return
  {ok, data/error}, while changePin / addNoteToTransaction resolve with the
  updated record. Destructuring `ok` off the second family reports success as
  failure.
- A stale canvas surface hid the page: it is derived from the last a2ui-surface
  message and replaces the page body until dismissed, but the dismiss effect
  keyed on pathname only, so a ?tab= switch left it covering the page.
- Suggestion pills ignore clicks while a run is in flight, since a double-click
  orphaned the previous run's tool call.

Deliberately NOT included: the @copilotkit/license-verifier pnpm patch (local
workaround for the "Invalid license token" banner) stays uncommitted, because it
patches a dependency for every install and is not demo scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 16:22:36 -07:00
Maxim f6d6d70fb7 chore(banking): finalize product inspector migration
Drop the stale doc-comment reference to the deleted src/lib/glass-engine.ts in
presenter.ts (final verification sweep).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:12:28 -07:00
Maxim 49c4ded95e docs(banking): replace Glass Engine docs with product inspector
Remove the GLASS_ENGINE_AVAILABLE env block from .env.example and replace the
README's 'Advanced mode — Glass Engine' section with a note on the product
web-inspector (enabled via showDevConsole; Memory tab powered by
exposeMemoryRoutes in Intelligence mode).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:11:31 -07:00
Maxim be07ba7782 test(banking): retarget memory-learning e2e off the bespoke inspector
Delete the final e2e test that drove the bespoke Glass Engine pane and remove
the GLASS_ENGINE_AVAILABLE env from both playwright configs. Self-learning
recall stays covered by the headless recall test; the product web-inspector is
covered by packages/web-inspector's own tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:10:38 -07:00
Maxim 3e0d8aa00e refactor(banking): delete bespoke inspector, glass gate, and dead memory routes
Delete the 13 Glass Engine inspector files (pane, tabs, event store, event-card
mapping, deployment gate, env gate) and their tests, the dead Next /api/memories
proxy routes, and the now-unused src/lib/intelligence/memory.ts helper module
(+ test). Memory now flows through the product path (core memory store →
runtime /api/copilotkit/memories) rather than the banking-local Next proxies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:09:19 -07:00
Maxim 9f40ebe2a2 refactor(banking): remove Glass Engine deployment gate from layout
Drop useGlassEngine(), the Telescope toggle button, and the glassActive-driven
body padding from the app layout. The product inspector launcher replaces the
telescope toggle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:07:46 -07:00
Maxim 2614060266 refactor(banking): drop bespoke inspector providers from wrapper
Remove the GlassEngineProvider / InspectorStoreProvider wrappers and the
<InspectorPane/> mount from the client tree, and drop the glassAvailable prop
(and its server-side threading in layout.tsx). The product web-inspector
enabled in the prior commit replaces the bespoke pane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:07:46 -07:00
Maxim fc085e2a3a feat(banking): enable product web-inspector via showDevConsole
Set showDevConsole={true} on the CopilotKitProvider to surface the product
web-inspector on every host, and set exposeMemoryRoutes: true on the
Intelligence-mode CopilotRuntime so the inspector's Memory tab can list and
recall memories in the demo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:04:49 -07:00
David McKay a9c0910dea Merge branch 'main' into feat/banking-open-generative-ui 2026-07-09 12:07:23 -07:00
Maxim c1819f4932 test(banking): correct OGUI double-pill rationale comment
The .first() guard on the 'rendered on the canvas' handoff-pill assertion
was justified by an inaccurate comment (accumulation across exchanges). The
real cause is intra-turn: generateSandboxedUi has followUp:true, so aimock
re-serves the same fixture on the unchanged-userMessage follow-up turn in
replay -> a second identical pill. A terminating sequenceIndex follow-up
fixture was attempted but destabilized the suite (title-generation requests
substring-match the pill text and consume the sequence counter before the
real leg-1 turn), so the .first() guard remains. Test/fixtures only; no
source changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 20:34:29 +02:00
github-actions[bot] 87b6fa330d style: auto-fix formatting 2026-07-09 17:34:36 +00:00
Maxim cd7e49e467 test(banking): OGUI routing asserts the canvas surface 2026-07-09 19:27:57 +02:00
Maxim c541f1b32d feat(banking): render OGUI surfaces on the canvas with a chat handoff pill 2026-07-09 19:14:50 +02:00
Maxim 001b915af2 feat(banking): useOguiSurface reads the latest OGUI activity from the stream 2026-07-09 18:49:37 +02:00
Maxim c54148412a test(banking): deterministic OGUI routing guard over the adjacency set
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 16:43:47 +02:00