feat: expand skill command registration

This commit is contained in:
Peter Steinberger
2026-01-16 20:11:01 +00:00
parent 69761e8a51
commit 38b49aa0f6
21 changed files with 311 additions and 45 deletions

View File

@@ -1,8 +1,10 @@
import type { ModelAliasIndex } from "../../agents/model-selection.js";
import type { SkillCommandSpec } from "../../agents/skills.js";
import { resolveSandboxRuntimeStatus } from "../../agents/sandbox.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js";
import { listChatCommands, shouldHandleTextCommands } from "../commands-registry.js";
import { listSkillCommandsForWorkspace } from "../skill-commands.js";
import type { MsgContext, TemplateContext } from "../templating.js";
import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "../thinking.js";
import type { GetReplyOptions, ReplyPayload } from "../types.js";
@@ -24,6 +26,7 @@ export type ReplyDirectiveContinuation = {
commandSource: string;
command: ReturnType<typeof buildCommandContext>;
allowTextCommands: boolean;
skillCommands?: SkillCommandSpec[];
directives: InlineDirectives;
cleanedBody: string;
messageProviderKey: string;
@@ -65,6 +68,7 @@ export async function resolveReplyDirectives(params: {
cfg: ClawdbotConfig;
agentId: string;
agentDir: string;
workspaceDir: string;
agentCfg: AgentDefaults;
sessionCtx: TemplateContext;
sessionEntry?: SessionEntry;
@@ -83,6 +87,7 @@ export async function resolveReplyDirectives(params: {
model: string;
typing: TypingController;
opts?: GetReplyOptions;
skillFilter?: string[];
}): Promise<ReplyDirectiveResult> {
const {
ctx,
@@ -90,6 +95,7 @@ export async function resolveReplyDirectives(params: {
agentId,
agentCfg,
agentDir,
workspaceDir,
sessionCtx,
sessionEntry,
sessionStore,
@@ -106,6 +112,7 @@ export async function resolveReplyDirectives(params: {
model: initialModel,
typing,
opts,
skillFilter,
} = params;
let provider = initialProvider;
let model = initialModel;
@@ -132,11 +139,23 @@ export async function resolveReplyDirectives(params: {
surface: command.surface,
commandSource: ctx.CommandSource,
});
const shouldResolveSkillCommands =
allowTextCommands && command.commandBodyNormalized.includes("/");
const skillCommands = shouldResolveSkillCommands
? listSkillCommandsForWorkspace({
workspaceDir,
cfg,
skillFilter,
})
: [];
const reservedCommands = new Set(
listChatCommands().flatMap((cmd) =>
cmd.textAliases.map((a) => a.replace(/^\//, "").toLowerCase()),
),
);
for (const command of skillCommands) {
reservedCommands.add(command.name.toLowerCase());
}
const configuredAliases = Object.values(cfg.agents?.defaults?.models ?? {})
.map((entry) => entry.alias?.trim())
.filter((alias): alias is string => Boolean(alias))
@@ -385,6 +404,7 @@ export async function resolveReplyDirectives(params: {
commandSource,
command,
allowTextCommands,
skillCommands,
directives,
cleanedBody,
messageProviderKey,

View File

@@ -1,4 +1,5 @@
import { getChannelDock } from "../../channels/dock.js";
import type { SkillCommandSpec } from "../../agents/skills.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js";
import type { MsgContext, TemplateContext } from "../templating.js";
@@ -39,6 +40,7 @@ export async function handleInlineActions(params: {
allowTextCommands: boolean;
inlineStatusRequested: boolean;
command: Parameters<typeof handleCommands>[0]["command"];
skillCommands?: SkillCommandSpec[];
directives: InlineDirectives;
cleanedBody: string;
elevatedEnabled: boolean;
@@ -99,13 +101,16 @@ export async function handleInlineActions(params: {
let cleanedBody = initialCleanedBody;
const shouldLoadSkillCommands = command.commandBodyNormalized.startsWith("/");
const skillCommands = shouldLoadSkillCommands
? listSkillCommandsForWorkspace({
workspaceDir,
cfg,
skillFilter,
})
: [];
const skillCommands =
shouldLoadSkillCommands && params.skillCommands
? params.skillCommands
: shouldLoadSkillCommands
? listSkillCommandsForWorkspace({
workspaceDir,
cfg,
skillFilter,
})
: [];
const skillInvocation =
allowTextCommands && skillCommands.length > 0

View File

@@ -118,6 +118,7 @@ export async function getReplyFromConfig(
cfg,
agentId,
agentDir,
workspaceDir,
agentCfg,
sessionCtx,
sessionEntry,
@@ -136,6 +137,7 @@ export async function getReplyFromConfig(
model,
typing,
opts,
skillFilter: opts?.skillFilter,
});
if (directiveResult.kind === "reply") {
return directiveResult.reply;
@@ -145,6 +147,7 @@ export async function getReplyFromConfig(
commandSource,
command,
allowTextCommands,
skillCommands,
directives,
cleanedBody,
elevatedEnabled,
@@ -187,6 +190,7 @@ export async function getReplyFromConfig(
allowTextCommands,
inlineStatusRequested,
command,
skillCommands,
directives,
cleanedBody,
elevatedEnabled,