diff --git a/.changeset/permission-mode-reminder-env.md b/.changeset/permission-mode-reminder-env.md new file mode 100644 index 00000000000..73d5c3c462b --- /dev/null +++ b/.changeset/permission-mode-reminder-env.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Add the `KIMI_CODE_PERMISSION_MODE_REMINDER` environment variable: set it to `0` to stop injecting the auto permission-mode reminders into the model context. diff --git a/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts b/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts index f5f1e001531..1d3f9ad67a6 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts @@ -3,6 +3,8 @@ import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; +import { parseBooleanEnv } from '#/_base/utils/env'; +import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { PermissionModeInjection } from '#/agent/permissionMode/injection/permissionModeInjection'; import { IAgentReminderService } from '#/features/reminder/reminderService'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; @@ -20,6 +22,8 @@ import { PermissionSetMode, } from './permissionModeOps'; +export const PERMISSION_MODE_REMINDER_ENV = 'KIMI_CODE_PERMISSION_MODE_REMINDER'; + export class AgentPermissionModeService extends Service implements IAgentPermissionModeService { declare readonly _serviceBrand: undefined; @@ -33,11 +37,14 @@ export class AgentPermissionModeService extends Service implements IAgentPermiss @IAgentReminderService reminder: IAgentReminderService, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentStateService private readonly agentState: IAgentStateService, + @IBootstrapService bootstrap: IBootstrapService, ) { super(); this.agentState.contributeState(permissionModeKey); this.agentState.contributeState(permissionModeConfiguredKey); - this._register(new PermissionModeInjection(this, reminder, this.agentState)); + if (parseBooleanEnv(bootstrap.getEnv(PERMISSION_MODE_REMINDER_ENV)) !== false) { + this._register(new PermissionModeInjection(this, reminder, this.agentState)); + } } get mode(): PermissionMode { diff --git a/packages/agent-core-v2/test/agent/permissionMode/permissionMode.test.ts b/packages/agent-core-v2/test/agent/permissionMode/permissionMode.test.ts index 3f83c48c89f..30602f482aa 100644 --- a/packages/agent-core-v2/test/agent/permissionMode/permissionMode.test.ts +++ b/packages/agent-core-v2/test/agent/permissionMode/permissionMode.test.ts @@ -7,11 +7,15 @@ import { IAgentReminderService } from '#/features/reminder/reminderService'; import type { ContextInjectionProvider } from '#/features/reminder/types'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { PermissionModeInjection } from '#/agent/permissionMode/injection/permissionModeInjection'; -import { AgentPermissionModeService } from '#/agent/permissionMode/permissionModeService'; +import { + AgentPermissionModeService, + PERMISSION_MODE_REMINDER_ENV, +} from '#/agent/permissionMode/permissionModeService'; import { permissionModeKey } from '#/agent/permissionMode/permissionModeOps'; import type { PermissionMode } from '#/agent/permissionPolicy/types'; import { IAgentStateService } from '#/agent/state/agentState'; import { AgentStateService } from '#/agent/state/agentStateService'; +import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { AppendLogStore } from '#/persistence/backends/node-fs/appendLogStore'; import { InMemoryStorageService } from '#/persistence/backends/memory/inMemoryStorageService'; import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; @@ -19,6 +23,8 @@ import { IFileSystemStorageService } from '#/persistence/interface/storage'; import { IEventDispatcher } from '#/state/eventDispatcher'; import { AGENT_WIRE_RECORD_KEY, type WireRecord } from '#/wire/record'; +import { stubBootstrap } from '../../app/bootstrap/stubs'; + import { registerTestAgentWire, registerTestEventDispatcher, @@ -55,15 +61,18 @@ let log: IAppendLogStore; let dispatcher: IEventDispatcher; let svc: IAgentPermissionModeService; let reminderLive = false; +let bootstrapEnv: NodeJS.ProcessEnv; beforeEach(() => { registeredInjection = undefined; reminderLive = false; + bootstrapEnv = {}; disposables = new DisposableStore(); ix = disposables.add(new TestInstantiationService()); ix.stub(IFileSystemStorageService, new InMemoryStorageService()); ix.set(IAppendLogStore, new SyncDescriptor(AppendLogStore)); ix.stub(IAgentReminderService, injectorStub); + ix.stub(IBootstrapService, stubBootstrap('/tmp/kimi-home', bootstrapEnv)); ix.set(IAgentStateService, new AgentStateService()); ix.set(IAgentPermissionModeService, new SyncDescriptor(AgentPermissionModeService)); log = ix.get(IAppendLogStore); @@ -241,4 +250,51 @@ describe('AgentPermissionModeService (wire-backed)', () => { expect(written[0]).toMatchObject({ type: 'metadata' }); expect(written.slice(1)).toEqual([{ type: 'permission.set_mode', mode: 'auto' }]); }); + + it('skips the auto-mode reminder injection when KIMI_CODE_PERMISSION_MODE_REMINDER is disabled', () => { + registeredInjection = undefined; + const ix2 = disposables.add(new TestInstantiationService()); + ix2.stub(IFileSystemStorageService, new InMemoryStorageService()); + ix2.set(IAppendLogStore, new SyncDescriptor(AppendLogStore)); + ix2.stub(IAgentReminderService, injectorStub); + ix2.stub( + IBootstrapService, + stubBootstrap('/tmp/kimi-home', { [PERMISSION_MODE_REMINDER_ENV]: '0' }), + ); + ix2.set(IAgentStateService, new AgentStateService()); + ix2.set(IAgentPermissionModeService, new SyncDescriptor(AgentPermissionModeService)); + registerTestAgentWire(ix2, testWireScope(SCOPE, 'permission-mode-no-reminder'), { + log: ix2.get(IAppendLogStore), + }); + registerTestEventDispatcher(ix2); + + const svc2 = ix2.get(IAgentPermissionModeService); + + expect(registeredInjection).toBeUndefined(); + svc2.setMode('auto'); + expect(svc2.mode).toBe('auto'); + expect(registeredInjection).toBeUndefined(); + }); + + it('keeps the auto-mode reminder injection when the env override enables it explicitly', () => { + registeredInjection = undefined; + const ix2 = disposables.add(new TestInstantiationService()); + ix2.stub(IFileSystemStorageService, new InMemoryStorageService()); + ix2.set(IAppendLogStore, new SyncDescriptor(AppendLogStore)); + ix2.stub(IAgentReminderService, injectorStub); + ix2.stub( + IBootstrapService, + stubBootstrap('/tmp/kimi-home', { [PERMISSION_MODE_REMINDER_ENV]: '1' }), + ); + ix2.set(IAgentStateService, new AgentStateService()); + ix2.set(IAgentPermissionModeService, new SyncDescriptor(AgentPermissionModeService)); + registerTestAgentWire(ix2, testWireScope(SCOPE, 'permission-mode-reminder-on'), { + log: ix2.get(IAppendLogStore), + }); + registerTestEventDispatcher(ix2); + + ix2.get(IAgentPermissionModeService); + + expect((registeredInjection as { readonly name: string } | undefined)?.name).toBe('permission_mode'); + }); }); diff --git a/packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts b/packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts index d37297be07a..a464a1c3ab3 100644 --- a/packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts +++ b/packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts @@ -268,6 +268,7 @@ describe('AgentLifecycleService', () => { _serviceBrand: undefined, homeDir: '/tmp/kimi-agentLifecycle-home', cwd: '/tmp/kimi-agentLifecycle-home', + getEnv: () => undefined, } as unknown as IBootstrapService); ix.stub(IFlagService, { _serviceBrand: undefined,