From b9259abd3f2bf04eb7b35faea7579789137fe770 Mon Sep 17 00:00:00 2001 From: "haozhe.yang" Date: Wed, 1 Jul 2026 18:39:01 +0800 Subject: [PATCH] refactor(agent-core-v2): move thinking helpers from config to profile - Host resolveThinkingEffort/resolveThinkingLevel in the profile domain, the owner of the thinking/defaultThinking config sections, so they use the authoritative ThinkingConfig from configSection.ts. - Drop the local ThinkingConfigDefaults structural duplicate that existed only to keep config (L2) from importing upward into profile (L4). - Update profile/profileService consumers and the config barrel, and move the test alongside the helpers. --- .agents/skills/agent-core-dev/config.md | 2 +- .../src/agent/profile/profile.ts | 2 +- .../src/agent/profile/profileService.ts | 3 ++- .../{app/config => agent/profile}/thinking.ts | 21 +++++++------------ .../agent-core-v2/src/app/config/index.ts | 1 - .../test/{config => profile}/thinking.test.ts | 4 ++-- 6 files changed, 14 insertions(+), 19 deletions(-) rename packages/agent-core-v2/src/{app/config => agent/profile}/thinking.ts (71%) rename packages/agent-core-v2/test/{config => profile}/thinking.test.ts (97%) diff --git a/.agents/skills/agent-core-dev/config.md b/.agents/skills/agent-core-dev/config.md index 4e0f4ee5d..599325a44 100644 --- a/.agents/skills/agent-core-dev/config.md +++ b/.agents/skills/agent-core-dev/config.md @@ -89,7 +89,7 @@ pass `ConfigTarget.Memory` for a per-run override that is never written to disk. - `src/config/config.ts` — `IConfigRegistry` / `IConfigService` tokens, `ConfigSection`, `ConfigEffectiveOverlay`, event types. - `src/config/configService.ts` — `ConfigRegistry` + `ConfigService` impl; self-registers at App scope. - `src/config/toml.ts` — generic snake_case ↔ camelCase machinery plus the registry-aware `transformTomlData` / `applySectionToToml` entry points. Per-domain normalization lives in the section owner's `configSection.ts` (registered as `fromToml` / `toToml`); this module stays free of any other domain's semantics. -- `src/config/thinking.ts` — `resolveThinkingEffort` / `resolveThinkingLevel` helpers (own a local `ThinkingConfigDefaults` structural type; do not import `profile`). +- `src/profile/thinking.ts` (owner domain, not `config`) — `resolveThinkingEffort` / `resolveThinkingLevel` helpers; uses the authoritative `ThinkingConfig` from `configSection.ts`. - `src/config/configPure.ts` — `isPlainObject`, `deepMerge`, `omitUndefined`, `describeUnknownError`. A domain that owns a section keeps the schema in its own `configSection.ts` (e.g. `src/flag/flag.ts` for `experimental`, `src/profile/configSection.ts` for `thinking`, `src/loop/configSection.ts` for `loopControl`). A cross-section env overlay (e.g. the `KIMI_MODEL_*` synthesis) lives in the owning domain too (`src/provider/envOverlay.ts`) and is registered via `IConfigRegistry.registerEffectiveOverlay`. diff --git a/packages/agent-core-v2/src/agent/profile/profile.ts b/packages/agent-core-v2/src/agent/profile/profile.ts index 7a4b00520..be7a626f5 100644 --- a/packages/agent-core-v2/src/agent/profile/profile.ts +++ b/packages/agent-core-v2/src/agent/profile/profile.ts @@ -2,10 +2,10 @@ import type { ChatProvider, ModelCapability, ProviderConfig, + ThinkingEffort, } from '@moonshot-ai/kosong'; import { createDecorator } from "#/_base/di"; -import type { ThinkingEffort } from '#/app/config/thinking'; import type { ToolSource } from '#/agent/tool'; /** diff --git a/packages/agent-core-v2/src/agent/profile/profileService.ts b/packages/agent-core-v2/src/agent/profile/profileService.ts index d591ad0c2..fd2a8d30d 100644 --- a/packages/agent-core-v2/src/agent/profile/profileService.ts +++ b/packages/agent-core-v2/src/agent/profile/profileService.ts @@ -16,13 +16,14 @@ import { type ChatProvider, type ModelCapability, type ProviderConfig, + type ThinkingEffort, } from '@moonshot-ai/kosong'; import picomatch from 'picomatch'; import { ErrorCodes, KimiError } from "#/errors"; import { IBootstrapService } from '#/app/bootstrap'; import { IConfigRegistry, IConfigService } from '#/app/config'; -import { resolveThinkingEffort, type ThinkingEffort } from '#/app/config/thinking'; +import { resolveThinkingEffort } from './thinking'; import { applyKimiModelOverrides, IChatProviderFactory, type KimiModelOverrides } from '#/app/chatProvider'; import type { LoopControl } from '#/agent/loop/configSection'; import { IKaos } from '#/app/kaos'; diff --git a/packages/agent-core-v2/src/app/config/thinking.ts b/packages/agent-core-v2/src/agent/profile/thinking.ts similarity index 71% rename from packages/agent-core-v2/src/app/config/thinking.ts rename to packages/agent-core-v2/src/agent/profile/thinking.ts index 1a81c4cc2..3ffc5d0e2 100644 --- a/packages/agent-core-v2/src/app/config/thinking.ts +++ b/packages/agent-core-v2/src/agent/profile/thinking.ts @@ -1,26 +1,21 @@ /** - * `config` domain (L2) — thinking-level normalization helpers. + * `profile` domain — thinking-level resolution helpers. * - * Owns a local structural `ThinkingConfigDefaults` type so `config` does not - * reach upward into `profile`, which owns the authoritative - * `ThinkingConfigSchema`. + * Resolves the effective `ThinkingEffort` from a requested level, the + * `thinking` config section (`ThinkingConfig`, owned here in `profile`), and + * the `defaultThinking` toggle. Pure functions; own no scoped state. */ import type { ThinkingEffort } from '@moonshot-ai/kosong'; -export type { ThinkingEffort }; - -export interface ThinkingConfigDefaults { - readonly mode?: 'auto' | 'on' | 'off' | undefined; - readonly effort?: string | undefined; -} +import type { ThinkingConfig } from './configSection'; const DEFAULT_THINKING_EFFORT: ThinkingEffort = 'high'; const THINKING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'max']); export interface ResolveThinkingLevelOptions { - readonly defaultThinking?: boolean | undefined; - readonly thinking?: ThinkingConfigDefaults | undefined; + readonly defaultThinking?: boolean; + readonly thinking?: ThinkingConfig; } export function resolveThinkingLevel( @@ -39,7 +34,7 @@ export function resolveThinkingLevel( export function resolveThinkingEffort( requested: string | undefined, - defaults: ThinkingConfigDefaults | undefined, + defaults: ThinkingConfig | undefined, ): ThinkingEffort { const configEffort = parseEffort(defaults?.effort) ?? DEFAULT_THINKING_EFFORT; const normalized = requested?.trim().toLowerCase(); diff --git a/packages/agent-core-v2/src/app/config/index.ts b/packages/agent-core-v2/src/app/config/index.ts index 790c1ce83..2aeac6632 100644 --- a/packages/agent-core-v2/src/app/config/index.ts +++ b/packages/agent-core-v2/src/app/config/index.ts @@ -6,4 +6,3 @@ export * from './config'; export * from './configService'; -export * from './thinking'; diff --git a/packages/agent-core-v2/test/config/thinking.test.ts b/packages/agent-core-v2/test/profile/thinking.test.ts similarity index 97% rename from packages/agent-core-v2/test/config/thinking.test.ts rename to packages/agent-core-v2/test/profile/thinking.test.ts index 5fe12cdc9..c8ae40261 100644 --- a/packages/agent-core-v2/test/config/thinking.test.ts +++ b/packages/agent-core-v2/test/profile/thinking.test.ts @@ -3,9 +3,9 @@ import { describe, expect, it } from 'vitest'; import { resolveThinkingEffort, resolveThinkingLevel, -} from '#/app/config/thinking'; +} from '#/agent/profile/thinking'; -describe('config/thinking', () => { +describe('profile/thinking', () => { describe('resolveThinkingEffort', () => { it('returns config effort when no request', () => { expect(resolveThinkingEffort(undefined, { effort: 'low' })).toBe('low');