refactor: dedupe agent and reply runtimes

This commit is contained in:
Peter Steinberger
2026-03-02 19:47:30 +00:00
parent 8768487aee
commit 9617ac9dd5
53 changed files with 1828 additions and 1176 deletions

View File

@@ -1,14 +1,22 @@
import { type Api, type Context, complete, type Model } from "@mariozechner/pi-ai";
import { type Context, complete } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox";
import type { OpenClawConfig } from "../../config/config.js";
import { extractPdfContent, type PdfExtractedContent } from "../../media/pdf-extract.js";
import { resolveUserPath } from "../../utils.js";
import { getDefaultLocalRoots, loadWebMediaRaw } from "../../web/media.js";
import { loadWebMediaRaw } from "../../web/media.js";
import {
coerceImageModelConfig,
type ImageModelConfig,
resolveProviderVisionModelFromConfig,
} from "./image-tool.helpers.js";
import {
applyImageModelConfigDefaults,
buildTextToolResult,
resolveMediaToolLocalRoots,
resolveModelFromRegistry,
resolveModelRuntimeApiKey,
resolvePromptAndModelOverride,
} from "./media-tool-shared.js";
import { hasAuthForProvider, resolveDefaultModelRef } from "./model-config.helpers.js";
import { anthropicAnalyzePdf, geminiAnalyzePdf } from "./pdf-native-providers.js";
import {
@@ -23,9 +31,6 @@ import {
discoverAuthStorage,
discoverModels,
ensureOpenClawModelsJson,
getApiKeyForModel,
normalizeWorkspaceDir,
requireApiKey,
resolveSandboxedBridgeMediaPath,
runWithImageModelFallback,
type AnyAgentTool,
@@ -176,18 +181,7 @@ async function runPdfPrompt(params: {
native: boolean;
attempts: Array<{ provider: string; model: string; error: string }>;
}> {
const effectiveCfg: OpenClawConfig | undefined = params.cfg
? {
...params.cfg,
agents: {
...params.cfg.agents,
defaults: {
...params.cfg.agents?.defaults,
imageModel: params.pdfModelConfig,
},
},
}
: undefined;
const effectiveCfg = applyImageModelConfigDefaults(params.cfg, params.pdfModelConfig);
await ensureOpenClawModelsJson(effectiveCfg, params.agentDir);
const authStorage = discoverAuthStorage(params.agentDir);
@@ -205,18 +199,13 @@ async function runPdfPrompt(params: {
cfg: effectiveCfg,
modelOverride: params.modelOverride,
run: async (provider, modelId) => {
const model = modelRegistry.find(provider, modelId) as Model<Api> | null;
if (!model) {
throw new Error(`Unknown model: ${provider}/${modelId}`);
}
const apiKeyInfo = await getApiKeyForModel({
const model = resolveModelFromRegistry({ modelRegistry, provider, modelId });
const apiKey = await resolveModelRuntimeApiKey({
model,
cfg: effectiveCfg,
agentDir: params.agentDir,
authStorage,
});
const apiKey = requireApiKey(apiKeyInfo, model.provider);
authStorage.setRuntimeApiKey(model.provider, apiKey);
if (providerSupportsNativePdf(provider)) {
if (params.pageNumbers && params.pageNumbers.length > 0) {
@@ -338,6 +327,7 @@ export function createPdfTool(options?: {
? Math.floor(maxPagesDefault)
: DEFAULT_MAX_PAGES;
<<<<<<< HEAD
const localRoots = (() => {
const workspaceDir = normalizeWorkspaceDir(options?.workspaceDir);
if (options?.fsPolicy?.workspaceOnly) {
@@ -349,6 +339,18 @@ export function createPdfTool(options?: {
}
return Array.from(new Set([...roots, workspaceDir]));
})();
||||||| parent of 4a741746c (refactor: dedupe agent and reply runtimes)
const localRoots = (() => {
const roots = getDefaultLocalRoots();
const workspaceDir = normalizeWorkspaceDir(options?.workspaceDir);
if (!workspaceDir) {
return roots;
}
return Array.from(new Set([...roots, workspaceDir]));
})();
=======
const localRoots = resolveMediaToolLocalRoots(options?.workspaceDir);
>>>>>>> 4a741746c (refactor: dedupe agent and reply runtimes)
const description =
"Analyze one or more PDF documents with a model. Supports native PDF analysis for Anthropic and Google models, with text/image extraction fallback for other providers. Use pdf for a single path/URL, or pdfs for multiple (up to 10). Provide a prompt describing what to analyze.";
@@ -412,12 +414,10 @@ export function createPdfTool(options?: {
};
}
const promptRaw =
typeof record.prompt === "string" && record.prompt.trim()
? record.prompt.trim()
: DEFAULT_PROMPT;
const modelOverride =
typeof record.model === "string" && record.model.trim() ? record.model.trim() : undefined;
const { prompt: promptRaw, modelOverride } = resolvePromptAndModelOverride(
record,
DEFAULT_PROMPT,
);
const maxBytesMbRaw = typeof record.maxBytesMb === "number" ? record.maxBytesMb : undefined;
const maxBytesMb =
typeof maxBytesMbRaw === "number" && Number.isFinite(maxBytesMbRaw) && maxBytesMbRaw > 0
@@ -573,15 +573,7 @@ export function createPdfTool(options?: {
})),
};
return {
content: [{ type: "text", text: result.text }],
details: {
model: `${result.provider}/${result.model}`,
native: result.native,
...pdfDetails,
attempts: result.attempts,
},
};
return buildTextToolResult(result, { native: result.native, ...pdfDetails });
},
};
}