Add outcome-shopping-template: multi-vendor, outcome-based shopping orchestrator#970
Add outcome-shopping-template: multi-vendor, outcome-based shopping orchestrator#970mconroy-cf wants to merge 3 commits intocloudflare:mainfrom
Conversation
Multi-vendor, outcome-based shopping orchestrator. Takes a natural-language shopping intent, decomposes it with Workers AI, and composes a cross-merchant recommendation from each merchant's commerce-llms-txt-template /api/products endpoint. The React SPA at / runs the pipeline end-to-end against a bundled sample catalog so the template is immediately useful after deploy. - Required CATALOG_CACHE KV binding (cache key includes merchant fingerprint so config changes bust the cache automatically) - @cloudflare/vite-plugin pattern: single vite build produces the SPA plus the Worker bundle; SPA owns /, Worker owns /api/* and /llms.txt - Default AI model: @cf/google/gemma-4-26b-a4b-it - Bundled sample catalog (3 merchants, 9 products) mirrors the shape emitted by commerce-llms-txt-template - 8 vitest tests via @cloudflare/vitest-pool-workers - Playwright e2e spec under playwright-tests/ Registered in templates.json.
The previous default, @cf/google/gemma-4-26b-a4b-it, is a reasoning
model on Workers AI. When called via the legacy `ai.run({messages})`
shape it writes its thinking to `message.reasoning` and only emits
`message.content` after, frequently hitting the default max_tokens
before the answer is produced. Result: decomposition silently falls
back to single-need mode, leaving deployments looking broken with no
obvious error.
Llama 3.3 70B FP8 Fast returns the structured JSON this pipeline
expects consistently under the same call shape, is featured on
Workers AI, and is fast enough for the per-need matcher. No other
code changes required — the response extractor already handles both
wire formats.
Verified: `pnpm turbo run check --filter=outcome-shopping-template`,
`pnpm run check:templates`, `pnpm run check:prettier`, and the 8
template tests all pass.
|
Two updates since you received this. Correctness fix in Reference implementation at gitlab.cfdata.org/mconroy/outcome-shopping has moved well past this template since the PR opened — streaming endpoint, stateful MCP agent (Durable Object per session), real Shopify merchants via a multi-tenant proxy, |
KV keys are limited to 512 bytes. The previous cacheKey() built an unbounded fingerprint by concatenating every merchant's name + URL, which a fresh deploy with more than ~5 merchants (each URL contributes ~70-100 chars) can exceed \u2014 `KV.put()` would reject the write, and the orchestrator would silently bypass the cache on every request. SHA-256 hashing the fingerprint produces a fixed-length 64-char hex suffix that always fits. Collision risk is irrelevant: a collision just serves another merchant set's cache, which triggers invalidation on the next request anyway. Caught while reviewing drift between the gitlab reference implementation and this template (the gitlab side already had the fix). No template tests change; this is a fresh-deploy correctness fix that only manifests with several real merchants configured.
|
Pushed The previous Caught while reviewing drift between the gitlab reference implementation and this template — the gitlab side already had the fix. |
Summary
Adds
outcome-shopping-template— a multi-vendor, outcome-based shopping orchestrator that pairs withcommerce-llms-txt-template.Takes a natural-language shopping intent (e.g. "outfit my 3-year-old for skiing"), decomposes it with Workers AI into component product needs, and composes a cross-merchant recommendation from each merchant's
commerce-llms-txt-template/api/productsendpoint.The React SPA at
/runs the full decompose → match → compose pipeline against the bundled sample catalog, so the template demos itself end-to-end on first deploy.What's in the template
src/orchestrator-worker/index.tsserving/api/shop,/api/catalogs,/api/merchants,/llms.txt, and an/apidocs endpoint.src/react-app/via@cloudflare/vite-plugin— singlevite buildproduces both the SPA (as Workers Static Assets) and the Worker bundle.CATALOG_CACHEKV binding with a placeholder ID inwrangler.jsonc. No optional fallback. Cache key incorporates the merchant fingerprint so changingMERCHANT_ENDPOINTSbusts the cache automatically.commerce-llms-txt-template, served whenMERCHANT_ENDPOINTSis empty or every configured merchant fails.@cf/google/gemma-4-26b-a4b-it, consistent with where we landed oncommerce-llms-txt-template.@cloudflare/vitest-pool-workers.playwright-tests/outcome-shopping-template.spec.ts.Applying feedback from #968
Both new templates deliberately pre-apply the KV-required + SPA-on-top-of-API feedback from #968 so this reviewer doesn't have to re-litigate the same points.
Verification
pnpm turbo run check --filter=outcome-shopping-template— passespnpm turbo run test --filter=outcome-shopping-template— 8/8 passingpnpm run check:templates— passespnpm run check:prettier— clean