mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-23 23:56:41 +00:00
1149 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b6144f94ea
|
ci: release packages (#2846)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
314b39489e
|
refactor(agent-core-v2): extract swarm into a scope-organized feature (#2874)
* refactor(agent-core-v2): extract swarm into a scope-organized feature
- move src/agent/swarm, src/session/swarm, and src/agent/tools/agent-swarm
into src/features/swarm/{agent,session,tools/agent-swarm}; swarmOps.ts
stays a static import=register wire channel at the feature root
- add SwarmFeature carrying the three runtime registrations
(IAgentSwarmService, ISessionSwarmService, IAgentSwarmTool) with
ScopeActivation.OnScopeCreated preserved
- switch src/index.ts to precise leaf exports and update import sites,
including the kap-server and kimi-inspect deep-path imports
- move tests to test/features/swarm and re-assert service overrides in
the test harness so stubs keep winning over feature contributions
* fix(agent-core-v2): keep feature-contributed tools in Agent tool descriptions
SubagentTool.knownToolReferences() now reads the full AgentToolContribution
collection (static registrations and feature contributions alike) instead
of the static contribution table. A caller profile that does not activate
a feature-contributed tool (e.g. AgentSwarm) no longer drops it from the
per-profile tool listings the description advertises for spawned profiles
when a workspace/session restriction forces explicit enumeration.
Add a regression test with a caller profile lacking AgentSwarm under a
global tool restriction.
* refactor(kap-server): lift session profile updates to the route edge
- add sessionProfile.ts/sessionAgentConfig.ts route helpers that resume
the session and dispatch title/metadata and the agent_config patch to
the native v2 services directly
- drop updateProfile from ISessionLegacyService, leaving only the
status rollup and the goal read in the legacy adapter
- wire shape and client-visible behavior unchanged
|
||
|
|
6e31722df1
|
chore: drop deprecations for unreleased [subagent] pool keys (#2877)
The [subagent] default_model / models deprecations added in #2700 guard a migration path that has no users: the pool keys only existed in #2700's own intermediate commits and never shipped in any release, so no config written against a released version can contain them. Remove the two deprecation entries (the mechanism stays — the released loop_control renames still use it), the migration notes in the en/zh config docs, the agent-core-dev skill note, and the obsolete test; regenerate the config manifest. No changeset: #2700 is still unreleased, so no published version ever emitted these warnings — the removal is invisible to users. |
||
|
|
c9bfe8b2c8
|
feat: replace the secondary-model experiment with a declarative subagent model pool (#2700)
* feat: replace secondary-model experiment with [subagent.models] pool
Add a declarative subagent model pool to agent-core-v2: [subagent.models]
maps [models] entry ids to selection hints rendered in the Agent/AgentSwarm
tool descriptions, and [subagent].default_model picks the spawn model when
the caller passes none. The tools' model parameter becomes a free-form
alias string (stripped when no pool is configured), description rendering
is caller-aware (primary (alias) [main model]), and a session-start
validation service fails fast with CONFIG_INVALID on a missing/invalid
default_model or an unresolvable pool alias.
Remove the secondary-model experiment from the v2 engine, node-sdk,
kap-server, and the TUI (the /secondary_model command), and drop the
agent-profile modelPreference / model_preference frontmatter field on v2.
The legacy v1 engine keeps the experiment unchanged; v2 ignores leftover
[secondary_model] config silently.
* fix(agent-core-v2): harden subagent model-pool validation and error/picker mapping
Deep-review follow-ups to the [subagent.models] pool:
- validate the pool before session materialization (after config.ready)
and before the fork file copy, so a broken pool no longer leaves
orphaned session dirs or leaked MCP overlay connections; the
Session-scope validation service stays as a backstop
- reject the reserved "primary" pool alias at startup, and again
defensively in resolveSubagentBinding so a pool broken by a runtime
config edit fails loudly at spawn instead of binding the wrong model
- keep the [default] marker when the caller's own model is the pool
default (primary (alias) [main model] [default])
- recompile the cached tool-args validator when a tool advertises a new
schema object (mid-session pool edits no longer hit a stale validator)
- map config.invalid to VALIDATION_FAILED in kap-server's session routes,
the debug transport mapper, and the catch-all error handler
- hide the v1-synthesized __secondary__ entry from the /model and
/provider pickers again
- fold per-export doc blocks into file headers per package comment
conventions; add pre-flight/reserved-key/validator/mapping tests and
document that create/resume/fork all fail on a broken pool
* feat: re-add /secondary_model and accept a lone subagent default_model
- v2 engine: a pool-less [subagent] default_model forms an implicit
single-entry pool — validated at session create/resume/fork like an
explicit pool, and advertised through the Agent/AgentSwarm model
parameter.
- Tool descriptions: the caller's own alias is a normal pool entry
marked [main model]; the primary line stays distinct because only it
inherits the caller's thinking level.
- TUI: /secondary_model returns, persisting [subagent] default_model
(merging into an existing pool with an empty description); the picker
hides the no-op Thinking footer and rejects the reserved primary
alias.
- kap-server: /api/v1/config accepts and echoes subagent; the
snake-to-camel patch conversion preserves user-defined map keys under
providers/models/experimental/raw without leaking preserve mode into
a colliding alias's own fields.
- v1 config schema learns subagent.defaultModel/models so the shared
config.toml round-trips; the v1 engine still ignores them at runtime.
- Docs (en/zh) and changesets updated.
* docs: use public model identifiers in the subagent model pool examples
* refactor: rename /secondary_model to /secondary-model
* test: cover the /secondary-model command name resolution
* Revert "test: cover the /secondary-model command name resolution"
This reverts commit
|
||
|
|
504e6292ed
|
feat(mcp): inspect effective authorization state in v1 (#2856)
* feat(mcp): inspect effective authorization state * test(agent-core-v2): register MCP auth coordinator fixture * fix(mcp): validate runtime names against full catalog * fix(mcp): reconnect after pending auth updates * docs(mcp): describe auth coordinator collaborator * fix(mcp): ignore disabled runtime name collisions * fix(mcp): serialize OAuth token refresh * test(mcp): await OAuth credential writes * fix(mcp): queue trailing credential reconnect * fix(oauth): preserve access-only refresh winners * fix(mcp): preserve legacy offline auth state * fix(mcp): redact inspection credentials * refactor(mcp): keep app inspection on v1 * fix(mcp): guard legacy auth status mutations * fix(mcp): avoid deterministic legacy auth probes * fix(mcp): cover initialization credential updates --------- Co-authored-by: 刘仲诺 <liuzhongnuo@dev.msh.team> |
||
|
|
23e68eee8b
|
refactor(agent-core-v2): remove the agent RPC aggregation layer (#2871)
* refactor(agent-core-v2): remove the agent RPC aggregation layer
- delete src/agent/rpc/ (AgentRPCService, IAgentRPCService, core-api,
prompt-metadata, types) and sink each method's orchestration into its
owning domain service
- prompt: new submit/submitSteer composing disabledTools gating,
MAIN-only session metadata, and engine-side {turn_id} settlement
- skill: activate now returns PromptLaunchResult and writes session
metadata internally (MAIN-only, unified across prompt/steer/skill/
pluginCommand); node-sdk and kap-server drop their edge-side writes
- pluginCommand: new agent-scope domain owning command activation and
the plugin_command.activated domain event
- permissionMode/loop/fullCompaction: new setModeAndBroadcast /
cancelFromUser / cancel; setMode and loop.cancel stay pure for
internal callers
- klient: agentRpcContract split into per-domain contracts; facade
re-routes to domain channels with its public API unchanged
- node-sdk, kap-server, kimi-inspect and the v2 test harness now call
domain services directly; ctx.rpc keeps its name as a composed
adapter
- externally visible: the agentRPCService debug channel is gone and
session metadata writes are now MAIN-agent-only (see changeset)
* refactor(agent-core-v2): move disabledTools gating out of the prompt domain
Prompt should not own session tool policy: submit no longer accepts or
applies disabledTools. The klient facade keeps its prompt({ disabledTools })
API and composes it edge-side — applying agentToolPolicyService
setSessionDisabledTools before calling agentPromptService.submit, the same
way kap-server's prompt route already does. Over klient, a profile-less
engine now surfaces the raw profile error instead of request.invalid.
Also restores the RPC-removal changeset, which did not make it into the
previous commit.
* chore(agent-core-v2): drop the RPC-removal changeset
* refactor(klient): drop disabledTools from the prompt entry entirely
The prompt path no longer carries session tool gating on any surface:
the klient facade prompt() loses the disabledTools field and calls
agentPromptService.submit directly, and the node-sdk
SessionPromptRpcInput stops accepting or forwarding it (v1 always
ignored the field). Session tool gating remains available through
IAgentToolPolicyService.setSessionDisabledTools, composed at the edge
the way kap-server's prompt route does; the klient toolPolicy contract
added for facade-side composition is removed as unused.
|
||
|
|
719da94648
|
chore: rebuild web dist against kimi-code 0.35.0 (#2853)
Some checks are pending
CI / lint (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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 / Native release artifact (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
code-app: c5440b863d02f99457f48520c16c609eae73f12b |
||
|
|
fe3cdae5f8
|
fix(agent-core-v2): drop interrupted thinking-only assistant messages at step settle (#2819)
* fix(agent-core-v2): drop interrupted thinking-only assistant messages at settle A turn interrupted while the model is still streaming thinking leaves the open assistant holding only an unsigned thinking fragment. The fold used to seal it into history because a non-empty thinking block is not vacuous; on OpenAI-compatible providers the serialized message then carries neither content nor tool_calls, and strict gateways reject every later request with a 400 (#1404). Treat unsigned-thinking-only content as unsendable at settle so the fold drops the message instead — replaying the records of an already bricked session repairs it. * fix(agent-core-v2): preserve reasoning-only assistant history --------- Signed-off-by: 7Sageer <sag77r@hotmail.com> |
||
|
|
30f56a2d2d
|
fix(agent-core-v2): disable SDK-internal retries that blocked cancellation (#2855)
* fix(agent-core-v2): disable SDK-internal retries that blocked cancellation
The OpenAI and Anthropic SDK clients default to maxRetries=2 with a
backoff sleep that never observes the request AbortSignal, so Ctrl+C
during a 429/5xx/connection-error retry only took effect after the
sleep elapsed, and the hidden attempts were invisible to the engine
(no turn.step.retrying) while double-counting its retry budget.
Build those clients with maxRetries: 0 so retryable failures surface
to the engine's step-retry layer immediately (observable countdown,
abortable sleep, single retry budget). The Google GenAI main request
path only retries when httpOptions.retryOptions is explicitly set, so
there is nothing to disable; instead its error converter now recovers
the server-directed delay from the wire body's google.rpc.RetryInfo
detail, since the SDK's ApiError drops the Retry-After header.
* chore: simplify the retry-cancellation changeset entry
* fix(agent-core-v2): recover GenAI retry delay from prefixed mid-stream error chunks
Mid-stream error chunks throw ApiError with the message wrapped as
"got status: <STATUS>. {json}", so a strict JSON.parse of the whole
message missed the google.rpc.RetryInfo detail. Locate the JSON object
start before parsing; the non-stream path (pure JSON body) is
unaffected.
|
||
|
|
ec84a6f9a3
|
feat(kimi-code): re-baseline pi-tui on upstream v0.84.1 and add fullscreen tui_mode (#2830)
* feat(kimi-code): re-baseline pi-tui on upstream v0.84.1 and add fullscreen tui_mode Re-baseline the vendored pi-tui fork on upstream @earendil-works/pi-tui v0.84.1, keeping all local patches: narrow-terminal hardening, processed-line render caching (re-implemented into TuiMainScreen), editor history hooks, the paste-burst fallback, and multi-root @ completion. Upstream highlights absorbed: the renderer splits into TuiMainScreen and TuiAltScreen behind a TUI interface, the Markdown component gains opt-out LaTeX rendering (disabled on the kimi-code side), paste-registry repair on delete/undo, Windows input-latency and Shift+Enter fixes, and Kitty image layout fixes. Editor.setText gains a preservePasteRegistry option so paste-marker expansion survives wholesale text replacement. New tui_mode = "fullscreen" preference mounts TuiAltScreen: the transcript lives in a primary ScrollView with follow-end, the chrome docks at the bottom, mouse selection and scrollbar come from the renderer, and full-screen viewers (tasks browser, output viewer, approval preview) swap the layout root via screen-takeover. Viewport navigation keys fall through to the focused component when the primary scroll view cannot scroll. * feat(pi-tui): merge upstream main through 40a3d85 (post-0.84.1) Bring in upstream's merged-but-unreleased changes on top of the v0.84.1 re-baseline: - Fullscreen transcript search (ctrl+shift+f, next/previous navigation) - Alternate-screen render-churn reduction (9-18x less per-frame allocation by painting full-width rows as direct line references) - Unbound single-line scroll actions (tui.altScreen.lineUp/lineDown), wired into the fork's canScroll gating like the other viewport keys - SSH-aware escape-timeout default and PI_TUI_ESC_TIMEOUT override - Search snapping and SGR-mouse fragmentation fixes; LaTeX newline argument fix Conflicts resolved by union: upstream's search/line scroll bindings stay ungated, fork's primaryScrollable guard applies to all scroll actions. * fix(kimi-code): keep fullscreen dock from crushing the editor box The fullscreen layout gave the transcript ScrollView its intrinsic content height as basis and let the dock participate in shrink distribution with no minSize. Once the transcript exceeded the screen, the VStack shrink pass crushed the dock to a couple of rows, and the editor (3 rows: top border / input / bottom border) lost its bottom border row to clipping. Adopt pi's sizing contract: the ScrollView starts from basis 0 and grows, the dock keeps its intrinsic height, the editor never shrinks below 3 rows, and the footer below 1. Adds a VirtualTerminal-level regression test that replays a full streaming cycle in fullscreen. * docs(kimi-code): document the tui_mode preference in tui.toml * fix(pi-tui): let terminal focus reports fan out in fullscreen TuiAltScreen's viewport input listener consumed FOCUS_IN/FOCUS_OUT reports. Since the renderer installs that listener at construction — before any app-level listeners — terminal focus tracking and clipboard-image hints never saw focus transitions in fullscreen mode (notification_condition = "unfocused" went blind, refocus clipboard hints stopped). Keep the selection cleanup but stop consuming, matching the main-screen fan-out. Addresses Codex review on PR #2830. * fix(kimi-code): wire openUrl and right-click paste in fullscreen Mouse capture in the alternate screen intercepts the terminal's native link activation, leaving OSC 8 hyperlinks (like the footer's PR link) unclickable in fullscreen. Route renderer link clicks to the app's openUrl, and on Windows feed right-clicks to the focused component as a bracketed paste read from the clipboard. * feat(kimi-code): fullscreen prompt navigation, exit replay, progress resync - Mark user/assistant transcript messages with OSC 133 zones (start / end / final) so the fullscreen renderer's Ctrl-Shift-Up/Down prompt jumps work; GutterContainer keeps the markers at byte 0 when prefixing its gutter, and message render caches store already-marked lines. - On exit from fullscreen, preserve the frame and replay the transcript through a fresh main-screen renderer so native scrollback gets the regular inline layout (pi's "transcript" exit form). - Re-sync the OSC 9;4 progress indicator after a stop/start cycle: terminal.stop() clears it, and the cached progressActive flag used to suppress the re-send when returning from the external editor mid-turn. * feat(kimi-code): enable Markdown LaTeX rendering with a render_latex opt-out Align with the upstream pi-tui default: LaTeX math in Markdown messages renders as Unicode text. The explicit renderLatex:false we set during the re-baseline becomes a shared Markdown options helper fed by a new tui.toml preference (render_latex, default true), wired at startup and refreshed on /reload. * refactor(kimi-code): gate fullscreen behind KIMI_CODE_TUI_FULL_SCREEN Drop the public tui_mode preference from tui.toml before release; the fullscreen UI is experimental, so enable it with the KIMI_CODE_TUI_FULL_SCREEN=1 env var instead. Docs move from the config-file reference to the env-vars page. * chore(changesets): clarify fullscreen mode and LaTeX formula entries * chore(changesets): trim fullscreen mode entry * chore(changesets): trim LaTeX formula entry * chore(changesets): drop redundant kimi-code entries * test(kimi-code): add stepRetry to fullscreen layout fixture after main merge * fix(kimi-code): apply render_latex before theme-driven Markdown rebuilds Codex review on PR #2830: applyReloadedTuiConfig set the shared LaTeX toggle after applyTheme(), but theme application invalidates transcript components and their rebuilt Markdown children copy the options at construction — so a /reload that only flipped render_latex kept the old value until some later invalidation. Move the setter before applyTheme and pin the ordering with a test. * fix(kimi-code): carry renderLatex through TUI config saves Codex review on PR #2830: currentTuiConfig omitted renderLatex, so saving an unrelated preference (theme/editor/upgrade/cache-hint) serialized render_latex as the default true and silently reset a user's opt-out. Carry the appState value through the shared save payload. * feat(kimi-code): report tui_mode in lifecycle telemetry Tag startup_perf and exit events with the active renderer mode (regular/fullscreen) so fullscreen adoption is measurable while it is gated behind KIMI_CODE_TUI_FULL_SCREEN. |
||
|
|
35d9a36a69
|
chore(changelog): thank security reporters in 0.35.0 entry (#2845)
Some checks are pending
CI / lint (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (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
|
||
|
|
3b0936d8e0
|
fix(agent-core): only discover the root SKILL.md for plugin skills fallback (#2847)
When a plugin manifest omits `skills` and the plugin root contains a SKILL.md, the fallback treated the whole plugin root as a generic skill scan directory, so sibling Markdown files such as CHANGELOG.md were misidentified as skills and inflated the plugin skill count. Mark the fallback root as root-skill-only so discovery parses only the root SKILL.md; explicit `skills` entries (including "./") keep the directory scan semantics. Applied to both agent-core and agent-core-v2. |
||
|
|
f40bf04998
|
refactor(agent-core-v2): unify model-facing reminder scheduling (#2623)
* refactor(agent-core-v2): unify model-facing reminder scheduling Route every model-facing reminder through the contextInjector boundary scheduler. Past-tense events go through a persisted once-reminder queue (reminderQueue) that delivers exactly once at turn, step, compaction, and restore boundaries; present-tense state renders through context-injection providers reconciled against live history. - interruption, goal (cancel/budget/fork-cleared), image-compression captions, btw, and init reminders enqueue into reminderQueue instead of writing the context directly; the interruptionReminder wire model is removed and its recorded type is retired silently on replay - swarm mode announcements render through a provider seeded from the replayed history on restore, replacing live side effects and the ContextModel pop reducer on swarm_mode.exit - loadable-tools announcements become an isNewTurn-gated provider, dropping the compaction boundary flag - plugin session-start guidance re-renders as a supersedes reminder at the next boundary via a dirty flag instead of appending immediately - legacy system_trigger origins of migrated reminders still fold on replay * fix(agent-core-v2): make system reminders undo-aware * test(agent-core-v2): migrate plugin session-start harness * fix(agent-core-v2): preserve reminder boundary ordering * refactor(agent-core-v2): narrow reminder and swarm helper exposure - drop the swarmInjection re-export from the package index; SwarmInjection stays a domain-internal collaborator like permissionMode/plan injections - move INTERRUPTION_REMINDER text back to a private constant in the service; only the variant stays in the Ops module - make reminderQueue.enqueue return void; no caller consumed the entry id * chore(agent-core-v2): keep comments in module headers * refactor(agent-core-v2): track reminder state via injection disclosure - derive swarm active/inactive state from ctx.lastDisclosure instead of byte-matching rendered markdown, with variant-only fallback for legacy swarm_mode/swarm_mode_exit journal entries - record once_reminder disclosure (entry id) on queue-appended messages and dedupe the crash window by the contiguous tail id set, covering multi-entry drains - move reminderQueue draining behind a sync onWillInject event so the injector no longer depends on the queue domain - centralize the system-reminder wrap format behind wrapSystemReminder / systemReminderContent and use injector-provided positions in the plugin session-start provider - spell out the step-boundary fallback and sync-only contract of registerAtTurnStart via shouldRunAtBoundary * fix(agent-core-v2): isolate failing turn-start providers and warn once per missing sessionStart skill * refactor(agent-core-v2): compute injection positions on read Drop the per-provider positions cache from the context injector: the registration scan, the context.spliced index arithmetic, and the post-restore resync all existed only to mirror what the history already records. Each provider call now derives its injected positions by scanning context memory for its surviving injection messages, so silent history edits (such as vacuous-step folds) can no longer desync a cached index. * refactor(agent-core-v2): formalize injector once-channels and raw message results * refactor(agent-core-v2): declare dynamic tool schemas at injection boundaries Move the dynamic-tool schema declaration out of toolSelect.load(): the loaded names are recorded as pending and drained by a dedicated toolSelectSchemas provider through the contextInjector boundary scheduler, so the declaration message lands at a quiescent boundary instead of mid-step inside a streaming tool exchange. The folded history remains the loaded-tool ledger, so undo, compaction, and resume still self-heal by re-folding. * refactor(agent-core-v2): deliver AGENTS.md reminders through the reminder queue The tool hook now only observes and enqueues a once-per-agent reminder through the reminderQueue once-channel instead of prepending text to the tool result: results stay verbatim for the truncation pipeline and the reminder can never be truncated away with an oversized output. The reminderQueue is resolved lazily through the instantiation service at enqueue time, breaking the contextInjector -> loop -> llmRequester -> profile -> agentsMdReminder constructor cycle. * refactor(agent-core-v2): make injection disclosures opaque and domain-owned contextMemory no longer declares the ContextInjectionDisclosure union: InjectionOrigin.disclosure becomes an opaque unknown, and providers bind their own payload type through register<D>, so lastDisclosure arrives at the provider already typed by its own variant. The date, swarm_mode, and once_reminder payload shapes move into the dateChange, swarm, and reminderQueue domains respectively; reminderQueue keeps a runtime guard for its cross-message tail scan, the only place that reads disclosures it did not write. Persisted origin shapes are byte-identical, so existing journals replay unchanged. * fix(agent-core-v2): isolate failing step context providers A step or compaction boundary provider that threw or rejected made the injector's inject() promise reject, which propagated through the onWillBeginStep hook chain and failed the whole turn, and starved every provider registered after it. Log and skip the bad provider instead, matching the turn-start path's existing isolation. * refactor(agent-core-v2): derive injector isNewTurn per injection boundary Replace the shared read-and-clear isNewTurn flag (set by turn.started and injectAfterCompaction, consumed by the first inject()) with values each trigger supplies from an authoritative source: the loop marks a turn's first step via BeforeStepContext.firstStepOfTurn (standalone runs never count), and the compaction follow-up passes true explicitly, so interleaved triggers can no longer consume or steal the marker. A compaction follow-up that lands inside a step hook chain (the auto-compaction path) doubles as that step's new-turn delivery: the enclosing step then injects with isNewTurn false, so the upcoming request receives one new-turn injection, not two. * refactor(agent-core-v2): unify disclosure placement and injector param naming * fix(agent-core-v2): keep pending tool schemas across compaction splices A load announced by select_tools sits in pendingLoaded until the next injection boundary declares it. A compaction fold in that window publishes a replacement splice, and the splice-time reconciliation dropped the pending entries before the post-compaction inject could declare them — the model was told "Loaded: X" yet X never became available. Drop pending entries only on removal splices (undo/clear, which carry no replacement messages); compaction's replacement splice keeps them so the declaration lands at the post-compaction boundary. * fix(agent-core-v2): consume the plugin session-start refresh after a successful render reconcileSessionStartReminder cleared the refresh-pending flag before awaiting the render, so a throwing render (skipped by the injector's provider isolation) lost the forced refresh until the next catalog change. Consume the flag only after the render resolves, and move the warn-once rationale into the module header per the comment convention. * refactor(agent-core-v2): remove the generic reminder queue * chore(agent-core-v2): drop the stale reminder-queue mention in systemReminder * test(node-sdk): align side-question fork parity with event-point reminders * chore(agent-core-v2): address reminder review standards * docs(agent-core-v2): condense the model-facing reminders section * refactor(agent-core-v2): write all system reminders through wrapSystemReminder * fix(agent-core-v2): preserve reminder lifecycle invariants * refactor(agent-core-v2): reconcile context injections at the step head Unify the injector's delivery timings into one point on the onWillBeginStep chain, before the step's request is built: - providers run before every request instead of after every step, so reminders are visible from the first response of a turn - a compaction splice re-arms the new-turn flag via context.spliced; when compaction runs inside the hook chain (full-compaction's beforeStep), a follow-up inject at the chain tail keeps the first post-compaction request covered - registerAtTurnStart and injectAfterCompaction are removed; reconcileWhenIdle stays as the v1-parity surface for SDK-driven triggers (swarm toggle, plugin reload) * refactor(agent-core-v2): clarify the injector's step-hook handler Name the handler reconcileAroundStep, rename the rearm flag to compactionRearmPending with a single takeCompactionRearm() consumer, and extract isCompactionSplice. Consuming the flag into a local before computing isNewTurn also avoids hiding the side effect inside a || short-circuit. |
||
|
|
43c68f58f5
|
feat(agent-core-v2): keep session updatedAt stable across meta management writes (#2815)
* feat(agent-core-v2): keep session updatedAt stable across meta management writes Rename, archive/restore, and fork no longer bump a session's updatedAt, so recency-sorted session lists stop reshuffling on management actions: - setTitle/setArchived pass touchUpdatedAt: false; an explicit patch.updatedAt always wins (fork inherits the source's recency, so a fork lands next to the source instead of floating to the top) - new SessionMeta.archivedAt records the archive moment (cleared on restore) and is surfaced through the session index, the v1/v2 session routes (archived_at), and the klient contract, so the archived list keeps an accurate archive time without relying on the updatedAt bump * fix(agent-core-v2): normalize a legacy ISO-string updatedAt when forking a cold session A cold legacy/v1 state.json read from disk can still carry an ISO-string updatedAt; passing it through as the fork's explicit patch.updatedAt would persist a string into the v2 metadata. Normalize with toEpochMs (falling back to now when absent/unparseable). * fix(agent-core-v2): write fork metadata after agent recreation Registering each copied agent during fork is an ordinary metadata write that bumps updatedAt, which overwrote the inherited source recency and still floated normal forks (sessions with agents) to the top. Move the fork's metadata update after the agent recreation loop so the inherited updatedAt is the final write. * fix(agent-core-v2): preserve persisted recency when restoring a cold session Resume creates the main agent for a cold session that has no persisted agents.main entry (e.g. an empty session), and that registration bumps updatedAt — so unarchiving an empty session still floated it to the top. Capture the index summary's updatedAt before resume and re-apply it in the restore write (archived:false, archivedAt cleared, explicit updatedAt wins over the bump). * fix(agent-core-v2): make agent registration non-touching for recency Registering an agent is a structural write, not content activity — but it went through an ordinary metadata update that bumped updatedAt. That reordered recency-sorted listings whenever materialization created an agent: resume of a cold session without a persisted agents.main (so archive-via-resume and restore of empty sessions still floated), and runtime subagent registration mid-turn. registerAgent now passes touchUpdatedAt: false; restore goes back to the plain unarchive write and no longer needs the capture/reapply workaround. * fix(agent-core-v2): duplicate cron tasks only after the fork metadata is durable With the metadata write moved after agent recreation, cron duplication ran before it — a rejected metadata update left cloned cron records pointing at a fork whose directory the catch block just removed. Keep cron duplication after the durable metadata write. * style(agent-core-v2): fold new invariants into module headers The package convention keeps comments in the top-of-file block only — move the touchUpdatedAt precedence, non-touching registration, and fork ordering notes out of statement-level positions into the respective module headers. * chore: scope the changeset to agent-core-v2 |
||
|
|
c212ae9715
|
fix(kimi-code): show MCP launch targets in the workspace trust prompt (#2843)
* fix(kimi-code): show MCP launch targets in the workspace trust prompt Render each gated project MCP server's launch target (transport, command, args, cwd, or url) in the workspace trust prompt without leaking env or header secrets, stripping terminal control characters from the workspace-supplied text, default the prompt to "Don't trust", and resolve fd binaries to absolute paths so untrusted workspaces cannot plant a bare-name fd executable that runs before trust confirmation. * fix(kimi-code): resolve stty to an absolute path before the trust gate |
||
|
|
26a37f30a3
|
fix(kap-server): restrict debug RPC fallback to feature-contributed services (#2808)
The decorator-registry fallback resolved every decorator name, including kernel tokens like instantiationService — a call to instantiationService/dispose would tear down the root container. Record Feature.contributeService tokens in a contributed-service table and fall back to that table only, so runtime-contributed services stay callable while unregistered kernel tokens remain unreachable. |
||
|
|
dc8db90cdd
|
docs(server): add local server guide and API reference (#2839)
* docs(server): add local server guide and API reference * docs(server): qualify binary endpoint HTTP semantics |
||
|
|
26ddc1d0fb
|
feat(plugins): add Modern Web Guidance to marketplace (#2842)
* feat(plugins): add Modern Web Guidance to marketplace * chore: drop changeset * chore: backfill 0.35.0 changelog entry |
||
|
|
3fc841ff23
|
docs(changelog): sync 0.35.0 from apps/kimi-code/CHANGELOG.md (#2841)
* docs(changelog): sync 0.35.0 from apps/kimi-code/CHANGELOG.md * docs(changelog): add Modern Web Guidance plugin entry to 0.35.0 |
||
|
|
f6ee44e426
|
ci: release packages (#2710)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
101c4d1997
|
feat(agent-core-v2): remove Agent and AgentSwarm from builtin profile tool lists (#2837)
* feat(agent-core-v2): remove Agent and AgentSwarm from builtin profile tool lists The builtin agent and coder profiles no longer expose the Agent and AgentSwarm tools, so sessions on the v2 engine do not offer subagent delegation by default. The tools themselves remain registered; profiles that list them explicitly can still opt in. * feat(agent-core): remove Agent and AgentSwarm from builtin profile tool lists Align the v1 builtin agent/coder profiles with the v2 change: the default profiles no longer offer subagent delegation, while the tools stay registered for profiles that list them explicitly. The parity projection drops v1's inactive Agent/AgentSwarm roster entries: v1 reports registered-but-inactive builtin tools where v2 only registers the tools a profile lists, so an inactive entry has no v2 counterpart. Active entries still compare in full. * fix: keep Agent and AgentSwarm in the builtin agent profile Scope the removal to the coder subagent profile on both engines: the main agent keeps Agent/AgentSwarm so default sessions can still delegate, while coder subagents no longer spawn nested subagents by default. Snapshots and token counts shift only for the embedded coder tool list; the v1 parity projection needs no change since the main agent rosters match again. |
||
|
|
68ce3c7a0c
|
chore: sync web dist from code-app (#2840) | ||
|
|
df8ce73e45
|
feat(kimi-code): show step retry progress in the activity indicator (#2825)
* feat(kimi-code): show step retry progress in the activity indicator Wire the engine's turn.step.retrying event into the TUI: while a failed model request is backing off for another attempt, the waiting spinner shows 'retrying (N/M) · errorName · in Xs' with a dim detail line for the status code and provider error message, and the loading tip is suppressed. The retry state clears on the step's terminal events (completed / interrupted), turn.ended, and tool.result. It intentionally survives turn.step.started because the v2 engine re-emits that event for every retried attempt of the same step. * fix(kimi-code): show the retry indicator for mid-stream failures A retryable failure raised after thinking/assistant deltas had already streamed left the pane in thinking/composing mode, so the retry label and detail never rendered during the backoff. Drive the pane and the streaming phase back to waiting when a retry begins. * fix(kimi-code): drop the stale retry countdown once the attempt starts The v2 engine re-emits turn.step.started when the retried attempt begins running after the backoff sleep. Track a backoff/attempt phase so the label keeps showing the retry attempt and error but drops the already-elapsed 'in Xs' countdown, instead of either clearing the state or showing stale timing through a slow attempt. * fix(kimi-code): advance the retry phase on a timer instead of step starts The legacy engine retries inside the same step and never re-emits turn.step.started, so the backoff-to-attempt transition keyed on that event never fired there and the stale countdown stayed up through the attempt. Schedule the flip from delayMs instead, which matches when both engines actually start the next attempt, and drop the step-start hook. * fix(kimi-code): cancel the retry phase timer on TUI shutdown A pending backoff timer survived KimiTUI.stop(), keeping the event loop alive and firing setAppState against a disposed UI when stop() runs without an immediate process exit. Expose the timer cleanup and invoke it from the shutdown path. * fix(kimi-code): align the retry detail line with the spinner label * fix(kimi-code): capitalize the retry spinner label |
||
|
|
3c9e3b297c
|
feat(kimi-code): paginate the session picker list (#2826)
* feat(kimi-code): paginate the session picker list The /sessions picker and kimi -r used to materialize the full session list before showing anything, which gets slow with hundreds of sessions. - node-sdk: add listSessionsPage (limit/before -> items + nextCursor); the v2 engine pages through the session index (draining past entries whose workDir is unrecoverable), the v1 engine answers one full page - TUI: open the picker on the first page, fetch the next page when the cursor reaches the fetched end, and drain remaining pages in the background once a search query is typed so search still covers all sessions - kimi -r now fetches a one-item page for the latest session * chore: simplify session picker changeset * fix(kimi-code): join in-flight page fetch in session search drain A query typed while a scroll-triggered page fetch was still running stopped the background drain at the loadingMore early return, leaving the search covering only the pages fetched so far. fetchMoreSessions now optionally joins the in-flight fetch and continues with the next page; scroll triggers still drop when busy. |
||
|
|
e5be39164b
|
fix(kimi-code): resolve footer git status commands through PATH (#2838)
The footer git status cache spawns git (and gh for PR lookup) on the startup path, before the workspace trust prompt. On Windows, a bare command name lets cmd.exe resolve a git.exe planted in the workspace before the user confirms trust — a gap left by #2695. Resolve git once at cache creation and gh per lookup with resolveCommandPath(), which returns an absolute PATH hit and refuses matches inside the workspace; when resolution fails the cache reports no repository instead of spawning anything. |
||
|
|
619564dcf9
|
fix(kap-server): add WebSocket heartbeat to survive proxy idle timeouts (#2813)
Some checks are pending
CI / typecheck (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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 / Native release artifact (push) Blocked by required conditions
Release / Release (push) Waiting to run
CI / lint (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
The v1 WS connection had no keepalive: by design it stayed open until the client disconnected, which only holds for direct connections. Behind a reverse proxy or gateway with an idle timeout (30s defaults are common), any quiet stretch — e.g. waiting on a slow model response — got the connection killed, surfacing as a recurring 'Realtime connection error' in the web UI. Send an application-level ping every 10s and advertise heartbeat_ms in server_hello (the schema and all shipped clients already answer pong). Application-level rather than protocol-level ping because browser JS cannot observe the latter, and the client's stale-socket detector keys on incoming message frames. Any inbound frame refreshes liveness; after two silent cycles the connection is presumed half-open and closed with 1001 so dead peers get reaped instead of leaking. |
||
|
|
911d41b0f6
|
chore(changesets): simplify pending CLI changelog entries (#2823) | ||
|
|
ad12ad8a14
|
feat(kimi-code): show live background agent activity in the /tasks panel (#2816)
* feat(kimi-code): show live background agent activity in the /tasks panel Background agents (run_in_background or Ctrl+B) showed no run details: the /tasks panel only had static metadata, and its output view stays "[no output captured]" until completion because agent tasks capture output only once at the end. Tee child-agent events into a bounded in-memory per-agent activity store segmented by the engine's own turn.step.started events (recent 10 steps, bounded text/output tails). The /tasks preview pane now shows a live activity preview for agent tasks, and Enter/O opens a full-screen detail view rendering step-grouped Markdown text and per-tool results through the main transcript's renderers, with Ctrl+O to expand. Agent tasks without an in-memory record (e.g. lost after resume) fall back to the captured-output view. * feat(kimi-code): retain 20 recent steps in the background agent activity view * fix(kimi-code): cap the streaming-args buffer in the subagent activity store * chore(kimi-code): simplify the background agent activity changeset * fix(kimi-code): drop activity records of foreground-only subagents at terminal state * fix(kimi-code): cap retained tool argument strings in the subagent activity store * test(acp-server): retry temp-dir cleanup to deflake ENOTEMPTY on CI * fix(kimi-code): tighten subagent activity store lifecycle edges - drop delta-only arg buffers when their step is evicted - keep records of spawn-time background agents even when the task sync lags - mark records terminal on background.task.terminated for stopped agents that never emit subagent.failed * fix(kimi-code): release leftover arg buffers when an activity record turns terminal * fix(kimi-code): prune foreground-only activity records when the main turn ends |
||
|
|
158c81d705
|
fix: surface a readable error when Git Bash is missing on Windows (#2814)
* fix: surface a readable error when Git Bash is missing on Windows * fix(agent-core-v2): translate probe rejection into HostProcessError for ready awaiters - HostEnvironmentService.ready now rejects with the translated HostProcessError(shell.git_bash_not_found) instead of the raw ProbeShellNotFoundError, matching what sync field reads throw and what SDKRpcClientV2.ensureConfigFile() surfaces, while an internal no-op handler keeps the rejection from becoming an unhandledRejection. - Replace the Windows-gated probe-failure tests with vi.mock-stubbed deterministic suites that run identically on any platform. - Move the ProbeShellNotFoundError explanation into the environmentProbe file header per the package comment convention. * fix(agent-core-v2): narrow probe error to Error to satisfy only-throw-error lint * fix(agent-core-v2): preserve probe error as cause when translating to HostProcessError * fix(agent-core-v2): keep checked paths out of the public probe error message * fix(node-sdk): gate the host-environment wait in ensureConfigFile to Windows The missing-Git-Bash failure is Windows-only, and IHostEnvironment.ready also covers the login-shell PATH enrichment, which spawns the user's login shell with a 5s timeout. Awaiting it on POSIX coupled config-only commands (kimi provider list/remove, export, ...) to the user's shell profile for no benefit. --------- Co-authored-by: liruifengv <liruifeng1024@gmail.com> |
||
|
|
64abebc95a
|
fix(apps/kimi-code): allow deselecting Other option in multi-select question dialog (#2810) | ||
|
|
860354976e
|
feat(agent-core-v2): add event-subscription introspection (#2806)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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
- name Emitters and surface their subscriptions as on:<name> ledger labels through a named EventSubscription class and IDisposableDebugLabel - add IDebugEventsService.subscriptions(), merging unit-book entries with per-bus listener counts, contributed at App scope by the new debugEvents feature - kap-server debug dispatcher falls back to the global decorator registry so runtime-contributed services stay callable - kimi-inspect: add an Events panel to the DI view |
||
|
|
e702817124
|
fix(agent-core-v2): degrade idle-session steer to turn launch like v1 (#2723)
- return the enqueue-launched turn instead of rejecting with prompt.not_found when no prompt is pending at steer time - report steer as queued when a manual compaction holds the context - sync title/lastPrompt metadata on main-agent steer, matching v1 - update the v1-v2 parity test to assert converged behavior |
||
|
|
71ff2a0fff
|
fix(kimi-code): close pre-trust-gate bare command resolution on Windows (#2695)
On Windows, cmd.exe / CreateProcess resolve a bare command name from the current directory before PATH. Several startup-path child processes ran before the workspace trust prompt, so a binary planted in an untrusted workspace (stty.exe, npm.cmd, fd.exe) could execute before the user confirmed trust. - skip the POSIX-only stty save/restore entirely on win32 - defer fd detection from the KimiTUI field initializer to startBackgroundFdAutocomplete(), which runs after the trust gate - add resolveCommandPath(): resolve commands through PATH (PATHEXT-aware on win32) to an absolute path and refuse hits inside the cwd - route update-preflight package-manager spawns and the npm global-prefix probe through it - run the workspace trust prompt before the migration branch as well, closing the blind spot where a pending ~/.kimi migration skipped it - document the no-bare-command-before-trust-gate rule in apps/kimi-code/AGENTS.md |
||
|
|
2acf22f66e
|
refactor(agent-core-v2): invert sessionLifecycle/MCP dependency via lifecycle event (#2803)
- add onWillCreateSession to ISessionLifecycleService: a synchronous participation event fired before a session's services activate, exposing a session-domain facade (readSeed / contributeSeed / onSessionDispose) - workspaceMcp subscribes and activates ephemeral-server overlays itself: the configs travel as the new ISessionEphemeralMcpServers session seed, the stdio cwd is read from ISessionContext, the merged ISessionMcpHandle is contributed over the seed adapter's workspace projection, and the overlay shutdown is attached to the session's teardown - sessionLifecycle drops its IWorkspaceMcpService dependency, the overlay tracking map, handle-dispose wrapping, and the dispose backstop - rename ScopeOptions.extra to seeds and ScopeOptions.assemble to configureContainer |
||
|
|
0401ec4286
|
refactor(agent-core-v2): extract btw into a features/btw Feature unit (#2724)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
Release / Publish native release assets (push) Blocked by required conditions
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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
- move session/btw to features/btw, mirroring the plan feature layout - contribute ISessionBtwService at Session scope through BtwFeature (contributeService) instead of a static registerScopedService call - keep the package root exports unchanged; move the test to test/features/btw |
||
|
|
01c74e9372
|
fix(agent-core): isolate builtin profile catalogs per session (#2740)
Some checks failed
CI / build (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test (5) (push) Has been cancelled
CI / test-pi-tui (push) Has been cancelled
CI / test-windows (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
|
||
|
|
437a1b8ba1
|
fix(sdk): probe MCP auth status through connection (#2731)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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
|
||
|
|
0b2e803d5e
|
feat(sdk): expose global MCP auth status (#2706)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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 / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
|
||
|
|
7cd64766c8
|
feat: isolate the full-text search index from the session index and the main thread (#2701)
* feat(minidb): instrument open lifecycle with phase timings and status Add MiniDb.lifecycleStatus() exposing the no-generation/generation-load/ wal-catch-up/full-rebuild/ready/degraded state machine plus per-phase timings (generation candidate load, store/non-text/text image load, postings integrity check, WAL scan/apply, full recovery, text rebuild hosting), so snapshot load, WAL catch-up and full rebuild can be told apart in diagnostics. Also add a repeatable open-lifecycle bench (small data, large WAL delta, large full-text generation, corrupt generation) and fixtures proving a healthy generation open performs no full-corpus tokenization while a corrupt or missing generation falls back. Log search-index and query-store open diagnostics in kap-server and agent-core-v2 so a listSessions call can be attributed to the database it touches. No persistence format or product behavior change. * feat(agent-core-v2): isolate the session index from the global search index Harden the separation between the session read model and the full-text search index so session operations never depend on search availability: - Reject text index definitions in MiniDbQueryStore at definition level, keeping the session query-store a structural-only read model with no postings/tokenizer artifacts, and assert its generation carries no full-text files. - Share one authoritative scan between the first list and the initial projection (single-flight) instead of scanning twice; reads may only join an in-flight scan, and every fallback read folds the mirror's pending queue so read-your-writes holds while preparing. - Keep withReadModel() fallback semantics pinned by tests: uninitialized/preparing reads hit authoritative metadata immediately, ready reads use the read model, degraded keeps falling back with a diagnosable status reason. - Guard session metadata writes so a mirror failure degrades only the read model and never fails the session lifecycle. - Prove via tests that listSessions/--resume/--continue never open the global search DB (including when search-index is unopenable), and that only real full-text search requests report building/stale/degraded. * perf(minidb): slice open-time work so it never blocks the main thread Make the whole generation-open path cooperative: - Replace the synchronous postings/store CRC verification with chunked async variants (readGenerationFileCheckedAsync, verifyFileIntegrityAsync) that keep the exact bytes/crc-mismatch error semantics. - Give the WAL-delta apply a primitive-op + wall-clock budget (walApplySlicer), so a batch frame unrolling into thousands of ops can no longer run as one uninterruptible slice; torn-tail, corrupt-batch and read-only behaviors are unchanged. - Slice the big attach loops: Store.bulkLoadRefsAsync + SkipList.bulkLoadAsync for the store image, async parsers and loadImageAsync for secondary/compound images, and TextIndex.attachImageAsync for the docs/dictionary map construction. - Queue text builds on worker-slot pressure (WorkerSlots.acquireBounded, bounded by MiniDb.textBuildSlotWaitMs, abort-aware) instead of falling back to an unbounded inline build; a persisted drought hosts the bounded inline core as the explicit last resort with stats accounting. Bench (bench/open-lifecycle, seed 42): event-loop delay max across the four open scenarios drops from 45/734/331/492 ms to ~12-28 ms with wall time flat or better. * feat(kap-server): run the global search index in a dedicated worker Move the whole search-index MiniDb lifecycle (open, generation load, WAL replay, sync, rebuild, compaction) off the main thread into a long-lived worker_threads host, so it never shares the event loop with TUI input: - Add a versioned request/response protocol and worker entry hosting a host-agnostic SearchIndexCore; the same core also backs an inline backend kept as the explicit rollback (KIMI_CODE_EXPERIMENTAL_SEARCH_WORKER=false, flag default ON). - The worker exclusively owns the search-index handle. The lock token is reported at acquire time (new MiniDb OpenOptions.onLockAcquired hook) and reaped on dirty exit; an orphan-lock detector (same-pid lock row whose token no live holder owns) recovers the window where the token report is lost, so a mid-open crash can never freeze the index into a silent permanent read-only. - Crash handling: in-flight requests are rejected with typed errors, respawn uses capped exponential backoff, per-request watchdogs terminate wedged workers, and beginClose propagates into the worker so dispose stays bounded during a long sync. Page tokens pin a boot-salted generation, so tokens issued before a transparent worker restart fail closed with invalid_page_token. - The main process keeps the sync coordinator (debounce/coalescing/ single-flight), live transcript routing, query normalization and page-token codec; searches keep reading the published generation and report building/stale/degraded instead of waiting for sync/rebuild. - Wire the worker into the CLI packaging: self-contained worker bundles for npm dist and the SEA asset manifest/installer/smoke check, plus a dev runtime (type-stripping + .ts resolve hook) scoped to worker execArgv. * feat(kap-server): model search and session-index lifecycles explicitly Consolidate the two-index separation into explicit, diagnosable lifecycles: - Surface the global search state machine (stopped / opening / building / ready / degraded / closing) end to end: SearchIndexCore.lifecycleState, SearchWorkerHost lifecycle snapshots cached from RPC responses (and invalidated across worker generations), a never-throwing status() carrying the lifecycle, and a synchronous lifecycleReport() that neither kicks the open nor spawns the worker. Corrupt search-index rebuilds are announced with a dedicated warn log so building, stale, degraded, corrupt and worker-unavailable stay distinguishable. - Turn MiniDb read-only replica catch-up fully cooperative: catchUpWalAsync scans frames with the windowed async scanner and yields per primitive op on the shared walApplySlicer budget, while a per-instance catchUpChain serializes concurrent catch-ups so each caller keeps its atomic watermark advance. The stale synchronous implementations are removed. - Pin the dependency direction and availability timing with tests: session list/create/resume survive a corrupt or unopenable search index (also end-to-end with a dead query-store), search generation reuse and stale-serving keep working across restarts, concurrent cold callers open the index / spawn the worker exactly once, resume-then- fetchSessions performs no duplicate authoritative scan, and a clean dispose releases the lock and settles at stopped. - Document the experimental flag surface (persistence_minidb_readmodel, search_worker) in the root guide. * feat(agent-core-v2): default the session read model on and roll out the separation Rollout and validation for the index separation plan: - Flip persistence_minidb_readmodel to default ON (rollback via KIMI_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL=false or the experimental config section); session list/--resume/--continue now always go through the isolated session read model with the authoritative fallback. Test harnesses pin the flag off where shared fixtures require hermetic homes, while the dedicated suites keep explicit on/off coverage. - Add a probe proving the main thread stays responsive while the search worker rebuilds and swaps a generation (reindex), completing the TUI responsiveness matrix. - Record the rollout state in the agent-core-v2 guide (session index section) and the root flag line. - Add changesets for the CLI (worker isolation, session index independence) and minidb (cooperative open lifecycle). Validation: full suites green across minidb (551), agent-core-v2 (4760), kap-server (1005), node-sdk (343), klient (91) and the CLI app (2567); open-lifecycle bench event-loop delay max is down from 45/734/331/492 ms to ~16-22 ms across the four scenarios with wall time flat or better. * fix(agent-core-v2): evict deleted sessions from the mirror queue and drain the index on close Two issues surfaced by the read-model default in the acp-server suite: - ISessionIndex.remove only deleted from the query store, but a summary still queued in the mirror was folded back into reads (and re-written by the next flush), resurrecting a deleted session in listings. The mirror now exposes evict(id): drop the queued summary and wait out an in-flight flush before the store delete. - RunningAcpServer.close and SDKRpcClientV2.close disposed the engine without awaiting the asynchronous mirror flush / query-store close, so a host removing homeDir right after close() raced in-flight shard closes (ENOTEMPTY). Both now follow the kap-server shutdown order: drain the mirror while the store is open, dispose, then await the drains. * fix(minidb): pause active expiry during the sliced bulk load The store's active-expire timer is armed at construction, so during a sliced bulkLoadRefsAsync a tick can fire mid-load: it reaps a TTL key from the map while the order skiplist is still the old empty one, and the final bulkLoadAsync then rebuilds order from the stale orderEntries snapshot — resurrecting the expired key in the ordered index (and duplicating it if the key is later set again). The sync bulkLoadRefs had no yield windows, so guard the async path with a bulkLoading flag that defers expiry ticks until the load settles (finally-safe). * chore: consolidate changesets into the TUI startup freeze fix |
||
|
|
c0b61c6e55
|
fix(agent-core-v2): count compaction tokens on the full-request basis (#2699)
Some checks are pending
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (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
- tokensBefore/tokensAfter now include the system prompt and non-deferred tool schemas, matching the measured-anchor basis the context gauge uses between exchanges - the post-compaction ledger rebase carries the same full-request size, so the reported context size no longer dips to a messages-only estimate and jumps back on the next exchange - the PreCompact hook tokenCount uses the same basis |
||
|
|
476787fec9
|
docs(agents): rework changelog curation rules for the user-facing changelog (#2708)
* docs(agents): rework changelog curation rules for the user-facing changelog * docs(agents): refine catch-all wording and add reviewer notes to the changelog preview * docs(agents): surface folded entries at the sync review checkpoint |
||
|
|
d9ec566e51
|
docs(changelog): sync 0.34.0 from apps/kimi-code/CHANGELOG.md (#2704)
Some checks are pending
CI / test (5) (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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 / Publish native release assets (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
* docs(changelog): sync 0.34.0 from apps/kimi-code/CHANGELOG.md * chore: link |
||
|
|
51ef78b8c9
|
docs: add Official Plugins section with WebBridge and Computer Use (#2653)
* docs: add Official Plugins section with WebBridge and Computer Use Group the three official capabilities (Kimi Datasource, Kimi WebBridge, Kimi Computer Use) under a new Official Plugins section on the plugins page, with a single shared install/upgrade flow. Add an authorization walkthrough screenshot for Computer Use and regroup the Datasource coverage table by category with named data sources. * docs: add browser extension install steps for Kimi WebBridge Installing via /plugins is not enough on its own: AI can only drive the browser after the Kimi WebBridge extension is present. Document both install paths (Chrome Web Store / Edge Add-ons, and manual load-unpacked via chrome://extensions with Developer mode) plus a quick way to verify. * docs: split WebBridge manual install into illustrated steps Break the manual extension install into numbered steps with per-step screenshots: enable Developer mode on chrome://extensions, then load the unpacked kimi-webbridge-extension folder. * docs: tighten WebBridge install screenshots to the relevant area * docs: add WebBridge ready-state verification screenshot * docs: note WebBridge's two-part install in the shared install steps * docs: even out WebBridge install screenshot edges * docs: replace WebBridge install screenshots with clean crops Re-shoot source images: split the two-step manual install guide into per-step screenshots with clean edges, and replace the ready-state popup screenshot with the toolbar-icon success indicator. * docs: use newly provided WebBridge step screenshots * docs: sharpen Computer Use auth screenshot and center it Replace the downscaled auth-window image with a crisp native capture, constrain its display width to 380px, and center it on the page. Also move the WebBridge two-part install note into an info callout directly under the shared install steps. * docs: drop the coverage start year from the Datasource table * docs: spell out the two WebBridge extension install options * docs: show the Kimi Code toggle enabled in the Computer Use auth screenshot * docs: show version badges for WebBridge and Computer Use, rework Computer Use scenarios Add version badges next to all three official plugin names. Rewrite the Computer Use capability list around verified task shapes and add a warning callout for operations that should not be delegated. Keep the final WebBridge install step inside the numbered list. * docs: add Windows (WinCU) notes to Computer Use Computer Use now ships a Windows runtime with a different install path and behavior: it may briefly take over the real mouse and keyboard instead of running fully in the background. Document the install command, system requirements, permission model, and privilege matching, and stop claiming the feature is macOS-only. * docs: break up the plugin manager wall of text Split the Installation and Management paragraph into bullets, drop the parts duplicated by the Official Plugins section (including the outdated macOS-only note), and link to that section instead. * docs: list the plugin manager tabs and drop the tab-behavior block * docs: give the WebBridge extension install section an English anchor * docs: restore the /reload or /new activation step for official plugins * docs: align the plugins page wording with the published docs site * chore: retrigger CI --------- Co-authored-by: qer <wbxl2000@outlook.com> |
||
|
|
f0614c53e5
|
ci: release packages (#2641)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
794714ebef
|
fix(agent-core-v2): gate plugin changes behind session baselines and reminders (#2702)
* fix(agent-core-v2): gate plugin changes behind session baselines and reminders
- capture a per-session MCP server baseline (ISessionMcpHandle.isBaselineServer)
so servers added mid-session (plugin install, mcp.json edit) never register
tools in live sessions; they take effect on /new, /reload, or resume, while
removed servers stay tombstoned and fail calls with a removal notice
- stop rebuilding the system prompt on plugin-source catalog changes: the
frozen skill listing and plugin sections cannot move anyway, and the rebuild
only churned the ${now} timestamp, invalidating the provider prompt cache
- freeze the Agent tool description's catalog profile list once the session
catalog has loaded, keeping the tools payload byte-stable across mutations
- append a plugin_change system reminder to live sessions on plugin mutations
(new IPluginService.onDidMutate; explicit reloadPlugins does not raise it)
- revert the TUI hint to "Run /new or /reload to apply plugin changes." and
update the plugin/MCP docs and changesets to the corrected contract
* fix(agent-core-v2): import LifecycleScope from app/scopes in sessionOutcomeMirror
#2666 imported LifecycleScope from #/_base/di/scope, which does not export
it (it lives in #/app/scopes), breaking the package build and typecheck on
main.
* fix(agent-core-v2): close the mutation-driven session-start refresh and overlay baseline leaks
Codex review on the PR found two contract leaks:
- a plugin mutation re-pulls the plugin skill source, and the existing
catalog listener answered with a fresh plugin_session_start reminder —
injecting the newly installed plugin's instructions into the live session
alongside (and contradicting) the plugin_change notice. The session-start
refresh now skips mutation-driven catalog changes (one per mutation,
counted; explicit reloads keep the old refresh behavior).
- a session created with ephemeral mcpServers kept its MCP baseline open
until the overlay connect finished; a workspace server added in that
window (plugin install, config edit) leaked into the live session through
the merged view. The overlay handle's baseline now freezes on the
workspace manager's initial load, with the ephemeral names baseline by
construction.
* fix(agent-core-v2): drop duplicate LifecycleScope import in sessionOutcomeMirror test
---------
Signed-off-by: Haozhe <yanghaozhe@moonshot.ai>
|
||
|
|
fa3325404b
|
fix(agent-core-v2): import LifecycleScope from the L3 scopes module (#2703)
The L3 unit layer refactor moved LifecycleScope out of the _base DI kernel into the app tier, leaving the session outcome mirror with a stale import that broke typecheck and import-time evaluation on main. |
||
|
|
03aa66ca0c
|
fix(tui): show WebBridge setup steps after install (#2692)
* fix(tui): show WebBridge setup steps after install * fix(tui): scope WebBridge hint to capability install * fix(tui): format WebBridge setup links * fix(tui): align WebBridge setup with live reload * fix(tui): retain WebBridge session activation step * fix(tui): compact WebBridge setup links * fix(tui): list WebBridge setup links clearly * fix(tui): show clickable WebBridge URLs * Revert "fix(tui): show clickable WebBridge URLs" This reverts commit 373ffae4b8cf4256131002b990f9a1869e9ee156. * fix(tui): restore WebBridge setup heading |
||
|
|
335588e259
|
feat(agent-core-v2): persist the last turn outcome into session metadata for cold listings (#2666)
* feat(agent-core-v2): persist the last turn outcome into session metadata for cold listings A cold session (no live handle) reported no lastTurnReason, so after a server restart the session list could not mark a session whose last turn failed until it was opened and resumed. A new Session-scope SessionOutcomeRecorder subscribes to the activity aggregate's turn_ended changes and persists the outcome (completed/failed) into the session metadata document; the summary pipeline (mirror + cold reader) carries it as SessionSummary .lastTurnReason, and toWireSession falls back to it when no live fact exists. 'cancelled' is deliberately not persisted: it is also what an in-flight turn ends with during scope disposal, and writing there races the host's home-dir teardown. Verified end to end with an isolated home and a dead provider: a turn fails, the server restarts, and GET /sessions reports last_turn_reason=failed without opening the session. * fix(klient): carry lastTurnReason/lastTurnOutcome in the validated contracts Review follow-up: zod strips unknown keys on parse, so the new outcome fields never reached klient callers; add them to the session summary and metadata/patch/key schemas (contract parity test covers the engine mirror). * fix(agent-core-v2): persist user-cancelled outcomes, never teardown aborts Review follow-up: skipping every 'cancelled' left a stale earlier outcome in the metadata (e.g. a prior failed reported for a session whose latest turn was stopped by the user). The recorder now subscribes to the main agent's turn.ended facts directly and keys on interruptReason: user_cancelled is persisted like any other terminal state, while programmatic aborts — including the cancel every in-flight turn suffers during scope disposal — are never written, so no metadata write races the host's home-dir teardown. * fix(kap-server): only fall back to the persisted outcome for cold sessions Review follow-up: a warm session that just started a new turn clears its live lastTurn, and the unconditional ?? fallback would then report the previous turn's persisted outcome for a turn that is still running. SessionFacts now reports whether a live handle exists, and the wire projection only reads the persisted value when the session is cold. * docs(agent-core-v2): keep the outcome-recorder header at role level * fix(agent-core-v2): settle turn outcomes on turn start and drain metadata writes on close Review follow-ups: - a new main turn now clears the persisted outcome (turn.started), so a process that dies mid-retry no longer reports the previous turn's terminal state for a turn that never ended - the dedupe marker only advances after a successful write, so a failed persist no longer suppresses the next identical outcome - session metadata writes are tracked in a module-level pending set with drainSessionMetadataWrites(), awaited by kap-server close alongside the mirror/query-store drains — an event-driven write (e.g. the outcome recorder) can no longer land in a session dir while the host removes it * fix(agent-core-v2): track the metadata dispose flag locally Disposable exposes no public isDisposed accessor; keep a class-local flag set in the dispose override. * fix(kap-server): drain session metadata writes before the mirror and disposal A write still in flight when close() begins must settle before the mirror flushes its summary into the read model and before scope disposal marks the service disposed — not after. * fix(agent-core-v2): reattach the recorder when the main agent is recreated Review follow-up: a failed bootstrap still fires onDidCreate before the handle is dropped; the subscription then pointed at a dead bus and the guard blocked any later reattach. Track onDidDispose and reset so the next main creation attaches cleanly. * test(agent-core-v2): resolve the recorder through the scoped DI harness Review follow-up: construct SessionOutcomeRecorder via registerScopedService + a Session-scope test host (stubbed lifecycle/metadata), so the test covers the production registration path; add the durable-value adoption case. * fix(agent-core-v2): unbreak CI — iterable Promise.all and the debug channel surface - Promise.all takes the pending-writes set directly (oxlint error) - the disposed flag moves into a _register'd marker instead of a public dispose() override, which the debug channels listing (and its test) correctly rejects as framework plumbing * fix(kap-server): surface persisted failures on the v2 session status The v2 list folds the outcome into activity.status, which previously read only live facts — a cold session always looked idle. Cold sessions now map a persisted failed outcome to status 'failed' (completed and cancelled stay idle, matching the live fold); warm sessions are unchanged, and the statuses filter inherits the mapping. * refactor(agent-core-v2): name the persisted field lastTurnReason Aligns with the established name for the same concept end to end (activity view's lastTurnReason, the v1 wire's last_turn_reason, and the SessionSummary mirror), instead of introducing a third variant. * fix(agent-core-v2): drain pending metadata writes before session teardown Review follow-up: closing/archiving a session right after a turn ended could dispose the scope while the outcome write was still queued, and delete() removes the session dir immediately after close. Await the pending metadata writes before the handle goes away. * fix(node-sdk): carry lastTurnReason through the SDK session summary Review follow-up: the in-process SDK path maps the engine summary through v2SummaryToSessionSummary, which dropped the new outcome field. Add it to the public SessionSummary type and the mapper; the parity gate projects it away (the v1 engine never records an outcome). * fix(node-sdk): populate lastTurnReason on live SDK summaries Review follow-up: resumeSession/reloadSession build their summary from the live session's metadata document, which now carries the outcome — surface it there too so the SDK reports it consistently for live and listed sessions. * fix(agent-core-v2): carry the last turn outcome across session forks Review follow-up: fork skips state.json when copying the session dir, so the fork's fresh metadata never had the outcome and a restart dropped a marker the warm fork was still reporting. The fork's metadata patch now inherits the source's lastTurnReason. * fix(agent-core-v2): settle pending outcome writes before reading a fork source Review follow-up: a fork requested right after the source's turn ended could read the metadata before the recorder's queued write landed, inheriting a stale or absent outcome. Drain pending metadata writes first. * fix(agent-core-v2): backfill restored outcomes into the session metadata Review follow-up: for sessions whose last turn ended before this field existed, the cold-resume seed restores the outcome into the activity view without a turn.ended fact, so the recorder never persisted it and cold listings stayed blank. The recorder now also watches the main agent's activity updates and backfills the restored outcome when nothing is persisted yet. * fix(agent-core-v2): never backfill restored cancellations Review follow-up: a restored 'cancelled' cannot be told apart from a programmatic abort (the activity event carries no interruptReason), and those are never persisted. Backfill now covers only completed/failed; user stops are still persisted from the live turn.ended fact. * refactor(agent-core-v2): rename the outcome recorder to outcome mirror Mirror is the codebase's established term for a write side that reflects live state into a store (SessionIndexMirror); Recorder has no precedent. * fix(agent-core-v2): backfill without bumping recency; header-only comments Review follow-ups: - a mere resume must not float an old session to the top of the list: metadata updates accept touchUpdatedAt:false and the outcome mirror's backfill uses it (live outcome writes keep bumping — turn end is a recency moment) - the mirror service's inline notes move into the file header per the package comment convention - drop the redundant |undefined from the SDK's optional outcome field * fix(node-sdk): read the live outcome for resumed session summaries Review follow-up: on a fresh resume the restored outcome can still be queued as a metadata backfill, so the document may lag a tick; the live activity aggregate already holds it. Resume/reload summaries now prefer the live value and fall back to the metadata field. * fix(agent-core-v2): confine the outcome backfill to pure resumes Review follow-up: the view publishes its turn.ended fold before this mirror's own turn.ended handler runs, so a live ending reached the backfill branch first and got persisted without the recency bump. The backfill now only applies when no turn ever started in this process — live endings always take the bumped write. * fix(agent-core-v2): drain the session-index mirror before session teardown Review follow-up: settling the metadata write alone left the fresh summary in the mirror's pending queue, so a list right after close could read a stale outcome from the read model. close/archive now also drain ISessionIndexMirror. Test harnesses register a mirror stub for the new dependency. * docs(agent-core-v2): fold the metadata drain contract into the file header * chore: include the SDK package in the changeset; fold the drain note into the header * fix(agent-core-v2): backfill restored cancellations too, quietly Review follow-ups: dropping every restored cancel loses legitimate user stops whose live write never landed (or was rejected) before a restart — cold surfaces never mark cancelled anyway, so healing them is harmless and strictly more accurate. The metadata disposal note moves into the file header per the comment convention. * fix(node-sdk): prefer the live outcome over the index in SDK listings Review follow-up: a live session that just started a new turn after a failure can briefly keep the stale outcome in the index while the mirror's clear is queued. listSessions now reads the live activity aggregate for warm sessions, matching the kap-server cold-only fallback. * fix(node-sdk): never read the metadata outcome for a live session Review follow-up: with a retry in flight the live aggregate has no outcome while the document may still hold the previous failure — the fallback showed the stale one. Live summaries now take the live aggregate's answer alone; the restored outcome is already seeded there on resume. |
||
|
|
e6e4ba2357
|
chore: sync web dist from code-app (#2697)
* chore: sync web dist from code-app * chore: add changesets for the synced web UI changes * chore: drop changesets already covered by the previous web bundle sync * chore: correct the drop-folder changeset for web * chore: drop the drop-folder changeset (desktop-only feature, no web announcement) |
||
|
|
02c026d487
|
feat(agent-core-v2): tombstone removed MCP servers and freeze plugin prompt inputs (#2694)
* feat(mcp): tombstone removed MCP servers and apply plugin changes immediately (20 files) - add 'removed' MCP server status: workspace config removals call markRemoved instead of remove, keeping tool registrations alive while short-circuiting calls with a removal notice - fire onDidReload after every plugin mutation (install/enable/disable/remove) so workspace consumers refresh contributions immediately - TUI renders the removed status in the MCP panel/startup summary and shows an apply-immediately hint on the v2 engine * feat(agent-core-v2): freeze plugin prompt inputs for live agents (2 files) - snapshot the model skill listing and plugin system-prompt sections on the first successful prompt build and reuse the frozen values for the agent's lifetime, so plugin install / enable / disable / remove / reload never rewrites a live agent's prompt (same keep-live-sessions-stable philosophy as the MCP tombstone) - freeze only on success: a not-yet-ready skill catalog or a failed enabledSystemPrompts() read must not pin empty values for the agent's lifetime - refreshSystemPrompt still rebuilds on catalog change events but reuses the frozen values, so the prompt only moves when non-plugin inputs change (AGENTS.md, [tools] section, session tool policy, compaction); new agents snapshot the then-current state * chore(changeset): add changesets for MCP tombstone and frozen plugin prompt inputs * docs: describe immediate plugin changes and the removed MCP status on the v2 engine * fix(klient): mirror the removed MCP server status in the wire contract * docs: drop the legacy-engine behavior notes from the plugin and MCP pages * fix(agent-core-v2): freeze plugin sections only on a loaded snapshot - enabledSystemPrompts() resolves to its consumption fallback (never rejects) while the initial plugin load has failed; freezing that empty read locked plugin sections out of the live agent even after a later successful reload - expose hasLoadedSnapshot() on IPluginService so resolvePluginSections can tell a real empty snapshot from the fallback before freezing |