kimi-code / packages /agent-core-v2 /src /agent /pluginCommand /pluginCommandService.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
68d7816 verified
Raw History Blame Contribute Delete
3.82 kB
import { randomUUID } from 'node:crypto';
import { LifecycleScope } from '#/app/scopes';
import { ScopeActivation, registerScopedService } from '#/_base/di/scope';
import { IEventService } from '#/app/event/event';
import { ErrorCodes, Error2 } from '#/errors';
import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext';
import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle';
import { expandCommandArguments } from '#/app/plugin/commands';
import { IPluginService } from '#/app/plugin/plugin';
import { IAgentLoopService } from '#/agent/loop/loop';
import { promptMetadataTextFromText } from '#/agent/prompt/promptMetadataText';
import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata';
import { ISessionContext } from '#/session/sessionContext/sessionContext';
import { applyPromptMetadataUpdate } from '#/session/sessionMetadata/promptMetadata';
import { IEventDispatcher } from '#/state/eventDispatcher';
import {
IAgentPluginCommandService,
PluginCommandActivated,
type ActivatePluginCommandPayload,
} from './pluginCommand';
export class AgentPluginCommandService implements IAgentPluginCommandService {
declare readonly _serviceBrand: undefined;
constructor(
@IPluginService private readonly plugins: IPluginService,
@IAgentLoopService private readonly loop: IAgentLoopService,
@IEventDispatcher private readonly dispatcher: IEventDispatcher,
@ISessionMetadata private readonly metadata: ISessionMetadata,
@IEventService private readonly eventService: IEventService,
@ISessionContext private readonly sessionContext: ISessionContext,
@IAgentScopeContext private readonly scopeContext: IAgentScopeContext,
) { }
async activate(payload: ActivatePluginCommandPayload): Promise<void> {
const commands = await this.plugins.listPluginCommands();
const def = commands.find(
(command) => command.pluginId === payload.pluginId && command.name === payload.commandName,
);
if (def === undefined) {
throw new Error2(
ErrorCodes.REQUEST_INVALID,
`Plugin command "${payload.pluginId}:${payload.commandName}" was not found`,
);
}
const commandArgs = payload.args ?? '';
const expanded = expandCommandArguments(def.body, commandArgs);
const origin = {
kind: 'plugin_command' as const,
activationId: randomUUID(),
pluginId: payload.pluginId,
commandName: payload.commandName,
commandArgs: payload.args,
trigger: 'user-slash' as const,
};
await this.dispatcher.dispatch(
new PluginCommandActivated({
agentId: this.scopeContext.agentId,
activationId: origin.activationId,
pluginId: origin.pluginId,
commandName: origin.commandName,
commandArgs: origin.commandArgs,
trigger: origin.trigger,
}),
);
this.loop.submit({
message: { role: 'user', content: [{ type: 'text', text: expanded }] },
meta: { origin, tracked: true },
});
if (this.scopeContext.agentId === MAIN_AGENT_ID) {
await applyPromptMetadataUpdate(
{
metadata: this.metadata,
eventService: this.eventService,
sessionId: this.sessionContext.sessionId,
},
promptMetadataTextFromPluginCommand(payload),
);
}
}
}
function promptMetadataTextFromPluginCommand(
payload: ActivatePluginCommandPayload,
): string | undefined {
const args = payload.args?.trim();
const command = `/${payload.pluginId}:${payload.commandName}`;
return promptMetadataTextFromText(
args === undefined || args.length === 0 ? command : `${command} ${args}`,
);
}
registerScopedService(
LifecycleScope.Agent,
IAgentPluginCommandService,
AgentPluginCommandService,
ScopeActivation.OnScopeCreated,
'pluginCommand',
);