MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / onSessionIdle

Function onSessionIdle

apps/kimi-web/src/composables/useKimiWebClient.ts:2240–2303  ·  view source on GitHub ↗
(sid: string, status: 'idle' | 'aborted')

Source from the content-addressed store, hash-verified

2238});
2239
2240function onSessionIdle(sid: string, status: 'idle' | 'aborted'): void {
2241 // The turn finished — this session no longer has a prompt in flight.
2242 inFlightPromptSessions.delete(sid);
2243 rawState.sendingBySession = { ...rawState.sendingBySession, [sid]: false };
2244 // Drop any cached prompt_id so a later skill activation (which has no
2245 // prompt_id) doesn't accidentally reuse this stale id for :abort.
2246 if (rawState.promptIdBySession[sid] !== undefined) {
2247 const next = { ...rawState.promptIdBySession };
2248 delete next[sid];
2249 rawState.promptIdBySession = next;
2250 }
2251
2252 // For the session on screen, refresh git status (edits the agent just made)
2253 // and runtime status (model/context usage may have changed this turn).
2254 if (sid === rawState.activeSessionId) {
2255 appearance.resetFastMoon();
2256 void workspaceState.loadGitStatus(sid);
2257 void refreshSessionStatus(sid);
2258 } else if (status === 'idle') {
2259 // A background session finished a turn the user hasn't seen — light up its
2260 // unread dot until they open it. Aborted (cancelled/failed) turns are
2261 // excluded on purpose: there is no fresh result to read, and counting them
2262 // is what made the sidebar fill with stale unreads after a refresh.
2263 rawState.unreadBySession = { ...rawState.unreadBySession, [sid]: true };
2264 saveUnread({ [sid]: true });
2265 }
2266
2267 // Browser notification when the user isn't watching this session.
2268 notification.maybeNotifyCompletion(sid, {
2269 isActiveAndVisible:
2270 sid === rawState.activeSessionId &&
2271 typeof document !== 'undefined' &&
2272 document.visibilityState === 'visible',
2273 sessionTitle: rawState.sessions.find((s) => s.id === sid)?.title ?? '',
2274 onClick: () => {
2275 void workspaceState.selectSession(sid);
2276 },
2277 });
2278
2279 // Completion sound — only for real completions (aborted/cancelled turns stay
2280 // silent). Plays regardless of visibility so it also reaches a backgrounded tab.
2281 if (status === 'idle') {
2282 sound.maybePlayCompletionSound();
2283 }
2284
2285 const queue = rawState.queuedBySession[sid] ?? [];
2286 if (queue.length === 0) return;
2287
2288 const [next, ...rest] = queue;
2289 rawState.queuedBySession = { ...rawState.queuedBySession, [sid]: rest };
2290 // Flush the first queued message; on failure put it back at the head so a
2291 // transient error doesn't silently drop the prompt.
2292 if (next !== undefined) {
2293 void workspaceState.submitPromptInternal(sid, next.text, next.attachments).then((ok) => {
2294 if (!ok) {
2295 const current = rawState.queuedBySession[sid] ?? [];
2296 rawState.queuedBySession = {
2297 ...rawState.queuedBySession,

Callers 1

processEventFunction · 0.85

Calls 3

saveUnreadFunction · 0.90
refreshSessionStatusFunction · 0.85
deleteMethod · 0.65

Tested by

no test coverage detected