Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .changeset/agent-manager-yolo-toggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
"kilo-code": minor
---

Agent Manager: Add YOLO mode toggle and session rename features

**New Features:**

- Add YOLO mode toggle button in session header to enable/disable auto-approval of operations
- Add YOLO mode indicator (⚡) in session list for sessions running in YOLO mode
- Add inline session rename functionality - click on session title to edit

**Bug Fixes:**

- Fix messages not loading when reopening Agent Manager panel (pre-existing bug)
- Fix race condition where pending session timeout could fire after provisional session was already created

**Improvements:**

- Add TypeScript types for `respondToApproval` message
- Add translations for YOLO mode and rename features in all 21 supported locales
7 changes: 4 additions & 3 deletions apps/kilocode-docs/docs/agent-behavior/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ Skills are loaded from multiple locations, allowing both personal skills and pro

### Global Skills (User-Level)

Global skills are located in the `.kilocode` directory within your Home directory.
* Mac and Linux: `~/.kilocode/skills/`
* Windows: `\Users\<yourUser>\.kilocode\`
Global skills are located in the `.kilocode` directory within your Home directory.

- Mac and Linux: `~/.kilocode/skills/`
- Windows: `\Users\<yourUser>\.kilocode\`

```
~/.kilocode/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ Common dashboards which offer filtering based on provider, model, and tool:

Implement [multi-window, multi-burn-rate alerting](https://sre.google/workbook/alerting-on-slos/) against error budgets:

| Window | Burn Rate | Action | Use Case |
| ------ | --------- | ------ | ------------------- |
| 5 min | 14.4x | Page | Major Outage |
| 30 min | 6x | Page | Incident |
| Window | Burn Rate | Action | Use Case |
| ------ | --------- | ------ | ------------------ |
| 5 min | 14.4x | Page | Major Outage |
| 30 min | 6x | Page | Incident |
| 6 hr | 1x | Ticket | Change in behavior |

Paging should **only occur on Recommended Models when using the Kilo Gateway**. All other alerts should be tickets, and some may be configured to be ignored.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ Note that available settings vary by provider and model. Each provider offers di
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="Provider selection dropdown" width="550" />
- Enter API key

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API key entry field" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API key entry field" width="550" />

- Choose a model

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="Model selection interface" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="Model selection interface" width="550" />

- Adjust model parameters

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="Model parameter adjustment controls" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="Model parameter adjustment controls" width="550" />

### Switching Profiles

Expand Down
2 changes: 1 addition & 1 deletion apps/kilocode-docs/docs/providers/kilocode.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Kilo Code provides access to the latest frontier coding models through its built

You can also bring your own key (BYOK) to the Kilo Gateway. We currently support the following providers: Anthropic, OpenAI, Google AI Studio, MiniMax, Mistral AI, xAI, and Z.ai.

You can access the BYOK section of the Kilo Gateway [here](https://app.kilo.ai/byok).
You can access the BYOK section of the Kilo Gateway [here](https://app.kilo.ai/byok).

## Configuration in Kilo Code

Expand Down
3 changes: 2 additions & 1 deletion apps/kilocode-docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ const config: Config = {
{
id: "llms-txt",
name: "Kilo Code Documentation",
description: "Comprehensive documentation for Kilo Code, an AI-powered coding assistant for VS Code, Jetbrains, CLI & Cloud",
description:
"Comprehensive documentation for Kilo Code, an AI-powered coding assistant for VS Code, Jetbrains, CLI & Cloud",
url: "https://kilo.ai/docs",
email: "[email protected]",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ API 配置配置文件允许您创建和切换不同的 AI 设置集。每个配

- 选择您的 API 提供商

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="提供商选择下拉菜单" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="提供商选择下拉菜单" width="550" />

- 输入 API 密钥

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API 密钥输入字段" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API 密钥输入字段" width="550" />

- 选择模型

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="模型选择界面" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="模型选择界面" width="550" />

- 调整模型参数

<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="模型参数调整控件" width="550" />
<img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="模型参数调整控件" width="550" />

### 切换配置文件

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Kilo Code 使用一个影子 Git 仓库(独立于您的主版本控制系统

- **恢复文件和任务** - 恢复工作区文件并删除所有后续对话消息。当您希望将代码和对话完全重置回检查点的时间点时使用。此选项需要在对话框中进行确认,因为它无法撤消。

<img src="/docs/img/checkpoints/checkpoints-9.png" alt="恢复文件和任务检查点的确认对话框" width="300" />
<img src="/docs/img/checkpoints/checkpoints-9.png" alt="恢复文件和任务检查点的确认对话框" width="300" />

### 限制和注意事项

Expand Down
75 changes: 44 additions & 31 deletions cli/src/__tests__/cli-yolo-mode.test.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,76 @@
import { describe, it, expect } from "vitest"

/**
* Tests for YOLO mode behavior in JSON-IO mode.
* Tests for YOLO mode isolation behavior.
*
* In JSON-IO mode (--json-io flag), we don't send the yoloMode message to the extension host.
* This prevents Task.ts from auto-answering followup questions, allowing the CLI's own
* approval layer to handle YOLO behavior (which correctly excludes followups from auto-approval).
* IMPORTANT: The CLI does NOT send yoloMode messages to the extension host.
* This is intentional to ensure session isolation:
*
* 1. Each CLI instance manages its own yoloMode state locally via yoloModeAtom
* 2. Sending yoloMode to the extension host would pollute the global state
* 3. This would affect other sessions (like Agent Manager) that should have
* isolated yoloMode per session via the --yolo flag
*
* See: https://github.com/Kilo-Org/kilocode/pull/4890
*/
describe("CLI yoloMode in JSON-IO mode", () => {
describe("shouldSendYoloModeToExtension", () => {
// Extract the logic we're testing into a pure function
function shouldSendYoloModeToExtension(options: {
describe("CLI yoloMode isolation", () => {
describe("yoloMode state management", () => {
/**
* This function represents the OLD behavior that was removed.
* Previously, CLI would send yoloMode to extension host in non-JSON-IO mode.
* Now, yoloMode is NEVER sent to extension host to ensure session isolation.
*/
function shouldSendYoloModeToExtension(_options: {
jsonInteractive?: boolean
ci?: boolean
yolo?: boolean
}): boolean {
// This mirrors the condition in cli.ts:
// if (!this.options.jsonInteractive) { sendWebviewMessage({ type: "yoloMode", ... }) }
return !options.jsonInteractive
// NEW BEHAVIOR: Never send yoloMode to extension host
// Each CLI instance manages its own state locally
return false
}

function getYoloModeValue(options: { ci?: boolean; yolo?: boolean }): boolean {
// This mirrors: Boolean(this.options.ci || this.options.yolo)
/**
* Helper to get local yoloMode value based on CLI flags.
* This value is stored in the CLI's local yoloModeAtom, not sent to extension.
*/
function getLocalYoloModeValue(options: { ci?: boolean; yolo?: boolean }): boolean {
return Boolean(options.ci || options.yolo)
}

it("should send yoloMode message when not in JSON-IO mode", () => {
expect(shouldSendYoloModeToExtension({ jsonInteractive: false })).toBe(true)
expect(shouldSendYoloModeToExtension({ jsonInteractive: undefined })).toBe(true)
expect(shouldSendYoloModeToExtension({})).toBe(true)
it("should NEVER send yoloMode message to extension host (session isolation)", () => {
// Even in non-JSON-IO mode, we don't send yoloMode to avoid global state pollution
expect(shouldSendYoloModeToExtension({ jsonInteractive: false })).toBe(false)
expect(shouldSendYoloModeToExtension({ jsonInteractive: undefined })).toBe(false)
expect(shouldSendYoloModeToExtension({})).toBe(false)
})

it("should NOT send yoloMode message when in JSON-IO mode", () => {
it("should NOT send yoloMode message in JSON-IO mode", () => {
expect(shouldSendYoloModeToExtension({ jsonInteractive: true })).toBe(false)
})

it("should NOT send yoloMode message in JSON-IO mode even with yolo flag", () => {
it("should NOT send yoloMode message with any flag combination", () => {
expect(shouldSendYoloModeToExtension({ jsonInteractive: true, yolo: true })).toBe(false)
})

it("should NOT send yoloMode message in JSON-IO mode even with ci flag", () => {
expect(shouldSendYoloModeToExtension({ jsonInteractive: true, ci: true })).toBe(false)
expect(shouldSendYoloModeToExtension({ jsonInteractive: false, yolo: true })).toBe(false)
expect(shouldSendYoloModeToExtension({ jsonInteractive: false, ci: true })).toBe(false)
})

it("should set yoloMode value to true when yolo flag is set", () => {
expect(getYoloModeValue({ yolo: true })).toBe(true)
it("should set local yoloMode value to true when yolo flag is set", () => {
expect(getLocalYoloModeValue({ yolo: true })).toBe(true)
})

it("should set yoloMode value to true when ci flag is set", () => {
expect(getYoloModeValue({ ci: true })).toBe(true)
it("should set local yoloMode value to true when ci flag is set", () => {
expect(getLocalYoloModeValue({ ci: true })).toBe(true)
})

it("should set yoloMode value to true when both flags are set", () => {
expect(getYoloModeValue({ yolo: true, ci: true })).toBe(true)
it("should set local yoloMode value to true when both flags are set", () => {
expect(getLocalYoloModeValue({ yolo: true, ci: true })).toBe(true)
})

it("should set yoloMode value to false when neither flag is set", () => {
expect(getYoloModeValue({})).toBe(false)
expect(getYoloModeValue({ yolo: false, ci: false })).toBe(false)
it("should set local yoloMode value to false when neither flag is set", () => {
expect(getLocalYoloModeValue({})).toBe(false)
expect(getLocalYoloModeValue({ yolo: false, ci: false })).toBe(false)
})
})
})
9 changes: 3 additions & 6 deletions cli/src/__tests__/commander-flags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,9 @@ describe("Commander.js Short Flag Validation", () => {
const testProgram = new Command()
testProgram.exitOverride()

expect(
() => {
testProgram.option(flags, description)
},
`Expected "${flags}" to throw because short flag is multi-character`,
).toThrow()
expect(() => {
testProgram.option(flags, description)
}, `Expected "${flags}" to throw because short flag is multi-character`).toThrow()
})
})
})
Expand Down
30 changes: 15 additions & 15 deletions cli/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export default async function authWizard(): Promise<void> {

// Prompt user to select a provider
const selectedProvider = await withRawMode(() =>
select({
message: "Select an AI provider:",
choices: providerChoices,
loop: false,
pageSize: process.stdout.rows ? Math.min(20, process.stdout.rows - 2) : 10,
})
)
select({
message: "Select an AI provider:",
choices: providerChoices,
loop: false,
pageSize: process.stdout.rows ? Math.min(20, process.stdout.rows - 2) : 10,
}),
)

// Find the selected provider
const provider = authProviders.find((p) => p.value === selectedProvider)
Expand Down Expand Up @@ -86,14 +86,14 @@ export default async function authWizard(): Promise<void> {
})

const selectedModel = await withRawMode(() =>
select({
message: "Select a model to use:",
choices: modelChoices,
default: defaultModel,
loop: false,
pageSize: 10,
})
)
select({
message: "Select a model to use:",
choices: modelChoices,
default: defaultModel,
loop: false,
pageSize: 10,
}),
)

const modelKey = getModelIdKey(providerId)
authResult.providerConfig[modelKey] = selectedModel
Expand Down
16 changes: 6 additions & 10 deletions cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,16 +302,12 @@ export class CLI {
await this.injectConfigurationToExtension()
logs.debug("CLI configuration injected into extension", "CLI")

const extensionHost = this.service.getExtensionHost()
// In JSON-IO mode, don't set yoloMode on the extension host.
// This prevents Task.ts from auto-answering followup questions.
// The CLI's approval layer handles YOLO behavior and correctly excludes followups.
if (!this.options.jsonInteractive) {
extensionHost.sendWebviewMessage({
type: "yoloMode",
bool: Boolean(this.options.ci || this.options.yolo),
})
}
// NOTE: We intentionally do NOT send yoloMode to the extension host here.
// Each CLI instance manages its own yoloMode state locally via yoloModeAtom.
// Sending yoloMode to the extension host would pollute the global state,
// affecting other sessions (like Agent Manager sessions) that should have
// isolated yoloMode per session via the --yolo flag.
// See: https://github.com/Kilo-Org/kilocode/pull/4890

// Request router models after configuration is injected
void this.requestRouterModels()
Expand Down
4 changes: 2 additions & 2 deletions cli/src/commands/checkpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ function getCheckpointsPath(): string {
}

/**
* Handle /checkpoint disable
*/
* Handle /checkpoint disable
*/
async function handleDisable(context: CommandContext): Promise<void> {
const { addMessage, sendWebviewMessage } = context

Expand Down
28 changes: 24 additions & 4 deletions cli/src/services/__tests__/autocomplete.detectInputState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,18 @@ describe("detectInputState", () => {
{
condition: (context) => context.getArgument("subcommand") === "select",
provider: async () => [
{ value: "personal", description: "Personal account", matchScore: 1, highlightedValue: "personal" },
{ value: "kilo-code", description: "Kilo Code team", matchScore: 1, highlightedValue: "kilo-code" },
{
value: "personal",
description: "Personal account",
matchScore: 1,
highlightedValue: "personal",
},
{
value: "kilo-code",
description: "Kilo Code team",
matchScore: 1,
highlightedValue: "kilo-code",
},
],
},
],
Expand Down Expand Up @@ -108,7 +118,12 @@ describe("detectInputState", () => {
},
provider: async () => [
{ value: "gpt-4", description: "GPT-4", matchScore: 1, highlightedValue: "gpt-4" },
{ value: "claude-sonnet", description: "Claude Sonnet", matchScore: 1, highlightedValue: "claude-sonnet" },
{
value: "claude-sonnet",
description: "Claude Sonnet",
matchScore: 1,
highlightedValue: "claude-sonnet",
},
],
},
],
Expand All @@ -132,7 +147,12 @@ describe("detectInputState", () => {
required: true,
provider: async () => [
{ value: "code", description: "Code mode", matchScore: 1, highlightedValue: "code" },
{ value: "architect", description: "Architect mode", matchScore: 1, highlightedValue: "architect" },
{
value: "architect",
description: "Architect mode",
matchScore: 1,
highlightedValue: "architect",
},
],
},
],
Expand Down
Loading