diff --git a/.changeset/fix-read-media-video-upload-fallback.md b/.changeset/fix-read-media-video-upload-fallback.md new file mode 100644 index 0000000000..c3655aac65 --- /dev/null +++ b/.changeset/fix-read-media-video-upload-fallback.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Fix ReadMediaFile failing on videos when the provider has no file upload channel — such videos now fall back to inline delivery. diff --git a/.changeset/prompt-video-inline.md b/.changeset/prompt-video-inline.md new file mode 100644 index 0000000000..bd3cacc543 --- /dev/null +++ b/.changeset/prompt-video-inline.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": minor +--- + +Videos attached to a prompt — pasted in the TUI or uploaded in the web UI — now reach the model together with the prompt, with no extra tool round trip, and stay playable in the chat after a reload. diff --git a/apps/kimi-code/src/tui/kimi-tui.ts b/apps/kimi-code/src/tui/kimi-tui.ts index 464c7237aa..14951c6ed8 100644 --- a/apps/kimi-code/src/tui/kimi-tui.ts +++ b/apps/kimi-code/src/tui/kimi-tui.ts @@ -1135,7 +1135,18 @@ export class KimiTUI { this.showError(LLM_NOT_SET_MESSAGE); return; } - const extraction = extractMediaAttachments(text, this.imageStore); + let extraction: ReturnType; + try { + // Pasted videos are copied into the cache and expand to a `file://` + // `video_url` part; the engine resolves (uploads or degrades) them + // inside the turn, so submission stays fully synchronous. + extraction = extractMediaAttachments(text, this.imageStore); + } catch (error) { + // A video cache copy failed (unwritable cache dir, vanished source…); + // nothing was dispatched. + this.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); + return; + } if (!this.validateMediaCapabilities(extraction)) return; const session = this.session; if (session === undefined) { diff --git a/apps/kimi-code/src/tui/utils/image-placeholder.ts b/apps/kimi-code/src/tui/utils/image-placeholder.ts index 56edcee88b..87d53eabc2 100644 --- a/apps/kimi-code/src/tui/utils/image-placeholder.ts +++ b/apps/kimi-code/src/tui/utils/image-placeholder.ts @@ -1,17 +1,28 @@ /** - * Scan submitted text for media placeholders and produce - * the `PromptPart[]` we'll send to the SDK prompt endpoint. + * Scan submitted text for media placeholders and produce the prompt content + * we'll send to the SDK prompt endpoint. * - * Rules: + * `extractMediaAttachments` (sync) is the single expansion path for prompts: + * - image placeholders expand to inline image content parts (preceded by a + * compression caption when paste-time compression shrank the bytes — see + * `ImageAttachment.original`); + * - video placeholders are copied into the shared cache (`getCacheDir()`) + * and expand to a `video_url` part pointing at the cache copy with a + * `file://` url. The v1 engine resolves that local reference inside the + * turn — uploading it (the `ms://` inline form) or degrading to a + * `