From c27184d82e2fb57117fec644a6e7a5eded8bb559 Mon Sep 17 00:00:00 2001 From: Mark Buckaway Date: Thu, 10 Sep 2026 19:05:45 -0400 Subject: [PATCH] fix: restore swarm preference and add default_swarm_mode The 0.39.1 upstream sync stripped the proactiveness/action directives from both engines' system prompts (upstream #3028) and made swarm mode per-session (upstream #3433), which left the agent preferring sequential Agent subagent tasks over the parallel AgentSwarm tool even with swarm mode enabled, and the task path appeared to ignore coding standards. Restore the removed directives and add explicit swarm-preference and subagent-rules guidance to both system prompts, and add a default_swarm_mode config option (v1 + v2 engines + protocol) so new sessions can start in swarm mode. --- .changeset/restore-swarm-preference.md | 5 + docs/en/configuration/config-files.md | 1 + docs/zh/configuration/config-files.md | 1 + fork/PATCHES.md | 1 + .../agent-core-v2/docs/config-manifest.toml | 11 ++- .../src/app/agentProfileCatalog/system.md | 11 ++- .../src/features/swarm/configSection.ts | 10 ++ .../sessionLifecycleService.ts | 10 ++ .../sessionLifecycle/sessionLifecycle.test.ts | 93 +++++++++++++++++++ packages/agent-core/src/config/schema.ts | 2 + packages/agent-core/src/config/toml.ts | 1 + .../agent-core/src/profile/default/system.md | 11 ++- packages/agent-core/src/rpc/core-impl.ts | 3 + .../src/services/config/configService.ts | 1 + packages/protocol/src/rest/config.ts | 2 + 15 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 .changeset/restore-swarm-preference.md diff --git a/.changeset/restore-swarm-preference.md b/.changeset/restore-swarm-preference.md new file mode 100644 index 00000000000..16a57dcab92 --- /dev/null +++ b/.changeset/restore-swarm-preference.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Restore the preference for parallel swarm work over single sequential subagent tasks, and add a `default_swarm_mode` config option so new sessions can start in Swarm mode. diff --git a/docs/en/configuration/config-files.md b/docs/en/configuration/config-files.md index 8009f2fcbc2..c3ba3354e21 100644 --- a/docs/en/configuration/config-files.md +++ b/docs/en/configuration/config-files.md @@ -104,6 +104,7 @@ Fields in the config file fall into two categories: **top-level scalars** that d | `planning_model` | `string` | — | Model alias used while Plan mode is active; must be defined in `models` and have the same context window as `default_model` | | `default_permission_mode` | `string` | `manual` | Default permission mode for new sessions; one of `manual` (prompt each time), `yolo` (auto-approve tool actions, but the agent may still ask questions), or `auto` (fully autonomous — the agent decides everything without asking) | | `default_plan_mode` | `boolean` | `false` | Whether new sessions start in Plan mode (produce a plan before executing) by default | +| `default_swarm_mode` | `boolean` | `false` | Whether new sessions start in Swarm mode (prefer parallel `AgentSwarm` subagents) by default | | `merge_all_available_skills` | `boolean` | `true` | Whether to merge Agent Skills from all available directories | | `extra_skill_dirs` | `array` | — | Extra skill search directories, layered on top of the default directories | | `extra_agent_dirs` | `array` | — | Extra custom agent search directories, layered on top of the default directories | diff --git a/docs/zh/configuration/config-files.md b/docs/zh/configuration/config-files.md index 90fc6bbda4e..dc2f740c10a 100644 --- a/docs/zh/configuration/config-files.md +++ b/docs/zh/configuration/config-files.md @@ -104,6 +104,7 @@ timeout = 5 | `planning_model` | `string` | — | Plan 模式激活时使用的模型别名,必须在 `models` 中定义,且上下文窗口需与 `default_model` 相同 | | `default_permission_mode` | `string` | `manual` | 新会话的默认权限模式,可选 `manual`(逐次询问)、`yolo`(自动批准工具操作,Agent 仍可能提问)、`auto`(完全自主,Agent 自己做决定,不再提问) | | `default_plan_mode` | `boolean` | `false` | 新会话是否默认以 Plan 模式(先出计划再执行)启动 | +| `default_swarm_mode` | `boolean` | `false` | 新会话是否默认以 Swarm 模式(优先使用并行的 `AgentSwarm` 子代理)启动 | | `merge_all_available_skills` | `boolean` | `true` | 是否合并所有目录中的 Agent Skills | | `extra_skill_dirs` | `array` | — | 额外 Skill 搜索目录,叠加到默认目录之上 | | `extra_agent_dirs` | `array` | — | 额外自定义 Agent 搜索目录,叠加到默认目录之上 | diff --git a/fork/PATCHES.md b/fork/PATCHES.md index e3dadfeffa5..fed23785dbe 100644 --- a/fork/PATCHES.md +++ b/fork/PATCHES.md @@ -38,6 +38,7 @@ mark the row `merged-upstream` (keep the row as history). | planning-model switching | `feat/planning-model-switching` | `planning_model` config + v1/v2 plan-mode model flip, `modelquery`/`modellist`/`modelset` tools with a context-window switch guard, `/planning-model` TUI command; web "Planning model" setting in `kimi-code-web` | — | — | local | | disable kimi OAuth by default | `feat/disable-kimi-oauth-by-default` | Kimi OAuth login (kimi.com/kimi.ai device-code) disabled by default; opt-in via `[experimental] kimi_oauth` / `KIMI_CODE_EXPERIMENTAL_KIMI_OAUTH` / `kimi web --enable-kimi-oauth`; token/apiKey auth stays the default; web + TUI hide the login unless enabled | — | — | not-submitting | | Windows native installer | `feat/windows-installer` | Fork-style `install.ps1` (win32-x64/arm64, GitHub Releases + gh-pages channel); publish `install.ps1` to the update channel; point `README.md` + `README.zh-CN.md` + `fork/README.md` at the fork install commands | — | — | not-submitting | +| swarm-task preference + default_swarm_mode | `fix/swarm-task-preference` | Restore the #3028-removed proactiveness/action directives and add explicit swarm-preference + subagent-rules guidance to both engines' system prompts; add a `default_swarm_mode` config (v1 + v2 + protocol) so new sessions can start in swarm mode | — | [#3433](https://github.com/MoonshotAI/kimi-code/issues/3433) | local | Changesets under `.changeset/` deliberately name the upstream package `@moonshot-ai/kimi-code`, not the fork's `@mbuckaway/kimi-code`, so a change can diff --git a/packages/agent-core-v2/docs/config-manifest.toml b/packages/agent-core-v2/docs/config-manifest.toml index 5536a5716de..c1e06ebaeb1 100644 --- a/packages/agent-core-v2/docs/config-manifest.toml +++ b/packages/agent-core-v2/docs/config-manifest.toml @@ -8,12 +8,13 @@ # commented "# field: type" lines describe the remaining schema fields. # Values resolve as: default -> config.toml -> env overlay -> memory. -# Index (28 sections · 2 overlay(s)) +# Index (29 sections · 2 overlay(s)) # background src/agent/task/configSection.ts # builtinProductSkills src/features/skill/catalog/configSection.ts # cron src/features/cron/configSection.ts # defaultPermissionMode src/agent/permissionMode/configSection.ts # defaultPlanMode src/features/plan/configSection.ts +# defaultSwarmMode src/features/swarm/configSection.ts # experimental src/app/flag/flag.ts # extraAgentDirs src/workspace/workspaceAgentProfileLoader/configSection.ts # extraSkillDirs src/features/skill/catalog/configSection.ts @@ -110,6 +111,14 @@ manual_tick = false default_plan_mode = false +# ########################################################################## +# defaultSwarmMode (config.toml: default_swarm_mode) +# owner: src/features/swarm/configSection.ts +# scope: core +# ########################################################################## + +default_swarm_mode = false + # ########################################################################## # experimental # owner: src/app/flag/flag.ts diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/system.md b/packages/agent-core-v2/src/app/agentProfileCatalog/system.md index c2fb47c0e32..98e6a77ef70 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/system.md +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/system.md @@ -1,6 +1,6 @@ You are ${product_name}, an interactive general AI agent running on a user's computer. -Your primary goal is to help users with software engineering tasks. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. +Your primary goal is to help users with software engineering tasks by taking action — use the tools available to you to make real changes on the user's system. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. ${role_additional} @@ -13,7 +13,9 @@ Keep code, commands, identifiers, file paths, and technical terms in their origi # Prompt and Tool Use -When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. +For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task. For instance, "change `methodName` to snake_case" is a task, not a question — locate the method in the code and edit it; do not just reply with `method_name`. + +When handling the user's request, if it involves creating, modifying, or running code or files, you MUST use the appropriate tools available to you to make actual changes — do not just describe the solution in text. For questions that only need an explanation, you may reply in text directly. When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. When a dedicated tool fits the job, reach for it before raw shell: `Read` a known path, `Glob` to find files by name, and `Grep` to search file contents. These resolve paths through the workspace access policy and cap their output, so they keep large raw dumps out of the conversation. @@ -118,10 +120,15 @@ At any time, you should be HELPFUL, CONCISE, ACCURATE, and CANDID. Be thorough i - Try your best to avoid any hallucination. Do fact checking before providing any factual information. - Think about the best approach, then take action decisively. - Do not give up too early. +- Default to making progress, not to asking: once the goal is clear and you have the user's go-ahead to act on it, carry it through and work blockers yourself; ask only when the user's answer would actually change your next step. This never overrides the rule to stop and discuss when the goal is unclear, or to wait for explicit instruction before writing code. - ALWAYS, keep it stupidly simple. Do not overcomplicate things. - Talk like a seasoned engineer, not a cheerleader. Skip flattery, motivational filler, and hollow reassurance — the user wants the work done, not to be impressed. A correct, plainly-stated answer respects them more than praise does. - Think and reply in the user's language; artifacts that go into the repository follow the project's conventions instead. - When you have evidence the user is wrong, say so and show the evidence — agreeing to be agreeable wastes their time and can break their code. Defer once they've decided; until then, an honest objection is the helpful answer. +- When the task requires creating or modifying files, always use tools to do so. Never treat displaying code in your response as a substitute for actually writing it to the file system. +- Deliver the complete change. Never stub out code with placeholders like `// ... rest unchanged` or leave the user to fill in the gaps; write out every line you mean to change. +- Prefer the `AgentSwarm` tool (parallel swarm of subagents) over a single sequential `Agent` call whenever the work decomposes into independent parts: partition it, run the subagents in parallel, and cross-check their results. +- When delegating to any subagent, include in its prompt the requirement to read and follow the project's coding standards and `AGENTS.md` before writing code. - After a change, sweep for comments and docstrings that now describe the old behavior, and bring them in line with what the code actually does. - Before calling a task done, verify it: run the checks that cover your change and look at the result instead of assuming. Don't mark work complete while tests are red or the implementation is still partial — this holds whether or not you are tracking the work in a todo list. - When the context fills up it is compacted automatically, so you may suddenly see a summary of the work so far in place of the full thread. Assume compaction happened while you were working: continue naturally from the summary instead of restarting, and make reasonable assumptions about anything it omits rather than redoing settled work. Treat any "done" it reports as unverified until you re-check. diff --git a/packages/agent-core-v2/src/features/swarm/configSection.ts b/packages/agent-core-v2/src/features/swarm/configSection.ts index 3d557aeb58d..ab6fe9cca20 100644 --- a/packages/agent-core-v2/src/features/swarm/configSection.ts +++ b/packages/agent-core-v2/src/features/swarm/configSection.ts @@ -42,3 +42,13 @@ export function resolveSwarmTimeoutMs(config: IConfigService): number { config.get(SWARM_SECTION)?.timeoutMs ?? DEFAULT_SWARM_TIMEOUT_MS ); } + +export const DEFAULT_SWARM_MODE_SECTION = 'defaultSwarmMode'; + +export const DefaultSwarmModeSchema = z.boolean().optional(); + +export type DefaultSwarmMode = z.infer; + +registerConfigSection(DEFAULT_SWARM_MODE_SECTION, DefaultSwarmModeSchema, { + defaultValue: false, +}); diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts index eac4368b663..1fedf7fd7e9 100644 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts +++ b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts @@ -14,6 +14,8 @@ import { ILogService } from '#/_base/log/log'; import { drainLogCloses } from '#/_base/log/logService'; import { DEFAULT_PLAN_MODE_SECTION } from '#/features/plan/configSection'; import { IAgentPlanService } from '#/features/plan/plan'; +import { DEFAULT_SWARM_MODE_SECTION } from '#/features/swarm/configSection'; +import { IAgentSwarmService } from '#/features/swarm/agent/swarm'; import { LifecycleScope } from '#/app/scopes'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; @@ -211,6 +213,14 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec } await planHandle.accessor.get(IAgentPlanService).enter(); } + if (this.config.get(DEFAULT_SWARM_MODE_SECTION) === true) { + const swarmAgent = main ?? (await ensureMainAgent(handle)); + const swarmHandle = agents.handleOf(swarmAgent.agentId); + if (swarmHandle === undefined) { + throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found'); + } + swarmHandle.accessor.get(IAgentSwarmService).enter('manual'); + } await this.appendSessionIndexEntry(sessionId, opts.workDir); } catch (error) { const sessionDir = handle.accessor.get(ISessionContext).sessionDir; diff --git a/packages/agent-core-v2/test/workspace/sessionLifecycle/sessionLifecycle.test.ts b/packages/agent-core-v2/test/workspace/sessionLifecycle/sessionLifecycle.test.ts index 1a9850cff5e..16d215f247c 100644 --- a/packages/agent-core-v2/test/workspace/sessionLifecycle/sessionLifecycle.test.ts +++ b/packages/agent-core-v2/test/workspace/sessionLifecycle/sessionLifecycle.test.ts @@ -44,6 +44,7 @@ import { WorkspaceDirsService } from '#/workspace/workspaceDirs/workspaceDirsSer import { IWorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructions'; import { IWorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcp'; import { IAgentPlanService } from '#/features/plan/plan'; +import { IAgentSwarmService } from '#/features/swarm/agent/swarm'; import { SECONDARY_MODEL_FLAG_ID } from '#/session/subagent/flag'; import { IModelCatalog } from '#/kosong/model/catalog'; import { IModelService } from '#/kosong/model/model'; @@ -2111,4 +2112,96 @@ describe('SessionLifecycleService', () => { expect(enter).not.toHaveBeenCalled(); }); }); + + describe('defaultSwarmMode bootstrap', () => { + it('enters swarm mode on a fresh session when config.defaultSwarmMode is true', async () => { + const { lifecycle, enter, create } = agentLifecycleCapturingSwarmSpy(); + const svc = await build([ + stubPair(IConfigService, configStub({ defaultSwarmMode: true })), + stubPair(IAgentLifecycleService, lifecycle), + ]); + + await svc.create({ sessionId: 's1', workDir: '/tmp/proj' }); + + expect(create).toHaveBeenCalledTimes(1); + expect(enter).toHaveBeenCalledWith('manual'); + }); + + it('leaves swarm mode inactive when config.defaultSwarmMode is absent', async () => { + const { lifecycle, enter, create } = agentLifecycleCapturingSwarmSpy(); + const svc = await build([ + stubPair(IConfigService, configStub({})), + stubPair(IAgentLifecycleService, lifecycle), + ]); + + await svc.create({ sessionId: 's1', workDir: '/tmp/proj' }); + + expect(create).not.toHaveBeenCalled(); + expect(enter).not.toHaveBeenCalled(); + }); + + it('does not apply config.defaultSwarmMode when resuming a session', async () => { + const workDir = '/tmp/proj'; + const summary = { id: 's1', workspaceId: 'wd_stub', cwd: workDir } as SessionSummary; + const { lifecycle, enter, create } = agentLifecycleCapturingSwarmSpy({ + mainPreexists: true, + }); + const svc = await build([ + stubPair(IConfigService, configStub({ defaultSwarmMode: true })), + stubPair(IAgentLifecycleService, lifecycle), + stubPair(ISessionIndex, { + ...sessionIndexStub(), + get: () => Promise.resolve(summary), + }), + ]); + + await svc.resume('s1'); + + expect(create).not.toHaveBeenCalled(); + expect(enter).not.toHaveBeenCalled(); + }); + }); }); + +function makeSwarmAgentHandle(agentId: string, swarmService: unknown): IAgentScopeHandle { + return { + id: agentId, + kind: LifecycleScope.Agent, + accessor: { + get: (token: unknown) => (token === IAgentSwarmService ? swarmService : {}), + }, + dispose: () => {}, + } as unknown as IAgentScopeHandle; +} + +function agentLifecycleCapturingSwarmSpy(opts: { mainPreexists?: boolean } = {}): { + lifecycle: IAgentLifecycleService; + enter: ReturnType; + create: ReturnType; +} { + const enter = vi.fn(); + const swarmService = { + enter, + exit: vi.fn(), + isActive: false, + }; + let mainContext: AgentContext | undefined = opts.mainPreexists + ? agentContextStub(MAIN_AGENT_ID) + : undefined; + let mainHandle: IAgentScopeHandle | undefined = opts.mainPreexists + ? makeSwarmAgentHandle(MAIN_AGENT_ID, swarmService) + : undefined; + const create = vi.fn((args: CreateAgentOptions | undefined) => { + const agentId = args?.agentId ?? MAIN_AGENT_ID; + mainContext = agentContextStub(agentId); + mainHandle = makeSwarmAgentHandle(agentId, swarmService); + return Promise.resolve(mainContext); + }); + const lifecycle: IAgentLifecycleService = { + ...agentLifecycleStub(), + get: (id: string) => (id === MAIN_AGENT_ID ? mainContext : undefined), + create, + handleOf: (id: string) => (id === MAIN_AGENT_ID ? mainHandle : undefined), + }; + return { lifecycle, enter, create }; +} diff --git a/packages/agent-core/src/config/schema.ts b/packages/agent-core/src/config/schema.ts index 0f426dfbc32..fc5436d0e26 100644 --- a/packages/agent-core/src/config/schema.ts +++ b/packages/agent-core/src/config/schema.ts @@ -362,6 +362,7 @@ export const KimiConfigSchema = z.object({ yolo: z.boolean().optional(), defaultPermissionMode: PermissionModeSchema.optional(), defaultPlanMode: z.boolean().optional(), + defaultSwarmMode: z.boolean().optional(), permission: PermissionConfigSchema.optional(), hooks: z.array(HookDefSchema).optional(), services: ServicesConfigSchema.optional(), @@ -414,6 +415,7 @@ export const KimiConfigPatchSchema = z yolo: z.boolean().optional(), defaultPermissionMode: PermissionModeSchema.optional(), defaultPlanMode: z.boolean().optional(), + defaultSwarmMode: z.boolean().optional(), permission: PermissionConfigPatchSchema.optional(), hooks: z.array(HookDefSchema).optional(), services: ServicesConfigPatchSchema.optional(), diff --git a/packages/agent-core/src/config/toml.ts b/packages/agent-core/src/config/toml.ts index 965deb143d9..7b1d1b738cb 100644 --- a/packages/agent-core/src/config/toml.ts +++ b/packages/agent-core/src/config/toml.ts @@ -495,6 +495,7 @@ export function configToTomlData(config: KimiConfig): Record { 'yolo', 'defaultPermissionMode', 'defaultPlanMode', + 'defaultSwarmMode', 'mergeAllAvailableSkills', 'extraSkillDirs', 'extraAgentDirs', diff --git a/packages/agent-core/src/profile/default/system.md b/packages/agent-core/src/profile/default/system.md index 9d64ae9eace..41632355d60 100644 --- a/packages/agent-core/src/profile/default/system.md +++ b/packages/agent-core/src/profile/default/system.md @@ -1,6 +1,6 @@ You are Kimi Code CLI, an interactive general AI agent running on a user's computer. -Your primary goal is to help users with software engineering tasks. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. +Your primary goal is to help users with software engineering tasks by taking action — use the tools available to you to make real changes on the user's system. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. {{ ROLE_ADDITIONAL }} @@ -12,7 +12,9 @@ Keep code, commands, identifiers, file paths, and technical terms in their origi # Prompt and Tool Use -When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. +For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task. For instance, "change `methodName` to snake_case" is a task, not a question — locate the method in the code and edit it; do not just reply with `method_name`. + +When handling the user's request, if it involves creating, modifying, or running code or files, you MUST use the appropriate tools available to you to make actual changes — do not just describe the solution in text. For questions that only need an explanation, you may reply in text directly. When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. When a dedicated tool fits the job, reach for it before raw shell: `Read` a known path, `Glob` to find files by name, and `Grep` to search file contents. These resolve paths through the workspace access policy and cap their output, so they keep large raw dumps out of the conversation. @@ -144,10 +146,15 @@ At any time, you should be HELPFUL, CONCISE, ACCURATE, and CANDID. Be thorough i - Try your best to avoid any hallucination. Do fact checking before providing any factual information. - Think about the best approach, then take action decisively. - Do not give up too early. +- Default to making progress, not to asking: once the goal is clear and you have the user's go-ahead to act on it, carry it through and work blockers yourself; ask only when the user's answer would actually change your next step. This never overrides the rule to stop and discuss when the goal is unclear, or to wait for explicit instruction before writing code. - ALWAYS, keep it stupidly simple. Do not overcomplicate things. - Talk like a seasoned engineer, not a cheerleader. Skip flattery, motivational filler, and hollow reassurance — the user wants the work done, not to be impressed. A correct, plainly-stated answer respects them more than praise does. - Think and reply in the user's language; artifacts that go into the repository follow the project's conventions instead. - When you have evidence the user is wrong, say so and show the evidence — agreeing to be agreeable wastes their time and can break their code. Defer once they've decided; until then, an honest objection is the helpful answer. +- When the task requires creating or modifying files, always use tools to do so. Never treat displaying code in your response as a substitute for actually writing it to the file system. +- Deliver the complete change. Never stub out code with placeholders like `// ... rest unchanged` or leave the user to fill in the gaps; write out every line you mean to change. +- Prefer the `AgentSwarm` tool (parallel swarm of subagents) over a single sequential `Agent` call whenever the work decomposes into independent parts: partition it, run the subagents in parallel, and cross-check their results. +- When delegating to any subagent, include in its prompt the requirement to read and follow the project's coding standards and `AGENTS.md` before writing code. - After a change, sweep for comments and docstrings that now describe the old behavior, and bring them in line with what the code actually does. - Before calling a task done, verify it: run the checks that cover your change and look at the result instead of assuming. Don't mark work complete while tests are red or the implementation is still partial — this holds whether or not you are tracking the work in a todo list. - When the context fills up it is compacted automatically, so you may suddenly see a summary of the work so far in place of the full thread. Assume compaction happened while you were working: continue naturally from the summary instead of restarting, and make reasonable assumptions about anything it omits rather than redoing settled work. Treat any "done" it reports as unverified until you re-check. diff --git a/packages/agent-core/src/rpc/core-impl.ts b/packages/agent-core/src/rpc/core-impl.ts index ebf61866b80..53f43c1d0cf 100644 --- a/packages/agent-core/src/rpc/core-impl.ts +++ b/packages/agent-core/src/rpc/core-impl.ts @@ -493,6 +493,9 @@ export class KimiCore implements PromisableMethods { if (config.defaultPlanMode === true) { await mainAgent.planMode.enter(); } + if (config.defaultSwarmMode === true) { + mainAgent.swarmMode.enter('manual'); + } await session.writeMetadata(); await session.flushMetadata(); } catch (error) { diff --git a/packages/agent-core/src/services/config/configService.ts b/packages/agent-core/src/services/config/configService.ts index e83eab6c99a..ca273456da8 100644 --- a/packages/agent-core/src/services/config/configService.ts +++ b/packages/agent-core/src/services/config/configService.ts @@ -60,6 +60,7 @@ function toConfigResponse(config: KimiConfig): ConfigResponse { yolo: config.yolo, default_permission_mode: config.defaultPermissionMode, default_plan_mode: config.defaultPlanMode, + default_swarm_mode: config.defaultSwarmMode, permission: config.permission, hooks: config.hooks, services: config.services, diff --git a/packages/protocol/src/rest/config.ts b/packages/protocol/src/rest/config.ts index c31280d96e8..08a90db069e 100644 --- a/packages/protocol/src/rest/config.ts +++ b/packages/protocol/src/rest/config.ts @@ -20,6 +20,7 @@ export const configResponseSchema = z yolo: z.boolean().optional(), default_permission_mode: z.string().optional(), default_plan_mode: z.boolean().optional(), + default_swarm_mode: z.boolean().optional(), permission: z.unknown().optional(), hooks: z.array(z.unknown()).optional(), services: z.unknown().optional(), @@ -45,6 +46,7 @@ export const patchConfigRequestSchema = z.object({ yolo: z.boolean().optional(), default_permission_mode: z.string().optional(), default_plan_mode: z.boolean().optional(), + default_swarm_mode: z.boolean().optional(), permission: z.unknown().optional(), hooks: z.array(z.unknown()).optional(), services: z.unknown().optional(),