Commit Graph

13442 Commits

Author SHA1 Message Date
Maxim 0f9524f1a9 feat(showcase): Glass Engine inspector pane shell (gates on active)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:43 +02:00
Maxim 7d38b93cf8 feat(showcase): Glass Engine Learning tab (event-driven teach->save->recall)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:43 +02:00
Maxim 8d9af0778d feat(showcase): Glass Engine Memory tab (event-driven recall + reframed list)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:43 +02:00
Maxim 9a805c1f78 feat(showcase): /api/memories proxy routes (404 availability gate + OSS degrade)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:42 +02:00
Maxim 9b1225ae19 feat(showcase): REST /api/memories/recall caller with per-user TTL cache
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:42 +02:00
Maxim 4090aa64e0 refactor(showcase): extract shared resolveUserId for runtime + memory proxy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:42 +02:00
Maxim 8ca184f91a feat(showcase): Glass Engine Timeline tab
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:41 +02:00
Maxim 1cb63e654c feat(showcase): AG-UI event subscription bridge for the inspector
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:41 +02:00
Maxim 03201c8ba6 feat(showcase): inspector store (React context) for timeline cards
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim 5239a6ce4c feat(showcase): AG-UI event->timeline-card mapping (banking-trimmed)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim f7a80553d0 feat(showcase): GlassEngine context with availability + activation gates
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim a6b380691f feat(showcase): GLASS_ENGINE_AVAILABLE deployment gate helper
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:39 +02:00
Maxim 88e2d072c4 test(showcase): add vitest unit runner to banking demo
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:39 +02:00
Maxim 24cc2d3829 fix(showcase): enable Enterprise Learning so banking memory tools attach
The durable-memory demo depends on the Intelligence platform's recall_memory /
save_memory tools, which are served from `${apiUrl}/mcp` and attached to the
local BuiltInAgent run via MCP middleware ONLY when CopilotKitIntelligence is
constructed with `enableEnterpriseLearning: true` (gated in
attachIntelligenceEnterpriseLearning). The banking route never set the flag, so
in any real (non-aimock) run the memory tools never loaded: save_memory was a
no-op during teaching and recall_memory was absent, making the agent re-offer
workflow recording on every over-limit charge instead of recalling the learned
procedure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim 4730301c4c fix(showcase): bump banking agent gpt-5.4-mini -> gpt-5.4 for reliable tool routing
The teach-flow's multi-step tool sequencing is the weak spot for the mini model;
the non-mini gpt-5.4 follows the recall->offer->demonstrate->save routing far
more consistently. openai/gpt-5.4 is the alias already used across the repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim ec946821bb fix(showcase): offer card shows 'Recording started', not 'not recording', after Start
My collapse fix branched on isRecording, but the render closure captures a stale
isRecording (false), so clicking 'Start recording' wrongly collapsed the card to
'Okay — not recording.'. Branch on the resolved `result` instead (fresh on
complete, like the save card): onDeny resolves 'declined' -> 'not recording';
onApprove resolves the directive -> 'Recording started'. Drops the now-unused
isRecording destructure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim 57fb3bd64f fix(showcase): remove conflicting over-limit routing cues + temperature 0
The 'Record a workflow?' card appeared inconsistently because two intro prompt
lines still steered the agent the wrong way on an over-limit approve — 'review
... over-limit charges -> showPendingApprovals' and 'showApprovalFlow -> explain
how an over-limit charge gets cleared' — competing with the recall->offer block.
Scope both to browse/explain only and exclude them from the approve path, and
drop the agent temperature 0.3 -> 0 so it picks the same route every time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:37 +02:00
Maxim 744f064621 fix(showcase): collapse the save + demonstrate teach cards once resolved
Same lingering-button bug as the offer card: saveLearnedWorkflow and
awaitDashboardDemonstration only special-cased status 'inProgress', so after
clicking 'Save workflow' / 'I'm done' the card kept its button (confusing —
looked like nothing happened, though the save/respond went through). Add a
status 'complete' branch that collapses each to a static line, using the HITL
render's 'result' to show saved vs discarded / finished vs cancelled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:37 +02:00
Maxim cb014feb04 fix(showcase): route over-limit approval to recall->offer, not the explainer/queue cards
On 'approve the over-limit charge' with no saved procedure, gpt-5.4-mini
sometimes called showApprovalFlow ('diagram of how to clear an over-limit
charge') or showPendingApprovals ('...including over-limit charges') instead of
recall_memory -> offerWorkflowRecording, so it never asked to record. Scope
those two tools to their real uses (explainer only when asked how it works;
queue only for reviewing pending) and explicitly exclude them from the
over-limit approve path. The approval-flow diagram stays as an informational
tool — just not a response to an approve request.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:36 +02:00
Maxim 14f4f77d2c fix(showcase): advance the record->demonstrate beat + collapse the resolved offer card
After 'Start recording', offerWorkflowRecording resolved a bare 'started', so
gpt-5.4-mini often just SAID awaitDashboardDemonstration's 'go ahead and I'll
watch' line (from its description) instead of CALLING it — leaving the offer
card frozen with the Start-recording button and a confusing text reply, even
though recording (the vignette) had begun.

- Resolve a directive result telling the agent to immediately call
  awaitDashboardDemonstration and not reply in prose (mirrors the working
  awaitDashboardDemonstration -> saveLearnedWorkflow beat).
- Collapse the offer card to a static line once resolved (status 'complete')
  so the button can't linger or be re-clicked; the live 'Recording your
  workflow' card takes over.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:36 +02:00
Maxim cad70feacc fix(showcase): lift all Radix popper overlays above the chat sidebar (z-index)
Generalizes the row-action dropdown fix: every shadcn overlay (Select,
DropdownMenu, Popover, Tooltip) portals to <body> at z-50 and renders behind
the CopilotKit chat sidebar (z-1200) when opened in-chat — the policy-code
Select in the exception form hit this too. One globals.css rule lifts every
Radix popper wrapper to z-1300 (the file's existing 'above the chat panel'
value), fixing the whole class instead of per-component patches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:35 +02:00
Maxim 592e847e4c fix(showcase): render row-action dropdown above the chat panel (z-index)
The 'More actions' menu portals to <body> at z-50, but the CopilotKit chat
sidebar is z-1200 — so the menu opened BEHIND the panel and was invisible
(clicking the three-dots appeared to do nothing). Lift this dropdown's content
to z-[1300] so it renders in front of the panel. Pairs with the earlier
pointer-events-auto fix; together the row's overflow menu works in-chat.

Verified: menu computed z-index is now 1300 vs panel 1200.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:35 +02:00
Maxim bfee2c492a fix(showcase): make in-chat pending-approvals card clickable (pointer-events-auto)
showPendingApprovals is a display-only useComponent, which CopilotKit paints
pointer-events:none on the assistant message. The table is interactive
(Approve / Deny / File policy exception 'More actions' menu), so the inherited
none made every row action unclickable in the chat. Opt the card subtree back
into pointer events.

Verified live: the 'More actions' button's computed pointer-events flips
none -> auto with the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:34 +02:00
Maxim c03c064371 feat(showcase): dev-only POST /api/v1/dev/reset to re-seed the demo store
Re-running the over-limit teach demo mutates the in-memory store (approve +
filed exception flip the charge overLimit→cleared). This endpoint re-seeds the
store in place so the $5,000 Google Ads / Marketing charge (t-1) returns to
pending/over-limit without a server restart. Gated off when NODE_ENV=production.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:34 +02:00
Maxim d033b02837 test(showcase): use confirmed @copilotkit/aimock export (LLMock) in E2E launcher
Drops the non-existent AIMock/MockServer fallback names (TS-flagged once aimock was
installed); LLMock/loadFixtureFile/validateFixtures are the real exports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:33 +02:00
Maxim cdcd5460d6 test(showcase): deterministic aimock+Playwright cross-thread memory proof (FOR-149)
AUTHORED + statically validated (playwright --list compiles spec+config, fixtures/
package JSON valid, launcher syntax OK). NOT yet green-verified — needs aimock
installed (pnpm i), the docker memory stack up, and the dev server in Intelligence
mode (multi-process; not runnable in the current sandbox). Each file carries a
'VERIFY ON FIRST GREEN RUN' checklist for the shakedown.

- e2e/memory-learning.spec.ts: seeds the procedure via REST (recall-half isolation
  per the plan), drives a fresh thread, asserts recall->unlock with no recording
  offer + the over-limit gate lifted. Save half stays HITL+LLM (drift smoke / manual).
- e2e/fixtures/memory-learning.fixtures.json: pins recall_memory -> openPolicyException
  -> finalizePolicyException -> approveTransaction.
- e2e/aimock-server.mjs: aimock launcher (programmatic, CLI fallback documented).
- playwright.config.ts: webServer array (aimock + dev in Intelligence mode, OPENAI_BASE_URL->aimock).
- package.json: +@copilotkit/aimock devDep; test:self-learning -> the spec.
- remove scripts/self-learning-smoke.mjs (dead #192 distill path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:32 +02:00
Maxim 177a68f7d4 docs(showcase): memory-based durable-learning runbook + real-LLM recall drift smoke
- README: replace dead sl-worker/knowledge/annotate Phase-C section with the
  memory runbook (docker compose one-command stack, host-TEI override for Apple
  Silicon, 715x ports, .env, cross-thread+cross-persona FOR-149 walkthrough,
  aimock E2E + drift-smoke testing notes)
- scripts/memory-drift-smoke.mjs: non-gating real-LLM tripwire that the live model
  still emits recall_memory on a fresh-thread over-limit request (save half is
  HITL-gated; covered by the manual walkthrough + aimock E2E)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:30 +02:00
Maxim 841f6db2fb feat(showcase): saveLearnedWorkflow resolves a save-triggering result (drives save_memory)
Save action now resolves a string the agent reads as status:saved + an explicit
save_memory(scope:project, kind:operational) instruction with the demonstrated
code, preserving the already-approved/don't-re-run guard. respond() takes a
string in this file, so the result is delivered as text the recall-first prompt
(Task 3) acts on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:29 +02:00
Maxim bf8a01b250 feat(showcase): recall-first over-limit handling + save learned procedure to project memory
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:27 +02:00
Maxim 66cccfb8a6 refactor(showcase): remove POC /annotate recording seam (superseded by save_memory)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:25 +02:00
Maxim 7dcb5dd4d5 feat(showcase): wire banking runtime for memory (license token + locks); full .env.example
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:24 +02:00
Maxim 42a4066d45 fix(showcase): harden banking memory stack (minio-init DNS retry, pluggable embedder, non-colliding host ports)
Surfaced while verifying Task 0 against a live stack:
- minio-init: retry mc alias set until Docker DNS resolves (idempotent bucket create)
- embedder pluggable: MEMORY_EMBEDDINGS_URL overridable + bundled tei dependency required:false
  (point at host/native TEI on RAM-constrained Apple Silicon where the emulated tei OOMs)
- deps default host ports remapped to 715x so a bare `docker compose up` coexists with a dev's Intelligence stack

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:24 +02:00
Maxim f447e1a624 feat(showcase): vendor memory-enabled Intelligence stack (cloned memory-chat recipe) for banking demo
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:23 +02:00
Ran Shem Tov 2392af3bea fix(showcase/mastra): bake tsconfig + shared-tools into runner for --dev
The mastra runtime image stripped two build-only artifacts that next dev
needs to re-resolve at request time: tsconfig.json (the @/* and
@copilotkit/showcase-shared-tools path aliases) and shared-tools/. Under
'showcase up mastra --dev' the dev overlay bind-mounts only ./src and runs
next dev, which recompiles from source and then failed with 'Module not
found: Can't resolve @/mastra' / '@copilotkit/showcase-shared-tools', so
every agent route (incl. /api/copilotkit-a2ui-recovery) returned 500 and no
agent run ever fired. next start (prod) is unaffected since .next has the
aliases pre-resolved. Mirrors langgraph-typescript's runner, which likewise
bakes shared-tools/ for dev.

Verified: with the fix baked, the recovery route compiles and POSTs 200 in
dev (LLM calls fire, aimock recovery fixtures match) instead of 500. The
a2ui-recovery e2e (heal paints Column+2 Metric, exhaust shows the fallback)
is 3/3 green on the committed-state built image.
2026-07-02 19:26:32 +02:00
Ran Shem Tov e8b1652427 fix(showcase/mastra): stream shared state via updateWorkingMemory STATE_DELTA (OSS-423)
The shared-state-streaming demo mapped to the generic weatherAgent (state
{proverbs}, no `document` field) and its aimock fixture returned plain text
gated on a stale "stream the counter to 5" match, so nothing ever streamed
into `state.document` and the e2e failed.

Add a dedicated `sharedStateStreamingAgent` with working memory enabled on a
`{ document: string }` schema. It writes drafts through Mastra's built-in
`updateWorkingMemory` tool; the @ag-ui/mastra bridge intercepts the streamed
tool-call args (OSS-414) and emits a leading STATE_SNAPSHOT followed by
incremental STATE_DELTA on /document, so the UI renders the document
token-by-token. This is the Mastra-native equivalent of langgraph-python's
StateStreamingMiddleware / predictive-state pattern.

- agents: add sharedStateStreamingAgent + SharedStateStreamingAgentState
- index: register the agent on the Mastra instance
- route: map shared-state-streaming -> sharedStateStreamingAgent with a
  dedicated resourceId, build guard, and LocalMastraAgentName entry
- fixture: drive updateWorkingMemory with the streamed document for all three
  pills (poem / email / quantum) plus a confirmation turn on hasToolResult
2026-07-02 19:07:52 +02:00
Ran Shem Tov 65e6254006 docs(showcase/mastra): add qa checklists for the interrupt cells (OSS-383)
Parity with langgraph-python gold, which ships qa/gen-ui-interrupt.md +
qa/interrupt-headless.md; mastra had neither. Mastra-accurate: native
schedule_meeting suspend() -> @ag-ui/mastra bridge -> useInterrupt, the
TimePickerCard testids/states (time-picker-card/picked/cancelled, slot,
cancel), and the headless app-surface variant (interrupt-headless-popup/
empty/slot-<iso>). No shell-docs change — human-in-the-loop/interrupt-flow.mdx
already documents the native path and the correct context.agent destructure.
2026-07-02 19:06:20 +02:00
Ran Shem Tov 04d34384fc fix(showcase/mastra): read suspend/resumeData off executionContext.agent (OSS-383)
The native interrupt tool destructured `suspend`/`resumeData` off the top level
of the ToolExecutionContext, but in @mastra/core 1.48 they live under
`executionContext.agent` (the AgentToolExecutionContext sub-object). So
`suspend` was `undefined`, `return suspend(...)` threw `suspend is not a
function`, the model got a tool-error and re-called schedule_meeting, and the
agentic loop spun to the step cap (~30 LLM calls) with NO `tool-call-suspended`
chunk -> no `on_interrupt` -> the time-picker never rendered.

Reading off `executionContext.agent` (matching the proven @ag-ui/mastra dojo
tool) makes the loop pause at the interrupt. Verified e2e against aimock:
gen-ui-interrupt 4/4 and the interrupt-headless probe flow both green
(picker renders backend suspend-payload slots -> pick -> resume -> confirmation).
2026-07-02 18:42:04 +02:00
Ran Shem Tov b47a8dd8e8 fix(showcase/mastra): interrupt suspend-tool execute signature + bg untilIdle
Two fixes surfaced by running the actual Playwright e2e (per showcase-demo-debugging):

- interrupt.ts: Mastra createTool execute is (inputData, executionContext) —
  suspend/resumeData live on arg2, not arg1. Was destructured off arg1 →
  suspend was undefined → suspend() threw → loop never paused. Fixed signature.
  (NOTE: e2e still shows the loop not pausing — a deeper suspend-path issue
  remains; tracked to the interrupt fix chip.)
- background-agents route: use getLocalAgents({ untilIdle: true }) (plural; the
  singular getLocalAgent lacks the toggle) so the background-task lifecycle
  (incl. background-task-completed + result) pipes in-band per Mastra's
  resolution-order docs — card can complete in-turn instead of stuck 'working'.

Honest status: the advanced Mastra cells (interrupt, a2ui-recovery, reasoning,
shared-state-streaming) are NOT yet e2e-green under aimock; 7 focused follow-up
tasks spawned (one per item) with repro + the sanctioned up --dev validation rig.
2026-07-02 18:00:49 +02:00
Markus Ecker 02a10800bb Merge remote-tracking branch 'origin/mme/memory-core' into mme/memory-core 2026-07-02 17:27:18 +02:00
Markus Ecker 01469359a8 merge: integrate origin/main into mme/memory-core
Resolve the single conflict in packages/web-inspector/src/index.ts by keeping
both additions: this branch's CpkMemoryList memory-tab element and main's
ɵCpkThreadDetails back-compat alias (independent top-level declarations).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 17:26:01 +02:00
Benjamin Taylor 95345f10ef test(suggestions): cover header/credential forwarding, multi-route dispatch, 405, explicit-false; fix comments 2026-07-02 09:32:30 -05:00
Benjamin Taylor d440b30e51 fix(core): treat aborted-signal fetch failures as expected; cover suggest error-body branches 2026-07-02 09:32:30 -05:00
Benjamin Taylor 7cfbfe4df3 fix(runtime): log suggest failures server-side, harden route exhaustiveness, prove marker round-trip 2026-07-02 09:32:29 -05:00
Benjamin Taylor f94cc45a76 fix(runtime): make stateless suggest side-effect-free and cancel on client abort
The suggest path called configureAgentForRequest, which conditionally
attaches A2UI/MCPApps/OpenGenerativeUI middleware. MCPApps setup can
incur a listTools network round-trip per suggestion under
available:"always" — contradicting the handler's side-effect-free
contract. Since suggest runs force toolChoice: copilotkitSuggest, those
middleware-injected tools are dead weight. Replace the call with only
the header forwarding it needs (extractForwardableHeaders).

Also wire request.signal to agent.abortRun() so an aborted client
request cancels the server-side provider run instead of letting it run
to completion (best-effort; the listener never throws).

Tests: assert no middleware is attached (agent.use never called),
forwarded headers land on agent.headers, and aborting the signal calls
agent.abortRun(). Runtime mock is now typed (no as any); runner spies
kept to prove the direct-run path is preserved.
2026-07-02 09:32:29 -05:00
Benjamin Taylor 5a57fb8bab fix(core): harden stateless suggestions (single-route fallback, loading balance, abort detection, response guards) 2026-07-02 09:32:29 -05:00
Benjamin Taylor cb7c8be1cb test(runtime): lock in stateless /suggest no-thread-leak + cross-mode coverage 2026-07-02 09:32:29 -05:00
Benjamin Taylor 629f7208d8 feat(core): generate suggestions via stateless /suggest when advertised 2026-07-02 09:32:28 -05:00
Benjamin Taylor b8cf717a5a feat(core): surface the runtime suggestions capability 2026-07-02 09:32:28 -05:00
Benjamin Taylor e9c4eec9e2 feat(runtime): route POST /agent/:agentId/suggest to handleSuggestAgent 2026-07-02 09:32:28 -05:00
Benjamin Taylor 52e4f6823f feat(runtime): add stateless handleSuggestAgent handler 2026-07-02 09:32:28 -05:00