From 21791a3f9a9a903ab1c2b26c7818b0077b9a73d3 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:40:52 +0800 Subject: [PATCH 1/9] refactor(agent-core): make Agent constructable --- packages/agent-core/src/agent/index.ts | 31 ++++++++++----------- packages/agent-core/src/agent/tool/index.ts | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index 8c6cacf805..e490c72a09 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -82,20 +82,20 @@ export interface AgentOptions { } export class Agent { + readonly type: AgentType; readonly runtime: RuntimeConfig; readonly kimiConfig?: KimiConfig; readonly homedir?: string; - readonly skills?: SkillManager; + readonly rpc?: SDKAgentRPC; readonly pluginSessionStarts: readonly EnabledPluginSessionStart[]; readonly rawGenerate: typeof generate; - readonly rpc?: SDKAgentRPC; + readonly providerManager?: ProviderManager; + readonly subagentHost?: SessionSubagentHost; + readonly mcp?: McpConnectionManager; + readonly hooks?: HookEngine; + readonly log: Logger; readonly telemetry: TelemetryClient; - readonly providerManager: ProviderManager | undefined; - readonly subagentHost: SessionSubagentHost | undefined; - readonly mcp: McpConnectionManager | undefined; - readonly hooks: HookEngine | undefined; - readonly type: AgentType; readonly blobStore: BlobStore | undefined; readonly records: AgentRecords; readonly fullCompaction: FullCompaction; @@ -107,30 +107,28 @@ export class Agent { readonly planMode: PlanMode; readonly usage: UsageRecorder; readonly tools: ToolManager; + readonly skills: SkillManager | null; readonly background: BackgroundManager; readonly cron: CronManager | null; readonly replayBuilder: ReplayBuilder; - readonly log: Logger; private lastLlmConfigLogSignature?: string; constructor(options: AgentOptions) { - this.log = options.log ?? log; - this.kimiConfig = options.config; + this.type = options.type ?? 'main'; this.runtime = options.runtime; + this.kimiConfig = options.config; this.homedir = options.homedir; - if (options.skills !== undefined) { - this.skills = new SkillManager(this, options.skills); - } + this.rpc = options.rpc; this.pluginSessionStarts = options.pluginSessionStarts ?? []; this.rawGenerate = options.generate ?? generate; this.providerManager = options.providerManager; this.subagentHost = options.subagentHost; this.mcp = options.mcp; this.hooks = options.hookEngine; - this.type = options.type ?? 'main'; - this.rpc = options.rpc; + this.log = options.log ?? log; this.telemetry = options.telemetry ?? noopTelemetryClient; + this.blobStore = options.homedir ? new BlobStore({ blobsDir: join(options.homedir, 'blobs') }) : undefined; @@ -155,6 +153,7 @@ export class Agent { this.planMode = new PlanMode(this); this.usage = new UsageRecorder(this); this.tools = new ToolManager(this); + this.skills = options.skills === undefined ? null : new SkillManager(this, options.skills); this.background = new BackgroundManager(this); this.cron = this.type === 'sub' ? null : new CronManager(this); this.replayBuilder = new ReplayBuilder(this); @@ -344,7 +343,7 @@ export class Agent { this.context.clear(); }, activateSkill: (payload) => { - if (this.skills === undefined) { + if (this.skills === null) { throw new KimiError(ErrorCodes.SKILL_NOT_FOUND, `Skill "${payload.name}" was not found`); } this.skills.activate(payload); diff --git a/packages/agent-core/src/agent/tool/index.ts b/packages/agent-core/src/agent/tool/index.ts index 1d255d0792..313f82b3ad 100644 --- a/packages/agent-core/src/agent/tool/index.ts +++ b/packages/agent-core/src/agent/tool/index.ts @@ -377,7 +377,7 @@ export class ToolManager { this.agent.cron && new b.CronCreateTool(this.agent.cron), this.agent.cron && new b.CronListTool(this.agent.cron), this.agent.cron && new b.CronDeleteTool(this.agent.cron), - this.agent.skills !== undefined && + this.agent.skills !== null && this.agent.skills.registry.listInvocableSkills().length > 0 && new b.SkillTool(this.agent), this.agent.subagentHost && From cd3476d9da6193919f79dcbf62158deec5e5ab47 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:45:02 +0800 Subject: [PATCH 2/9] wip --- packages/agent-core/src/agent/compaction/full.ts | 2 +- packages/agent-core/src/agent/config/index.ts | 2 +- packages/agent-core/src/agent/index.ts | 4 ++-- packages/agent-core/src/agent/tool/index.ts | 2 +- packages/agent-core/src/agent/turn/index.ts | 2 +- packages/agent-core/src/session/provider-manager.ts | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/agent-core/src/agent/compaction/full.ts b/packages/agent-core/src/agent/compaction/full.ts index d3d008a46a..34c699aa06 100644 --- a/packages/agent-core/src/agent/compaction/full.ts +++ b/packages/agent-core/src/agent/compaction/full.ts @@ -61,7 +61,7 @@ export class FullCompaction { { ...DEFAULT_COMPACTION_CONFIG, reservedContextSize: - agent.providerManager?.config.loopControl?.reservedContextSize ?? + agent.kimiConfig?.loopControl?.reservedContextSize ?? DEFAULT_COMPACTION_CONFIG.reservedContextSize, } ); diff --git a/packages/agent-core/src/agent/config/index.ts b/packages/agent-core/src/agent/config/index.ts index 653c99fe76..79b20a7711 100644 --- a/packages/agent-core/src/agent/config/index.ts +++ b/packages/agent-core/src/agent/config/index.ts @@ -50,7 +50,7 @@ export class ConfigState { if (changed.thinkingLevel !== undefined) { this._thinkingLevel = resolveThinkingEffort( changed.thinkingLevel, - this.agent.providerManager?.config.thinking, + this.agent.kimiConfig?.thinking, ); } if (changed.systemPrompt !== undefined) { diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index e490c72a09..aa61d44cbd 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -169,7 +169,7 @@ export class Agent { const withAuth = modelAlias === undefined ? undefined - : this.providerManager?.createAuthResolverForModel(modelAlias, { log: this.log }); + : this.providerManager?.resolveAuth(modelAlias, { log: this.log }); if (withAuth === undefined) { this.logLlmRequest(provider, systemPrompt, tools, history, options); return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, options); @@ -185,7 +185,7 @@ export class Agent { get llm(): KosongLLM { const model = this.config.model; const provider = this.config.provider.withThinking(this.config.thinkingLevel); - const loopControl = this.providerManager?.config.loopControl; + const loopControl = this.kimiConfig?.loopControl; const completionBudgetConfig = resolveCompletionBudget({ reservedContextSize: loopControl?.reservedContextSize, }); diff --git a/packages/agent-core/src/agent/tool/index.ts b/packages/agent-core/src/agent/tool/index.ts index 313f82b3ad..c03c5deca0 100644 --- a/packages/agent-core/src/agent/tool/index.ts +++ b/packages/agent-core/src/agent/tool/index.ts @@ -403,7 +403,7 @@ export class ToolManager { if (uploadVideo === undefined) return undefined; const modelAlias = this.agent.config.modelAlias!; - const withAuth = this.agent.providerManager?.createAuthResolverForModel(modelAlias, { + const withAuth = this.agent.providerManager?.resolveAuth(modelAlias, { log: this.agent.log, }); if (withAuth === undefined) return (input) => uploadVideo(input); diff --git a/packages/agent-core/src/agent/turn/index.ts b/packages/agent-core/src/agent/turn/index.ts index e4a7b1c444..c14a4727f3 100644 --- a/packages/agent-core/src/agent/turn/index.ts +++ b/packages/agent-core/src/agent/turn/index.ts @@ -362,7 +362,7 @@ export class TurnFlow { while (true) { signal.throwIfAborted(); const model = this.agent.config.model; - const loopControl = this.agent.providerManager?.config.loopControl; + const loopControl = this.agent.kimiConfig?.loopControl; try { const result = await runTurn({ turnId: String(turnId), diff --git a/packages/agent-core/src/session/provider-manager.ts b/packages/agent-core/src/session/provider-manager.ts index 402d9ed43b..1366b5aa8b 100644 --- a/packages/agent-core/src/session/provider-manager.ts +++ b/packages/agent-core/src/session/provider-manager.ts @@ -34,7 +34,7 @@ type AuthorizedRequest = ( export class ProviderManager { constructor(private readonly options: ProviderManagerOptions) {} - get config(): KimiConfig { + private get config(): KimiConfig { const { config } = this.options; return typeof config === 'function' ? config() : config; } @@ -88,7 +88,7 @@ export class ProviderManager { }; } - createAuthResolverForModel( + resolveAuth( model: string, options?: { readonly log?: Logger }, ): AuthorizedRequest | undefined { From 1e1aa347830ac598cca080e6360a7fdcddb72f8b Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:52:53 +0800 Subject: [PATCH 3/9] feat: SingleModelProvider --- packages/agent-core/src/agent/config/index.ts | 2 +- packages/agent-core/src/agent/index.ts | 12 ++++----- packages/agent-core/src/agent/tool/index.ts | 2 +- packages/agent-core/src/session/index.ts | 2 +- .../src/session/provider-manager.ts | 27 ++++++++++++++++--- .../agent-core/test/agent/compaction.test.ts | 2 +- .../agent-core/test/agent/harness/agent.ts | 2 +- .../test/agent/skill-tool-manager.test.ts | 2 +- .../test/harness/runtime-provider.test.ts | 2 -- 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/packages/agent-core/src/agent/config/index.ts b/packages/agent-core/src/agent/config/index.ts index 79b20a7711..4af98fd0b4 100644 --- a/packages/agent-core/src/agent/config/index.ts +++ b/packages/agent-core/src/agent/config/index.ts @@ -128,7 +128,7 @@ export class ConfigState { private get resolvedProviderConfig(): ResolvedRuntimeProvider | undefined { if (this._modelAlias === undefined) return undefined; - return this.agent.providerManager?.resolveProviderConfig(this._modelAlias); + return this.agent.modelProvider?.resolveProviderConfig(this._modelAlias); } private tryResolvedProviderConfig(): ResolvedRuntimeProvider | undefined { diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index aa61d44cbd..74117ae696 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -16,7 +16,7 @@ import type { EnabledPluginSessionStart } from '#/plugin'; import type { McpConnectionManager } from '../mcp'; import type { PreparedSystemPromptContext, ResolvedAgentProfile } from '../profile'; -import type { ProviderManager } from '../session/provider-manager'; +import type { ModelProvider } from '../session/provider-manager'; import type { RuntimeConfig } from '../runtime-types'; import type { SessionSubagentHost } from '../session/subagent-host'; import type { SkillRegistry } from '../skill'; @@ -69,7 +69,7 @@ export interface AgentOptions { readonly type?: AgentType; readonly generate?: typeof generate; readonly compactionStrategy?: CompactionStrategy; - readonly providerManager?: ProviderManager | undefined; + readonly modelProvider?: ModelProvider | undefined; readonly subagentHost?: SessionSubagentHost | undefined; readonly skills?: SkillRegistry; readonly mcp?: McpConnectionManager; @@ -89,7 +89,7 @@ export class Agent { readonly rpc?: SDKAgentRPC; readonly pluginSessionStarts: readonly EnabledPluginSessionStart[]; readonly rawGenerate: typeof generate; - readonly providerManager?: ProviderManager; + readonly modelProvider?: ModelProvider; readonly subagentHost?: SessionSubagentHost; readonly mcp?: McpConnectionManager; readonly hooks?: HookEngine; @@ -122,7 +122,7 @@ export class Agent { this.rpc = options.rpc; this.pluginSessionStarts = options.pluginSessionStarts ?? []; this.rawGenerate = options.generate ?? generate; - this.providerManager = options.providerManager; + this.modelProvider = options.modelProvider; this.subagentHost = options.subagentHost; this.mcp = options.mcp; this.hooks = options.hookEngine; @@ -169,7 +169,7 @@ export class Agent { const withAuth = modelAlias === undefined ? undefined - : this.providerManager?.resolveAuth(modelAlias, { log: this.log }); + : this.modelProvider?.resolveAuth?.(modelAlias, { log: this.log }); if (withAuth === undefined) { this.logLlmRequest(provider, systemPrompt, tools, history, options); return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, options); @@ -298,7 +298,7 @@ export class Agent { // Validate the alias resolves before recording it so resume / runtime // callers fail fast on missing aliases instead of deferring to the // next prompt. - const resolved = this.providerManager?.resolveProviderConfig(payload.model); + const resolved = this.modelProvider?.resolveProviderConfig(payload.model); if (this.config.modelAlias !== payload.model) { this.config.update({ modelAlias: payload.model }); this.telemetry.track('model_switch', { model: payload.model }); diff --git a/packages/agent-core/src/agent/tool/index.ts b/packages/agent-core/src/agent/tool/index.ts index c03c5deca0..0b222665c9 100644 --- a/packages/agent-core/src/agent/tool/index.ts +++ b/packages/agent-core/src/agent/tool/index.ts @@ -403,7 +403,7 @@ export class ToolManager { if (uploadVideo === undefined) return undefined; const modelAlias = this.agent.config.modelAlias!; - const withAuth = this.agent.providerManager?.resolveAuth(modelAlias, { + const withAuth = this.agent.modelProvider?.resolveAuth?.(modelAlias, { log: this.agent.log, }); if (withAuth === undefined) return (input) => uploadVideo(input); diff --git a/packages/agent-core/src/session/index.ts b/packages/agent-core/src/session/index.ts index 5e3d77ea49..222872f271 100644 --- a/packages/agent-core/src/session/index.ts +++ b/packages/agent-core/src/session/index.ts @@ -413,7 +413,7 @@ export class Session { homedir, skills: this.skills, rpc: proxyWithExtraPayload(this.rpc, { agentId: id }), - providerManager: this.options.providerManager, + modelProvider: this.options.providerManager, hookEngine: config.hookEngine ?? this.hookEngine, subagentHost: config.subagentHost ?? new SessionSubagentHost(this, id, this.backgroundTaskTimeoutMs()), diff --git a/packages/agent-core/src/session/provider-manager.ts b/packages/agent-core/src/session/provider-manager.ts index 1366b5aa8b..bf09eb6724 100644 --- a/packages/agent-core/src/session/provider-manager.ts +++ b/packages/agent-core/src/session/provider-manager.ts @@ -14,7 +14,6 @@ export type OAuthTokenProviderResolver = ( ) => BearerTokenProvider | undefined; export interface ResolvedRuntimeProvider { - readonly modelName: string; readonly providerName: string; readonly provider: KosongProviderConfig; readonly modelCapabilities: ModelCapability; @@ -31,7 +30,30 @@ type AuthorizedRequest = ( request: (auth: ProviderRequestAuth) => Promise, ) => Promise; -export class ProviderManager { +export interface ModelProvider { + resolveProviderConfig(model: string): ResolvedRuntimeProvider; + resolveAuth?(model: string, options?: { readonly log?: Logger }): AuthorizedRequest | undefined; +} + +export class SingleModelProvider implements ModelProvider { + constructor( + private readonly providerConfig: KosongProviderConfig, + private readonly modelCapabilities: ModelCapability = UNKNOWN_CAPABILITY, + ) {} + + resolveProviderConfig(model: string): ResolvedRuntimeProvider { + if (model !== this.providerConfig.model) { + throw new Error(`Model "${model}" is not supported by SingleModelProvider.`); + } + return { + modelCapabilities: this.modelCapabilities, + providerName: 'single-model-provider', + provider: this.providerConfig, + } + } +} + +export class ProviderManager implements ModelProvider { constructor(private readonly options: ProviderManagerOptions) {} private get config(): KimiConfig { @@ -81,7 +103,6 @@ export class ProviderManager { ); return { - modelName: model, providerName, provider, modelCapabilities: resolveModelCapabilities(alias, provider), diff --git a/packages/agent-core/test/agent/compaction.test.ts b/packages/agent-core/test/agent/compaction.test.ts index d82acee4fc..87e955ae3a 100644 --- a/packages/agent-core/test/agent/compaction.test.ts +++ b/packages/agent-core/test/agent/compaction.test.ts @@ -1309,7 +1309,7 @@ describe('Agent compaction', () => { provider: CATALOGUED_PROVIDER, modelCapabilities: CATALOGUED_MODEL_CAPABILITIES, }); - const providerManager = ctx.agent.providerManager; + const providerManager = ctx.agent.modelProvider; if (providerManager === undefined) throw new Error('Expected provider manager'); const resolveProviderConfig = providerManager.resolveProviderConfig.bind(providerManager); providerManager.resolveProviderConfig = (model) => ({ diff --git a/packages/agent-core/test/agent/harness/agent.ts b/packages/agent-core/test/agent/harness/agent.ts index b38f682c14..120bffe0c6 100644 --- a/packages/agent-core/test/agent/harness/agent.ts +++ b/packages/agent-core/test/agent/harness/agent.ts @@ -181,7 +181,7 @@ export class AgentTestContext { persistence, generate: options.generate ?? this.scriptedGenerate.generate, compactionStrategy: options.compactionStrategy, - providerManager, + modelProvider: providerManager, subagentHost: options.subagentHost, type: options.type, permission: options.permission, diff --git a/packages/agent-core/test/agent/skill-tool-manager.test.ts b/packages/agent-core/test/agent/skill-tool-manager.test.ts index 06eba5b819..4eff1dc68d 100644 --- a/packages/agent-core/test/agent/skill-tool-manager.test.ts +++ b/packages/agent-core/test/agent/skill-tool-manager.test.ts @@ -51,7 +51,7 @@ function makeAgent( rpc, skills, persistence, - providerManager: testProviderManager(), + modelProvider: testProviderManager(), }); agent.config.update({ cwd: process.cwd(), diff --git a/packages/agent-core/test/harness/runtime-provider.test.ts b/packages/agent-core/test/harness/runtime-provider.test.ts index ece99af8f9..a0b3e8c7cc 100644 --- a/packages/agent-core/test/harness/runtime-provider.test.ts +++ b/packages/agent-core/test/harness/runtime-provider.test.ts @@ -67,7 +67,6 @@ describe('resolveRuntimeProvider model metadata', () => { tool_use: true, max_context_tokens: 1_000_000, }); - expect(resolved.modelName).toBe('kimi-code/kimi-for-coding'); expect(resolved.provider.model).toBe('kimi-for-coding'); }); @@ -97,7 +96,6 @@ describe('resolveRuntimeProvider model metadata', () => { }); expect(resolved.providerName).toBe('openai'); - expect(resolved.modelName).toBe('gpt-alias'); expect(resolved.provider).toMatchObject({ type: 'openai', model: 'gpt-runtime', From 45b98959975f63248361bfbe84efc41281aa0d37 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:54:07 +0800 Subject: [PATCH 4/9] fix --- packages/agent-core/src/agent/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index 74117ae696..4f70230a1d 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -74,7 +74,6 @@ export interface AgentOptions { readonly skills?: SkillRegistry; readonly mcp?: McpConnectionManager; readonly hookEngine?: HookEngine; - readonly cronSessionDir?: string; readonly permission?: PermissionManagerOptions | undefined; readonly log?: Logger; readonly telemetry?: TelemetryClient | undefined; From ab7cf1d138eb3eb612e6951467f4d609f9948cad Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:55:48 +0800 Subject: [PATCH 5/9] fix --- packages/agent-core/src/agent/config/index.ts | 1 + packages/agent-core/src/session/provider-manager.ts | 5 +++++ packages/agent-core/test/agent/harness/agent.ts | 1 + 3 files changed, 7 insertions(+) diff --git a/packages/agent-core/src/agent/config/index.ts b/packages/agent-core/src/agent/config/index.ts index 4af98fd0b4..83d8c20c23 100644 --- a/packages/agent-core/src/agent/config/index.ts +++ b/packages/agent-core/src/agent/config/index.ts @@ -24,6 +24,7 @@ export class ConfigState { constructor(protected readonly agent: Agent) { this._cwd = agent.runtime.kaos.getcwd(); + this._modelAlias = agent.modelProvider?.defaultModel; } update(changed: AgentConfigUpdateData): void { diff --git a/packages/agent-core/src/session/provider-manager.ts b/packages/agent-core/src/session/provider-manager.ts index bf09eb6724..9b85a0a4de 100644 --- a/packages/agent-core/src/session/provider-manager.ts +++ b/packages/agent-core/src/session/provider-manager.ts @@ -31,6 +31,7 @@ type AuthorizedRequest = ( ) => Promise; export interface ModelProvider { + readonly defaultModel?: string; resolveProviderConfig(model: string): ResolvedRuntimeProvider; resolveAuth?(model: string, options?: { readonly log?: Logger }): AuthorizedRequest | undefined; } @@ -41,6 +42,10 @@ export class SingleModelProvider implements ModelProvider { private readonly modelCapabilities: ModelCapability = UNKNOWN_CAPABILITY, ) {} + get defaultModel(): string { + return this.providerConfig.model; + } + resolveProviderConfig(model: string): ResolvedRuntimeProvider { if (model !== this.providerConfig.model) { throw new Error(`Model "${model}" is not supported by SingleModelProvider.`); diff --git a/packages/agent-core/test/agent/harness/agent.ts b/packages/agent-core/test/agent/harness/agent.ts index 120bffe0c6..481a2de7eb 100644 --- a/packages/agent-core/test/agent/harness/agent.ts +++ b/packages/agent-core/test/agent/harness/agent.ts @@ -177,6 +177,7 @@ export class AgentTestContext { ); this.agent = new Agent({ runtime, + config: this.kimiConfig, rpc: this.createRpcProxy(), persistence, generate: options.generate ?? this.scriptedGenerate.generate, From 4620122725fdf5899fb563afc3bea09ed9a9f0d0 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:57:00 +0800 Subject: [PATCH 6/9] chore: add changeset for constructable agent refactor --- .changeset/constructable-agent-model-provider.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/constructable-agent-model-provider.md diff --git a/.changeset/constructable-agent-model-provider.md b/.changeset/constructable-agent-model-provider.md new file mode 100644 index 0000000000..e6bd10507f --- /dev/null +++ b/.changeset/constructable-agent-model-provider.md @@ -0,0 +1,6 @@ +--- +"@moonshot-ai/agent-core": patch +"@moonshot-ai/kimi-code": patch +--- + +Introduce `ModelProvider` interface and `SingleModelProvider` to decouple `Agent` from `ProviderManager`. From 3f85d5afa6570d645437ac3c934077b2d73e49e9 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 21:59:40 +0800 Subject: [PATCH 7/9] fix --- .../agent-core/src/tools/builtin/collaboration/skill-tool.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/agent-core/src/tools/builtin/collaboration/skill-tool.ts b/packages/agent-core/src/tools/builtin/collaboration/skill-tool.ts index b7350e3c2a..db40cdfd21 100644 --- a/packages/agent-core/src/tools/builtin/collaboration/skill-tool.ts +++ b/packages/agent-core/src/tools/builtin/collaboration/skill-tool.ts @@ -105,7 +105,7 @@ export class SkillTool implements BuiltinTool { } const skills = this.agent.skills; - if (skills === undefined) { + if (skills === null) { return errorResult(`Skill "${args.skill}" not found in the current skill listing.`); } const skill = skills.registry.getSkill(args.skill); From 0680d4012d9b34a38848c478442314078cb2118c Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 22:06:34 +0800 Subject: [PATCH 8/9] fix --- packages/agent-core/src/agent/tool/index.ts | 3 +++ packages/agent-core/src/index.ts | 2 ++ packages/agent-core/src/session/provider-manager.ts | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/agent-core/src/agent/tool/index.ts b/packages/agent-core/src/agent/tool/index.ts index 0b222665c9..07dac46cbf 100644 --- a/packages/agent-core/src/agent/tool/index.ts +++ b/packages/agent-core/src/agent/tool/index.ts @@ -43,6 +43,9 @@ export class ToolManager { constructor(protected readonly agent: Agent) { this.attachMcpTools(); + if (agent.config.hasProvider) { + this.initializeBuiltinTools(); + } } protected get toolStore(): ToolStore { diff --git a/packages/agent-core/src/index.ts b/packages/agent-core/src/index.ts index cba2de5081..7e78d3103c 100644 --- a/packages/agent-core/src/index.ts +++ b/packages/agent-core/src/index.ts @@ -40,8 +40,10 @@ export type { BackgroundTaskStatus, } from './tools/background/manager'; export type { RuntimeConfig } from './runtime-types'; +export { SingleModelProvider } from './session/provider-manager'; export type { BearerTokenProvider, + ModelProvider, OAuthTokenProviderResolver, } from './session/provider-manager'; diff --git a/packages/agent-core/src/session/provider-manager.ts b/packages/agent-core/src/session/provider-manager.ts index 9b85a0a4de..c0e3917900 100644 --- a/packages/agent-core/src/session/provider-manager.ts +++ b/packages/agent-core/src/session/provider-manager.ts @@ -48,7 +48,10 @@ export class SingleModelProvider implements ModelProvider { resolveProviderConfig(model: string): ResolvedRuntimeProvider { if (model !== this.providerConfig.model) { - throw new Error(`Model "${model}" is not supported by SingleModelProvider.`); + throw new KimiError( + ErrorCodes.CONFIG_INVALID, + `Model "${model}" is not supported by SingleModelProvider.`, + ); } return { modelCapabilities: this.modelCapabilities, From 2fa39d165c05881100ca38de9680e18e66e54e0f Mon Sep 17 00:00:00 2001 From: _Kerman Date: Thu, 28 May 2026 22:25:43 +0800 Subject: [PATCH 9/9] fix --- packages/agent-core/src/agent/index.ts | 10 +++++----- packages/agent-core/src/agent/permission/index.ts | 10 +++++----- packages/agent-core/src/agent/tool/index.ts | 7 +++---- .../src/tools/builtin/collaboration/ask-user.ts | 2 +- packages/agent-core/test/agent/question.test.ts | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index 4f70230a1d..f9b0d15f6e 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -64,7 +64,7 @@ export interface AgentOptions { readonly runtime: RuntimeConfig; readonly config?: KimiConfig; readonly homedir?: string; - readonly rpc?: SDKAgentRPC; + readonly rpc?: Partial; readonly persistence?: AgentRecordPersistence; readonly type?: AgentType; readonly generate?: typeof generate; @@ -85,7 +85,7 @@ export class Agent { readonly runtime: RuntimeConfig; readonly kimiConfig?: KimiConfig; readonly homedir?: string; - readonly rpc?: SDKAgentRPC; + readonly rpc?: Partial; readonly pluginSessionStarts: readonly EnabledPluginSessionStart[]; readonly rawGenerate: typeof generate; readonly modelProvider?: ModelProvider; @@ -105,8 +105,8 @@ export class Agent { readonly permission: PermissionManager; readonly planMode: PlanMode; readonly usage: UsageRecorder; - readonly tools: ToolManager; readonly skills: SkillManager | null; + readonly tools: ToolManager; readonly background: BackgroundManager; readonly cron: CronManager | null; readonly replayBuilder: ReplayBuilder; @@ -151,8 +151,8 @@ export class Agent { this.permission = new PermissionManager(this, options.permission); this.planMode = new PlanMode(this); this.usage = new UsageRecorder(this); + this.skills = options.skills ? new SkillManager(this, options.skills) : null; this.tools = new ToolManager(this); - this.skills = options.skills === undefined ? null : new SkillManager(this, options.skills); this.background = new BackgroundManager(this); this.cron = this.type === 'sub' ? null : new CronManager(this); this.replayBuilder = new ReplayBuilder(this); @@ -361,7 +361,7 @@ export class Agent { emitEvent(event: AgentEvent): void { if (this.records.restoring) return; - void this.rpc?.emitEvent(event); + void this.rpc?.emitEvent?.(event); } emitStatusUpdated(): void { diff --git a/packages/agent-core/src/agent/permission/index.ts b/packages/agent-core/src/agent/permission/index.ts index 6acfa450a2..ddd51d5298 100644 --- a/packages/agent-core/src/agent/permission/index.ts +++ b/packages/agent-core/src/agent/permission/index.ts @@ -131,11 +131,7 @@ export class PermissionManager { const startedAt = Date.now(); let response: ApprovalResponse; - if (this.agent.rpc === undefined) { - response = { - decision: 'approved', - }; - } else { + if (this.agent.rpc?.requestApproval) { try { response = await this.agent.rpc.requestApproval( { @@ -163,6 +159,10 @@ export class PermissionManager { ? Promise.reject(error) : this.permissionPolicyResolutionToPrepare(resolved, context, policyName); } + } else { + response = { + decision: 'approved', + }; } const sessionApprovalRule = diff --git a/packages/agent-core/src/agent/tool/index.ts b/packages/agent-core/src/agent/tool/index.ts index 07dac46cbf..77c7dde3f2 100644 --- a/packages/agent-core/src/agent/tool/index.ts +++ b/packages/agent-core/src/agent/tool/index.ts @@ -96,7 +96,7 @@ export class ToolManager { return { approvalRule: name, execute: async (context) => { - return this.agent.rpc!.toolCall( + return this.agent.rpc!.toolCall!( { turnId: Number(context.turnId), toolCallId: context.toolCallId, @@ -372,7 +372,7 @@ export class ToolManager { new b.ReadMediaFileTool(kaos, workspace, modelCapabilities, videoUploader), new b.EnterPlanModeTool(this.agent), new b.ExitPlanModeTool(this.agent), - this.agent.rpc && new b.AskUserQuestionTool(this.agent), + this.agent.rpc?.requestQuestion && new b.AskUserQuestionTool(this.agent), new b.TodoListTool(this.toolStore), new b.TaskListTool(background), new b.TaskOutputTool(background), @@ -380,8 +380,7 @@ export class ToolManager { this.agent.cron && new b.CronCreateTool(this.agent.cron), this.agent.cron && new b.CronListTool(this.agent.cron), this.agent.cron && new b.CronDeleteTool(this.agent.cron), - this.agent.skills !== null && - this.agent.skills.registry.listInvocableSkills().length > 0 && + this.agent.skills?.registry.listInvocableSkills().length && new b.SkillTool(this.agent), this.agent.subagentHost && new b.AgentTool( diff --git a/packages/agent-core/src/tools/builtin/collaboration/ask-user.ts b/packages/agent-core/src/tools/builtin/collaboration/ask-user.ts index 1c71d7ce37..9ee7dc7788 100644 --- a/packages/agent-core/src/tools/builtin/collaboration/ask-user.ts +++ b/packages/agent-core/src/tools/builtin/collaboration/ask-user.ts @@ -104,7 +104,7 @@ export class AskUserQuestionTool implements BuiltinTool { }: ExecutableToolContext, ): Promise { try { - const result = await this.agent.rpc!.requestQuestion( + const result = await this.agent.rpc!.requestQuestion!( { turnId: numericTurnId(turnId), toolCallId, diff --git a/packages/agent-core/test/agent/question.test.ts b/packages/agent-core/test/agent/question.test.ts index aef540c082..624d25b620 100644 --- a/packages/agent-core/test/agent/question.test.ts +++ b/packages/agent-core/test/agent/question.test.ts @@ -6,7 +6,7 @@ describe('Agent question', () => { it('roundtrips a question request through wire rpc', async () => { const ctx = testAgent(); - const resultPromise = ctx.agent.rpc!.requestQuestion( + const resultPromise = ctx.agent.rpc!.requestQuestion!( { questions: [ { @@ -29,7 +29,7 @@ describe('Agent question', () => { it('sends multiple questions in one request', async () => { const ctx = testAgent(); - const resultPromise = ctx.agent.rpc!.requestQuestion( + const resultPromise = ctx.agent.rpc!.requestQuestion!( { questions: [ {