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
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)
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