Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/vscode-busy-error-message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kimi-code": patch
---

Stop reporting a busy chat session as "Internal error occurred." A prompt sent while a response is still being generated now surfaces as "A message is being sent. Please wait." (code `turn.agent_busy`) with the original detail attached, instead of the generic internal-error message that the plain `Error` was mapped to.
5 changes: 3 additions & 2 deletions apps/vscode/src/runtime/session-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
isKimiError,
KimiError,
type ContentPart as SdkContentPart,
type Event,
type PromptInput,
Expand Down Expand Up @@ -188,7 +189,7 @@ export class SessionRuntime {
// such terminal event, so reject terminally: the caller's composer must
// unlock rather than hang until the handshake timeout.
this.emitError(
new Error(ALREADY_GENERATING_MESSAGE),
new KimiError("turn.agent_busy", ALREADY_GENERATING_MESSAGE),
"runtime",
{ terminal: this.hasActiveWork ? false : undefined },
);
Expand Down Expand Up @@ -225,7 +226,7 @@ export class SessionRuntime {
beginHostAction(input: string | LegacyContentPart[], forkable = false): number {
this.ensureOpen();
if (this.isBusy) {
throw new Error(ALREADY_GENERATING_MESSAGE);
throw new KimiError("turn.agent_busy", ALREADY_GENERATING_MESSAGE);
}
const actionId = ++this.hostActionSequence;
this.hostActionActive = true;
Expand Down
2 changes: 2 additions & 0 deletions apps/vscode/test/kimi-runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ describe("Kimi runtime (owns shared SDK sessions for Webviews)", () => {
const busyWarning = broadcasts.find(({ data }) => (data as { type?: string }).type === "error");
expect(busyWarning?.data).toMatchObject({
type: "error",
code: "turn.agent_busy",
message: "A message is being sent. Please wait.",
phase: "runtime",
detail: "A response is already being generated for this session.",
terminal: false,
Expand Down
6 changes: 3 additions & 3 deletions apps/vscode/test/settings-store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,15 @@ describe("Webview mid-turn warnings", () => {

useChatStore.getState().processEvent({
type: "error",
code: "internal",
message: "Internal error occurred.",
code: "turn.agent_busy",
message: "A message is being sent. Please wait.",
detail: "A response is already being generated for this session.",
phase: "runtime",
terminal: false,
});

// The turn is still running: nothing unlocks, nothing flushes, nothing is retried.
expect(boundary.toastWarning).toHaveBeenCalledWith("Internal error occurred.");
expect(boundary.toastWarning).toHaveBeenCalledWith("A message is being sent. Please wait.");
const state = useChatStore.getState();
expect(state.isStreaming).toBe(true);
expect(state.queue).toHaveLength(1);
Expand Down