Skip to content

feat(agent-core): custom agent files and secondary model on the v1 engine - #2232

Merged
7Sageer merged 31 commits into
mainfrom
v1-subagent
Jul 29, 2026
Merged

feat(agent-core): custom agent files and secondary model on the v1 engine#2232
7Sageer merged 31 commits into
mainfrom
v1-subagent

Conversation

@7Sageer

@7Sageer 7Sageer commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained in the next section.

Problem

Custom agents (Markdown agent files) and the secondary model for subagents were only available on the v2 engine (kimi web / experimental kimi -p). Sessions on the default engine — the interactive TUI and plain kimi -p — could not discover or delegate to custom agents, override the main agent's system prompt via SYSTEM.md, select the main agent with --agent/--agent-file, or bind subagents to a cheaper secondary model. This PR migrates both capabilities to the v1 engine with full v2 semantics.

What changed

Custom agent files on v1

  • New profile/agentfile/ module: frontmatter parsing (shared with the skill parser; Claude Code comma-list and OpenCode file-name fallback compatible), user/extra/project/explicit discovery roots mirroring skill discovery, per-source priority merge, override: true gate before a file replaces a same-name builtin, SYSTEM.md main-prompt override, and dead-pattern warnings (bare *, incomplete mcp__ literals, unknown tool names).
  • SessionAgentProfileCatalog merges builtin and file profiles. ${base_prompt} binds to an "effective default" slot (the SYSTEM.md override when present, else the builtin default); the slot is structurally disjoint from the merge, so a file that overrides the default cannot recurse into itself. The delegation graph links file profiles' subagents allowlists and extends the default profile's delegatable set with custom agents.
  • Session integration: catalog loading rides the existing skills readiness gate (an invalid --agent-file fails session creation); the three hardcoded DEFAULT_AGENT_PROFILES lookups (subagent host, persisted-profile restore, Agent tool description) now read the catalog.
  • CLI/SDK: --agent/--agent-file work in print mode on either engine (the TUI still rejects them, matching v2); CreateSessionOptions gains agentProfile/agentFiles.

Secondary model on v1 (experimental flag)

  • [secondary_model] config section (a model pointer plus model patch fields) with KIMI_SECONDARY_MODEL/KIMI_SECONDARY_EFFORT env overlays; a recipe with patch fields synthesizes an in-memory __secondary__ derived entry that is stripped on write and never reaches config.toml.
  • Spawn binding with three-level precedence (tool-call model > profile model_preference > configured secondary default), upfront validation via the provider manager with a wrapped error pointing at [secondary_model]; with the flag on, resume/retry keeps the subagent's bound model (v2 semantics), and with the flag off, inheritance behavior is unchanged.
  • The Agent/AgentSwarm tools gain a primary|secondary model parameter (available models advertised in the tool description); startup validation surfaces secondary-model-invalid / secondary-model-effort-not-listed through the existing session warnings channel.
  • Full disallowedTools deny semantics: exact names and mcp__ glob patterns evaluated by the tool manager against resolved tool names (partial server denies like mcp__github__* work under a broad mcp__* allow). The deny list persists in the agent wire as an additive optional field (old records and older binaries are both compatible), so resumed agents keep the denylist.
  • The interactive TUI gains a /secondary_model command (mirrors /model: a picker with a thinking-effort step) that persists [secondary_model] and live-applies to the current session via Session.applyPersistedSecondaryModel (node-sdk wrapper included), so newly spawned subagents bind the new model right away. The /model picker hides the synthesized __secondary__ derived entry, and the update-config builtin skill now lists the section.
  • Running subagents surface their bound model in the TUI: the spawned agent's agent.status.updated carries its model alias, which the tool-call subagent stats and agent-group rows resolve to a display name.

Verification: full agent-core suite green (4075 tests, ~60 new cases covering parser/discovery/catalog merge/${base_prompt} chain/secondary config round-trip/spawn binding/tool deny/wire replay/session secondary-model override); kimi-code options, run-prompt, and TUI suites green (2401 tests, including the /secondary_model command and the subagent model display); end-to-end smoke on the v1 engine (custom agent discovery, --agent selection, invalid --agent-file failure). Docs updated in both English and Chinese.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • 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.

…gine

Migrate the custom agentfile and secondary-model capabilities from
agent-core-v2 to the v1 engine so they work in the TUI and plain
kimi -p sessions:

- discover Markdown agent files from user/project/extra/explicit
  directories with the v2 precedence rules, a merged session profile
  catalog replacing the hardcoded builtin profile lookups, SYSTEM.md
  main prompt override, and ${base_prompt} backed by the effective
  default
- --agent/--agent-file now work in print mode on the default engine;
  CreateSessionOptions gains agentProfile/agentFiles
- [secondary_model] config + KIMI_SECONDARY_MODEL/EFFORT bind newly
  spawned subagents to a cheaper model behind the secondary-model
  experiment flag, with primary/secondary model params on Agent and
  AgentSwarm and upfront session warnings
- full disallowedTools deny semantics (exact names + mcp__ globs)
  evaluated by the tool manager and persisted in the agent wire
@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e83cd85

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 Minor

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 Jul 27, 2026

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

commit: e83cd85

7Sageer and others added 27 commits July 27, 2026 13:27
runPrompt is also driven programmatically (headless goal flow) with
options that never pass through the CLI parser defaults, so agentFiles
can be undefined; mirror the addDirs optional-chaining pattern. Also
extend the SDK experimental-feature assertion with the secondary-model
flag.
Signed-off-by: 7Sageer <sag77r@hotmail.com>
Signed-off-by: 7Sageer <sag77r@hotmail.com>
Signed-off-by: 7Sageer <sag77r@hotmail.com>
Signed-off-by: 7Sageer <sag77r@hotmail.com>
The resume path only forwards the agent file's name for the bound-profile
assertion; the file's content is never re-applied (the session keeps its
creation-time catalog snapshot). Previously the combination was silently
accepted, so an edited file (or a same-named one) appeared to apply but did
not. Reject it at option validation and document the constraint.
… agentfile headers

The Windows notes, additional-dirs and skills prose blocks existed twice:
inline in the builtin default template (system.md) and as constants in the
agent-file renderer (from-file.ts). Extract them to profile/prompt-sections.ts
as the single source: system.md renders them through injected KIMI_* template
variables and from-file.ts imports the same constants. Rendered prompts are
byte-identical for all four builtin profiles across macOS/Windows and
skills/dirs on/off; a new test pins system.md to the shared constants.

Also mark each profile/agentfile file with the path of its agent-core-v2
counterpart so format/semantics changes land in both engines.
Mirror /model: a picker with a thinking-effort step that persists [secondary_model] and live-applies to the current session via a new Session.setSecondaryModel RPC (node-sdk wrapper included), so newly spawned subagents bind the new model right away. The /model picker now hides the synthesized __secondary__ derived entry; docs and the update-config builtin skill mention the section.
Subagents report their model alias via agent.status.updated after spawn; resolve it to a display name and surface it in tool-call subagent stats and agent-group rows.
Show each subagent's model in the subagent card header and agent-group rows. Requires the secondary-model experiment (KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1); run /secondary_model to pick a model and thinking effort, applied to the current session immediately.

Signed-off-by: 7Sageer <sag77r@hotmail.com>
Bind the selected agent profile to the startup session when launching
the TUI with --agent/--agent-file, including the session created after
an OAuth login at startup. Sessions created later in the process (/new)
keep the default profile.

Make both flags creation-only in every mode: combining them with
--session/--continue is now rejected in print mode too, since resume
restores the bound agent from the session automatically.
…rrides

stripSecondaryModelConfig restored secondary_model.model/default_effort
from raw whenever KIMI_SECONDARY_MODEL/KIMI_SECONDARY_EFFORT was set, so
a /secondary_model pick made under the env vars was silently discarded
on write. Restore from raw only when the value being written still
equals the env value (an overlay round-trip), mirroring the pointer
check in stripEnvModelConfig; a genuinely different selection now
reaches config.toml.
7Sageer added 3 commits July 28, 2026 13:09
… pick

/secondary_model toasted the picked alias even when
KIMI_SECONDARY_MODEL/KIMI_SECONDARY_EFFORT made the session bind a
different model. Read the effective binding back from the reloaded
config (as /model does from session status) and warn with the
env-overridden values instead.
# Conflicts:
#	apps/kimi-code/src/cli/run-shell.ts
@7Sageer
7Sageer merged commit efac96c into main Jul 29, 2026
13 of 14 checks passed
@7Sageer
7Sageer deleted the v1-subagent branch July 29, 2026 04:06
@github-actions github-actions Bot mentioned this pull request Jul 29, 2026
zicochaos added a commit to zicochaos/kimi-code that referenced this pull request Jul 29, 2026
…odel/agentfile (MoonshotAI#2232)

Syncs 30 upstream commits. Upstream MoonshotAI#2232 ported custom agent files +
secondary-model binding to the v1 engine, covering the fork's exact-alias
subagent model selection (fb6d57c) and subagent model surfacing
(353a1c5) — so the fork's v1-side implementation is retired in favor of
upstream's:

- v1 collision files restored to upstream (agent/agent-swarm tools,
  subagent-host, tool registry, flags, docs); fork's v1
  subagent-model-directory.ts dropped as dead code
- TUI subagent model display deduplicated onto upstream's stats placement
  (agent-group, tool-call); fork's per-row model chip removed
- config schema/toml unions keep the fork's disabledSkills alongside
  upstream's extraAgentDirs
- footer quota readout ported onto upstream's slot-based footer
  (status_line); managed-usage rows adapted to upstream's structured
  ManagedUsageRow shape (window/name, no label)
- node-sdk getSessionWarnings passes pathClass for the fork's AGENTS.md
  include expansion
- state manifest regenerated

Fork-unique deltas kept: disabled_skills denylist (PR MoonshotAI#1983 upstream),
session-only default model, managed plan quota display, AGENTS.md include
expansion, v2-side subagent model selection, misc fixes.

Review follow-ups (PR #12):

- v1 subagent-host + node-sdk getSessionWarnings: thread
  agentsMdExpandIncludes through spawned-subagent and warning prompt
  contexts (with a subagent-host test covering include expansion)
- TUI: keep the status-derived subagent model when later events carry no
  model (subagent-event-handler, tool-call); AgentSwarm header shows a
  shared model only when all reported members agree (setMemberModel)
- kap-server subagentRosterTracker learns the model from
  agent.status.updated; kimi-web agentEventProjector projects it onto the
  task
- lint: drop useless spread in skillCatalogService; FORK.md + config docs
  note the v1 exact-alias retirement (v2-only)
zicochaos added a commit to zicochaos/kimi-code that referenced this pull request Jul 29, 2026
chore: merge upstream main (f8ec3d1) and adopt upstream secondary-model/agentfile (MoonshotAI#2232)
Pidbid added a commit to Pidbid/kkm that referenced this pull request Jul 30, 2026
* feat(agent-core): custom agent files and secondary model on the v1 engine (MoonshotAI#2232)

* feat(agent-core): custom agent files and secondary model on the v1 engine

Migrate the custom agentfile and secondary-model capabilities from
agent-core-v2 to the v1 engine so they work in the TUI and plain
kimi -p sessions:

- discover Markdown agent files from user/project/extra/explicit
  directories with the v2 precedence rules, a merged session profile
  catalog replacing the hardcoded builtin profile lookups, SYSTEM.md
  main prompt override, and ${base_prompt} backed by the effective
  default
- --agent/--agent-file now work in print mode on the default engine;
  CreateSessionOptions gains agentProfile/agentFiles
- [secondary_model] config + KIMI_SECONDARY_MODEL/EFFORT bind newly
  spawned subagents to a cheaper model behind the secondary-model
  experiment flag, with primary/secondary model params on Agent and
  AgentSwarm and upfront session warnings
- full disallowedTools deny semantics (exact names + mcp__ globs)
  evaluated by the tool manager and persisted in the agent wire

* fix(cli): guard optional agentFiles in the prompt runner

runPrompt is also driven programmatically (headless goal flow) with
options that never pass through the CLI parser defaults, so agentFiles
can be undefined; mirror the addDirs optional-chaining pattern. Also
extend the SDK experimental-feature assertion with the secondary-model
flag.

* fix(agent-core): preserve custom agent bindings on v1

* fix(agent-core): narrow secondary model error hints

* fix(agent-core): persist custom agent profile bindings

* Delete .changeset/sdk-agent-profile-options.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* Update v1-custom-agent-files.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* Update v1-secondary-model.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* Update v1-custom-agent-files.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* fix(agent-core): keep SYSTEM.md a prompt-only overlay for delegation

* docs: update agent file and secondary model availability wording

* fix(cli): reject --agent-file combined with session resume

The resume path only forwards the agent file's name for the bound-profile
assertion; the file's content is never re-applied (the session keeps its
creation-time catalog snapshot). Previously the combination was silently
accepted, so an edited file (or a same-named one) appeared to apply but did
not. Reject it at option validation and document the constraint.

* refactor(agent-core): share prompt-section prose and note v2 twins in agentfile headers

The Windows notes, additional-dirs and skills prose blocks existed twice:
inline in the builtin default template (system.md) and as constants in the
agent-file renderer (from-file.ts). Extract them to profile/prompt-sections.ts
as the single source: system.md renders them through injected KIMI_* template
variables and from-file.ts imports the same constants. Rendered prompts are
byte-identical for all four builtin profiles across macOS/Windows and
skills/dirs on/off; a new test pins system.md to the shared constants.

Also mark each profile/agentfile file with the path of its agent-core-v2
counterpart so format/semantics changes land in both engines.

* feat(cli): add /secondary_model command for the subagent model

Mirror /model: a picker with a thinking-effort step that persists [secondary_model] and live-applies to the current session via a new Session.setSecondaryModel RPC (node-sdk wrapper included), so newly spawned subagents bind the new model right away. The /model picker now hides the synthesized __secondary__ derived entry; docs and the update-config builtin skill mention the section.

* feat(tui): show the bound model in subagent run stats

Subagents report their model alias via agent.status.updated after spawn; resolve it to a display name and surface it in tool-call subagent stats and agent-group rows.

* fix(agent-core): validate agent profile before session persistence

* fix(agent-core): refresh subagent tools after model switch

* fix(agent-core): show subagent model preferences

* fix(agent-core): preserve secondary model recipe on live apply

* fix(agent-core): make secondary model apply explicit

* fix(tui): refresh secondary model display state

* chore: merge secondary model changesets into one

* Add /secondary_model command for subagent configuration

Show each subagent's model in the subagent card header and agent-group rows. Requires the secondary-model experiment (KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1); run /secondary_model to pick a model and thinking effort, applied to the current session immediately.

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* fix(agent-core): align explicit agent file precedence

* fix(agent-core): let disallowedTools deny select_tools

* chore(cli): drop engine mention from --agent/--agent-file help text

* feat(cli): support --agent/--agent-file in the interactive TUI

Bind the selected agent profile to the startup session when launching
the TUI with --agent/--agent-file, including the session created after
an OAuth login at startup. Sessions created later in the process (/new)
keep the default profile.

Make both flags creation-only in every mode: combining them with
--session/--continue is now rejected in print mode too, since resume
restores the bound agent from the session automatically.

* fix(agent-core): persist new secondary-model selections under env overrides

stripSecondaryModelConfig restored secondary_model.model/default_effort
from raw whenever KIMI_SECONDARY_MODEL/KIMI_SECONDARY_EFFORT was set, so
a /secondary_model pick made under the env vars was silently discarded
on write. Restore from raw only when the value being written still
equals the env value (an overlay round-trip), mirroring the pointer
check in stripEnvModelConfig; a genuinely different selection now
reaches config.toml.

* fix(cli): report the effective secondary model when env overrides the pick

/secondary_model toasted the picked alias even when
KIMI_SECONDARY_MODEL/KIMI_SECONDARY_EFFORT made the session bind a
different model. Read the effective binding back from the reloaded
config (as /model does from session status) and warn with the
env-overridden values instead.

* feat(tui): show the bound model name in the AgentSwarm panel header

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
(cherry picked from commit efac96c)

* fix(node-sdk): wire applyPersistedSecondaryModel to agent-core-v2 (MoonshotAI#2345)

* test(node-sdk): drop v1-only subagentNames from the resume parity projection

Custom agent files made v1's resumed agent config carry the bound
profile's delegatable subagent roster; v2's resumed agent state has no
equivalent field, so the resume parity cases fail on main. Project the
engine-owned field away instead of pinning it as a resume-data gap.

* fix(node-sdk): wire applyPersistedSecondaryModel to agent-core-v2

On the v2 engine route the /secondary_model command persisted the recipe
but failed to apply it to the current session: the SDK method fell
through to the base class's not_implemented getRpc().

v1 pushes a reloaded config snapshot into the session because its spawn
binding, tool descriptions, and cached startup warning all read that
snapshot. agent-core-v2 resolves the secondary model live against
IConfigService at spawn time and rebuilds the tool description per read,
so the setConfig write already takes effect session-wide. The override
keeps the rest of v1's contract: config reload, the same loud
validations (session lookup, persist-first recipe check, pointed-model
resolution wrapped at [secondary_model].model), and a warning-cache
refresh via a new recheckSecondaryModelWarning on the session warning
service. getSessionWarnings also surfaces the v2 secondary-model warning
next to the AGENTS.md one, matching v1's aggregate.

* fix(agent-core-v2): surface the subagent's bound model on status events

The v2 model slice rides only the bind-time agent.status.updated, which
precedes subagent.spawned and is dropped by clients that key child events
off the spawn, so subagent cards never learned the model — and a
single-step run emits no usage/context slice until it ends, so the model
only appeared at completion. Re-affirm the binding right after the spawn
announcement via a new IAgentProfileService.republishStatus, and fold a
consistent usage/context/model snapshot into every status event at both
v1 edges (kap-server's broadcaster and the in-process SDK session
wiring, resolving the secondary-model derived id to a readable display
name.
EOF
)

* Delete .changeset/subagent-card-model.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* style(agent-core-v2): remove inline implementation comments

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
(cherry picked from commit b850c5f)

* docs: fix dead anchor links in en/zh docs (MoonshotAI#2348)

* docs: fix dead anchor links in en/zh docs

- #loop_control -> #loop-control (heading slug uses hyphens)
- #secondary_model -> #secondary-model
- env-vars model section anchors: kimi_model -> kimi-model
- provider credential section anchors: configtoml -> config-toml
- /provider management anchors: point at the renamed heading in each locale
- hooks: point the stale config-files#hooks reference at the local Configuration section
- en files: replace two leftover Chinese anchors with their English targets

* docs: add missing .md extension to themes page links

---------

Co-authored-by: qer <wbxl2000@outlook.com>
(cherry picked from commit f8ec3d1)

* feat(agent-core-v2): let plugins contribute system prompt instructions via the manifest systemPrompt field (MoonshotAI#2314)

* feat(agent-core-v2): let plugins contribute system prompt instructions via the manifest systemPrompt field

* feat(agent-core-v2): add systemPromptPath to load plugin system prompt from a file

* docs: explain plugin system prompt templates

* fix(agent-core-v2): refresh plugin system prompts after changes

* fix(agent-core-v2): freeze restored profile bindings and converge plugin contributions at session scope

- restore no longer re-renders or re-persists prompts: a resumed agent
  keeps its replayed profile binding (prompt and tool set) as persisted
- a new Session-level convergence point reloads plugin skills into the
  session skill catalog before fanning out to every live agent prompt,
  and every catalog-kind plugin mutation awaits the whole pipeline;
  MCP-only toggles carry a distinct change kind and skip it
- live refreshes after a restart re-resolve the bound profile by name
  and rebind the full slice (prompt, disallowed tools, active tools)
  atomically, warning and keeping the persisted state when the profile
  is gone; renders reuse the first-render timestamp and unchanged
  prompts are not re-persisted, so convergence never churns the wire
- cap plugin system-prompt contributions (32 KB per field/file, 64 KB
  aggregate per prompt build) with manifest diagnostics and warnings
- bump the changeset to minor: this is a new user-facing capability

* fix(agent-core-v2): register the new session domain and dedupe the missing-profile warning

- add sessionPluginContribution to the domain-layer registry so
  lint:domain stays green
- emit system-prompt-refresh-profile-missing once per profile name,
  matching the service's other deduped warnings
- document the convergence timeout escape hatch and the klient
  exclusion of enabledSystemPrompts

* fix(agent-core-v2): dedupe the plugin budget warning and surface section read failures

- emit plugin-sections-oversized once per skipped-plugin signature
- let enabledSystemPrompts failures propagate to the refresh catch
  (keeps the current prompt and warns) instead of silently rendering
  and persisting a prompt without plugin instructions
- cover the convergence timeout cut-off with a fake-timers test
- clarify that the first-render timestamp anchors per process

* fix(agent-core-v2): serialize session convergence and restore onDidReload timing

- run at most one convergence per session and bound each change's wait
  by the timeout, so a fan-out emitter never interleaves deliveries
  after a timed-out convergence
- fire onDidReload as soon as the reload commits again, keeping hook
  reloads independent of prompt convergence
- sign the plugin budget warning with an unambiguous key

* docs(agent-core-v2): align convergence wording with the serialized semantics

- the timeout retry promise only holds once stalled work clears
- note the per-session serial delivery cost model on the plugin change
  contract and the dual-queue invariant on the service

* fix(agent-core-v2): keep empty plugin sections byte-neutral in the prompt template

- place ${plugin_sections} on the same template line as
  ${skills_section} so prompts without either block render exactly as
  before this feature
- note on the change contract that waitUntil work must not call back
  into plugin mutations, and spell out the per-session convergence
  order in the user docs

* fix(agent-core-v2): pin a fork's profile so refresh triggers never rebind it

- applyBindingSnapshot left the fork with no pinned profile, which
  routed in-process forks into the post-restart catalog rebind and
  could reset an inherited tool set; forks now inherit the source
  agent's pinned profile object
- pin the first-render timestamp reuse with a ${now}-embedding test
  and document the anchored ${now} semantics
- tighten the plugin docs budget and resume-refresh wording

* fix(agent-core-v2): join in-flight convergence during agent bootstrap

- an agent created while a plugin convergence is in flight now waits
  for it, and a restored agent refreshes once after it, so a plugin
  mutation never straddles an agent's bootstrap
- warn on a non-string systemPrompt field and strip a UTF-8 BOM from
  systemPromptPath files before trimming
- correct the consumption-surface wording (every CLI surface on the
  experimental flag, not just kimi -p), the per-session queueing note,
  and the single-plugin combined budget clause

* fix(agent-core-v2): bound the bootstrap convergence join by the timeout

A permanently wedged convergence kept convergeTail pending forever,
and the unconditional settled() wait in bindBootstrap would have
blocked every later agent creation in that session; the join now
races the shared convergence timeout and continues (a restored agent
still refreshes once, which never touches the tail), and the timeout
constant moves to the contract for reuse

* fix(agent-core-v2): close the convergence race against in-progress restores

- a convergence fan-out could land while an agent's wire log is still
  replaying, dispatching a replay-visible config record whose effect
  the rest of the replay then overwrites; refreshSystemPrompt now
  skips while the wire restore is in progress
- convergence completion is tracked by a generation counter; bootstrap
  compares it (after a bounded join) and refreshes a restored agent
  exactly once when a round completed after its creation began,
  replacing the wasConverging flag that could miss both windows

* fix(agent-core-v2): bound each convergence so a wedged participant cannot stop the pipeline

- the fan-out now races the convergence timeout, so convergeTail always
  settles: a permanently hung refresh delays its round (blocked entries
  drain oldest-first on later changes) instead of killing the session's
  convergence for good
- warn when agent bootstrap stops waiting on a stalled convergence
- diagnose a blank systemPromptPath and pin the plugin-root escape
  guard with traversal, absolute-path, and symlink tests

* fix(agent-core-v2): bound the skill reload, preserve user-tool overlays, roll the prompt clock daily

- the convergence's skill-reload segment now races the same timeout as
  the fan-out, so no segment of the pipeline can wedge a session for
  good; it continues with the previous catalog and retries next change
- a cold rebind that resets the tool set replays session-added user
  tools onto the new base instead of dropping them for the rest of the
  process
- the rendered timestamp re-anchors when the UTC date rolls over, so
  long-lived processes keep a fresh clock while steady-state renders
  stay byte-stable within a day
- the plugin budget warning dedupes per plugin id, and the docs note
  that systemPromptPath content is frozen until the next reload

* feat(agent-core-v2): converge cold plugin changes on resume through a drift-free gate

- restore replays the persisted binding untouched, then bootstrap
  refreshes only when drift-free inputs changed while the session was
  cold: the catalog profile's tool set/denylist, or the plugin-sections
  baseline persisted alongside the prompt on the existing bind/update
  payloads; directory-listing and date drift wait for live triggers,
  so quiet resumes append no replay-visible records
- the rendered timestamp is day-precision (UTC date at 00:00,
  re-anchored on rollover), keeping steady-state renders byte-stable
  across resumes and sessions on the same day
- consolidate both timeout helpers onto a shared raceOutcome, and drop
  the generation counter the gate supersedes
- align the plugin-sections precedence prose with the AGENTS.md
  disclaimer (no self-granted authority, system instructions win on
  conflict)

* fix(agent-core-v2): bound the restored-prompt gate and land the sections baseline

- the gate's plugin-sections read now races the convergence timeout, so
  agent creation never blocks behind an unrelated plugin mutation
- refreshes serialize per agent through a tail, so overlapping triggers
  cannot write prompts out of order
- when plugin sections change but a plugin-free custom prompt does not,
  the new baseline lands as a sections-only update instead of making
  every later resume re-render in vain
- align the system prompt's Date and Time paragraph with the
  day-precision anchored timestamp

* Update plugin system-prompt instructions in changeset

Live sessions pick up plugin changes, while the default TUI and `kimi -p` paths ignore these fields.

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* refactor(agent-core-v2): keep plugin skill reload user-driven

Plugin mutations still converge live agent prompts, but the session
skill catalog goes back to refreshing only on explicit plugin reload,
as before: the prompt feature does not need skill convergence, and the
pre-existing manual-reload semantics stay uniform across all plugin
contributions. Removes the convergence-driven skill reload, the
reloadSource de-privatization, and their tests; restores the
PluginSkillSource onDidReload forwarding and its catalog tests.

* refactor(agent-core-v2): apply plugin system-prompt changes only on explicit reload

Drop the live convergence machinery (the plugin onDidChange barrier,
the sessionPluginContribution fan-out, the restored-prompt drift gate,
and the day-precision render clock) so plugin system-prompt sections
take effect at the same point as every other plugin contribution:
/plugins reload or a new session. The profile now refreshes when the
session skill catalog re-pulls its plugin source on reload, reading
both the skill list and the prompt sections fresh.

* feat(agent-core): let plugins contribute system prompt instructions via the manifest systemPrompt field

* chore(agent-core-v2): remove inline implementation comment

* docs: clarify plugin prompt refresh semantics

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
(cherry picked from commit 02d77b2)

* feat: support plugin-contributed custom agents (MoonshotAI#2365)

* feat: support plugin-contributed custom agents

* fix: await plugin loading before agent catalog

* fix: refresh plugin agents on v1 reload

* test(agent-core-v2): add enabledSystemPrompts to the plugin service stub

(cherry picked from commit fa2c5ce)

* fix: remove the blocking wait from the TaskOutput tool (MoonshotAI#2379)

* fix: remove the blocking wait from the TaskOutput tool

The block/timeout parameters let a model stall the whole turn waiting
for a background task (up to 3600s), even though completion already
arrives via automatic notification. Remove both parameters from the v1
and v2 engines (kept in model-facing parity), simplify retrieval_status
to success/not_ready, and update the tool, Bash, and Agent prompt
wording plus user docs accordingly. Stale callers passing block are
silently treated as a non-blocking snapshot.

* fix: align background-task prompts with the non-blocking TaskOutput

The compaction reminder promised TaskOutput could fetch a task's result
for tasks that are still running, where it now returns not_ready —
reword it to snapshot semantics and point at the completion
notification. Also list AskUserQuestion(background=true) as a task
source in the TaskOutput description.

* test: exercise stale TaskOutput args through the runtime validator

A stale block/timeout argument never reaches the tool: the executor's
preflight validates args against the closed tool schema and rejects
them immediately, so the old test documented silent-tolerance semantics
the runtime never exhibits. Assert the real behavior through
compileToolArgsValidator/validateToolArgs instead, and drop
statement-adjacent comments to match the package's header-only comment
convention.

(cherry picked from commit 691ec46)

* fix(vscode): all AskUserQuestions should be answered and added to the context

(cherry picked from commit 3bbc3c5)

* fix(vscode): open plan files from review

(cherry picked from commit 729e69f)

* fix(vscode): bind plan reviews to their files

(cherry picked from commit f6b7f45)

* fix(agent-core-v2): honor configured permission rules

(cherry picked from commit ee0cc67)

* fix(anthropic): omit incompatible tool schemas

(cherry picked from commit 4e9ffbb)

* fix(agent-core-v2): rescan agent profile catalog when a dispatch lookup misses

Long-lived sessions (e.g. hosted by kimi web) scan agent file directories
once at session materialization, so agent Markdown files written afterward
can never be dispatched: the Agent tool, AgentSwarm tool, and swarm spawn
path all fail with "Unknown agent type" until the server restarts.

Add getProfileOrReload(), a small lookup helper in the
sessionAgentProfileCatalog domain: on a miss it calls the catalog's
existing (previously unwired) reload() once — deduped across concurrent
misses — and retries before the caller's original error path applies.
The three dispatch sites read the catalog live, so a rescan is visible
to existing sessions immediately; the happy path is unchanged.

(cherry picked from commit 27c4342)

* fix(tui): refresh task output previews

(cherry picked from commit 5d56451)

* fix(tui): stop polling completed task output

(cherry picked from commit 1a6df5b)

* fix(tui): preserve final task output refresh

(cherry picked from commit 56e7a72)

* fix(tui): stop polling newly completed task output

(cherry picked from commit ebe87b6)

* fix(kimi-web): follow window width for the chat column

The reading column was capped at 760px, leaving wide empty margins on large screens. Let it follow the pane width instead.

(cherry picked from commit b6d88b5)

* fix(kimi-web): swallow Ctrl+S in the composer to block the Save Page dialog

preventDefault ran only while a turn was running, so an idle Ctrl+S/Cmd+S fell through to the browser and opened the Save Page dialog. Always swallow the shortcut; steering still only fires when a turn is running.

(cherry picked from commit 7e44ece)

* fix(kimi-web): anchor the conversation outline to the pane's right edge

With the reading column no longer capped at a fixed width, the outline rail's old anchor (the 760px column edge) left it floating in the middle of the widened content. Pin the rail to the pane's right edge inside the scrollbar gutter, reveal labels leftward over the content on hover, and measure the expanded fit in that direction.

(cherry picked from commit 6edc9c0)

* fix(kimi-web): swallow Ctrl+S app-wide so the browser never opens Save Page

The composer's keydown only fires while the composer is focused, so a Ctrl+S/Cmd+S pressed anywhere else still fell through to the browser's Save Page dialog. A capture-phase preventDefault in App.vue's global keydown now swallows the shortcut everywhere; steering stays in the composer's handler.

(cherry picked from commit 0d9835e)

* fix(kimi-web): keep code font metrics in bare markstream code blocks

Plain-text code blocks rendered without the container wrapper nest <code> deeper than pre > code, so the inline-code chip rule (font: .9em) applied inside them and shrank the code to 10.8px/normal while the line-number overlay stayed at 12px/18px — the numbers drifted progressively below their lines. Extend the font:inherit guard to all markstream pres.

(cherry picked from commit c1eab79)

* fix(kimi-web): drop the TOC hover bridge and uncap the design-system demo

The rail's invisible hover bridge sat over the right edge of full-width content and intercepted clicks and text selection from the messages beneath it; only the actual outline rows receive pointer events now. Also drop the 560px cap from the design-system chat demo so the spec matches the full-width behavior.

(cherry picked from commit d78caaf)

* Infer the Anthropic wire from a provider's /anthropic endpoint path

The models.dev catalog resolver decided a provider's wire from type/npm/id
only. A provider exposing its Anthropic-compatible surface under a /anthropic
path, without an explicit type or an anthropic/claude token in npm/id, fell
through to the OpenAI-compatible fallback and persisted the Anthropic endpoint
under the OpenAI wire. Infer the Anthropic wire from a /anthropic endpoint path
segment (matched on the path only), in both lockstep copies of the resolver,
with unit and import-integration coverage.

(cherry picked from commit 83e27aa)

* fix(agent-core): nudge todo reconciliation when a turn ends with unfinished todos

(cherry picked from commit aae8d7f)

* fix(agent-core): honor same-turn TodoList writes in the turn-end reminder

Addresses review feedback: the turn-end check now scans the whole
just-finished turn (back to the user prompt that started it) for a TodoList
write, so a mid-turn update followed by a closing text reply no longer
triggers a spurious reminder. Also adds the required changeset.

(cherry picked from commit 81f48ee)

* fix(kap-server): defer global search activation

(cherry picked from commit b514266)

* fix(tui): preserve quotes in Windows status line commands

(cherry picked from commit a555f1f)

* test(tui): stabilize Windows quote regression

(cherry picked from commit b7f549e)

* fix(agent-core-v2): preserve select_tools for disclosure

(cherry picked from commit a361352)

* test(agent-core-v2): align optional harness option

(cherry picked from commit bb3d4c8)

* fix(tui): bound completed shell output frames

(cherry picked from commit 6fb6bac)

* feat(hooks): expose effective permission mode

(cherry picked from commit 2dd7d01)

* fix(mcp): reinitialize expired HTTP sessions

(cherry picked from commit e03fd73)

* fix(acp): stream agent-initiated turns

(cherry picked from commit 0d7614c)

* chore: prepare kkm 0.30.0 portable upstream release

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
Co-authored-by: 7Sageer <sag77r@hotmail.com>
Co-authored-by: wenhua020201-arch <wenhua020201@gmail.com>
Co-authored-by: qer <wbxl2000@outlook.com>
Co-authored-by: Kai <me@kaiyi.cool>
Co-authored-by: rickgao <rickgao@tencent.com>
Co-authored-by: zhaojy <zhaojy01@rd.netase.com>
Co-authored-by: ericzhao.zhao <ericzhao.zhao@cyberklick.com>
Co-authored-by: gunnlace <docdoby14470814@163.com>
Co-authored-by: Ben Younes <benyounes.ousama@gmail.com>
Co-authored-by: lostforwurdz <222525123+lostforwurdz@users.noreply.github.com>
Co-authored-by: Tolik Trek <tolik.trek@gmail.com>
Co-authored-by: octo-patch <266937838+octo-patch@users.noreply.github.com>
Co-authored-by: airudotsh <airudotsh@users.noreply.github.com>
Co-authored-by: Xule Lin <43122877+linxule@users.noreply.github.com>
Co-authored-by: luren <lurenjia534@outlook.com>
Co-authored-by: Codex <codex@openai.com>
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