mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-28 17:03:34 +00:00
docs: document provider tool helpers
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// OpenAI Chat Completions compatibility helpers. Some providers only accept
|
||||
// role/content messages with plain string content instead of text block arrays.
|
||||
function flattenStringOnlyCompletionContent(content: unknown): unknown {
|
||||
if (!Array.isArray(content)) {
|
||||
return content;
|
||||
@@ -17,6 +19,7 @@ function flattenStringOnlyCompletionContent(content: unknown): unknown {
|
||||
return textParts.join("\n");
|
||||
}
|
||||
|
||||
/** Flatten string-only text block content arrays into newline-joined strings. */
|
||||
export function flattenCompletionMessagesToStringContent(messages: unknown[]): unknown[] {
|
||||
return messages.map((message) => {
|
||||
if (!message || typeof message !== "object") {
|
||||
@@ -34,6 +37,7 @@ export function flattenCompletionMessagesToStringContent(messages: unknown[]): u
|
||||
});
|
||||
}
|
||||
|
||||
/** Strip completion messages to role/content fields for strict providers. */
|
||||
export function stripCompletionMessagesToRoleContent(messages: unknown[]): unknown[] {
|
||||
return messages.map((message) => {
|
||||
if (!message || typeof message !== "object" || Array.isArray(message)) {
|
||||
|
||||
@@ -12,6 +12,9 @@ import { loadPluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.types.js";
|
||||
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
|
||||
|
||||
// Provider auth aliases map deprecated or plugin-defined provider IDs to the
|
||||
// canonical provider used for credential lookup. Plugin origin priority keeps
|
||||
// configured aliases ahead of bundled/global/workspace aliases.
|
||||
export type ProviderAuthAliasLookupParams = {
|
||||
config?: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
@@ -51,6 +54,7 @@ function buildProviderAuthAliasMapCacheKey(
|
||||
});
|
||||
}
|
||||
|
||||
/** Clear provider auth alias cache for tests that mutate plugin metadata. */
|
||||
export function resetProviderAuthAliasMapCacheForTest(): void {
|
||||
providerAuthAliasMapCache = new WeakMap<NodeJS.ProcessEnv, Map<string, Record<string, string>>>();
|
||||
}
|
||||
@@ -108,6 +112,7 @@ function setPreferredAlias(params: {
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolve canonical auth provider aliases from plugin metadata. */
|
||||
export function resolveProviderAuthAliasMap(
|
||||
params?: ProviderAuthAliasLookupParams,
|
||||
): Record<string, string> {
|
||||
@@ -116,6 +121,8 @@ export function resolveProviderAuthAliasMap(
|
||||
let cacheKey: string | undefined;
|
||||
let envCache: Map<string, Record<string, string>> | undefined;
|
||||
if (!params?.metadataSnapshot) {
|
||||
// Plugin metadata is process-stable for a control-plane fingerprint, so
|
||||
// cache per env object without hiding explicit test snapshots.
|
||||
cacheKey = buildProviderAuthAliasMapCacheKey(params, env);
|
||||
envCache = providerAuthAliasMapCache.get(env);
|
||||
if (!envCache) {
|
||||
@@ -195,6 +202,7 @@ export function resolveProviderAuthAliasMap(
|
||||
return aliases;
|
||||
}
|
||||
|
||||
/** Resolve the provider ID that should be used for credential lookup. */
|
||||
export function resolveProviderIdForAuth(
|
||||
provider: string,
|
||||
params?: ProviderAuthAliasLookupParams,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
|
||||
// Shared validation for model-supplied tool call names. Names are kept compact
|
||||
// and ASCII-ish before comparing against any allowed-tool set.
|
||||
const TOOL_CALL_NAME_MAX_CHARS = 64;
|
||||
const TOOL_CALL_NAME_RE = /^[A-Za-z0-9_:.-]+$/;
|
||||
|
||||
/** Normalize an optional iterable of allowed tool names for lookup. */
|
||||
export function normalizeAllowedToolNames(allowedToolNames?: Iterable<string>): Set<string> | null {
|
||||
if (!allowedToolNames) {
|
||||
return null;
|
||||
@@ -21,6 +24,7 @@ export function normalizeAllowedToolNames(allowedToolNames?: Iterable<string>):
|
||||
return normalized.size > 0 ? normalized : null;
|
||||
}
|
||||
|
||||
/** Return whether a model-supplied tool call name is syntactically and policy allowed. */
|
||||
export function isAllowedToolCallName(
|
||||
name: unknown,
|
||||
allowedToolNames: Set<string> | null,
|
||||
|
||||
@@ -7,6 +7,8 @@ import { redactToolPayloadText } from "../logging/redact.js";
|
||||
import { resolveExecDetail, type ToolDetailMode } from "./tool-display-exec.js";
|
||||
import { asRecord } from "./tool-display-record.js";
|
||||
|
||||
// Shared formatting helpers for compact tool-call display labels. Display text
|
||||
// is redacted and summarized so tool updates stay readable in chat/UI streams.
|
||||
type ToolDisplayActionSpec = {
|
||||
label?: string;
|
||||
detailKeys?: string[];
|
||||
@@ -35,10 +37,12 @@ type CoerceDisplayValueOptions = {
|
||||
maxArrayEntries?: number;
|
||||
};
|
||||
|
||||
/** Normalize a tool name for fallback display. */
|
||||
export function normalizeToolName(name?: string): string {
|
||||
return (name ?? "tool").trim();
|
||||
}
|
||||
|
||||
/** Convert a tool identifier into a human-readable title. */
|
||||
export function defaultTitle(name: string): string {
|
||||
const cleaned = name.replace(/_/g, " ").trim();
|
||||
if (!cleaned) {
|
||||
@@ -75,6 +79,7 @@ function resolveActionArg(args: unknown): string | undefined {
|
||||
return action || undefined;
|
||||
}
|
||||
|
||||
/** Resolve display verb/detail from tool args and optional display metadata. */
|
||||
export function resolveToolVerbAndDetailForArgs(params: {
|
||||
toolKey: string;
|
||||
args?: unknown;
|
||||
@@ -183,6 +188,7 @@ function lookupValueByPath(args: unknown, path: string): unknown {
|
||||
return current;
|
||||
}
|
||||
|
||||
/** Format a detail path/key into a short display label. */
|
||||
export function formatDetailKey(raw: string, overrides: Record<string, string> = {}): string {
|
||||
let last = "";
|
||||
for (const segment of raw.split(".")) {
|
||||
@@ -364,6 +370,8 @@ function collectWebSearchQueries(record: Record<string, unknown>): string[] {
|
||||
}
|
||||
|
||||
function parseToolSearchCall(code: string): { target: string; args?: string } | undefined {
|
||||
// This is a bounded summary parser for display only; execution still uses the
|
||||
// real tool-search bridge and schema validation.
|
||||
const prefixMatch = code.match(/openclaw\.tools\.call\s*\(\s*/s);
|
||||
if (!prefixMatch || prefixMatch.index === undefined) {
|
||||
return undefined;
|
||||
@@ -565,6 +573,7 @@ function summarizeToolSearchCallInput(raw: string | undefined): string | undefin
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Infer the bridged tool target displayed for tool_search_code snippets. */
|
||||
export function resolveToolSearchCodeDisplayTarget(
|
||||
args: unknown,
|
||||
): ToolSearchCodeDisplayTarget | undefined {
|
||||
@@ -771,6 +780,7 @@ function resolveToolVerbAndDetail(params: {
|
||||
return { verb, detail };
|
||||
}
|
||||
|
||||
/** Normalize final detail text before attaching it to a tool display line. */
|
||||
export function formatToolDetailText(
|
||||
detail: string | undefined,
|
||||
opts: { prefixWithWith?: boolean } = {},
|
||||
|
||||
Reference in New Issue
Block a user