How Experimental Features Are Gated Behind Flags in Kimi-Code: Architecture and Implementation Guide
Kimi-code gates experimental features behind a hierarchical flag system located in packages/agent-core/src/flags that evaluates environment variables, config files, and registry defaults to determine runtime feature availability.
Kimi-code implements a self-contained flag system to safely roll out experimental functionality without impacting production users. Understanding how experimental features are gated behind flags in kimi-code helps developers enable cutting-edge capabilities while maintaining stability. The system relies on three core components housed in the packages/agent-core/src/flags directory: a registry of definitions, TypeScript type safety, and a synchronous resolver.
Architecture of the Experimental Flag System
Flag Definitions in the Registry
The FLAG_DEFINITIONS constant in packages/agent-core/src/flags/registry.ts serves as the single source of truth for all experimental features. Each entry includes an id, title, description, env variable name, default boolean state, and surface designation indicating UI visibility. The as const satisfies assertion automatically derives the literal FlagId union, giving compile-time safety when referencing flags throughout the codebase.
Type Safety with Flag Types
The packages/agent-core/src/flags/types.ts file defines TypeScript interfaces for flag metadata and resolved states. It exports the FlagId union type derived from registry keys, providing compile-time autocomplete and preventing invalid flag references. This ensures that only defined experimental features can be queried via the resolver API.
The Flag Resolver Logic
packages/agent-core/src/flags/resolver.ts implements the FlagResolver class, a pure synchronous evaluator that determines feature availability. The resolver exposes three key methods:
enabled(id): Returns boolean state for a given flag ID (lines 39-41)explain(id): Details the resolution path and precedence (lines 47-53)snapshot(): Captures current state of all flags for debugging
Flag Resolution Precedence and Priority
The resolver evaluates experimental feature flags in strict precedence order according to the logic in FlagResolver.explain:
- Master switch (
KIMI_CODE_EXPERIMENTAL_FLAG): When truthy, forces all experimental flags to the enabled state (highest precedence) - Per-feature environment variables: Individual flag env vars like
KIMI_CODE_EXPERIMENTAL_TOOL_SELECToverride defaults and the master switch - Config file overrides: Boolean values in the
[experimental]section ofconfig.toml - Registry defaults: The
defaultfield fromFLAG_DEFINITIONSwhen no override exists
Accessing the Flag Resolver in Code
Scoped Resolver Instances
Every KimiCore, Session, and Agent instance exposes a scoped resolver through the flags property. Access features within these contexts using:
if (this.flags.enabled('tool-select')) {
// Execute experimental tool selection logic
await this.experimentalToolSelection();
} else {
// Maintain stable behavior
await this.standardToolSelection();
}
Global Singleton Access
For code outside scoped instances, packages/agent-core/src/flags/resolver.ts exports a global singleton as flags (re-exported via packages/agent-core/src/flags/index.ts). Import using:
import { flags } from '#/flags';
if (flags.enabled('my-feature')) {
// Handle experimental path
}
Adding a New Experimental Flag
To gate a new capability behind the flag system, follow these steps:
First, define the flag in packages/agent-core/src/flags/registry.ts:
{
id: 'my_new_feature',
title: 'My New Feature',
description: 'A brief description of the experimental capability.',
env: 'KIMI_CODE_EXPERIMENTAL_MY_NEW_FEATURE',
default: false,
surface: 'both',
},
Then check the flag at runtime within an Agent, Session, or KimiCore:
if (this.flags.enabled('my_new_feature')) {
await this.performNewFeatureLogic();
} else {
await this.performLegacyLogic();
}
Optionally enable via config.toml:
[experimental]
my_new_feature = true
Or force-enable all experimental features via environment variable:
export KIMI_CODE_EXPERIMENTAL_FLAG=1
Key Files in the Flag System
packages/agent-core/src/flags/registry.ts: Catalog of all experimental flags and metadata; the single source of truthpackages/agent-core/src/flags/resolver.ts: Resolution algorithm and public API (enabled,explain,snapshot)packages/agent-core/src/flags/types.ts: TypeScript interfaces andFlagIdunion type definitionspackages/agent-core/src/flags/index.ts: Public entry point exporting the global resolver singleton
Summary
- Kimi-code gates experimental features through a centralized system in
packages/agent-core/src/flagswith three core components: registry, types, and resolver - The
FlagResolverclass evaluates flags using strict precedence: master env switch → per-feature env vars →config.tomloverrides → registry defaults - Type safety is enforced through the
FlagIdunion type generated fromFLAG_DEFINITIONSusingas const satisfies - Both scoped instances (on
Agent,Session,KimiCore) and a global singleton provide access toflags.enabled()for checking experimental status - New features require only a registry entry and runtime check to implement safe, reversible rollouts
Frequently Asked Questions
What is the fastest way to enable all experimental features in kimi-code?
Set the KIMI_CODE_EXPERIMENTAL_FLAG environment variable to any truthy value before starting the application. This master switch overrides all individual flag defaults and forces every experimental feature to the enabled state, regardless of their registry defaults or config file settings.
Can individual experimental flags be disabled after enabling the master switch?
Yes. The per-feature environment variable takes precedence over the master switch. Even with KIMI_CODE_EXPERIMENTAL_FLAG=1, setting a specific flag's env var like KIMI_CODE_EXPERIMENTAL_TOOL_SELECT=false will disable that particular feature while keeping others enabled, following the resolution order defined in FlagResolver.explain.
Where should developers define new experimental flags?
Add new flag definitions to the FLAG_DEFINITIONS array in packages/agent-core/src/flags/registry.ts. Each entry must include a unique id, an env name prefixed with KIMI_CODE_EXPERIMENTAL_, and a boolean default value. The TypeScript compiler automatically updates the FlagId union to include the new flag identifier.
How does the flag system handle type safety?
The FlagId union type is automatically derived from the FLAG_DEFINITIONS array using TypeScript's as const satisfies assertion in registry.ts. This provides compile-time checking and IDE autocomplete when calling flags.enabled(), preventing references to undefined flags and ensuring that only registered experimental features can be queried.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →