Skip to content

Live model: room to finish the brief, and a guaranteed fallback - #6

Merged
Yasuui merged 8 commits into
mainfrom
fix/live-model-path
Oct 27, 2026
Merged

Yasuui merged 8 commits into
mainfrom
fix/live-model-path

Conversation

@Yasuui

@Yasuui Yasuui commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Makes the live-model path safe to switch on. Merge after #5.

Why: gpt-5-mini counts reasoning tokens against maxOutputTokens. At the old 1,400 cap the reply could stop before the fenced JSON brief closed, so the brief would never render. Any provider error also left an empty reply.

What changed

  • lib/agent-stream.ts streams every reply, demo or live. The live path gets 6,000 output tokens, low reasoning effort and one retry.
  • Fallback order: gpt-5-mini, then gpt-4.1-mini, then the deterministic demo brief with the notice "The live model is unavailable right now, so this is the rule-based demo brief." Chunks are buffered until the first real token, so a failed attempt leaves nothing half-written.
  • A failure after text has started ends the turn with an error. It is not stitched into demo output.

Verification

  • npm run lint: clean. npm test: 51/51.
  • tests/agent-stream.test.mjs uses the SDK mock model to cover success, model fallback, demo fallback, no-key demo and a mid-stream failure.
  • Production build with a dummy key and no network to OpenAI: both models failed and the demo brief streamed with the notice.

Not checked: a real OpenAI response. There is no key in this environment. After adding OPENAI_API_KEY in Vercel, run one starter and confirm the brief renders.

Before turning the key on

Set a hard monthly budget on the OpenAI project. The site has no rate limit yet.


Generated by Claude Code

Yasuui and others added 7 commits October 26, 2026 13:42
- MapperFace reads reduced motion through useSyncExternalStore and derives
  the blink instead of resetting state inside an effect.
- WorkflowChat sends the intent per request, opens the brief from onFinish,
  and tracks streamed chunks during render instead of in an effect.
- factsAndAssumptions de-duplicates evidence lines, so React keys stay unique
  and the brief no longer repeats a line.
- Rendered-HTML tests now assert the current greeting and the data: URL
  download path that replaced blob URLs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
The route parsed the raw body with req.json() and forwarded whatever arrived:
any role (system included), any part type, remote file URLs and unbounded
sizes. Malformed JSON surfaced as a 500.

- lib/optimize-request.ts checks content type, body size (4 MB), message
  count, text length, file count, roles (user/assistant), part types, and
  inline data: attachments against one allowlist shared with the composer.
  Assistant history keeps only text parts. Rejections are 400/413/415 with a
  message the chat shows to the user.
- The composer normalizes attachment media types, refuses unsupported images
  and caps PDFs and images at 2.5 MB before upload.
- tests/optimize-request.test.mjs covers the UI's real payloads, injection of
  system turns, SSRF-style remote URLs, mislabelled binaries and size limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
- GitHub Actions runs lint, then tsc, next build and node --test, with no
  model key.
- README states what is live (demo mode), what is built but off (live model),
  what the tests cover and what they do not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
The earlier capture came from next dev and showed development issue badges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
gpt-5-mini spends reasoning tokens against maxOutputTokens, so the 1,400 cap
could end the reply before the fenced JSON brief closed. temperature was also
set on a reasoning model that ignores it.

- lib/agent-stream.ts streams every reply: 6,000 output tokens, low reasoning
  effort, one retry. If a model fails before its first token, the next model
  is tried; if all fail, the demo brief streams with a one-line notice. Output
  is buffered until the first token, so a failed attempt leaves nothing behind.
- tests/agent-stream.test.mjs covers success, model fallback, demo fallback,
  no-key demo and a mid-stream failure, using the SDK's mock model.

Verified against the production build with an unreachable provider: both
models fail and the demo brief arrives with the notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
workflow-friction-mapper Ready Ready Preview Oct 27, 2026 2:13pm UTC

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T14:14:47.125861Z a4bf035 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b9e6081e3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/chat-attachments.ts Resolved
Each file passed the 2.5 MB cap, but two 1.55 MB PDFs encode to about
4.13 MB together and the API guard rejected them with 413. The composer had
already cleared the files, so the advice to remove one could not be followed.
Earlier turns' attachments are re-sent on every turn and counted too.

The composer now sums inline attachment data across the conversation and the
new files before clearing anything, and keeps the files in place with a
message when they don't fit. A test pins the budget below the API body limit.

Reported by Codex review on #6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbmD6cAA88NEhhUnPW3ew9
@Yasuui
Yasuui merged commit d7c29b5 into main Oct 27, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — a4bf0356 Deployed Oct 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants