* fix(kimi-code): persist picked thinking effort up to the model's default effort
The persistence gate kept the model's top declared effort session-only
unconditionally, so users whose delivered default_effort is the top tier
(e.g. max) could never save an explicit pick of it. Compare the pick
against the model's default_effort instead, using support_efforts as the
strength ordering: picks above the default stay session-only, picks at
or below it persist. Models without a declared default keep the
historical top-tier rule. The same change lands in the VS Code
extension's mirrored logic.
* docs(kimi-code): document the effective-default ceiling for effort persistence
Clarify in both apps' comments, the changeset, and the config docs that
the persistence ceiling is the model's effective default effort, whether
declared via the catalog / overrides or synthesized by the protocol
profile inference (Claude models resolve to high, so an xhigh pick is
session-only there). Pin the inference path with tests in both apps.
* fix(vscode): resolve the save-config model with its provider type
Mirror the TUI's effectiveModelForHost: without the provider type the
Anthropic fallback profile (e.g. claude-latest) never matches, so the
inferred default effort that gates persistence was missed and an
above-default pick could persist where the TUI keeps it session-only.
* Delete .changeset/persist-effort-up-to-model-default.md
Signed-off-by: 7Sageer <sag77r@hotmail.com>
* fix(vscode): seed the persisted effort with the effective-default ceiling
* fix(vscode): project webview models with the provider type
* fix(kimi-code): apply a session-only effort pick to the runtime in the /provider flow
* fix(vscode): update the persisted-effort seed on model-switch saves
* docs(kimi-code): drop the default_effort persistence-ceiling note
---------
Signed-off-by: 7Sageer <sag77r@hotmail.com>
* feat(kimi-code): add China/International region selection for OAuth login
- Add region profiles (cn/overseas) and resolver in @moonshot-ai/kimi-code-oauth:
env override → persisted login host → install-channel marker → default cn
- /login now offers Kimi Code (China) / Kimi Code (International); the CLI
login entries (kimi login, kimi acp --login) accept --region cn|overseas
- Update/plugin/site/telemetry endpoints derive from the selected region;
plugin trust list covers both .com and .ai hosts
- kap-server: POST /oauth/login accepts an optional region; new GET /oauth/region
* fix(oauth): keep an explicit default-slot login ahead of the install marker
A China login persists no oauthHost (the default credential slot carries
no host trace), so after switching back from International the resolver
fell through to a stale overseas install marker. Treat a persisted
default-slot oauth ref (key === oauth/kimi-code) as an explicit-cn signal
that outranks the marker; getRegion() on the v2 side mirrors it.
* fix(agent-core-v2): thread the default-slot key through capability region resolution
Capability installs resolved the region from the persisted oauthHost only,
so an explicit China login (which persists no host) lost to a stale
overseas install marker. Pass the oauth ref key through as well, matching
getRegion(). Also move the region contract notes into the auth.ts file
header per the package comment convention.
* fix(agent-core-v2): honor the region-marker opt-out for the telemetry endpoint
Hosts that set KIMI_CODE_REGION_MARKER=off (the desktop embedded server)
skip the install marker in getRegion(), but the default telemetry endpoint
still consulted it, so a stale overseas marker could split the reported
region from the telemetry destination.
* feat(cli): show region site domains in login platform selector
* chore: reword oauth login changesets
* fix: honor the region marker opt-out in the CLI and capability resolvers
* refactor: rename login region values to mainland-cn and global
* fix: keep the --region help text in English
* fix: simplify the --region help text to site domains
* feat: drop the suggested login platform order
* feat: split a browser-safe region profile table out of the region resolver
* Revert "feat: split a browser-safe region profile table out of the region resolver"
This reverts commit a037b1143e.
* fix: read the install marker from the bootstrapped home directory
* fix: resolve the server plugin marketplace from the active login region
* feat: expose the login region option through the klient auth facade
* fix: drop a comment from the v2 auth region test
* fix: keep scoped base-only logins on their environment for a bare login
* fix: invalidate the region cache on the provider-manager logout path
* fix: route client-config fetches through the active region profile
* fix: resolve the telemetry endpoint per flush so a login region switch applies in-process
* test: expect the telemetry endpoint resolver in the CLI init assertions
* fix: resolve the default telemetry endpoint from the bootstrapped home
* chore: reword the oauth login changeset around the two login methods
* chore: trim the oauth login changeset to the headline
* feat: let hosts override the region marker env through the server bootstrap env bag
* fix(vscode): multi-select question jumps to next after only one answer selected
* chore: add changeset
---------
Co-authored-by: gaoyuan <gaoyuan@moonshot.ai>
* feat(agent-core): unify the v1 MCP management plane
- McpServerRegistry: one config view over global (layered mcp.json),
plugin (manifests, read-only, final effective config), and caller
(SDK-injected) servers; name collisions keep both entries.
- Write plane: add/update/removeGlobalMcpServer mutate the user-level
file and push into live sessions; getGlobalMcpServer returns the
effective config; mutations of read-only entries are rejected.
- testGlobalMcpServer accepts an inline config; addSessionMcpServer
connects a server in one live session with an optional persist flag;
reconnect accepts a replacement config and re-resolves via the registry.
- One process-wide McpOAuthService shared with every session: obtained_at
stamps, offline token state, single-flight and proactive refresh, and
credential events. Sessions self-subscribe in the constructor, so even
initializing sessions see every event; token writes serialize through
the process-local OAuthTokenTransaction per credential identity.
- inspectAppMcpServers + locator-addressed begin/complete/cancel/reset
cover plugin servers; inspection output redacts env/headers to sorted
key lists; locator OAuth ops reject ambiguous shared runtime names.
- The legacy auth-status surface reads the registry (offline by default,
verify=true probes) and never mutates credentials.
- VS Code panel receives source/origin/mutable and hides mutating
actions on read-only entries.
- v2 client facade in node-sdk mirrors the surface over agent-core-v2
(plugin inventory stays v1-only for now).
* fix(agent-core): close the v1 MCP live-session reconciliation gaps
Recompute each live session's MCP target from the registry's runtime
resolution (enabled plugin > project layer > user file; caller injection
shadows everything) behind every config mutation, instead of per-path
patching: shadowed file layers recover when a plugin winner is disabled or
removed, removing a user-level entry resurrects its project-layer shadow,
disabled plugin descriptors no longer block removals, persisted session
adds validate against the session's project layer and broadcast to other
live sessions, and per-session sync failures are logged with context.
Session status entries and read-only management entries now report
redacted config views (envKeys/headerKeys instead of literal env/headers
values); core-internal reconciliation compares full configs via the
connection manager's raw-entry accessor.
OAuth: interactive flows are serialized per credential (concurrent
begins join the in-flight flow instead of clobbering its PKCE/state), a
malformed credential meta sidecar no longer aborts core start, grants
inside the refresh-ahead window refresh immediately while far-future
grants re-arm through a max-length timer, and the service shuts its
timers and flows down with KimiCore/SDKRpcClient close.
* fix(agent-core): route the proactive MCP OAuth refresh through the token transaction
refreshNow ran its /token request with the SDK default fetch, outside the
credential-serializing OAuthTokenTransaction that every other token write
uses; a slower response carrying an older rotating refresh token could
overwrite a newer grant written by a concurrent transport-side refresh.
* fix(agent-core): keep disabled MCP servers out of auth-state classification
The unified mcpServerAuthState dropped the previous enabled short-circuit,
so a disabled oauth-flagged server reported oauth-required — or was even
probed over the network — instead of not-applicable.
* fix(kimi-code-sdk): short-circuit disabled MCP servers in the v2 auth-status classifier
The v2 parity copy of v1's mcpServerAuthState missed the same enabled
guard v1 just regained; a disabled oauth-flagged entry would report
oauth-required (or be probed). The parity suite now pins the disabled
case on both engines.
* fix(kimi-code): refresh the VS Code MCP list with the workspace cwd after mutations
The add/update/remove RPCs return a cwd-less management list, so the
webview broadcast dropped project-layer entries until the next full load;
re-list with the workspace cwd after every mutation instead.
* fix(agent-core): keep SDK token saves matched to the OAuth token transaction
saveTokens stamped obtained_at onto a fresh object before calling
tokenTransaction.save, so it never matched the exact payload the
transaction recorded for a grant fetch; the consume path was dead and
every save re-wrote. Between the fetch and the SDK callback an intervening
clear could then be overwritten — the resurrected grant came back after a
reset. The write callback stamps the durable record instead.
* fix(agent-core): reject ambiguous legacy name-based MCP auth lookups
The legacy begin/reset auth RPCs took the registry's first name match,
silently starting OAuth for one entry of a runtime-name collision while
the locator path refused the same ambiguity; align them on the shared
uniqueness rule and point callers at the locator-addressed variants.
* fix(agent-core): propagate registry errors during live-session MCP sync
resolveMcpRuntimeTarget collapsed every registry failure into "no target":
a project config file that turned malformed mid-session made sync treat a
still-configured server as gone (tearing down the live connection) and
made config-aware reconnects report "no longer configured" instead of the
actionable config error. Absence still resolves to undefined; malformed
config now propagates — per-session sync logs and keeps the entry, and
reconnect surfaces config.invalid.
* fix(agent-core): close the remaining registry-error and ambiguity gaps
The management guard lookup mapped every registry failure to "absent",
so a malformed project config let a persisted session add write a
user-level entry over an unknown state; only not-found is a miss now. And
the name-only connection test now shares the auth paths' uniqueness rule
instead of probing the first match of a runtime-name collision.
* fix(agent-core): probe the enabled MCP entry under a disabled-name collision
The name-only connection test counted enabled matches for its ambiguity
guard but still probed the first registry match, and the file layers list
before plugins. With a disabled file entry shadowing an enabled plugin of
the same runtime name, Test probed the disabled entry instead of the one a
live session would run. Select the sole enabled match, falling back to the
first entry only when every match is disabled so it reports as disabled.
* fix(agent-core): let session-local MCP adds shadow plugin entries
Caller injection shadows every registry source at session start, plugins
included, and reconciliation leaves caller entries untouched; the live
non-persist add path rejected plugin-owned names anyway, so SDK clients
could not apply the same per-session override without a restart. Gate the
plugin-source rejection on persist: session-local adds connect as caller,
while persisted adds stay rejected as user-level writes behind a read-only
owner.
* fix(agent-core): normalize session MCP names before connecting
The persisted store trims server names, but addSessionMcpServer used the
raw name for the live connect and cross-session reconciliation: a padded
name persisted under the trimmed key while the requesting session ran and
reconciled the raw one, and a blank name connected with no identity at
all. Normalize once up front (rejecting blank) so the store write, the
session entry, and reconciliation agree on the same server.
* fix(agent-core,node-sdk): close the collision-selection and probe-freshness gaps
The legacy name-only auth resolver started from the first registry match,
so a disabled file-layer shadow plus an enabled plugin of the same runtime
name was misread as an ambiguity conflict; select the sole enabled match
before judging ambiguity, exactly like the test probe path. On the v2
client, addSessionMcpServer connected the raw name while the store wrote
the trimmed key — normalize once for both, and route the verify-triggered
auth probes through the per-call OAuth service instead of the cached one
whose providers snapshot tokens at construction, so a grant saved after
the first probe is honored.
* fix(agent-core): normalize global MCP mutation names and guard disabled reconnect swaps
The global add/update/remove mutations guarded and reconciled with the raw
server name while the store persisted the trimmed key, so a padded name
left live sessions unreconciled and could slip past the plugin read-only
guard; normalize once before lookup, persistence, and reconciliation. And
a config-carrying reconnect assigned the replacement before the disabled
check fired, leaving a connected entry that reported the disabled config;
reject disabled replacements before mutating, keeping the same error.
* fix(agent-core): skip proactive refresh while an interactive flow owns the credential
refreshNow reset the shared provider's flow state before and after the
token request; when a proactive timer (or a manual refresh) fired while
beginAuthorization was waiting on the browser callback for the same store
key, that wiped the redirect URL, PKCE verifier, and state the in-flight
flow needed — complete() then failed the exchange even though the user
authorized. Refresh now skips when an interactive flow is active for the
credential: the flow delivers fresh tokens on completion, and the 401
transport path is the backstop if it fails.
* fix(agent-core): allow global MCP adds over disabled plugin descriptors
A disabled plugin entry is absent from the runtime target, but the
read-only guard still treated it as the owner, so a user-level fallback
could only exist if it predated the plugin disable. Relax the shared
guard: disabled plugin descriptors never block mutations (disabled
project entries still shadow the user file and keep their rejection).
* fix(node-sdk): close the v2 session-MCP parity gaps
A v2 reconnect with an explicit enabled:false replacement config used
connect()'s upsert semantics — closing the live client and reporting
success where v1's manager reconnect rejects before applying anything;
reject disabled replacements up front with the same error. And a persisted
v2 session add never consulted the workspace config, so a same-named
project-layer entry was silently shadowed: the user-level write never
takes effect while the direct workspace-manager upsert displaces the
project config for every live session. Resolve the workspace layers and
reject like v1's read-only rule.
* fix(agent-core): keep __proto__-named MCP servers through config parsing
A z.record() parse rebuilds its output via property assignment, so a
server literally named __proto__ hit the prototype setter and vanished
before validation; the layer merge then repeated the same trap with plain
object accumulators. Parse the server map entry-by-entry over the JSON own
keys and accumulate into null-prototype maps, so session startup and the
unified registry keep the declared server and its origin.
* fix(node-sdk): begin v2 MCP auth against a fresh OAuth service
The v2 begin path ran through the cached globalMcpOAuth, whose providers
snapshot tokens at construction: a grant another process saved (or reset)
after that cache materialized was invisible, so begin could open a browser
flow over a valid grant, or report already-authorized off a removed one.
Build the service per call — the read path and the verify probes already
do — and route the status list through the same helper. The test fixture
grows a real token endpoint honoring one rotating refresh token; the
regression fails against the cached-service implementation on v2.
* fix(agent-core): broadcast SDK-driven MCP token invalidations to live sessions
* test(agent-core-v2): give the no-op reconnect test runtime plumbing
The branch added the case against a bare McpConnectionManager, but #2961
made stdio connects resolve the runtime through runtimeResolver, matching
every other case in the file.
Chat components subscribed to the entire chat store, so every
streaming delta re-rendered every assistant message. Subscribe to
narrow store slices and memoize ChatMessage so settled messages no
longer re-render on each delta. Cap getImageDataUri at 10MB, matching
the media picker, so oversized local images are not inlined into the
webview DOM.
* fix(vscode): stop mid-turn core errors from corrupting the active turn
* fix(vscode): reject prompts during exclusive operations with a terminal error
* fix(vscode): count configured provider credentials as signed in and make the gear sign-in actually log in
* fix(vscode): keep the gear auth action scoped to the Kimi account session
* feat(vscode): migrate extension to Node SDK
* fix(vscode): address CI failures
* fix(vis): handle token count records
* fix(vscode): keep chat toolbar and header readable at narrow widths
* fix(vscode): map yolo to core yolo permission and honor the global yolo setting
* docs(vscode): record Node SDK migration design
* docs(vscode): split breaking changes out of the 0.6.0 changelog
* fix(vscode): keep a resumed session's thinking effort instead of reapplying the default
* fix(vscode): announce session status when a view attaches so the display matches it
* fix(vscode): align webview thinking effort handling with the TUI