feat: the sessionless draft view — "+ New session" creates nothing
The sidebar button no longer POSTs a record (no more "Untitled session"
litter): it opens /chat/new, a sessionless draft view visually identical
to a fresh chat (same header + probe chip, the same ConversationEmptyState,
the same composer blob + stats dock). The session comes to exist only
when the learner sends the first message — and that message becomes its
title (startDraftSession: POST /api/chats {title: msg} → PUT the lifted
pre-chat settings → redirect /chat/<id>?prompt=<msg>, whose initialPrompt
path delivers the message as turn 1 — the home composer's proven contract).
- app/chat/new/page.tsx: the static draft route (static beats [id]).
- components/new-session.tsx: DraftShell (pure render seam) + NewSession
(router wiring); the model picker's empty-chatId branch defers its save
and lifts the selection, so pre-chat model/thinking rides the creation.
- components/sidebar.tsx: newSession is a plain router.push("/chat/new").
- tests/render-new-session.test.tsx: 6 pins — the create-on-send contract
(title = message, settings PUT, no-op on empty text) + the shell render.
Live-verified end to end: button → draft (0 creations), pre-chat Qwen
pick, send → exactly one session titled with the message, settings
persisted, redirect + turn 1 running. Gates 431/431.
This commit is contained in:
@@ -186,13 +186,12 @@ function SessionsSidebar() {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
|
||||
/* New session: one POST, then hello. Search: a client-side filter over
|
||||
the poll snapshot — no server round trip. Both were visual-only in
|
||||
the wave-5 mock; wiring each is a single tiny handler. */
|
||||
const newSession = useCallback(async () => {
|
||||
const res = await fetch("/api/chats", { method: "POST", headers: { "content-type": "application/json" }, body: "{}" });
|
||||
const d = (await res.json().catch(() => null)) as { id?: string } | null;
|
||||
if (d?.id) router.push(`/chat/${d.id}`);
|
||||
/* New session (owner, 2026-09-13): NO POST — the button opens the
|
||||
sessionless draft view; the session is created only when the first
|
||||
message is sent (and that message becomes its title). Search: a
|
||||
client-side filter over the poll snapshot — no server round trip. */
|
||||
const newSession = useCallback(() => {
|
||||
router.push("/chat/new");
|
||||
}, [router]);
|
||||
|
||||
const shown = useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user