fix(showcase): bundle multimodal sample assets for agno and mastra#6157
Draft
jpr5 wants to merge 1 commit into
mainCopilotKit/CopilotKit:mainfrom
fix/multimodal-missing-demo-filesCopilotKit/CopilotKit:fix/multimodal-missing-demo-filesCopy head branch name to clipboard
Draft
fix(showcase): bundle multimodal sample assets for agno and mastra#6157jpr5 wants to merge 1 commit intomainCopilotKit/CopilotKit:mainfrom fix/multimodal-missing-demo-filesCopilotKit/CopilotKit:fix/multimodal-missing-demo-filesCopy head branch name to clipboard
jpr5 wants to merge 1 commit into
mainCopilotKit/CopilotKit:mainfrom
fix/multimodal-missing-demo-filesCopilotKit/CopilotKit:fix/multimodal-missing-demo-filesCopy head branch name to clipboard
Conversation
Contributor
Production Digest-Pinning AuditAll 41 services digest-pinned. Run 2026-07-24 16:16:50 PDT — 0 finding(s). |
agno and mastra were the only 2 of 20 integrations with no
`public/demo-files/` directory ever committed. Their Attachments demo
fetches `/demo-files/sample.png` before building the message, so the
demo failed at the fetch with:
[multimodal-demo] sample-attachment send failed Error: Could not
fetch sample "sample.png" — HTTP 404. Is the file bundled under
public/demo-files/sample.png?
Nothing was ever sent to the agent — `userMsgCount: 0` — so the D5
probe timed out on turn 1. Both integrations already have working
vision-capable multimodal agents and correct aimock fixtures; this was
purely a missing-asset/packaging bug.
Copies sample.png / sample.pdf / README.md byte-for-byte from
langgraph-python (the canonical source) into each integration's own
`public/demo-files/` — a per-integration duplicated directory, not part
of the `shared/` symlink mechanism, which is exactly how two
integrations came to be missing it.
The assets are committed as plain Git LFS pointers, governed by the
repo-root `*.png` / `*.pdf` LFS rules, with no per-integration
`.gitattributes` override. LFS tracking stays uniform across the
fleet; the deploy-time problem (integration image builds do not fetch
LFS) is fixed in the build, not by carving these files out of LFS.
The pointer OIDs are the ones already stored for the identical assets
in the other integrations, so the backing LFS objects exist server-side
and are not dangling:
sample.png sha256:01aa5681de99461247543e9215c1e4da3242e26b2bee11593fcdbe209672d973 10083
sample.pdf sha256:3da2afae36a1a81fd2c02f15e54bfc38b6c22e41655c31a5b54ff1e0e3daab41 2486
NOTE: this change does not make agno/mastra pass on its own. It
requires the build-side LFS fetch fix to land first or together.
jpr5
force-pushed
the
fix/multimodal-missing-demo-files
branch
from
July 24, 2026 23:16
7bff0bd to
e1c8013
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
agnoandmastrawere the only 2 of 20 showcase integrations with nopublic/demo-files/directory ever committed. This adds the two bundled sample assets (plus the provenance README) to both, LFS-tracked under the repo-root rules.The failure
The Attachments demo fetches its bundled sample and validates the magic bytes before building the message (
sample-attachment-buttons.tsx→fetchUrl: "/demo-files/sample.png"). With the asset absent, it never gets that far. Verbatim console output from the D5 probe, identical on both slugs:Page body at failure:
userMsgCount: 0— nothing was ever sent, sowaitForTurnCompletetimed out on turn 1 and the cell surfaced the genericconversation-errorbucket. The backends are fine: both integrations have real vision-capable multimodal agents (agno/src/agents/multimodal_agent.py,mastra/src/mastra/agents/index.ts) and correct aimock fixtures whoseuserMessagekeys match the component'sautoPromptstrings verbatim. This is purely a missing-asset / packaging bug — a different bug from the LFS-pointer problem, and the reason this PR is still needed.Why only these 2 of 20
public/demo-files/is not part of theshared/symlink mechanism — unlike_shared/,tools/, andshared-tools/, it is a per-integration duplicated directory. That is exactly how two integrations came to be missing it. Confirmed againstorigin/main: the directory has never existed in either integration's history, while all 18 others resolve to a real commit.What was added, and from where
sample.png(10083 B),sample.pdf(2486 B),README.md(1174 B) copied byte-for-byte fromshowcase/integrations/langgraph-python/public/demo-files/, the canonical source. Real files, not symlinks — matching the other 18 integrations. sha256 verified identical.Committed blob form
Both binaries are committed as LFS pointers. No
.gitattributesis added by this PR:mastrais byte-identical toagnofor both files. Git blob sizes are 130 / 129 bytes (pointer text), matching the pointer-mode integrations already onmain(llamaindex,ag2,pydantic-ai, …), which reference these same two OIDs.LFS objects are real, not dangling
A pointer with no backing object is worse than either alternative, so this was verified against the server rather than the local cache. The OIDs are the ones already stored for the identical assets in ten other integrations, so no new upload was required (
git lfs push --dry-run origin HEADreports nothing to transfer). Server-side existence, and then the actual bytes, were confirmed through the LFS batch API:The object downloaded from GitHub's LFS store is a real PNG whose hash matches the pointer.
Scope
Static assets only. No source, no fixtures, no manifests, no runtime code, no lockfile churn, no workflow changes.
SUPERSEDED — verification below no longer applies
Everything from here down was produced when this branch carried per-integration
.gitattributesoverrides that committed the assets as real binaries. Those overrides have been removed. The image-level and RED → GREEN evidence therefore describes a state this branch no longer produces. It is kept for the record of what was tested and why the missing-asset diagnosis is sound — not as a claim that this branch is green.Specifically, still valid from the run below: the RED evidence (both slugs failed with a 404 on the missing asset, and the langgraph-python CONTROL was green), and the finding that the attachment pipeline past the fetch works once the asset is genuinely present in the image. No longer valid: the GREEN result, because it depended on real binaries reaching the runtime layer, which now requires the build-side LFS fetch.
Superseded image-level and RED → GREEN evidence (click to expand)
Image-level verification (SUPERSEDED)
A file in git that Docker never copies fixes nothing, so this was checked in the built images, not just the source tree. Both Dockerfiles do
COPY --from=frontend /app/public ./public, and neither.dockerignoreexcludes the path.Before (
showcase build agno mastrafrom this branch's base):After (same command, post-change — with the since-removed
.gitattributesoverrides):Served over HTTP from the recreated containers:
(pre-change, same endpoints: page
200, both assets404)RED → GREEN → CONTROL (GREEN half SUPERSEDED)
All three exercised the real failure surface — the actual Playwright D5 probe driving the live demo page against the built image, not tests against fakes.
RED — before the change (still valid)
bin/showcase test mastra:multimodal --d5 --direct --verbosebin/showcase test agno:multimodal --d5 --direct --verboseGREEN — SUPERSEDED, does not describe this branch
Obtained with the since-removed
.gitattributesoverrides, i.e. with real binaries baked into the image. Same commands, aftershowcase build agno mastra+showcase recreate agno mastra.agno:mastra:Both turns passed on both slugs — the image turn and the PDF turn. What this settled and still stands: the attachment pipeline past the fetch had never once executed on these two services, and it works when the real asset is present. What it does not establish: that this branch as it now stands is green.
CONTROL — an already-green integration, unchanged (still valid)
bin/showcase test langgraph-python:multimodal --d5 --direct --verbose(no code touched):Confirms the local setup, the shared probe, the shared frontend and the shared fixtures were all healthy — the two REDs above were real per-integration failures, not a setup artifact.
Fleet state, for whoever lands the build fix
Measured on
origin/main,demo-files/sample.pngsplits three ways across the 20 integrations:ag2,built-in-agent,claude-sdk-python,claude-sdk-typescript,crewai-crews,langroid,llamaindex,ms-agent-harness-dotnet,pydantic-ai,spring-ai.gitattributes):google-adk,langgraph-fastapi,langgraph-python,langgraph-typescript,ms-agent-dotnet,ms-agent-python,strands-typescript,strandsagno,mastra— what this PR adds, in pointer modeSo
mainis currently inconsistent in both directions. This PR puts its two integrations on the uniform-LFS side. The remaining 8 raw-blob overrides should be removed by the build-side fix so the whole fleet is pointer-mode plus an LFS-fetching build.Noted, not fixed (out of scope)
showcase/integrations/mastra/shared-toolsis a real directory onorigin/main(mode040000), not the symlink the iron rules require. Pre-existing erosion, unrelated to this change, worth a separate PR.mastramultimodal page's<title>renders as "LangChain - Python" — a frontend-parity oddity visible in the probe diagnostics. Unrelated.