Commit Graph

3 Commits

Author SHA1 Message Date
David McKay 8cef043e92 feat(reskinnable-demo): accept spreadsheet attachments, and move to CopilotKit 1.71.0
Dropping an .xlsx into the composer did nothing: the accept filter silently
discarded it, and widening that filter alone would have killed the run, because
the pinned @ai-sdk/openai@3 converter accepts no document media type but
application/pdf and throws before a request is made.

Spreadsheets now work end to end:

- A dependency-free .xlsx / .csv reader (ZIP central directory + OOXML through
  DecompressionStream and DOMParser). It decodes date serials via styles.xml so
  a date does not render as 45231, and places cells by column reference so a
  gap does not shift every later value under the wrong header.
- The sheet is rendered to a column-aligned table document. Comparisons of
  table encodings put a markdown-style aligned table well ahead of CSV for
  model comprehension, and the same document is what a human sees.
- buildPdf paginates. It emitted a single page and drew overflow past the
  bottom margin, so anything after ~48 rows was silently absent from a
  perfectly valid PDF. Single-page output is byte-identical, so the existing
  golden assertions stand.
- A per-run bridge around the agent swaps the media type to application/pdf on
  the model leg only, and restores the original type and metadata on the way
  back. Both the composer chip and the transcript therefore read XLS with the
  real filename. The bridge keys on the exact payload, so a genuine PDF
  attachment is never mislabelled.
- onUploadFailed is wired. A rejected or unreadable file now says so instead of
  vanishing with no trace.

The demo workbook is committed as a generator rather than a binary blob, so the
fixture exercises the real reader: shared strings, date-styled serials, a
second sheet, deflate.

Also moves @copilotkit/* to 1.71.0 and @ag-ui/* to 0.0.59, and deletes the
@ag-ui canary overrides from both pnpm-workspace.yaml and package.json. Those
existed only because a released @ag-ui/core rejected SUBAGENT_* events and
killed banking's harness console; stable 0.0.59 ships SUBAGENT_STARTED,
SUBAGENT_FINISHED and SUBAGENT_ERROR, and 1.71.0 depends on exactly 0.0.59, so
the overrides would now hold the tree behind its own dependency.

Verified on the running demo, not just in tests: gen UI renders, the subagent
harness completes the offsite run (14 rows, 6 merchants, $2,377.15, 1m 4s),
memory recall returns seeded memories, and a spreadsheet answers with a table
built from the real file. Lint, typecheck, 2494 unit tests and build all pass.

Checked the reskin skill for staleness: buildPdf was documented as single-page
and two passages said onUploadFailed is wired by nobody. Both corrected here.
2026-09-10 10:03:57 -07: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
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