mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-25 17:14:54 +00:00
51 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5394feaabb
|
feat: hold print-mode turn until background subagents drain (#1371)
* feat: hold print-mode turn until background subagents drain In `kimi -p` (print mode), when the main agent ends a turn while background subagents (`kind === 'agent'`) are still running, hold the turn open and idle-wait until they finish, flushing their completions into the turn so the model can react before the run exits. Previously, the main agent could end its turn after launching background subagents; the print flow then drained them with their completion notifications suppressed, so the main agent never saw the results and the run exited with the work abandoned (e.g. no nomination). This was the root cause of the swarm-alpha-mining eval failures. The hold is gated on a new `drainAgentTasksOnStop` session option (set by the print flow), only affects `kind === 'agent'` background tasks, and is bounded by `background.printWaitCeilingS`. Backfill / fan-out is handled by re-enumerating active tasks. Other background task kinds and non-print modes are unaffected. |
||
|
|
02da587795
|
feat(cli): wait for background subagents before exiting kimi -p (#1347)
* feat(agent-core): guide the model away from repeating denied or failed tool calls - system.md: add a diagnose-before-retrying paragraph next to the existing permission-denial guidance, covering failed tool calls - permission: when the user rejects an approval on the main agent, tell the model not to re-attempt the exact same call (sub agents already had an equivalent hint) * fix(agent-core): close abandoned tool exchanges and dedupe duplicate tool_use ids A turn that dies between a recorded tool.call and its paired tool.result (e.g. a transcript write failure mid-batch) used to leave pendingToolResultIds open forever: every later message was stranded in deferredMessages and user input was silently swallowed. - runOneTurn now defensively closes any dangling tool calls when a turn ends (completed, cancelled, or failed), synthesizing an error result that names the cause, with a warn log and a tool_exchange_abandoned telemetry event - the projector drops assistant tool calls whose id already appeared earlier (first occurrence wins): a duplicate id is wire-invalid on strict providers and not repairable by the strict resend; reported via the existing projection-repair log and telemetry - resume-side closePendingToolResults now logs what it closes (warn for a mid-history gap, info for the routine trailing interruption) * chore: add changesets for tool exchange fixes * fix(agent-core): scope duplicate tool_use id dedup to the strict resend Unconditional dedup regressed providers that emit per-response counter ids (e.g. call_0 in every step) and accept their own duplicates: later tool exchanges silently vanished from the projected history, and a duplicate call's own recorded result was left dangling. - the dedupe pass is now opt-in via dedupeDuplicateToolCalls and enabled only in strictMessages, so the normal projection keeps the history the provider produced - the pass also drops every tool result after the first for an id, so no dangling tool message survives; when the kept call has no result of its own, the surviving one is reattached by the adjacency repair - kosong now classifies the Anthropic "tool_use ids must be unique" 400 as a recoverable request-structure error so it triggers the strict resend * feat(cli): wait for background subagents before exiting kimi -p When `background.keep_alive_on_exit` is enabled, `kimi -p` now waits for all background subagents to reach a terminal state before exiting, bounded by `background.print_wait_ceiling_s` (default 3600s). This lets concurrent background subagents run to completion in single-turn runs instead of being torn down when the main agent's turn ends. |
||
|
|
0fc0ae380b
|
feat(agent-core): announce image compression and keep originals readable (#1304)
* feat(agent-core): announce image compression and keep originals readable Every image ingestion point (ReadMediaFile, MCP tool results, clipboard paste, REST upload/inline base64, ACP) now places a <system> caption next to a compressed image stating the original vs. delivered dimensions, byte size, and format, so downsampling is never silent to the model. Originals stay readable: file uploads point at the stored blob, and in-memory images are persisted into the session's media-originals dir (content-addressed, size-capped, removed with the session; temp-dir fallback when no session is known). ReadMediaFile gains region (crop in original-image pixel coordinates, delivered at full fidelity) and full_resolution (skip downscaling, with an explicit error over the per-image byte limit), so the model can zoom into fine detail instead of silently degrading on large images. * fix(agent-core): exempt compression captions from the MCP text budget The caption announcing an image's compression was inserted before the shared 100K text budget was applied, so a chatty MCP result (page text + screenshot) consumed the budget first and the caption was evicted — or sliced mid-string into an unclosed <system> fragment — while the downsampled image survived, silently reintroducing the exact degradation the caption exists to report, and orphaning the persisted original. Split the size-limit pass in two and reorder the pipeline: the text budget now runs on the tool's own text BEFORE compression inserts captions (exempt by construction), and the per-part binary cap still runs after compression so compressible screenshots are kept. * fix(agent-core): harden crop error reporting and document readback semantics - cropImageForModel rejects non-finite region coordinates with a clean message instead of surfacing the codec's internal validation dump - the full_resolution and cropped-region over-budget errors now include exact byte counts alongside the rounded sizes, so a file a hair over budget no longer reads "is 3.8 MB, over the 3.8 MB limit" - read-media.md notes that re-reading a file without region or full_resolution reproduces the same downsampled image |
||
|
|
c070fbedde
|
feat: add model alias overrides (#1262)
* feat: add model alias overrides Preserve user model overrides across provider catalog refreshes and resolve effective model metadata for runtime, TUI, protocol, and ACP consumers. * fix: apply model display name overrides Show overridden model display names in the footer, welcome panel, status output, and model switch confirmations. * fix: pass through kimi effort when undeclared Keep support_efforts authoritative when declared, but pass requested Kimi thinking effort through when the model does not declare support_efforts. * fix: honor model overrides in effort commands Use effective model metadata for /effort choices and for always_thinking clamping when resolving thinking effort. |
||
|
|
ace7901066
|
feat(agent-core): compress oversized images before sending to the model (#1243)
* feat(agent-core): compress oversized images before sending to the model
Downsample images to a 2000px longest-edge and per-image byte budget at the
single prompt-ingestion chokepoint (the prompt/steer RPC) and on tool results
(ReadMediaFile, MCP), so every client transport — CLI, web, desktop, ACP, SDK —
is covered uniformly inside the core. PNG screenshots stay lossless and only
degrade to JPEG when the byte budget cannot otherwise be met. Best-effort: the
original image is sent unchanged if compression fails.
* fix(agent-core): serialize prompt/steer RPCs to avoid a turn-claim race
The prompt/steer RPC handlers await image compression before turn.launch()
synchronously claims the active turn, so two overlapping calls could both
compress first — letting the faster-to-compress one win the turn and strand the
other on agent_busy. Run these two RPCs through a per-agent serialization chain
so they claim in submit order; cancel and the other RPCs stay immediate.
* fix: update flake.nix pnpmDeps hash for the jimp dependency
Adding jimp to the workspace changed pnpm-lock.yaml, so the pnpmDeps
fixed-output hash was stale and the nix build failed. Update it to the value
the CI nix build reported.
* fix(agent-core): guard image compression against decompression bombs
A tiny-byte, huge-dimension image (e.g. a solid 30000x30000 PNG) would be fully
decoded into a multi-gigabyte bitmap by Jimp before any resize — an OOM vector
the byte budget never catches. Skip compression when the sniffed pixel count
exceeds MAX_DECODE_PIXELS (~100 MP), before the decode; oversized images pass
through uncompressed as they did before compression existed.
* fix(agent-core): cap decode byte size before compressing images
Compression runs before downstream size caps (e.g. the 10MB MCP per-part
limit), so a huge or invalid base64 image from an MCP tool was Buffer.from-
decoded — and handed to Jimp — just to be dropped afterward. Add a
MAX_DECODE_BYTES ceiling (64MB, overridable) checked before the base64 decode
and before Jimp, the byte-side complement to the pixel-count guard; oversized
payloads pass through uncompressed.
* refactor(agent-core): compress images at ingestion, not on the turn RPC
Move image compression off the prompt/steer RPC path and back to each ingestion
site (CLI paste, server upload resolution, ACP conversion; ReadMediaFile and MCP
already compressed at their producers). Compressing on the RPC control path put
an async step before the synchronous turn-claim, which spawned a series of
races: prompt/steer interleaving, and — with a cancel arriving mid-compression —
an ineffective abort that let a cancelled prompt launch anyway.
Treating compression as a pure input-stage transform (done while the content
part is built, before it ever enters the agent loop) removes those races
structurally: rpc.prompt/steer are plain synchronous handlers again, and the
serialization/cancel-window machinery is gone. Records stay compressed, resume
stays consistent, and coverage degrades gracefully (a new client that skips
compression just sends a larger image, as before this feature).
* fix: compress inline base64 prompts and honor ACP cancels mid-compression
Two contained ingestion-site follow-ups:
- server: resolvePromptMediaFiles now also compresses images submitted as an
inline `{ kind: 'base64' }` source, not just uploaded files, so the REST
inline-base64 path gets the same downsampling.
- acp-adapter: AcpSession tracks a pending-abort flag while prompt() awaits
image compression (before any turn exists). A session/cancel in that window
flips it, so the prompt returns `cancelled` instead of launching a turn the
client already stopped.
* fix(acp-adapter): cover all concurrent pre-turn prompts on cancel
The pending-abort marker was a single session field, so with two
`session/prompt` requests compressing large inline images at once the later
one overwrote it and a `session/cancel` could mark only one — the other
launched after the client had cancelled. Track a token per in-flight prompt in
a set and flip them all on cancel so every pre-turn prompt is covered.
* chore(node-sdk): declare jimp as a devDependency
The SDK re-exports the image compressor, whose lazy `import('jimp')` (inside
the bundled agent-core code) is inlined into the published dist. jimp was
resolved only transitively via agent-core, so declare it as an explicit build
input here — matching the CLI — to make the bundling reliable rather than
phantom. It stays a devDependency: jimp is bundled, not a runtime dependency.
|
||
|
|
108299be3c
|
refactor!: overhaul thinking config and effort resolution (#1132)
* feat: support multi-level thinking effort switching
- kimi provider: emit thinking.effort in the new wire format; keep reasoning_effort mirrored during the transition
- model catalog: thread support_efforts / default_effort from oauth through to /models
- config schema: add supportEfforts / defaultEffort on model aliases
- TUI: multi-segment thinking control in /model, new /effort command, footer effort display
- switch status uses displayName and distinguishes model vs effort-only changes
* docs: add thinking effort design plans
- thinking-effort-switching.md: implemented multi-level effort switching
- thinking-model-overhaul.md: follow-up refactor plan for the thinking state model
* docs: collapse thinking overhaul plan into a single PR
* refactor!: overhaul thinking config and effort resolution
Replace default_thinking and thinking.mode with a single [thinking] enabled/effort table. ThinkingEffort is now an open string ('off' | 'on' | model-declared effort); effort levels come from each model's support_efforts instead of a fixed enum.
Centralize default and always_thinking clamp logic in resolveThinkingEffort/defaultThinkingEffortFor, and honor an explicitly configured effort when an always_thinking model is forced back on.
TUI keeps a single thinkingEffort field instead of the boolean + level pair; 'on' is normalized to the model default at the UI boundary.
BREAKING CHANGE: default_thinking and thinking.mode are removed from config; migrate to [thinking] enabled/effort.
* refactor: rename residual thinking level wording to effort
Rename comments, error messages, parameter names, the SetThinkingPayload wire field (level -> effort), and TUI local variables so the thinking effort naming is consistent throughout. No behavior change.
* refactor: rename remaining camelCase thinking level identifiers to effort
Rename liveLevel/prevLevel/levelChanged/commitLevel/effectiveLevel to liveEffort/prevEffort/effortChanged/commitEffort/effectiveEffort in the TUI model picker and config commands.
* refactor: eliminate remaining thinking level wording in comments and tests
Rename levelLabel -> effortLabel, EffortSelectorOptions.levels -> efforts, and 'effort level(s)' / 'default level' / 'requested level' wording in comments, error messages, slash-command description, and test titles to effort. Also restore the withThinking(effort) parameter rename in the Kimi provider that was accidentally reverted.
* fix: address codex review feedback on thinking effort handling
- OpenAI thinkingEffortToReasoningEffort and Anthropic clampEffort now normalize 'on' / unrecognized efforts instead of throwing, so boolean non-Kimi models no longer crash on session start.
- ACP resolveCurrentThinkingEnabled treats a non-empty thinking.effort as enabled, matching agent-core's resolveThinkingEffort.
- REST promptThinkingSchema accepts any non-empty effort string so model-declared efforts are not rejected at the API boundary.
* test: align kimi e2e expectations with supportEfforts-gated reasoning_effort
The kimi provider now sends reasoning_effort only when the model declares support_efforts; boolean models (no support_efforts) send only thinking.type. Update the kimi e2e tests to drop the stale reasoning_effort expectation for the boolean test model.
* test: cover [thinking] effort parsing in config.test
Add effort = "high" to the documented [thinking] table in the config parse test and assert config.thinking.effort is resolved, so the new [thinking] effort field has direct parse coverage.
* docs: add thinking test coverage gap analysis
Capture the explore agent's test coverage review for the thinking overhaul PR, including P1/P2 gaps and the two open design questions, for follow-up test additions.
* feat(oauth): parse nested think_efforts from /models response
The /models endpoint now returns effort levels under a nested think_efforts object ({ support, valid_efforts, default_effort }). Parse it preferentially in both managed-kimi-code and open-platform model parsing, falling back to the legacy flat support_efforts / default_effort fields for older servers.
* refactor(oauth): only read nested think_efforts; gate on support=true
Drop the legacy flat support_efforts / default_effort fallback. The think_efforts object is now the single source, and its support flag gates the whole object — when support is not true, valid_efforts and default_effort are ignored entirely.
* chore: remove unused parseStringArray import in open-platform
* docs: finalize thinking effort release notes
Downgrade the changeset to minor with an English summary, drop the version-specific 'added in 1.0.0' info block, and present the deprecated config fields as a table (field / deprecated in 0.21.0 / description).
* refactor: drop temporary refresh toggles and kimi reasoning_effort mirror
Remove the always-true REFRESH_MODELS_ON_PICKER_OPEN / REFRESH_PROVIDER_MODELS_ON_STARTUP toggles and their stale re-enable TODOs, and stop sending reasoning_effort from the kimi provider (thinking.effort is the only wire field now).
* fix(tui): avoid persisting "on" as thinking effort
* fix: preserve persisted thinking effort across login and provider setup
* fix(tui): show actual thinking effort in /status and footer
* test(tui): align message-flow expectations with effort persistence and /status display
* fix(vis): rename thinkingLevel to thinkingEffort in config.update analysis
|
||
|
|
5cb80ce879
|
feat: support plugin slash commands (#1204)
* feat(agent-core): support plugin slash commands * feat(node-sdk): expose listPluginCommands * feat(kimi-code): register and dispatch plugin slash commands * chore: add changeset for plugin commands * feat(agent-core): activate plugin commands server-side * feat(node-sdk): add activatePluginCommand * feat(kimi-code): render plugin command activations compactly * feat(agent-core): recurse plugin command directories and preserve namespace * fix(kimi-code): parse nested plugin command names * fix(agent-core): update prompt metadata for plugin command turns * fix(kimi-code): replay plugin command turns as command cards * fix: treat plugin-command origins as real user prompts in undo * fix(kimi-code): guard model-empty and clear plugin command render ids * fix: propagate plugin_command to web and vis turn projectors * fix(kimi-code): refresh plugin commands through auth flow * fix(kimi-web): render plugin command cards in chat pane * fix(kimi-web): render plugin command card in desktop chat view * fix(kimi-code): treat slash-activation cards as transcript turn boundaries * fix(kimi-code): count slash-activation entries when trimming transcript turns * fix(kimi-code): preserve plugin command args in undo selector |
||
|
|
10ffb7d9f9
|
chore(telemetry): normalize telemetry property keys to snake_case (#1196)
- Rename camelCase telemetry keys to snake_case on compaction_finished, compaction_failed, micro_compaction_finished, and the tool error event (tokens_before, tokens_after, compacted_count, retry_count, thinking_level, error_type, input_tokens/output_tokens, and the micro compaction config/effect keys). - Emit a fixed client-attribution key set (client_id/name/version/ui_mode, null when absent) from both session_started producers (core-impl and kimi-harness) so they share a stable schema. - Drop the duplicate current/latest keys on update_prompted and the redundant ui_mode on server_started. - Additive fields: login.method=oauth and question_answered.answered. Telemetry-only change; no changeset. |
||
|
|
821847cb4b
|
feat(managed-kimi-code): route anthropic protocol via beta api (#1186)
* feat(managed-kimi-code): route anthropic protocol via beta api - kosong: add betaApi option to use client.beta.messages.create - agent-core: thread alias betaApi into the anthropic provider config - oauth: route managed models on the anthropic protocol through the beta Messages API * feat(providers): add KIMI_CODE_CUSTOM_HEADERS support - Add KIMI_CODE_CUSTOM_HEADERS env var for custom outbound LLM headers - Send User-Agent to non-Kimi providers - Forward Kimi identity headers to model catalog fetches - Support defaultHeaders in Google GenAI provider * feat(agent-core): add protocol attrs to turn and api error telemetry - Add type/protocol/alias to api_error for per-protocol error attribution - Add turn_ended event with reason/duration/mode/type/protocol - Add type/protocol to turn_interrupted * chore(oauth): remove hardcoded internal dev endpoint from shared OAuth base URLs --------- Co-authored-by: haozhe.yang <yanghaozhe@moonshot.ai> |
||
|
|
cf558cd742
|
feat(managed-kimi-code): support Anthropic-compatible protocol (#1170)
* fix(agent-core): recover from context overflow 413 - track provider-observed effective context limit after overflow - compact with the reduced limit before retrying the turn - treat large plain 413 responses as recoverable context overflow - add CLI patch changeset * feat(managed-kimi-code): support Anthropic-compatible protocol - switch managed provider to anthropic when models declare anthropic protocol - add base64 video content blocks to the kosong anthropic provider - downgrade unsupported media parts to text placeholders by capability - pass prompt cache key as Anthropic metadata.user_id for session affinity * feat(agent-core): add protocol/type to request and video upload telemetry - turn_started now carries `type` (configured provider wire type) and `protocol` (effective transport, i.e. alias.protocol ?? provider.type) - new video_upload event reports mime type, size, latency and success/failure, plus type/protocol/model context - ResolvedRuntimeProvider gains `type` and `protocol` fields |
||
|
|
e736349a7c
|
feat(feedback): support attaching logs and codebase (#1120)
* feat(feedback): support attaching logs and codebase Add an attachment picker to /feedback (none / logs / logs + codebase). Codebase uploads scan the working directory with sensitive files excluded and are sent through a new multipart upload API on the oauth/node-sdk layers. * fix(feedback): fall back to logs when codebase scan fails * tiny fix * fix(feedback): make diagnostic uploads partial-safe * refactor(feedback): reuse harness session export and normalize upload url types * docs(slash-commands): note optional feedback attachments * refactor(feedback): reorganize feedback upload modules Move the attachment orchestration out of tui/commands/info.ts into a dedicated feedback/feedback-attachments.ts, and split the former codebase-upload/attach.ts into a generic multipart uploader (feedback/upload.ts) and an archive lifecycle module (feedback/archive.ts). Both session and codebase archives now flow through a single upload lifecycle, which also removes the temp-dir leak that occurred when codebase packaging failed. Rename FeedbackCodebaseArchive to FeedbackArchive and the codebase-upload/ directory to codebase/ so module boundaries match their actual responsibilities (scan + package only). |
||
|
|
fe667d7c2e
|
fix(reload): re-inject plugin session-start reminder after /reload (#1086)
* fix(reload): re-inject plugin session-start reminder after /reload Reload reloaded plugins and resumed the session, but the model kept seeing the stale plugin session-start reminder from before the reload, so plugin skill changes only took effect in a fresh session. Append a fresh plugin_session_start reminder to the main agent after reload, gated on a new forcePluginSessionStartReminder flag that only the explicit /reload command sets, so config and experiment toggles that reuse the reload RPC do not spam the transcript. * fix(reload): keep reload result fresh and neutralize stale plugin reminder Append the plugin session-start reminder before constructing ResumeSessionResult so SDK callers reading getResumeState() see the refreshed plugin context instead of a pre-reload snapshot. When a plugin with a prior plugin_session_start reminder is disabled or removed, append a neutralizing reminder so the model does not keep following stale plugin instructions. * fix(reload): neutralize stale plugin reminder after compaction A full compaction folds the discrete plugin_session_start reminder into a compaction_summary, so the origin-only scan no longer detects it. Also treat a compaction_summary in history as a signal to neutralize, so disabling or removing a plugin after compaction still emits a superseding 'no active plugin session starts' reminder. * fix(reload): thread plugin reminder option through KimiHarness.reloadSession KimiHarness.reloadSession is a public SDK entry point; forward forcePluginSessionStartReminder to both the active-session and RPC reload paths so SDK callers using the harness can opt into the refreshed plugin reminder too. |
||
|
|
2db5fc20ec
|
feat: add shell mode (!) to the CLI (#1079)
* feat: add shell mode (`!`) to the CLI Add shell mode, letting users run shell commands directly from the prompt with `!`. Output streams live into the transcript, supports backgrounding (ctrl+b), cancellation (Esc / Ctrl+C), input queuing while running, and enters the conversation context with resume support. * feat(kimi-code): show shell mode label on editor border and add tip Render a "! shell mode" label on the top-left of the editor border while the editor is in `!` bash mode, so the active mode is visible at a glance. Also add a rotating toolbar tip (`! to run a shell command`) to surface the feature. * feat(kimi-code): refine shell mode queue, history, and display - Keep `!` commands out of input history so they never resurface as bare text stripped of their `!`. - Make `!` commands non-steerable: Ctrl-S skips them (they stay queued to run after the current task) and the steer hint is only shown when something is actually steerable. - Render queued `!` commands with a `$` prompt and the shell-mode hue so they read as commands, not as text to send to the model. - Echo executed shell commands with a `$` prompt instead of `!`. * fix(kimi-code): sanitize shell output and harden rendering Captured shell command output can contain terminal control sequences (colours, cursor moves, alternate-screen switches, OSC hyperlinks, carriage-return spinners, bells). pi-tui's Text passes strings straight to the terminal, so any unhandled sequence was executed by the terminal and fought with pi-tui's own cursor control, producing the blank-screen-plus-leftover-characters mess after running commands like pnpm dev or a nested TUI. - Sanitize CSI (incl. private modes), OSC, single-char ESC and C0 control chars (keeping newline and tab) in both the finished/resume view (previously unsanitized) and the running tail. - Make the sanitize, format, and ShellRunComponent render paths never-throw, and cap the live running buffer, so a misbehaving command cannot crash the TUI. - Dispose transcript children on clear so ShellRunComponent's timer is released on /clear or session switch. * fix(kimi-code): render shell command echo with $ instead of sparkles The shell command echo is a 'user' transcript entry, so UserMessageComponent prefixed it with the USER_MESSAGE_BULLET (sparkles), producing 'sparkles $ command'. Add an optional bullet override to UserMessageComponent / TranscriptEntry and set it to an empty string for the shell echo (both live and resume), so the '$ command' content sits at the leading column where the sparkles marker used to be. Normal user messages keep the sparkles bullet. * fix(kimi-code): enter shell mode when pasting a !-prefixed command The bash-mode trigger only handled the single ! keystroke, so a pasted !cmd was inserted as literal text in prompt mode and submitted as a normal message. After pi-tui inserts pasted content, detect an empty-prompt buffer that now starts with !, switch to bash mode, and strip the leading ! so the buffer holds only the command, matching the typed ! path. * fix(kimi-code): restore shell mode when recalling a queued command recallLastQueued() dropped the queued item's mode, and the Up-arrow recall only restored the text. A queued ! command (queued while another command runs, which resets the editor to prompt mode) therefore came back as a normal prompt and was submitted as a message instead of a shell command. Return the full QueuedMessage from recallLastQueued() and restore editor.inputMode (plus the onInputModeChange sync) from the recalled item's mode. * feat(kimi-code): use violet as the shell mode color Replace the claude-code-style magenta/rose shellMode token with a violet that is distinct from plan-mode blue, the user role amber, success green, error red, and the teal accent. Custom themes that omit the token fall back to this new default via the base+overrides merge, so existing custom themes keep working unchanged. * chore: refine the shell mode changeset * docs: document shell mode Add a Shell mode section to the interaction guide and list the ! and Ctrl+B shortcuts in the keyboard reference, in both English and Chinese. * test(protocol): include shell events in volatile classification check shell.output and shell.started were added as volatile event types for shell mode; update the snapshot test's volatile-type list and count accordingly. * fix(agent-core): surface shell command failure reason with no output When a ! shell command fails without producing stdout/stderr (non-zero exit with no output, timeout, spawn failure), the failure reason lived only in the tool result's output and the TUI showed '(no output)'. Fold it into stderr so the live view and replay show what went wrong. * fix(kimi-code): decode CSI-u ! to enter shell mode In terminals with the Kitty keyboard protocol (VSCode integrated terminal, Kitty), pressing ! arrives as a CSI-u sequence, so the raw normalized === '!' comparison never matched and shell mode could not be entered by typing !. Decode with printableChar before comparing, matching every other printable-key check in the TUI. * fix(kimi-code): do not steer while a shell command is running Ctrl-S steers queued input into the running turn, but a shell command is not an agent turn, so steering during streamingPhase === 'shell' would launch a turn before the command output is recorded. Keep Ctrl-S a no-op during shell runs; queued messages stay queued. * fix(agent-core): escape bash tag delimiters in shell output Shell command output is arbitrary text; if it contains a bash tag delimiter such as </bash-stdout>, the recorded pseudo-XML wrapper breaks and replay extracts the wrong slice. Escape the content when wrapping it in agent-core and unescape when extracting during replay, so output survives round-trip intact. * docs: document the shellMode theme token The shellMode color token was added to the palette but not propagated to its mirrors. Add it to the custom-theme docs token table, the theme JSON schema, and the custom-theme skill token list. * feat(agent-core): reset background task deadline on detach Add a resettable deadline timer to BackgroundManager and let tasks register a detach timeout; when a foreground task is moved to the background, its deadline resets to the background default counted from the detach moment. Wire this into shell mode so ! commands run with a 3-minute foreground timeout and get 10 minutes once detached to the background, instead of staying bounded by the original 60-second foreground deadline. * feat(agent-core): lower shell mode foreground timeout to 2 minutes |
||
|
|
66640380eb
|
feat: replace silent AGENTS.md truncation with a visible warning (#1040)
Oversized AGENTS.md files are no longer silently truncated. The full content is injected, and a warning is shown in the TUI status bar and the web UI when the combined AGENTS.md size exceeds the recommended 32 KB. A generic session-warnings API backs this so future warning types can be added without changing the API surface. |
||
|
|
c0eeca2469
|
feat: add workspace add-dir support (#812)
* feat: add workspace add-dir support
Add multi-directory /add-dir management with session-only or project-remembered persistence, directory completion, confirmation UI, and runtime workspace/permission wiring.
* fix: honor --add-dir for resumed sessions
Pass CLI additional directories through shell and prompt resume paths, resolve caller-relative dirs against workDir, and add regression coverage.
* fix: keep additional dirs AGENTS.md out of default context
Load only user-level and cwd AGENTS.md by default, while preserving additional directory listings in the prompt context.
* feat: append /add-dir result as user message
Add a session appendUserMessage RPC and use it after /add-dir so the command result is recorded as a normal user message and surfaced in the transcript.
* docs: add add-dir research and follow-up todos
Document the add-dir / local-command-stdout research findings and the follow-up tasks for stdout wrapping, slash file completion, and hints.
* feat: wrap /add-dir output as local-command-stdout
Insert the /add-dir result as a user-role <local-command-stdout> record with an injection origin directly inside Session.addAdditionalDir. It enters the model context on the next turn but does not start a turn, and stays out of the live and resumed transcript; the transient status toast is kept for immediate feedback. --add-dir is unaffected since it bypasses addAdditionalDir.
Remove the now-unused appendUserMessage RPC and SDK method.
* feat: reopen /add-dir completion after accepting a directory
Generalize the slash-argument completion reopen so it fires whenever the text before the cursor ends with '/', not only when the literal '/' key is typed. After Tab-accepting a directory (or auto-applying a single-child dir), the next level's completion list reappears automatically, so repeated Tab keeps drilling down into subdirectories. '@' file mention is unaffected.
* feat: reopen file mention completion after accepting a directory
Extend the path completion reopen so it also fires for '@' file mentions. After Tab-accepting a directory in an '@' mention, the next level's completion list reappears automatically, matching the '/add-dir' continuous-Tab behavior.
* feat: show inline argument hints for slash commands
Render a dim ghost-text argument hint inside the input box after a slash command that takes arguments, replacing the popup-only hint that was easy to miss. The hint appears once the command is typed and disappears as soon as an argument is entered, and is truncated to fit the box width. Add argument hints for /compact, /swarm, /goal and /title; /add-dir already had one.
* test: remove stale additional-dirs AGENTS.md assertion
The subagent-host test still asserted that an additional directory's AGENTS.md content appears in the agent system prompt, but additional-dirs AGENTS.md has been intentionally excluded from the default context since an earlier commit (covered by context.test.ts). Drop the stale assertion.
* fix: resolve /add-dir paths against workdir and persist via kaos
Resolve user-supplied /add-dir paths against the current workdir instead of the project root, so launching from a subdirectory behaves like the CLI --add-dir flag. Also route the local.toml read/write through the kaos abstraction instead of host fs, so the remember path works for non-local sessions.
* fix: expand ~ in /add-dir paths before resolving
The /add-dir completer emits ~/... values, but the core treated ~/foo as a relative path because pathe isAbsolute('~/foo') is false, producing <workDir>/~/foo. Expand ~ and ~/ to the home directory (via kaos.gethome()) before resolving.
* chore: remove add-dir dev docs from the branch
These were working notes (research and follow-up todos) that don't belong in the PR.
* chore: clarify add-dir changeset for users
* docs: document /add-dir, --add-dir, and local.toml
* test: flush records before reading wire in add-dir runtime tests
FileSystemAgentRecordPersistence.append buffers records and flushes asynchronously, so readMainWire can read the wire before the local-command-stdout record lands. Flush the main agent's records explicitly in the two add-dir runtime tests to make them deterministic.
|
||
|
|
ba64072559
|
feat: detach foreground tasks to background (#821)
Some checks failed
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
Nix Build / Check flake.nix workspace sync (push) Has been cancelled
Release / Release (push) Has been cancelled
Release / Native release artifact (push) Has been cancelled
Nix Build / nix build .#kimi-code (push) Has been cancelled
Release / Deploy docs (push) Has been cancelled
Release / Publish native release assets (push) Has been cancelled
|
||
|
|
42d648655a
|
refactor(telemetry): merge duplicate session-start and goal events (#885)
Some checks are pending
CI / build (push) Waiting to run
CI / test (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
* refactor(telemetry): merge duplicate session-start and goal events * test: align telemetry tests with merged session-start events - run-shell: assert sessionStartedProperties plumbing instead of the removed 'started' event, drop the now-redundant resumed-lifecycle test, and fix the startup_perf call-count assertion - node-sdk: cover process-level and session-level sessionStartedProperties merging on session_started * fix(telemetry): keep session_started canonical fields authoritative Caller-supplied sessionStartedProperties were merged after the canonical fields (client_name, client_version, ui_mode, resumed), so a caller could silently override them via the public SDK options. Reorder so the harness-owned canonical fields always win, while session-level properties still override process-level ones for non-canonical keys. |
||
|
|
9a8fea5c85
|
feat(web): introduce Kimi web app and daemon gateway (#625)
* docs(reports): collapse P3 plan into a single final-solution doc Drop the per-step TDD/commit scaffolding; keep the substance as one final approach per area (what it does, files to touch, key types/events/projection, component responsibilities, verification, risks, sequencing). * fix(kimi-web): normalize chat block spacing Group consecutive tool cards structurally so chat block spacing is applied consistently without leaking card borders or shadows. * feat(web): land P3 — goal / swarm / subagent + terminal + view split Implements the locked P3 design end-to-end: - subagent lifecycle projection (spawned→started→suspended→completed/failed) + inline Agent / AgentGroup cards; swarm progress card (multi-column) derived from swarmIndex; goal dock strip (expandable) from goal.updated; plan/goal/ swarm activation badges in the composer status line. - terminal as a view (xterm + WS terminal_* frames with since_seq replay) and a tab/view-dimension split (usePaneLayout tree + ViewGroup + SplitLayout, VSCode editor-group style), persisted to localStorage. Adds swarm-groups / subagent-goal / agent-group-turns unit tests and stub-daemon seeds. 98 tests pass; vue-tsc + oxlint clean; production build OK. Accepted by review (see reports/web-p3-acceptance.md); no blocking issues. * docs(reports): P3 landing acceptance review Comprehensive acceptance of the P3 landing ( |
||
|
|
843a731097
|
fix: classify OAuth token refresh errors by cause (#838)
Map OAuth token-fetch failures to distinct public error codes instead of collapsing them all to auth.login_required: - missing/revoked tokens or 401/403 from the refresh endpoint -> auth.login_required - transport failures and 429/5xx after internal retries -> provider.connection_error - anything else is rethrown as-is (surfaces as internal) rather than guessed The refresh helper already retries internally, so the agent loop does not re-retry these. Both the managed provider and the standalone SDK provider share the same mapping. |
||
|
|
8d251f8ab4
|
feat(config): tolerate invalid config.toml sections instead of failing startup (#689)
* feat(config): tolerate invalid config.toml sections instead of failing startup Schema errors now drop only the offending sections (single entries for providers/models) with a warning, so a typo no longer prevents startup or drops the login state. TOML syntax errors still fail fast with the parse location. Mid-run reloads keep the last good config when the file breaks. Warnings surface via the new getConfigDiagnostics API: as a startup notice in the TUI, on stderr in print mode, and in the status bar after /new. Write paths stay strict so a broken file is never silently rewritten, and now fail with a short actionable message instead of raw validation JSON; the /provider TUI flow and the kimi provider CLI report these errors instead of crashing on an unhandled rejection. * fix(config): keep entry-keyed sections when one entry has multiple issues A providers/models entry with several validation issues was deleted by the first issue, and the remaining issues from the same safeParse pass then escalated to deleting the entire section — one badly-typed custom provider could drop every provider, including the managed OAuth login. Issues on entry-keyed sections now only ever target the entry itself; once it is gone, later issues are no-ops. |
||
|
|
54302ad612
|
fix: scope interactive agent requests (#648) | ||
|
|
db82e33a20
|
fix: restore goal resume state from agent records (#552) | ||
|
|
879a7eeb33
|
fix(acp): restore legacy permission compatibility and stabilize ACP (#395)
* feat(acp-adapter): support embedded resource prompts - advertise embeddedContext support in ACP capabilities and docs - convert file:// resource_link blocks into decoded paths with optional line ranges - keep XML wrappers for non-file or unparseable resource_link URIs - update adapter tests for the new resource link behavior * feat(acp-adapter): add ACP built-in slash command routing and UNC path support - add local execution for /compact, /status, /usage, /mcp, /tasks, /help in ACP sessions - surface unknown slash commands as local errors instead of forwarding to model\n- export ACP_BUILTIN_SLASH_COMMANDS from acp-adapter for CLI reuse - fix file:// URI conversion for Windows UNC paths - rebuild agent builtin tools on session tool kaos rebind |
||
|
|
72c4b0adaa
|
feat: agent swarm (#424) | ||
|
|
4d113949c8
|
feat: honor HTTP_PROXY/HTTPS_PROXY/NO_PROXY for all outbound traffic (#487)
* feat: honor HTTP_PROXY/HTTPS_PROXY/NO_PROXY for all outbound traffic Install a global undici dispatcher at CLI startup so every in-process fetch (LLM APIs, MCP HTTP, web tools, telemetry, sign-in, update checks) honors the standard proxy variables, and propagate NODE_USE_ENV_PROXY to spawned stdio MCP child processes. Loopback hosts always bypass the proxy; an invalid proxy URL is reported and ignored rather than aborting startup. * feat: support SOCKS proxies via ALL_PROXY Recognize SOCKS proxies (socks5/socks5h/socks4/socks alias) from ALL_PROXY or a socks-scheme HTTP(S)_PROXY, routing traffic through a custom undici connector backed by the socks client (reusing undici's own TLS handling for https). HTTP(S) proxies keep precedence; NO_PROXY and loopback are honored for the SOCKS path too. Child stdio MCP node processes honor HTTP(S) proxies via NODE_USE_ENV_PROXY; SOCKS applies to the main process only. * fix: address proxy review comments (env masking, child NO_PROXY, nix hash) - Resolve HTTP(S)_PROXY explicitly via the first non-blank casing so a blank lowercase var can no longer mask a populated uppercase one (the dispatcher installed but went direct), and coerce a SOCKS-scheme value sitting in an HTTP(S) var to '' so it is never handed to EnvHttpProxyAgent. - Reconcile a child's NO_PROXY override across both casings using the first non-blank value run through resolveNoProxy, so a per-server config override is not shadowed by the injected lowercase value, keeps the loopback bypass, and passes '*' through verbatim. - Update flake.nix pnpmDeps hash for the added socks/undici dependencies. * fix(proxy): honor http ALL_PROXY, match port-qualified NO_PROXY, note child Node version - Honor an http-scheme ALL_PROXY as the catch-all fallback for both http and https (scheme-specific HTTP(S)_PROXY still wins), so an ALL_PROXY-only setup no longer installs a no-op dispatcher and connects direct. - Make the SOCKS-path NO_PROXY matcher port-aware: a `host:port` entry now matches only that port (with IPv6-safe parsing for `::1` / `[::1]:443`). - Document that child stdio MCP proxying via NODE_USE_ENV_PROXY only applies on Node versions that support it (>= 22.21 / >= 24.5). * fix(proxy): IPv6 + wildcard NO_PROXY and per-server child proxy edges - Strip IPv6 brackets from a SOCKS proxy host (e.g. ALL_PROXY=socks5://[::1]:1080) so the socks client connects to the bare address. - Add the bracketed [::1] to the loopback bypass: undici's EnvHttpProxyAgent only exempts IPv6 loopback when the NO_PROXY entry is bracketed (it mis-parses bare ::1). The SOCKS-path matcher normalizes brackets on both sides. - Match *.domain wildcard (and host:port) NO_PROXY entries in the SOCKS matcher. - Compute the child stdio proxy env from the MERGED env so a proxy declared only in a server's config.env also enables NODE_USE_ENV_PROXY. * fix(proxy): synthesize HTTP(S)_PROXY from ALL_PROXY for child processes proxyEnvForChild now hands spawned stdio MCP children the resolved HTTP_PROXY/HTTPS_PROXY (in both casings), synthesizing them from an http-scheme ALL_PROXY when no scheme-specific variable is set. Node's --use-env-proxy reads HTTP_PROXY/HTTPS_PROXY (not ALL_PROXY), so an ALL_PROXY-only parent now proxies the child consistently with the main process. Shared resolveHttpProxyUrls helper is reused by createProxyDispatcher and proxyEnvForChild. * chore(changeset): tighten proxy changeset wording |
||
|
|
6a4e4c75d4
|
feat(cli): add doctor command for config validation (#431)
* feat(cli): add doctor command for config validation * fix(cli): format doctor validation errors * fix(cli): validate doctor config through SDK RPC * chore(changeset): simplify doctor release note |
||
|
|
7856c03176
|
fix: avoid runtime check rpc (#432) | ||
|
|
be0da5ff39
|
fix: fail early when Git Bash is missing (#430)
* docs: mention Windows Git Bash requirement * docs: add Windows Git Bash changeset * fix: fail early when Git Bash is missing * test: update goal prompt harness mock |
||
|
|
86a42a26a1
|
feat: Add persistent experimental feature toggles and a TUI panel (#420)
* feat: Add persistent experimental feature toggles and a TUI panel * test(agent-core): isolate experimental flag tests * fix(tui): block experiments panel while busy * refactor(experimental): merge feature query APIs |
||
|
|
15d71b5130
|
feat: add reload commands (#383)
* Create CONFIG_RELOAD_RESEARCH.md * feat: add reload commands for session and tui * Delete CONFIG_RELOAD_RESEARCH.md * fix(tui): refresh terminal title on reload --------- Co-authored-by: qer <wbxl2000@outlook.com> |
||
|
|
232ed874d4
|
fix: scope managed OAuth credentials (#399)
* fix: scope managed OAuth credentials * refactor: centralize managed OAuth auth resolution |
||
|
|
3eafa79f39
|
feat(acp): implement ACP server with session lifecycle, tool streaming, and IDE integration (#368)
This commit scaffolds the @moonshot-ai/acp-adapter package and introduces the full ACP (Agent Communication Protocol) server implementation for Kimi Code CLI, including: - Scaffold @moonshot-ai/acp-adapter workspace package with build skeleton - `kimi acp` CLI subcommand and stdout-safe logging - ACP version negotiation and AgentSideConnection wrapper - Auth gate for session creation - Session lifecycle: new, list, load with history replay - Prompt content conversion (text, image, embedded resources, resource links) - Assistant streaming with thinking support and end-turn handling - Tool call streaming (started, delta, progress) with result conversion (text / diff) - Approval handling with diff/text display blocks mapped to ACP options - Kaos read/write interface (AcpKaos) for unsaved buffer access - Session mode (yolo/auto) and model management - Config options builder with thinking toggle - MCP server forwarding from ACP to harness - Agent plan updates and available commands updates - AskUserQuestion bridged to session/request_permission - Plan review options surfaced through requestPermission - Error mapping, ext_method stubs, and graceful shutdown - IDE integration guide (Zed + JetBrains) - End-to-end tests against ACP TS SDK client |
||
|
|
ba7dd736a3
|
feat: add btw side-channel command (#338) | ||
|
|
a6b16ce6b4
|
refactor: split SDK RPC client (#339) | ||
|
|
ac37d74484
|
feat: pursue a goal autonomously (#270) | ||
|
|
191059d400
|
feat: add background ask user questions (#315) | ||
|
|
0d074f1bae
|
feat(agent-core): propagate app version into agent record metadata (#308)
* feat(agent-core): propagate app version into agent record metadata - add appVersion option to AgentOptions, SessionOptions, and KimiCoreOptions - forward appVersion through Agent, Session, and SDKRpcClient - include app_version in agent record metadata events |
||
|
|
a217ff09aa
|
feat: add /undo slash command and keep replay in sync (#277) | ||
|
|
573c56e829
|
refactor: background task manager persistence (#285) | ||
|
|
ab546419c8
|
refactor: move Kimi for Coding provider to SDK (#281) | ||
|
|
ee69d0ac29
|
feat(cron): render scheduled reminders in TUI and expose fired events (#204)
* feat(cron): render scheduled reminders in TUI and expose fired events - add CronMessageComponent for distinct cron transcript entries in TUI - emit cron.fired events from agent-core and expose via node-sdk - report cron fire times with local ISO timestamps including timezone offsets - render cron_job and cron_missed origins during session replay instead of skipping - handle warning events in CLI and session event handler * docs(cron): clarify that users must ask the model to manage cron tasks - cron-create.md: instruct model to proactively tell users how to cancel/modify reminders - cron-list.md: add guideline that users cannot directly manage cron tasks\n- cron-delete.md: emphasize users must ask model to cancel reminders |
||
|
|
bab2da7b1c
|
feat(plugin): install plugins from a GitHub repository URL (#221)
* feat(plugin): install plugins from a GitHub repository URL Allow `/plugins install <github-url>` (and marketplace `source` entries) to take a GitHub repo URL directly. A new `github` source kind joins the existing `local-path` and `zip-url` kinds. Recognized URL forms (parsing in source.ts): - `https://github.com/<o>/<r>` — bare; resolves to latest release tag, falling back to default branch HEAD. - `https://github.com/<o>/<r>/tree/<ref>` — branch / tag / SHA; value passed to codeload in its short form so the backend resolves either. - `https://github.com/<o>/<r>/releases/tag/<tag>` — explicit tag, uses refs/tags/<tag> to avoid same-named-branch ambiguity. - `https://github.com/<o>/<r>/commit/<sha>` — explicit commit SHA. The resolver deliberately avoids `api.github.com`: its 60/hour anonymous quota is shared with every other tool on the egress IP (browser, gh CLI, IDE integrations) and a first-time install failing because some other tool ate the budget is unacceptable UX. Instead we: - GET `github.com/<o>/<r>/releases/latest` with manual redirect and parse the `Location` header (302 → tag URL; 404 → no own release). - Fall back to `codeload.github.com/<o>/<r>/zip/HEAD` for repos with no releases (or for forks that inherit upstream tags but have no own release page, which redirect to bare `/releases`). - Only treat the explicit 404 from `/releases/latest` as "no release" — 5xx, 403, 429, and any other non-2xx status surface a hard error rather than silently installing the default branch, so the user knows when transient GitHub issues changed the install path. UI changes in the TUI: - `/plugins install` now shows a live Braille spinner while resolving and downloading, then flips to a final status that distinguishes Installed (fresh) vs Updated (same repo identity, new version) vs Migrated (source changed, e.g. CDN zip-url → GitHub). - `/plugins list`, the `/plugins` overview, and `/plugins info` show the install provenance inline. `zip-url` installs now display the URL host (e.g. `via code.kimi.com`, `via 127.0.0.1:port`) instead of the opaque `zip-url` literal. GitHub installs show `github <owner>/<repo>@<ref>`. - Three-tier trust badge driven by the marketplace context recorded at install time: `official` (green) for `tier: official`, `curated` (blue) for `tier: curated`, `third-party` (muted) for anything not installed through the marketplace selector. CLI `/plugins install <url>` always records as third-party; the marketplace selector passes the tier through. A re-install replaces the marketplace context: switching to a third-party source clears the badge, which matches the underlying trust change. `installed.json` gains optional `github` and `marketplace` fields (back-compatible). PluginSummary surfaces `source`, `originalSource`, `github`, and `marketplace` so the TUI can label installs without an extra round trip to PluginInfo. The SDK's `session.installPlugin(source)` gains an optional `{ marketplace }` second argument so the marketplace selector can forward `{ id, tier }` through RPC; the CLI install path omits it. Tests: 112 plugin-suite tests (URL parser, resolver, store round-trip, manager integration). The manager integration tests assert codeload URLs shape (short form for `/tree/<ref>`, explicit `refs/tags/` for `/releases/tag/`) and verify marketplace context is persisted across reloads and cleared on a third-party re-install. * chore(changeset): plugin install from GitHub * docs(plugins): document GitHub install URLs and trust badges * fix(plugin): preserve URL-encoded characters in GitHub ref names Git permits ref characters that have special meaning in URLs — most notably `#`, which is a valid tag character (e.g. `release#1`) but the URL fragment delimiter. The resolver decoded the tag from GitHub's `/releases/latest` 302 redirect Location header and then interpolated the raw value into the codeload URL. The literal `#1` became a fragment and the HTTP request reached the server as `…/refs/tags/release` — a wrong or truncated ref, leading to install failure for a release whose URL was otherwise valid. Two symmetric changes: - The codeload URL builder now splits the ref on `/` (so multi-segment refs like `feat/foo` keep their path separators) and percent-encodes each segment. - The GitHub URL parser now percent-decodes each segment from the URL's pathname when extracting `/tree/<ref>`, `/releases/tag/<tag>`, and `/commit/<sha>`. Storage and display see the human-readable Git ref name; the resolver re-encodes on the way out. Malformed `%xx` sequences in user-typed URLs are tolerated: we keep the raw segment so the caller surfaces a normal "ref not found" error downstream instead of crashing during parse. * fix: restrict plugin trust badges * chore: remove fetch when show plugin list --------- Co-authored-by: qer <Anna_Knapprfr@mail.com> |
||
|
|
96bbc471c4
|
feat: add experimental feature-flag system (#205)
Introduce a central, env-driven flag registry in agent-core. Each flag is declared once with an id, full env var name, default, and surface. Within agent-core, flags are consulted through a process-global 'flags' constant that reads live process.env. Resolution precedence: master switch KIMI_CODE_EXPERIMENTAL_FLAG > per-feature KIMI_CODE_EXPERIMENTAL_<NAME> > registry default, with lenient boolean parsing via parseBooleanEnv. FlagId is a literal union derived from the registry for compile-time autocomplete and typo-checking.
SDK boundary: KimiHarness.getExperimentalFlags() returns the resolved values over RPC, and the SDK re-exports only the flag *types* — no runtime value crosses the boundary. The TUI caches that snapshot once at startup and reads it synchronously for command gating.
Gate the plugin system behind the 'plugins' flag, off by default: PluginManager.load() consults flags.enabled('plugins'), so when off no installed plugins are loaded or activated, and the TUI /plugins command is hidden from the palette and resolves as an unknown command.
Tests cover the resolver precedence matrix, registry invariants, the FlagId type guard, the live-env singleton, the plugin-load gate, the getExperimentalFlags RPC, and the TUI command gating.
|
||
|
|
8913440541
|
feat: show warning when resuming across working directories (#118) | ||
|
|
ebf6e8181e
|
feat: add plugin manager and official plugins (#119)
* feat: add plugin manager and official plugins * fix(agent-core): honor plugin capability overrides * fix: restrict plugin zip root detection * Update apps/kimi-code/src/constant/app.ts Co-authored-by: liruifengv <liruifeng1024@gmail.com> Signed-off-by: qer <wbxl2000@outlook.com> --------- Signed-off-by: qer <wbxl2000@outlook.com> Co-authored-by: liruifengv <liruifeng1024@gmail.com> |
||
|
|
028d069b12
|
feat(tui): add /export-md slash command (#113)
* feat(tui): add /export-md slash command Add a new /export-md (alias: /export) command that exports the current session conversation as a human-readable Markdown file. The export includes YAML frontmatter metadata, an overview section, and turn-by-turn dialogue with collapsible thinking blocks and tool call/result details. Also exposes Session.getContext() on the SDK to allow TUI-layer access to the agent's conversation history. * chore: add changeset for /export-md * fix: use static imports instead of dynamic imports in handleExportMdCommand * chore: simplify changeset wording |
||
|
|
d599183c8e
|
feat(export): record install source and shell environment in manifest (#105)
* feat(export): record install source and shell environment in manifest Capture how the CLI was installed (npm-global, native, etc.) and the user's terminal environment (TERM, TERM_PROGRAM, multiplexer, SHELL) so exported session archives carry richer diagnostic context. * chore: add changeset for export manifest enhancements * chore: simplify changeset description |
||
|
|
d95b01342a
|
fix(catalog): preserve reasoning fields in custom model (#70)
* fix(catalog): preserve reasoning fields
* fix(catalog): treat interleaved=true as reasoning_content
models.dev documents `interleaved` as `boolean | { field }`, where the
bare boolean means "general support" without an explicit field name.
The previous branch returned undefined for `true`, leaving openai-compat
gateways that publish `interleaved: true` without a round-tripped
reasoning field. Map `true` to the default `reasoning_content` so those
models still surface and replay thinking content.
* fix(catalog): preserve interleaved field in built-in catalog snapshot
`update-catalog.mjs` drives the bundled catalog that ships with release
builds and is the default source for `/connect`. The allowlist dropped
`interleaved`, so even after the runtime learned to read the field, the
default offline path never sees it — reasoning round-tripping silently
stayed off for openai-compat models in release builds. Keep
`interleaved` so the bundled snapshot carries the same metadata as the
live models.dev catalog.
---------
Co-authored-by: 7Sageer <7sageer@djwcb.cn>
|
||
|
|
cf2227e8a5
|
fix: warn instead of error on newer wire protocol version (#49)
* fix: warn instead of error on newer wire protocol version * fix * fix test |
||
|
|
a200a297ac
|
feat(kimi-code): add /connect command with bundled model catalog (#30)
* feat: add /connect command with models.dev catalog support Add a /connect slash command that configures a provider and model from a models.dev-style catalog. Users no longer need to hand-write model metadata (context window, output limit, capabilities). Architecture (3 layers): - kosong: pure data layer — Catalog schema, inferWireType, catalogModelToCapability - node-sdk: IO + config write — fetchCatalog, applyCatalogProvider, catalogModelToAlias - app: TUI flow — /connect command, provider/model selection, credential input, config persistence UI improvements in this PR: - ChoicePickerComponent: add searchable (fuzzy filter + search bar) - ModelSelectorComponent: add searchable (same) - Extract reusable paging.ts for list pagination Changesets included for kosong, kimi-code-sdk, and kimi-code. * feat: bundle pruned models.dev catalog for offline /connect When the network is unavailable, /connect now falls back to a built-in snapshot of the models.dev catalog. - `scripts/update-catalog.mjs`: fetches models.dev/api.json, strips unnecessary fields, and writes `src/built-in-catalog.ts` with the JSON string as a TS constant. - `loadBuiltInCatalog(text?)` in node-sdk: parses the JSON string safely; returns undefined on any failure. - `handleConnectCommand`: on fetch failure, shows an informative offline message and tries the built-in snapshot. - The snapshot file is a placeholder (`undefined`) in source control; `update-catalog.mjs` populates it before release builds so the actual catalog is inlined into the bundle by rolldown. * refactor(tui): share search and pagination across list pickers ChoicePicker and ModelSelector each carried their own copy of the cursor + fuzzy-search + pagination state machine. Extract it into a reusable SearchableList so both pickers share one implementation; behavior is unchanged. * fix(tui): filter unsupported catalog providers * docs(tui): clarify /connect stale-alias cleanup depends on removeProvider * fix(kimi-code): inject built-in catalog at release time * feat(tui): hint at /login and /connect when /model has no models Replace the bare "No models configured." error with a notice that points users to /login for Kimi and /connect for other providers. * fix(tui): tighten /connect error reporting for edge cases Two silent-failure cases in /connect could leave users without any feedback to act on: - Reject `--url` when its value is missing (e.g. `/connect --url` or `/connect --url=`). Previously the argument parser silently fell back to the default catalog, so a malformed flag still appeared to succeed but with the wrong source. - Show an explicit error when the resolved catalog yields no providers with supported wire types. Previously the picker resolved with no selection and the command returned without any UI feedback. * chore(tui): restore slash invalid intent type * fix(tui): support /logout for /connect-configured providers After /connect writes a non-managed provider (e.g. openai), /logout fell through to "Nothing to logout." because the handler only matched the managed default and isOpenPlatformId branches, leaving users no in-app way to drop the API key and model aliases they just configured. Collapse the OpenPlatform branch into a generic "provider is present in config" check so any non-managed provider in config — OpenPlatform OAuth targets and /connect catalog providers — goes through the same removeProvider path. * fix(tui): reject --url values that are not http(s) URLs `resolveConnectCatalogRequest` previously matched any non-space token after `--url` as the URL, so `/connect --url --refresh` parsed `--refresh` as the value and bypassed the missing-value error path. Bare non-URL tokens (`/connect --url not-a-url`) and non-http(s) schemes were also silently accepted. Constrain the captured value to `https?://...` so flag-like and non-URL tokens fall through to the existing `URL_FLAG_PRESENT_RE` check and surface a clear error. * ci(native): scope built-in catalog generation to signed macOS jobs The catalog-generation step ran whenever `inputs.sign-macos` was true, including Linux and Windows targets that take the local-profile build path and never consume the generated catalog. A transient models.dev outage would therefore fail unrelated artifact builds. Match the condition to the macOS signed release-profile build that actually consumes the bundled catalog. * fix(ci): embed built-in catalog in non-macOS native artifacts The earlier narrowing to `runner.os == 'macOS' && inputs.sign-macos` relied on a misread of build.mjs: its `profile === 'release'` guard only auto-fetches the catalog as a dev fallback. Whether the binary actually embeds the catalog is decided by tsdown's define at bundle time, which reads KIMI_CODE_BUILT_IN_CATALOG_FILE regardless of profile. Linux and Windows release artifacts therefore lost their bundled catalog and silently regressed offline /connect on those targets. Restore generation for all OS jobs when sign-macos is true. * chore(tui): mention /connect in welcome panel hints Align the welcome panel with the /model picker so the empty-state copy points users to both /login and /connect. |