Skip to content

fix(agent-core-v2): keep running sessions' models alive across concurrent provider refreshes - #3512

Open
sailist wants to merge 1 commit into
MoonshotAI:mainfrom
sailist:bug-145-09-03-provider-refresh-model-loss
Open

fix(agent-core-v2): keep running sessions' models alive across concurrent provider refreshes#3512
sailist wants to merge 1 commit into
MoonshotAI:mainfrom
sailist:bug-145-09-03-provider-refresh-model-loss

Conversation

@sailist

@sailist sailist commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — reported directly: when multiple Kimi Code processes start at the same time, each refreshes provider model lists on startup, and a refresh in one process can make a model in use by another process fail with Model "<provider>/<model>" is not configured in config.toml.

Problem

Every process refreshes provider model lists against the shared config.toml (startup refresh, interval refresh, manual refresh). The refresh writes were whole-section replacements of [models] / [providers] computed from a snapshot taken before the network fetch:

  • Any model written by another process (or by the user) between the snapshot and the write was silently reverted.
  • When an upstream catalog (e.g. rotating free-model registries) dropped a model, the refresh deleted its alias from the shared config even if another process had a running session on it.

Because every process watches config.toml live, the deletion propagated immediately: the running session's next request re-resolved the model against the updated config and failed with Model "..." is not configured in config.toml., killing the session mid-turn.

What changed

  • Refresh writes are now scoped to the refreshed providers: the refresh sends only the refreshed providers' entries and their owned model aliases instead of the whole [models] / [providers] tables, and the write rebases onto the latest on-disk config, so concurrent writes from other processes survive.
  • Provider removal during refresh is folded into the same single atomic config write as the refreshed entries, preserving the "no halfway-removed catalog" invariant.
  • The model catalog keeps serving a cached model whose config entry was deleted, so running sessions in the same process keep working when a refresh removes their model; if the model is truly retired upstream, requests now fail with the real upstream error instead of a misleading config error. New sessions resolving a deleted model still get the "not configured" error as before.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 68159b7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@68159b7
npx https://pkg.pr.new/@moonshot-ai/kimi-code@68159b7

commit: 68159b7

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2985f9bb77

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +479 to +480
providers: pickDefined(next.providers, [KIMI_CODE_PROVIDER_NAME]),
models: pickDefined(next.models, refreshedAliasKeys),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve full sections for atomic TUI refreshes

When a refresh runs through the v2 TUI harness, apps/kimi-code/src/tui/controllers/auth-flow.ts passes this patch to replaceConfigSections, which replaces each supplied top-level section rather than merging its entries. Because these lines now send only the refreshed provider and aliases, the first changed provider replaces [providers] and [models] with those sparse records, deleting every unrelated provider and model alias from the user's config. The atomic host must rebase sparse entries onto the latest complete sections, or this caller must continue receiving complete records.

Useful? React with 👍 / 👎.

Comment on lines +99 to +100
for (const id of this.cache.keys()) {
if (this.models.get(id) !== undefined) this.cache.delete(id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope retained catalog entries to active sessions

IModelCatalog is registered at app scope, so retaining every deleted cached alias is not limited to the running session that needs it. Once any session has resolved an alias, deleting that alias from config leaves this cache entry available indefinitely; a later session in the same daemon can explicitly bind the deleted alias and reuse its stale provider endpoint and authentication material instead of receiving MODEL_NOT_FOUND. Retention needs to be tied to active session usage rather than all previously cached entries.

Useful? React with 👍 / 👎.

@sailist
sailist force-pushed the bug-145-09-03-provider-refresh-model-loss branch from 2985f9b to 68159b7 Compare September 3, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant