215 lines
5.6 KiB
TypeScript
215 lines
5.6 KiB
TypeScript
import type { ClawdbotConfig } from "../../config/config.js";
|
|
import type { ExecAsk, ExecHost, ExecSecurity } from "../../infra/exec-approvals.js";
|
|
import { extractModelDirective } from "../model.js";
|
|
import type { MsgContext } from "../templating.js";
|
|
import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "./directives.js";
|
|
import {
|
|
extractElevatedDirective,
|
|
extractExecDirective,
|
|
extractReasoningDirective,
|
|
extractStatusDirective,
|
|
extractThinkDirective,
|
|
extractVerboseDirective,
|
|
} from "./directives.js";
|
|
import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
|
|
import type { QueueDropPolicy, QueueMode } from "./queue.js";
|
|
import { extractQueueDirective } from "./queue.js";
|
|
|
|
export type InlineDirectives = {
|
|
cleaned: string;
|
|
hasThinkDirective: boolean;
|
|
thinkLevel?: ThinkLevel;
|
|
rawThinkLevel?: string;
|
|
hasVerboseDirective: boolean;
|
|
verboseLevel?: VerboseLevel;
|
|
rawVerboseLevel?: string;
|
|
hasReasoningDirective: boolean;
|
|
reasoningLevel?: ReasoningLevel;
|
|
rawReasoningLevel?: string;
|
|
hasElevatedDirective: boolean;
|
|
elevatedLevel?: ElevatedLevel;
|
|
rawElevatedLevel?: string;
|
|
hasExecDirective: boolean;
|
|
execHost?: ExecHost;
|
|
execSecurity?: ExecSecurity;
|
|
execAsk?: ExecAsk;
|
|
execNode?: string;
|
|
rawExecHost?: string;
|
|
rawExecSecurity?: string;
|
|
rawExecAsk?: string;
|
|
rawExecNode?: string;
|
|
hasExecOptions: boolean;
|
|
invalidExecHost: boolean;
|
|
invalidExecSecurity: boolean;
|
|
invalidExecAsk: boolean;
|
|
invalidExecNode: boolean;
|
|
hasStatusDirective: boolean;
|
|
hasModelDirective: boolean;
|
|
rawModelDirective?: string;
|
|
rawModelProfile?: string;
|
|
hasQueueDirective: boolean;
|
|
queueMode?: QueueMode;
|
|
queueReset: boolean;
|
|
rawQueueMode?: string;
|
|
debounceMs?: number;
|
|
cap?: number;
|
|
dropPolicy?: QueueDropPolicy;
|
|
rawDebounce?: string;
|
|
rawCap?: string;
|
|
rawDrop?: string;
|
|
hasQueueOptions: boolean;
|
|
};
|
|
|
|
export function parseInlineDirectives(
|
|
body: string,
|
|
options?: {
|
|
modelAliases?: string[];
|
|
disableElevated?: boolean;
|
|
allowStatusDirective?: boolean;
|
|
},
|
|
): InlineDirectives {
|
|
const {
|
|
cleaned: thinkCleaned,
|
|
thinkLevel,
|
|
rawLevel: rawThinkLevel,
|
|
hasDirective: hasThinkDirective,
|
|
} = extractThinkDirective(body);
|
|
const {
|
|
cleaned: verboseCleaned,
|
|
verboseLevel,
|
|
rawLevel: rawVerboseLevel,
|
|
hasDirective: hasVerboseDirective,
|
|
} = extractVerboseDirective(thinkCleaned);
|
|
const {
|
|
cleaned: reasoningCleaned,
|
|
reasoningLevel,
|
|
rawLevel: rawReasoningLevel,
|
|
hasDirective: hasReasoningDirective,
|
|
} = extractReasoningDirective(verboseCleaned);
|
|
const {
|
|
cleaned: elevatedCleaned,
|
|
elevatedLevel,
|
|
rawLevel: rawElevatedLevel,
|
|
hasDirective: hasElevatedDirective,
|
|
} = options?.disableElevated
|
|
? {
|
|
cleaned: reasoningCleaned,
|
|
elevatedLevel: undefined,
|
|
rawLevel: undefined,
|
|
hasDirective: false,
|
|
}
|
|
: extractElevatedDirective(reasoningCleaned);
|
|
const {
|
|
cleaned: execCleaned,
|
|
execHost,
|
|
execSecurity,
|
|
execAsk,
|
|
execNode,
|
|
rawExecHost,
|
|
rawExecSecurity,
|
|
rawExecAsk,
|
|
rawExecNode,
|
|
hasExecOptions,
|
|
invalidHost: invalidExecHost,
|
|
invalidSecurity: invalidExecSecurity,
|
|
invalidAsk: invalidExecAsk,
|
|
invalidNode: invalidExecNode,
|
|
hasDirective: hasExecDirective,
|
|
} = extractExecDirective(elevatedCleaned);
|
|
const allowStatusDirective = options?.allowStatusDirective !== false;
|
|
const { cleaned: statusCleaned, hasDirective: hasStatusDirective } = allowStatusDirective
|
|
? extractStatusDirective(execCleaned)
|
|
: { cleaned: execCleaned, hasDirective: false };
|
|
const {
|
|
cleaned: modelCleaned,
|
|
rawModel,
|
|
rawProfile,
|
|
hasDirective: hasModelDirective,
|
|
} = extractModelDirective(statusCleaned, {
|
|
aliases: options?.modelAliases,
|
|
});
|
|
const {
|
|
cleaned: queueCleaned,
|
|
queueMode,
|
|
queueReset,
|
|
rawMode,
|
|
debounceMs,
|
|
cap,
|
|
dropPolicy,
|
|
rawDebounce,
|
|
rawCap,
|
|
rawDrop,
|
|
hasDirective: hasQueueDirective,
|
|
hasOptions: hasQueueOptions,
|
|
} = extractQueueDirective(modelCleaned);
|
|
|
|
return {
|
|
cleaned: queueCleaned,
|
|
hasThinkDirective,
|
|
thinkLevel,
|
|
rawThinkLevel,
|
|
hasVerboseDirective,
|
|
verboseLevel,
|
|
rawVerboseLevel,
|
|
hasReasoningDirective,
|
|
reasoningLevel,
|
|
rawReasoningLevel,
|
|
hasElevatedDirective,
|
|
elevatedLevel,
|
|
rawElevatedLevel,
|
|
hasExecDirective,
|
|
execHost,
|
|
execSecurity,
|
|
execAsk,
|
|
execNode,
|
|
rawExecHost,
|
|
rawExecSecurity,
|
|
rawExecAsk,
|
|
rawExecNode,
|
|
hasExecOptions,
|
|
invalidExecHost,
|
|
invalidExecSecurity,
|
|
invalidExecAsk,
|
|
invalidExecNode,
|
|
hasStatusDirective,
|
|
hasModelDirective,
|
|
rawModelDirective: rawModel,
|
|
rawModelProfile: rawProfile,
|
|
hasQueueDirective,
|
|
queueMode,
|
|
queueReset,
|
|
rawQueueMode: rawMode,
|
|
debounceMs,
|
|
cap,
|
|
dropPolicy,
|
|
rawDebounce,
|
|
rawCap,
|
|
rawDrop,
|
|
hasQueueOptions,
|
|
};
|
|
}
|
|
|
|
export function isDirectiveOnly(params: {
|
|
directives: InlineDirectives;
|
|
cleanedBody: string;
|
|
ctx: MsgContext;
|
|
cfg: ClawdbotConfig;
|
|
agentId?: string;
|
|
isGroup: boolean;
|
|
}): boolean {
|
|
const { directives, cleanedBody, ctx, cfg, agentId, isGroup } = params;
|
|
if (
|
|
!directives.hasThinkDirective &&
|
|
!directives.hasVerboseDirective &&
|
|
!directives.hasReasoningDirective &&
|
|
!directives.hasElevatedDirective &&
|
|
!directives.hasExecDirective &&
|
|
!directives.hasModelDirective &&
|
|
!directives.hasQueueDirective
|
|
)
|
|
return false;
|
|
const stripped = stripStructuralPrefixes(cleanedBody ?? "");
|
|
const noMentions = isGroup ? stripMentions(stripped, ctx, cfg, agentId) : stripped;
|
|
return noMentions.length === 0;
|
|
}
|