kimi-code/apps/kimi-web/test
qer ec8dc3456c
fix(web): stop sending prompts into a busy turn on the web UI (#1522)
* fix(web): prevent duplicate first prompts and keep goal drives from looking idle

- Guard startSessionAndSendPrompt with a per-workspace reentry lock so a
  double-click / repeated Enter during draft-session creation cannot fire
  two concurrent first prompts into the same new session.
- Track goal.active in the agent event projector so turn.ended between
  goal-driven continuation turns keeps the session 'running' instead of
  projecting a false 'idle' that drains the local queue into a still-busy
  core (turn.agent_busy).
- Show a 'starting conversation…' loading state on the empty-session
  landing while the first prompt is being created and submitted.
- Persist the resolved model in startSessionAndActivateSkill so the first
  skill turn on a fresh session does not fail with 'Model not set'.

* chore: add changeset for web first-prompt fixes

* fix(web): close remaining first-prompt and goal-settle gaps

- Pass the starting guard through the dock composer: draft-session
  creation selects the new session before submit, which swaps the empty
  composer for the dock; disabling both composers closes the last path
  to a concurrent first POST. Also take the workspace lock in
  startSessionAndActivateSkill / startSessionAndOpenSideChat.
- Emit the owed idle when a goal settles (blocked/paused/completed) in
  the inter-turn gap after a turn.ended was projected as 'running', so
  sending state, in-flight flags and queued prompts flush instead of
  the session staying 'running' forever.

* style(web): fix eqeqeq lint error in first-prompt guard

* fix(web): clear owed idle when a new goal turn starts

The idle debt from a 'running' projection survived turn.started, so an
UpdateGoal('complete'|'blocked') landing mid-turn in the NEXT goal turn
synthesized an early idle. onSessionIdle could then drain queued prompts
into a core that was mid-turn again, re-opening the turn.agent_busy race
for multi-turn goals. Clear the debt on turn.started: from that point the
turn's own turn.ended carries the idle with goalActive already false.

* fix(web): make first-prompt starting state workspace-id-agnostic

isStartingFirstPrompt now reads from the lock set directly (size > 0)
instead of the current activeWorkspaceId. createDraftSession can swap
activeWorkspaceId to a registered id mid-flight; a workspace-keyed read
would then return false while the first prompt is still in the create/
select/submit window, re-enabling the composer and reopening the
duplicate first-submit race.

* revert(web): drop goal-aware idle projection from agentEventProjector

The goalActive / idleOwed shadow state machine grew through multiple
review rounds and still leaves edge cases (snapshot-seeded turns, mid-
turn goal updates). Roll it back to the simple 'turn.ended projects idle'
behavior. Goal-driven sessions can once again race a queued prompt into a
busy core; this is accepted as a known limitation to be resolved properly
in a follow-up that has the core emit an authoritative idle signal.

* chore: align changeset with actual fix scope

* test(web): update profile-patch expectation for model field
2026-07-09 23:37:10 +08:00
..
agent-event-projector.test.ts feat(kimi-web): render cron fire notices in the web chat (#1426) 2026-07-06 22:25:19 +08:00
ask-user-tool-parse.test.ts feat(agent-core): feed AskUserQuestion answers back as question text and option labels (#1414) 2026-07-06 16:37:54 +08:00
attachment-upload.test.ts fix(web): refill attachments when editing a queued or undone message (#1357) 2026-07-04 23:32:32 +08:00
chat-turn-rendering.test.ts refactor(web): extract pure turn-rendering helpers from ChatPane (#1001) 2026-06-23 15:20:00 +08:00
clipboard.test.ts fix(web): make clipboard copy work over plain HTTP (#1044) 2026-06-23 22:21:10 +08:00
composer-draft.test.ts fix(web): clear composer draft synchronously on send (#1163) 2026-06-28 01:55:04 +08:00
event-batcher.test.ts fix: reduce streaming stutter in the web chat (#1085) 2026-06-25 13:06:38 +08:00
event-reducer.test.ts feat(kimi-web): render cron fire notices in the web chat (#1426) 2026-07-06 22:25:19 +08:00
input-history.test.ts feat(web): redesign web UI and add design system (#1258) 2026-07-01 20:47:12 +08:00
lib-logic.test.ts feat(kimi-web): render cron fire notices in the web chat (#1426) 2026-07-06 22:25:19 +08:00
mention-menu.test.ts refactor(web): extract @-mention menu into a composable (#1030) 2026-06-23 18:38:50 +08:00
notification-logic.test.ts feat(kimi-web): add status-aware browser notifications (#1479) 2026-07-09 12:30:15 +08:00
side-chat.test.ts fix(web): run new-session slash actions (skills, /goal, /btw) from the empty composer (#1445) 2026-07-07 14:18:40 +08:00
slash-menu.test.ts feat(web): prefix skill slash commands with skill: to distinguish them from built-in commands (#1492) 2026-07-08 15:03:30 +08:00
sound-notification.test.ts feat(web): add completion sound and question notifications (#1179) 2026-06-28 21:02:00 +08:00
storage-logic.test.ts feat(web): add completion sound and question notifications (#1179) 2026-06-28 21:02:00 +08:00
swarm-card-rows.test.ts feat(web): render AgentSwarm as an inline tool card (#1425) 2026-07-06 22:05:05 +08:00
swarm-groups.test.ts feat(web): render AgentSwarm as an inline tool card (#1425) 2026-07-06 22:05:05 +08:00
swarm-result.test.ts feat(web): render AgentSwarm as an inline tool card (#1425) 2026-07-06 22:05:05 +08:00
turn-logic.test.ts feat(web): redesign cron reminder as a message bubble (#1480) 2026-07-08 13:42:22 +08:00
workspace-order.test.ts feat(web): redesign web UI and add design system (#1258) 2026-07-01 20:47:12 +08:00
workspace-state.test.ts fix(web): stop sending prompts into a busy turn on the web UI (#1522) 2026-07-09 23:37:10 +08:00
ws-lifecycle.test.ts fix(web): recover from stale background websocket (#1451) 2026-07-07 14:48:22 +08:00