docs: document auto-reply directive helpers

This commit is contained in:
Peter Steinberger
2026-06-03 19:31:07 -04:00
parent 05d92d8761
commit d9d4514c00
6 changed files with 17 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
import type { InlineDirectives } from "./directive-handling.js";
/** Test helper that returns a fully cleared inline-directive object. */
export function createEmptyInlineDirectives(): InlineDirectives {
return {
cleaned: "",

View File

@@ -22,6 +22,7 @@ function isGenericMediaType(mediaType: string | undefined): boolean {
return normalized === "application/octet-stream" || normalized === "binary/octet-stream";
}
/** Resolves image media types from current-turn attachment metadata or filenames. */
function resolveCurrentImageMediaType(pathValue: unknown, mediaType?: unknown): string | undefined {
const mediaPath = normalizeOptionalString(pathValue);
if (!mediaPath) {
@@ -86,6 +87,7 @@ function createUndescribedImageContext(
};
}
/** Resolves current-turn image attachments that were not already described by media understanding. */
export async function resolveCurrentTurnImages(params: {
ctx: MsgContext;
cfg: OpenClawConfig;
@@ -112,6 +114,7 @@ export async function resolveCurrentTurnImages(params: {
}
try {
// Only send undescribed current images natively; described images already exist as text context.
const resolved = await resolveAgentTurnAttachments({
ctx: createUndescribedImageContext(params.ctx, undescribedImageAttachments),
cfg: params.cfg,

View File

@@ -21,6 +21,7 @@ import {
import { extractQueueDirective } from "./queue/directive.js";
import type { QueueDropPolicy, QueueMode } from "./queue/types.js";
/** Parsed inline directives removed from a user message before agent execution. */
export type InlineDirectives = {
cleaned: string;
hasThinkDirective: boolean;
@@ -75,6 +76,7 @@ export type InlineDirectives = {
hasQueueOptions: boolean;
};
/** Parses supported inline directives in the same order they are stripped from text. */
export function parseInlineDirectives(
body: string,
options?: {
@@ -171,6 +173,7 @@ export function parseInlineDirectives(
hasOptions: hasQueueOptions,
} = extractQueueDirective(modelCleaned);
// Later directives see text cleaned by earlier directives; preserve that ordering.
return {
cleaned: queueCleaned,
hasThinkDirective,

View File

@@ -17,6 +17,7 @@ const CLEARED_EXEC_FIELDS = {
invalidExecNode: false,
} satisfies Partial<InlineDirectives>;
/** Clears all inline directive state while preserving cleaned text. */
export function clearInlineDirectives(cleaned: string): InlineDirectives {
return {
cleaned,
@@ -58,6 +59,7 @@ export function clearInlineDirectives(cleaned: string): InlineDirectives {
};
}
/** Clears only exec-related directive state after execution policy is consumed. */
export function clearExecInlineDirectives(directives: InlineDirectives): InlineDirectives {
return {
...directives,

View File

@@ -1,3 +1,4 @@
/** Normalized history message used when building reply context. */
export type HistoryEntry = {
sender: string;
body: string;
@@ -6,6 +7,7 @@ export type HistoryEntry = {
media?: HistoryMediaEntry[];
};
/** Media metadata attached to a normalized history message. */
export type HistoryMediaEntry = {
path?: string;
url?: string;

View File

@@ -3,6 +3,7 @@ import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/st
import { splitTrailingAuthProfile } from "../../agents/model-ref-profile.js";
import { isModelKeyAllowedBySet } from "../../agents/model-selection-shared.js";
/** Alias lookup tables used by `/model` directive resolution. */
export type ModelAliasIndex = {
byAlias: Map<
string,
@@ -14,6 +15,7 @@ export type ModelAliasIndex = {
byKey: Map<string, string[]>;
};
/** Resolved model choice from a `/model` directive. */
export type ModelDirectiveSelection = {
provider: string;
model: string;
@@ -56,6 +58,7 @@ const FUZZY_VARIANT_TOKENS = [
"nano",
];
/** Builds the canonical provider/model key used by allowlists and aliases. */
export function modelKey(provider: string, model: string): string {
const providerId = provider.trim();
const modelId = model.trim();
@@ -72,6 +75,7 @@ export function modelKey(provider: string, model: string): string {
: `${providerId}/${modelId}`;
}
/** Resolves an explicit model directive string into a provider/model ref. */
export function resolveModelRefFromDirectiveString(params: {
raw: string;
defaultProvider: string;
@@ -260,6 +264,7 @@ function scoreFuzzyMatch(params: {
};
}
/** Resolves a `/model` directive into an allowlisted model selection or error. */
export function resolveModelDirectiveSelection(params: {
raw: string;
defaultProvider: string;
@@ -356,6 +361,7 @@ export function resolveModelDirectiveSelection(params: {
return Object.assign({ candidate }, details);
})
.toSorted((a, b) => {
// Tie-break deterministically so repeated prompts pick the same model.
if (b.score !== a.score) {
return b.score - a.score;
}