Download packages/agent-core-v2/src/session/subagent/subagentService.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 9.29 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/session/subagent/subagentService.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/agent-core-v2/src/session/subagent/subagentService.ts
-
curl -L -o subagentService.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/session/subagent/subagentService.ts
9.29 kB
| import { Service } from '#/_base/di/service'; | |
| import type { AgentContext } from '#/agent/agentContext/agentContext'; | |
| import { Error2, ErrorCodes } from '#/errors'; | |
| import { LifecycleScope } from '#/app/scopes'; | |
| import { | |
| type IAgentScopeHandle, | |
| ScopeActivation, | |
| registerScopedService, | |
| } from '#/_base/di/scope'; | |
| import { Emitter } from '#/_base/event'; | |
| import { applyProfilePromptPrefix } from '#/app/agentProfileCatalog/promptPrefix'; | |
| import { | |
| rootDelegationExtras, | |
| subagentAllowlistFor, | |
| subagentTypeNotAllowedMessage, | |
| withoutDelegatingTargets, | |
| } from '#/app/agentProfileCatalog/profile-shared'; | |
| import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; | |
| import { IAgentProfileService } from '#/agent/profile/profile'; | |
| import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; | |
| import { IAgentUserToolService } from '#/agent/userTool/userTool'; | |
| import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; | |
| import type { Runtime } from '#/runtime/runtime'; | |
| import { IConfigService } from '#/app/config/config'; | |
| import { IModelCatalog, type Model } from '#/llm-adapter/model/catalog'; | |
| import { ILogService } from '#/_base/log/log'; | |
| import { ISessionContext } from '#/session/sessionContext/sessionContext'; | |
| import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; | |
| import { createHooks } from '#/hooks'; | |
| import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; | |
| import { agentContextOf } from '#/agent/scopeContext/scopeContext'; | |
| import { IAgentReminderService } from '#/features/reminder/reminderService'; | |
| import { | |
| type AgentRunHandle, | |
| type AgentRunRequest, | |
| type AgentTaskHooks, | |
| type AgentTaskStopHookContext, | |
| ISessionSubagentService, | |
| type RunAgentOptions, | |
| } from './subagent'; | |
| import { runAgentTurn } from './runAgentTurn'; | |
| import { | |
| resolveSubagentBinding, | |
| resolveSubagentThinking, | |
| wrapSubagentModelError, | |
| } from './configSection'; | |
| import { | |
| DEFAULT_PROFILE_NAME, | |
| FORK_CONTEXT_NOTICE, | |
| type SpawnSubagentOptions, | |
| type SpawnedSubagent, | |
| type SubagentSpawnPlan, | |
| type SubagentSpawnPlanInput, | |
| } from './spawn'; | |
| export class SessionSubagentService extends Service implements ISessionSubagentService { | |
| declare readonly _serviceBrand: undefined; | |
| readonly hooks = createHooks<AgentTaskHooks, keyof AgentTaskHooks>(['onWillStartAgentTask']); | |
| private readonly onDidStopAgentTaskEmitter = this._register( | |
| new Emitter<AgentTaskStopHookContext>(), | |
| ); | |
| get onDidStopAgentTask() { | |
| return this.onDidStopAgentTaskEmitter.event; | |
| } | |
| constructor( | |
| private readonly agentLifecycle: IAgentLifecycleService, | |
| private readonly catalog: ISessionAgentProfileCatalog, | |
| private readonly configService: IConfigService, | |
| private readonly modelCatalog: IModelCatalog, | |
| private readonly sessionContext: ISessionContext, | |
| private readonly log: ILogService, | |
| ) { | |
| super(); | |
| } | |
| run(agent: AgentContext, request: AgentRunRequest, opts: RunAgentOptions): Promise<AgentRunHandle> { | |
| const handle = this.agentLifecycle.handleOf(agent.agentId); | |
| if (handle === undefined) { | |
| throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Agent "${agent.agentId}" does not exist`, { | |
| details: { agentId: agent.agentId }, | |
| }); | |
| } | |
| return runAgentTurn(handle, request, { signal: opts.signal, onReady: opts.onReady }); | |
| } | |
| async planSpawn(input: SubagentSpawnPlanInput): Promise<SubagentSpawnPlan> { | |
| const caller = this.requireCaller(input.callerAgentId); | |
| const fork = input.fork === true; | |
| await this.catalog.ready; | |
| const own = caller.accessor.get(IAgentProfileService).data(); | |
| const requested = input.profileName !== undefined && input.profileName.length > 0 | |
| ? input.profileName | |
| : undefined; | |
| const requestedProfileName = | |
| requested ?? (fork ? (own.profileName ?? DEFAULT_PROFILE_NAME) : DEFAULT_PROFILE_NAME); | |
| const extras = | |
| input.callerAgentId === MAIN_AGENT_ID | |
| ? rootDelegationExtras(this.catalog, own, this.catalog.list()) | |
| : undefined; | |
| let allowlist = subagentAllowlistFor(this.catalog, own, extras); | |
| if (allowlist !== undefined && own.subagents === undefined) { | |
| allowlist = withoutDelegatingTargets(this.catalog, allowlist); | |
| } | |
| if (!fork && allowlist !== undefined && !allowlist.includes(requestedProfileName)) { | |
| throw new Error2( | |
| ErrorCodes.AGENT_TYPE_NOT_ALLOWED, | |
| subagentTypeNotAllowedMessage(requestedProfileName, allowlist), | |
| { details: { profileName: requestedProfileName, allowlist } }, | |
| ); | |
| } | |
| const profile = this.catalog.get(requestedProfileName); | |
| if (!fork && profile === undefined) { | |
| throw new Error2(ErrorCodes.PROFILE_UNKNOWN, `Unknown agent type: "${requestedProfileName}"`, { | |
| details: { profileName: requestedProfileName }, | |
| }); | |
| } | |
| if (own.modelAlias === undefined) { | |
| throw new Error2(ErrorCodes.MODEL_NOT_CONFIGURED, 'Caller agent has no model bound', { | |
| details: { agentId: input.callerAgentId }, | |
| }); | |
| } | |
| const binding = fork | |
| ? { model: own.modelAlias, thinking: own.thinkingLevel, modelSource: 'inherited' as const } | |
| : resolveSubagentBinding( | |
| this.configService, | |
| { modelAlias: own.modelAlias, thinkingLevel: own.thinkingLevel }, | |
| input.model, | |
| ); | |
| let model: Model; | |
| try { | |
| model = this.modelCatalog.get(binding.model); | |
| } catch (error) { | |
| throw wrapSubagentModelError(error, binding.model, own.modelAlias); | |
| } | |
| return { | |
| profileName: profile?.name ?? requestedProfileName, | |
| model: binding.model, | |
| modelSource: binding.modelSource, | |
| thinking: resolveSubagentThinking(this.configService, model, binding.thinking), | |
| fork, | |
| }; | |
| } | |
| async spawn(opts: SpawnSubagentOptions): Promise<SpawnedSubagent> { | |
| const caller = this.requireCaller(opts.callerAgentId); | |
| const { plan } = opts; | |
| const lease = plan.fork | |
| ? undefined | |
| : caller.accessor.get(IAgentRuntimeService).acquire(['process']); | |
| try { | |
| let created: IAgentScopeHandle; | |
| try { | |
| if (plan.fork) { | |
| const forked = await this.agentLifecycle.fork(agentContextOf(caller), { | |
| labels: opts.labels, | |
| }); | |
| created = this.agentLifecycle.handleOf(forked.agentId)!; | |
| created.accessor | |
| .get(IAgentReminderService) | |
| .notify(FORK_CONTEXT_NOTICE, { variant: 'fork_context' }); | |
| } else { | |
| const createdContext = await this.agentLifecycle.create({ | |
| binding: { | |
| profile: plan.profileName, | |
| model: plan.model, | |
| thinking: plan.thinking, | |
| }, | |
| labels: opts.labels, | |
| runtimeId: lease!.runtime.identity.runtimeId, | |
| }); | |
| created = this.agentLifecycle.handleOf(createdContext.agentId)!; | |
| } | |
| } catch (error) { | |
| throw wrapSubagentModelError( | |
| error, | |
| plan.model, | |
| caller.accessor.get(IAgentProfileService).data().modelAlias, | |
| ); | |
| } | |
| created.accessor | |
| .get(IAgentPermissionModeService) | |
| .setMode(caller.accessor.get(IAgentPermissionModeService).mode); | |
| const createdUserTools = created.accessor.get(IAgentUserToolService); | |
| const callerUserTools = caller.accessor.get(IAgentUserToolService); | |
| if (plan.fork) { | |
| const activeToolNames = created.accessor.get(IAgentProfileService).getActiveToolNames(); | |
| createdUserTools.inheritUserTools(callerUserTools, activeToolNames); | |
| } else { | |
| createdUserTools.inheritUserTools(callerUserTools); | |
| } | |
| const promptText = plan.fork | |
| ? opts.prompt | |
| : await this.applyPromptPrefix(plan.profileName, opts.prompt, lease!.runtime); | |
| return { | |
| agentId: created.id, | |
| profileName: plan.profileName, | |
| model: plan.model, | |
| modelSource: plan.modelSource, | |
| promptText, | |
| }; | |
| } finally { | |
| lease?.dispose(); | |
| } | |
| } | |
| notifyAgentTaskStopped(context: AgentTaskStopHookContext): void { | |
| this.onDidStopAgentTaskEmitter.fire(context); | |
| } | |
| private async applyPromptPrefix( | |
| profileName: string, | |
| prompt: string, | |
| runtime: Runtime, | |
| ): Promise<string> { | |
| const profile = this.catalog.get(profileName); | |
| if (profile?.promptPrefix === undefined) return prompt; | |
| const view = new RuntimeWorkspaceView(runtime, { | |
| workDir: this.sessionContext.cwd, | |
| }); | |
| return applyProfilePromptPrefix(profile, prompt, { | |
| cwd: view.workDir, | |
| process: runtime.process!, | |
| log: this.log, | |
| }); | |
| } | |
| private requireCaller(agentId: string): IAgentScopeHandle { | |
| const handle = this.agentLifecycle.handleOf(agentId); | |
| if (handle === undefined) { | |
| throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Caller agent "${agentId}" does not exist`, { | |
| details: { agentId }, | |
| }); | |
| } | |
| return handle; | |
| } | |
| } | |
| registerScopedService( | |
| LifecycleScope.Session, | |
| ISessionSubagentService, | |
| SessionSubagentService, | |
| ScopeActivation.OnScopeCreated, | |
| 'subagent', | |
| ); | |