Files
tg-chat-bot/src/ai/tools/utils.ts
T
2026-05-14 20:55:48 +03:00

107 lines
3.0 KiB
TypeScript

import {Ollama} from "ollama";
import {toolsLogger} from "./tool-logger";
const logger = toolsLogger.child("utils");
export function asNonEmptyString(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0
? value.trim()
: undefined;
}
export function normalizeToolArguments(args: unknown): Record<string, unknown> {
if (!args) return {};
if (typeof args === "string") {
try {
const parsed = JSON.parse(args);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
return parsed as Record<string, unknown>;
}
} catch {
return {
raw: args,
};
}
return {};
}
if (typeof args === "object" && !Array.isArray(args)) {
return args as Record<string, unknown>;
}
return {};
}
export function asBoolean(value: unknown, defaultValue = false): boolean {
if (typeof value === "boolean") return value;
if (typeof value === "string") {
const normalized = value.trim().toLowerCase();
if (normalized === "true") return true;
if (normalized === "false") return false;
}
return defaultValue;
}
export function asString(value: unknown, defaultValue = ""): string {
return typeof value === "string" ? value : defaultValue;
}
export function asPositiveInt(value: unknown, defaultValue: number, maxValue: number): number {
const n = typeof value === "number"
? value
: typeof value === "string"
? Number(value)
: NaN;
if (!Number.isFinite(n) || n <= 0) return defaultValue;
return Math.min(Math.floor(n), maxValue);
}
export async function unloadAllOllamaModels(ollama: Ollama, exceptFor?: string[]) {
try {
const runningModels = await ollama.ps();
const modelsToUnload = runningModels.models
.filter(m => !exceptFor?.includes(m.model));
const unloadPromises = modelsToUnload
.map(model =>
ollama.generate({
model: model.name,
keep_alive: 0,
stream: false,
prompt: ""
})
);
await Promise.all(unloadPromises);
logger.info("ollama.unload_all.done", {count: modelsToUnload.length, exceptFor});
} catch (error) {
logger.error("ollama.unload_all.failed", {exceptFor, error});
}
}
export async function loadOllamaModel(model: string, ollama: Ollama, contextLength: number): Promise<boolean> {
try {
logger.info("ollama.load.start", {model, contextLength});
await ollama.generate({
model: model,
stream: false,
prompt: "",
options: {
num_ctx: contextLength
}
});
logger.info("ollama.load.done", {model, contextLength});
return true;
} catch (e: unknown) {
logger.error("ollama.load.failed", {model, contextLength, error: e});
return false;
}
}