Download packages/agent-core-v2/src/agent/userTool/userToolService.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 5.82 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/agent/userTool/userToolService.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/agent-core-v2/src/agent/userTool/userToolService.ts
-
curl -L -o userToolService.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/src/agent/userTool/userToolService.ts
5.82 kB
| import { randomUUID } from 'node:crypto'; | |
| import { type IDisposable } from '#/_base/di/lifecycle'; | |
| import { Service } from '#/_base/di/service'; | |
| import { LifecycleScope } from '#/app/scopes'; | |
| import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; | |
| import { abortable } from '#/_base/utils/abort'; | |
| import { IAgentProfileService } from '#/agent/profile/profile'; | |
| import type { | |
| ExecutableTool, | |
| ExecutableToolContext, | |
| ExecutableToolResult, | |
| } from '#/tool/toolContract'; | |
| import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; | |
| import { IAgentStateService } from '#/agent/state/agentState'; | |
| import { | |
| INTERACTION_TAG_AGENT_ID, | |
| INTERACTION_TAG_SESSION_ID, | |
| INTERACTION_TAG_TOOL_CALL_ID, | |
| INTERACTION_TAG_TURN_ID, | |
| type InteractionTags, | |
| } from '#/human/interaction/interaction'; | |
| import { interactions } from '#/human/interaction/facade'; | |
| import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; | |
| import { ISessionContext } from '#/session/sessionContext/sessionContext'; | |
| import { IEventDispatcher } from '#/state/eventDispatcher'; | |
| import { IAgentUserToolService, type UserToolRegistration } from './userTool'; | |
| import { | |
| ToolsRegisterUserTool, | |
| ToolsUnregisterUserTool, | |
| userToolKey, | |
| } from './userToolOps'; | |
| interface UserToolExecutionRequest { | |
| readonly turnId?: number; | |
| readonly toolCallId: string; | |
| readonly name: string; | |
| readonly args: unknown; | |
| } | |
| export class AgentUserToolService extends Service implements IAgentUserToolService { | |
| declare readonly _serviceBrand: undefined; | |
| private readonly registrations = new Map<string, IDisposable>(); | |
| constructor( | |
| private readonly scopeContext: IAgentScopeContext, | |
| private readonly registry: IAgentToolRegistryService, | |
| private readonly profile: IAgentProfileService, | |
| private readonly session: ISessionContext, | |
| private readonly dispatcher: IEventDispatcher, | |
| private readonly agentState: IAgentStateService, | |
| ) { | |
| super(); | |
| this.agentState.contributeState(userToolKey); | |
| this._register( | |
| this.dispatcher.hooks.onDidRestore.register('user-tool', async (_ctx, next) => { | |
| this.restoreRegisteredTools(); | |
| await next(); | |
| }), | |
| ); | |
| } | |
| list(): readonly UserToolRegistration[] { | |
| return [...this.agentState.get(userToolKey).values()]; | |
| } | |
| inheritUserTools( | |
| parent: IAgentUserToolService, | |
| activeToolNames?: readonly string[], | |
| ): void { | |
| for (const registration of parent.list()) { | |
| void this.dispatcher.dispatch( | |
| new ToolsRegisterUserTool({ ...registration, agentId: this.scopeContext.agentId }), | |
| ); | |
| const activate = | |
| activeToolNames === undefined || activeToolNames.includes(registration.name); | |
| this.applyRegister(registration, { activate }); | |
| } | |
| } | |
| register(input: UserToolRegistration): void { | |
| void this.dispatcher.dispatch( | |
| new ToolsRegisterUserTool({ ...input, agentId: this.scopeContext.agentId }), | |
| ); | |
| this.applyRegister(input); | |
| } | |
| unregister(name: string): void { | |
| void this.dispatcher.dispatch( | |
| new ToolsUnregisterUserTool({ agentId: this.scopeContext.agentId, name }), | |
| ); | |
| this.applyUnregister(name); | |
| } | |
| private restoreRegisteredTools(): void { | |
| const persistedActive = this.profile.getActiveToolNames(); | |
| for (const registration of this.agentState.get(userToolKey).values()) { | |
| const activate = | |
| persistedActive === undefined || persistedActive.includes(registration.name); | |
| this.applyRegister(registration, { activate }); | |
| } | |
| } | |
| private applyRegister(input: UserToolRegistration, options?: { readonly activate?: boolean }): void { | |
| const { name, description, parameters } = input; | |
| this.applyUnregister(name); | |
| const tool: ExecutableTool = { | |
| name, | |
| description, | |
| parameters, | |
| resolveExecution: (args) => ({ | |
| approvalRule: name, | |
| execute: (context) => this.executeUserTool(context, name, args), | |
| }), | |
| }; | |
| this.registrations.set( | |
| name, | |
| this._register( | |
| this.registry.register(tool, { source: 'user', disclosure: input.disclosure }), | |
| ), | |
| ); | |
| if (options?.activate === false) return; | |
| this.profile.addActiveTool(name); | |
| } | |
| private applyUnregister(name: string): void { | |
| const registration = this.registrations.get(name); | |
| if (registration === undefined) return; | |
| registration.dispose(); | |
| this.registrations.delete(name); | |
| this.profile.removeActiveTool(name); | |
| } | |
| private async executeUserTool( | |
| context: ExecutableToolContext, | |
| name: string, | |
| args: unknown, | |
| ): Promise<ExecutableToolResult> { | |
| const id = `user_tool_${randomUUID()}`; | |
| const tags: InteractionTags = { | |
| [INTERACTION_TAG_AGENT_ID]: this.scopeContext.agentId, | |
| [INTERACTION_TAG_SESSION_ID]: this.session.sessionId, | |
| [INTERACTION_TAG_TOOL_CALL_ID]: context.toolCallId, | |
| }; | |
| if (context.turnId !== undefined) tags[INTERACTION_TAG_TURN_ID] = context.turnId; | |
| const request = interactions.request<UserToolExecutionRequest, ExecutableToolResult>({ | |
| id, | |
| kind: 'user_tool', | |
| payload: { | |
| turnId: context.turnId, | |
| toolCallId: context.toolCallId, | |
| name, | |
| args, | |
| }, | |
| tags, | |
| }); | |
| try { | |
| return await abortable(request, context.signal); | |
| } catch (error) { | |
| if (context.signal.aborted) { | |
| interactions.respond(id, { | |
| output: `User tool "${name}" was aborted.`, | |
| isError: true, | |
| }); | |
| } | |
| throw error; | |
| } | |
| } | |
| } | |
| registerScopedService( | |
| LifecycleScope.Agent, | |
| IAgentUserToolService, | |
| AgentUserToolService, | |
| ScopeActivation.OnScopeCreated, | |
| 'userTool', | |
| ); | |