mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 05:32:53 +00:00
perf(inbound): trim reply startup imports (#51988)
* perf(inbound): narrow reply startup imports * perf(inbound): trim reply startup imports * fix(perf): dedupe archive helpers
This commit is contained in:
@@ -1,12 +1,25 @@
|
||||
import { getNativeCommandSurfaces } from "./commands-registry.data.js";
|
||||
import { listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { getActivePluginRegistryVersion } from "../plugins/runtime.js";
|
||||
import type { ShouldHandleTextCommandsParams } from "./commands-registry.types.js";
|
||||
|
||||
let cachedNativeCommandSurfaces: Set<string> | null = null;
|
||||
let cachedNativeCommandSurfacesVersion = -1;
|
||||
|
||||
export function isNativeCommandSurface(surface?: string): boolean {
|
||||
const normalized = surface?.trim().toLowerCase();
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return getNativeCommandSurfaces().has(normalized);
|
||||
const registryVersion = getActivePluginRegistryVersion();
|
||||
if (!cachedNativeCommandSurfaces || cachedNativeCommandSurfacesVersion !== registryVersion) {
|
||||
cachedNativeCommandSurfaces = new Set(
|
||||
listChannelPlugins()
|
||||
.filter((plugin) => plugin.capabilities.nativeCommands)
|
||||
.map((plugin) => plugin.id),
|
||||
);
|
||||
cachedNativeCommandSurfacesVersion = registryVersion;
|
||||
}
|
||||
return cachedNativeCommandSurfaces.has(normalized);
|
||||
}
|
||||
|
||||
export function shouldHandleTextCommands(params: ShouldHandleTextCommandsParams): boolean {
|
||||
|
||||
@@ -6,19 +6,18 @@ import { isCliProvider } from "../../agents/model-selection.js";
|
||||
import { queueEmbeddedPiMessage } from "../../agents/pi-embedded.js";
|
||||
import { hasNonzeroUsage } from "../../agents/usage.js";
|
||||
import {
|
||||
resolveAgentIdFromSessionKey,
|
||||
resolveSessionFilePath,
|
||||
resolveSessionFilePathOptions,
|
||||
resolveSessionTranscriptPath,
|
||||
type SessionEntry,
|
||||
updateSessionStore,
|
||||
updateSessionStoreEntry,
|
||||
} from "../../config/sessions.js";
|
||||
} from "../../config/sessions/paths.js";
|
||||
import { updateSessionStore, updateSessionStoreEntry } from "../../config/sessions/store.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
import type { TypingMode } from "../../config/types.js";
|
||||
import { emitAgentEvent } from "../../infra/agent-events.js";
|
||||
import { emitDiagnosticEvent, isDiagnosticsEnabled } from "../../infra/diagnostic-events.js";
|
||||
import { generateSecureUuid } from "../../infra/secure-random.js";
|
||||
import { enqueueSystemEvent } from "../../infra/system-events.js";
|
||||
import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { estimateUsageCost, resolveModelCostConfig } from "../../utils/usage-format.js";
|
||||
import {
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
extractVerboseDirective,
|
||||
} from "./directives.js";
|
||||
import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
|
||||
import type { QueueDropPolicy, QueueMode } from "./queue.js";
|
||||
import { extractQueueDirective } from "./queue.js";
|
||||
import { extractQueueDirective } from "./queue/directive.js";
|
||||
import type { QueueDropPolicy, QueueMode } from "./queue/types.js";
|
||||
|
||||
export type InlineDirectives = {
|
||||
cleaned: string;
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
resolveDefaultModelForAgent,
|
||||
} from "../../agents/model-selection.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { type SessionEntry, updateSessionStore } from "../../config/sessions.js";
|
||||
import { updateSessionStore } from "../../config/sessions/store.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
import { enqueueSystemEvent } from "../../infra/system-events.js";
|
||||
import { applyVerboseOverride } from "../../sessions/level-overrides.js";
|
||||
import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
|
||||
|
||||
@@ -9,13 +9,13 @@ import {
|
||||
resolveEmbeddedSessionLane,
|
||||
} from "../../agents/pi-embedded.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { resolveGroupSessionKey } from "../../config/sessions/group.js";
|
||||
import {
|
||||
resolveGroupSessionKey,
|
||||
resolveSessionFilePath,
|
||||
resolveSessionFilePathOptions,
|
||||
type SessionEntry,
|
||||
updateSessionStore,
|
||||
} from "../../config/sessions.js";
|
||||
} from "../../config/sessions/paths.js";
|
||||
import { updateSessionStore } from "../../config/sessions/store.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
import { logVerbose } from "../../globals.js";
|
||||
import { clearCommandLane, getQueueSize } from "../../process/command-queue.js";
|
||||
import { normalizeMainKey } from "../../routing/session-key.js";
|
||||
|
||||
@@ -3,7 +3,8 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { CURRENT_SESSION_VERSION, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { resolveSessionFilePath, type SessionEntry } from "../../config/sessions.js";
|
||||
import { resolveSessionFilePath } from "../../config/sessions/paths.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
|
||||
/**
|
||||
* Default max parent token count beyond which thread/session parent forking is skipped.
|
||||
|
||||
@@ -9,27 +9,27 @@ import { resolveSessionAgentId } from "../../agents/agent-scope.js";
|
||||
import { clearBootstrapSnapshotOnSessionRollover } from "../../agents/bootstrap-cache.js";
|
||||
import { normalizeChatType } from "../../channels/chat-type.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { resolveGroupSessionKey } from "../../config/sessions/group.js";
|
||||
import { deriveSessionMetaPatch } from "../../config/sessions/metadata.js";
|
||||
import { resolveSessionTranscriptPath, resolveStorePath } from "../../config/sessions/paths.js";
|
||||
import {
|
||||
DEFAULT_RESET_TRIGGERS,
|
||||
deriveSessionMetaPatch,
|
||||
evaluateSessionFreshness,
|
||||
type GroupKeyResolution,
|
||||
loadSessionStore,
|
||||
resolveAndPersistSessionFile,
|
||||
resolveChannelResetConfig,
|
||||
resolveThreadFlag,
|
||||
resolveSessionResetPolicy,
|
||||
resolveSessionResetType,
|
||||
resolveGroupSessionKey,
|
||||
resolveSessionKey,
|
||||
resolveSessionTranscriptPath,
|
||||
resolveStorePath,
|
||||
resolveThreadFlag,
|
||||
} from "../../config/sessions/reset.js";
|
||||
import { resolveAndPersistSessionFile } from "../../config/sessions/session-file.js";
|
||||
import { resolveSessionKey } from "../../config/sessions/session-key.js";
|
||||
import { loadSessionStore, updateSessionStore } from "../../config/sessions/store.js";
|
||||
import {
|
||||
DEFAULT_RESET_TRIGGERS,
|
||||
type GroupKeyResolution,
|
||||
type SessionEntry,
|
||||
type SessionScope,
|
||||
updateSessionStore,
|
||||
} from "../../config/sessions.js";
|
||||
} from "../../config/sessions/types.js";
|
||||
import type { TtsAutoMode } from "../../config/types.tts.js";
|
||||
import { archiveSessionTranscripts } from "../../gateway/session-utils.fs.js";
|
||||
import { archiveSessionTranscripts } from "../../gateway/session-archive.fs.js";
|
||||
import { resolveConversationIdFromTargets } from "../../infra/outbound/conversation-id.js";
|
||||
import { deliverSessionMaintenanceWarning } from "../../infra/session-maintenance-warning.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
|
||||
@@ -6,7 +6,7 @@ const providerRuntimeMocks = vi.hoisted(() => ({
|
||||
resolveProviderXHighThinking: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../plugins/provider-runtime.js", () => ({
|
||||
vi.mock("../plugins/provider-thinking.js", () => ({
|
||||
resolveProviderBinaryThinking: providerRuntimeMocks.resolveProviderBinaryThinking,
|
||||
resolveProviderDefaultThinkingLevel: providerRuntimeMocks.resolveProviderDefaultThinkingLevel,
|
||||
resolveProviderXHighThinking: providerRuntimeMocks.resolveProviderXHighThinking,
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
resolveProviderBinaryThinking,
|
||||
resolveProviderDefaultThinkingLevel,
|
||||
resolveProviderXHighThinking,
|
||||
} from "../plugins/provider-runtime.js";
|
||||
} from "../plugins/provider-thinking.js";
|
||||
|
||||
export function isBinaryThinkingProvider(provider?: string | null, model?: string | null): boolean {
|
||||
if (isBinaryThinkingProviderFallback(provider)) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import {
|
||||
archiveSessionTranscripts,
|
||||
cleanupArchivedSessionTranscripts,
|
||||
} from "../../gateway/session-utils.fs.js";
|
||||
} from "../../gateway/session-archive.fs.js";
|
||||
import { writeTextAtomic } from "../../infra/json-files.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import {
|
||||
|
||||
154
src/gateway/session-archive.fs.ts
Normal file
154
src/gateway/session-archive.fs.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import {
|
||||
formatSessionArchiveTimestamp,
|
||||
parseSessionArchiveTimestamp,
|
||||
type SessionArchiveReason,
|
||||
} from "../config/sessions/artifacts.js";
|
||||
import {
|
||||
resolveSessionFilePath,
|
||||
resolveSessionTranscriptPath,
|
||||
resolveSessionTranscriptPathInDir,
|
||||
} from "../config/sessions/paths.js";
|
||||
import { resolveRequiredHomeDir } from "../infra/home-dir.js";
|
||||
|
||||
export type ArchiveFileReason = SessionArchiveReason;
|
||||
|
||||
function canonicalizePathForComparison(filePath: string): string {
|
||||
const resolved = path.resolve(filePath);
|
||||
try {
|
||||
return fs.realpathSync(resolved);
|
||||
} catch {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSessionTranscriptCandidates(
|
||||
sessionId: string,
|
||||
storePath: string | undefined,
|
||||
sessionFile?: string,
|
||||
agentId?: string,
|
||||
): string[] {
|
||||
const candidates: string[] = [];
|
||||
const pushCandidate = (resolve: () => string): void => {
|
||||
try {
|
||||
candidates.push(resolve());
|
||||
} catch {
|
||||
// Ignore invalid paths/IDs and keep scanning other safe candidates.
|
||||
}
|
||||
};
|
||||
|
||||
if (storePath) {
|
||||
const sessionsDir = path.dirname(storePath);
|
||||
if (sessionFile) {
|
||||
pushCandidate(() =>
|
||||
resolveSessionFilePath(sessionId, { sessionFile }, { sessionsDir, agentId }),
|
||||
);
|
||||
}
|
||||
pushCandidate(() => resolveSessionTranscriptPathInDir(sessionId, sessionsDir));
|
||||
} else if (sessionFile) {
|
||||
if (agentId) {
|
||||
pushCandidate(() => resolveSessionFilePath(sessionId, { sessionFile }, { agentId }));
|
||||
} else {
|
||||
const trimmed = sessionFile.trim();
|
||||
if (trimmed) {
|
||||
candidates.push(path.resolve(trimmed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (agentId) {
|
||||
pushCandidate(() => resolveSessionTranscriptPath(sessionId, agentId));
|
||||
}
|
||||
|
||||
const home = resolveRequiredHomeDir(process.env, os.homedir);
|
||||
const legacyDir = path.join(home, ".openclaw", "sessions");
|
||||
pushCandidate(() => resolveSessionTranscriptPathInDir(sessionId, legacyDir));
|
||||
|
||||
return Array.from(new Set(candidates));
|
||||
}
|
||||
|
||||
export function archiveFileOnDisk(filePath: string, reason: ArchiveFileReason): string {
|
||||
const ts = formatSessionArchiveTimestamp();
|
||||
const archived = `${filePath}.${reason}.${ts}`;
|
||||
fs.renameSync(filePath, archived);
|
||||
return archived;
|
||||
}
|
||||
|
||||
export function archiveSessionTranscripts(opts: {
|
||||
sessionId: string;
|
||||
storePath: string | undefined;
|
||||
sessionFile?: string;
|
||||
agentId?: string;
|
||||
reason: "reset" | "deleted";
|
||||
restrictToStoreDir?: boolean;
|
||||
}): string[] {
|
||||
const archived: string[] = [];
|
||||
const storeDir =
|
||||
opts.restrictToStoreDir && opts.storePath
|
||||
? canonicalizePathForComparison(path.dirname(opts.storePath))
|
||||
: null;
|
||||
for (const candidate of resolveSessionTranscriptCandidates(
|
||||
opts.sessionId,
|
||||
opts.storePath,
|
||||
opts.sessionFile,
|
||||
opts.agentId,
|
||||
)) {
|
||||
const candidatePath = canonicalizePathForComparison(candidate);
|
||||
if (storeDir) {
|
||||
const relative = path.relative(storeDir, candidatePath);
|
||||
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(candidatePath)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
archived.push(archiveFileOnDisk(candidatePath, opts.reason));
|
||||
} catch {
|
||||
// Best-effort.
|
||||
}
|
||||
}
|
||||
return archived;
|
||||
}
|
||||
|
||||
export async function cleanupArchivedSessionTranscripts(opts: {
|
||||
directories: string[];
|
||||
olderThanMs: number;
|
||||
reason?: ArchiveFileReason;
|
||||
nowMs?: number;
|
||||
}): Promise<{ removed: number; scanned: number }> {
|
||||
if (!Number.isFinite(opts.olderThanMs) || opts.olderThanMs < 0) {
|
||||
return { removed: 0, scanned: 0 };
|
||||
}
|
||||
const now = opts.nowMs ?? Date.now();
|
||||
const reason: ArchiveFileReason = opts.reason ?? "deleted";
|
||||
const directories = Array.from(new Set(opts.directories.map((dir) => path.resolve(dir))));
|
||||
let removed = 0;
|
||||
let scanned = 0;
|
||||
|
||||
for (const dir of directories) {
|
||||
const entries = await fs.promises.readdir(dir).catch(() => []);
|
||||
for (const entry of entries) {
|
||||
const timestamp = parseSessionArchiveTimestamp(entry, reason);
|
||||
if (timestamp == null) {
|
||||
continue;
|
||||
}
|
||||
scanned += 1;
|
||||
if (now - timestamp <= opts.olderThanMs) {
|
||||
continue;
|
||||
}
|
||||
const fullPath = path.join(dir, entry);
|
||||
const stat = await fs.promises.stat(fullPath).catch(() => null);
|
||||
if (!stat?.isFile()) {
|
||||
continue;
|
||||
}
|
||||
await fs.promises.rm(fullPath).catch(() => undefined);
|
||||
removed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return { removed, scanned };
|
||||
}
|
||||
@@ -3,13 +3,16 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { deriveSessionTotalTokens, hasNonzeroUsage, normalizeUsage } from "../agents/usage.js";
|
||||
import {
|
||||
formatSessionArchiveTimestamp,
|
||||
parseSessionArchiveTimestamp,
|
||||
type SessionArchiveReason,
|
||||
resolveSessionFilePath,
|
||||
resolveSessionTranscriptPath,
|
||||
resolveSessionTranscriptPathInDir,
|
||||
} from "../config/sessions.js";
|
||||
export {
|
||||
archiveFileOnDisk,
|
||||
archiveSessionTranscripts,
|
||||
cleanupArchivedSessionTranscripts,
|
||||
type ArchiveFileReason,
|
||||
} from "../gateway/session-archive.fs.js";
|
||||
import { resolveRequiredHomeDir } from "../infra/home-dir.js";
|
||||
import { jsonUtf8Bytes } from "../infra/json-utf8-bytes.js";
|
||||
import { hasInterSessionUserProvenance } from "../sessions/input-provenance.js";
|
||||
@@ -194,109 +197,6 @@ export function resolveSessionTranscriptCandidates(
|
||||
return Array.from(new Set(candidates));
|
||||
}
|
||||
|
||||
export type ArchiveFileReason = SessionArchiveReason;
|
||||
|
||||
function canonicalizePathForComparison(filePath: string): string {
|
||||
const resolved = path.resolve(filePath);
|
||||
try {
|
||||
return fs.realpathSync(resolved);
|
||||
} catch {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
export function archiveFileOnDisk(filePath: string, reason: ArchiveFileReason): string {
|
||||
const ts = formatSessionArchiveTimestamp();
|
||||
const archived = `${filePath}.${reason}.${ts}`;
|
||||
fs.renameSync(filePath, archived);
|
||||
return archived;
|
||||
}
|
||||
|
||||
/**
|
||||
* Archives all transcript files for a given session.
|
||||
* Best-effort: silently skips files that don't exist or fail to rename.
|
||||
*/
|
||||
export function archiveSessionTranscripts(opts: {
|
||||
sessionId: string;
|
||||
storePath: string | undefined;
|
||||
sessionFile?: string;
|
||||
agentId?: string;
|
||||
reason: "reset" | "deleted";
|
||||
/**
|
||||
* When true, only archive files resolved under the session store directory.
|
||||
* This prevents maintenance operations from mutating paths outside the agent sessions dir.
|
||||
*/
|
||||
restrictToStoreDir?: boolean;
|
||||
}): string[] {
|
||||
const archived: string[] = [];
|
||||
const storeDir =
|
||||
opts.restrictToStoreDir && opts.storePath
|
||||
? canonicalizePathForComparison(path.dirname(opts.storePath))
|
||||
: null;
|
||||
for (const candidate of resolveSessionTranscriptCandidates(
|
||||
opts.sessionId,
|
||||
opts.storePath,
|
||||
opts.sessionFile,
|
||||
opts.agentId,
|
||||
)) {
|
||||
const candidatePath = canonicalizePathForComparison(candidate);
|
||||
if (storeDir) {
|
||||
const relative = path.relative(storeDir, candidatePath);
|
||||
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(candidatePath)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
archived.push(archiveFileOnDisk(candidatePath, opts.reason));
|
||||
} catch {
|
||||
// Best-effort.
|
||||
}
|
||||
}
|
||||
return archived;
|
||||
}
|
||||
|
||||
export async function cleanupArchivedSessionTranscripts(opts: {
|
||||
directories: string[];
|
||||
olderThanMs: number;
|
||||
reason?: ArchiveFileReason;
|
||||
nowMs?: number;
|
||||
}): Promise<{ removed: number; scanned: number }> {
|
||||
if (!Number.isFinite(opts.olderThanMs) || opts.olderThanMs < 0) {
|
||||
return { removed: 0, scanned: 0 };
|
||||
}
|
||||
const now = opts.nowMs ?? Date.now();
|
||||
const reason: ArchiveFileReason = opts.reason ?? "deleted";
|
||||
const directories = Array.from(new Set(opts.directories.map((dir) => path.resolve(dir))));
|
||||
let removed = 0;
|
||||
let scanned = 0;
|
||||
|
||||
for (const dir of directories) {
|
||||
const entries = await fs.promises.readdir(dir).catch(() => []);
|
||||
for (const entry of entries) {
|
||||
const timestamp = parseSessionArchiveTimestamp(entry, reason);
|
||||
if (timestamp == null) {
|
||||
continue;
|
||||
}
|
||||
scanned += 1;
|
||||
if (now - timestamp <= opts.olderThanMs) {
|
||||
continue;
|
||||
}
|
||||
const fullPath = path.join(dir, entry);
|
||||
const stat = await fs.promises.stat(fullPath).catch(() => null);
|
||||
if (!stat?.isFile()) {
|
||||
continue;
|
||||
}
|
||||
await fs.promises.rm(fullPath).catch(() => undefined);
|
||||
removed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return { removed, scanned };
|
||||
}
|
||||
|
||||
export function capArrayByJsonBytes<T>(
|
||||
items: T[],
|
||||
maxBytes: number,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { SessionEntry, SessionMaintenanceWarning } from "../config/sessions.js";
|
||||
import type { SessionMaintenanceWarning } from "../config/sessions/store-maintenance.js";
|
||||
import type { SessionEntry } from "../config/sessions/types.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { isDeliverableMessageChannel, normalizeMessageChannel } from "../utils/message-channel.js";
|
||||
import { buildOutboundSessionContext } from "./outbound/session-context.js";
|
||||
|
||||
49
src/plugins/provider-thinking.ts
Normal file
49
src/plugins/provider-thinking.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { normalizeProviderId } from "../agents/provider-id.js";
|
||||
import { getActivePluginRegistry } from "./runtime.js";
|
||||
import type {
|
||||
ProviderDefaultThinkingPolicyContext,
|
||||
ProviderPlugin,
|
||||
ProviderThinkingPolicyContext,
|
||||
} from "./types.js";
|
||||
|
||||
function matchesProviderId(provider: ProviderPlugin, providerId: string): boolean {
|
||||
const normalized = normalizeProviderId(providerId);
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
if (normalizeProviderId(provider.id) === normalized) {
|
||||
return true;
|
||||
}
|
||||
return (provider.aliases ?? []).some((alias) => normalizeProviderId(alias) === normalized);
|
||||
}
|
||||
|
||||
function resolveActiveThinkingProvider(providerId: string): ProviderPlugin | undefined {
|
||||
return getActivePluginRegistry()?.providers.find((entry) => {
|
||||
return matchesProviderId(entry.provider, providerId);
|
||||
})?.provider;
|
||||
}
|
||||
|
||||
type ThinkingHookParams<TContext> = {
|
||||
provider: string;
|
||||
context: TContext;
|
||||
};
|
||||
|
||||
export function resolveProviderBinaryThinking(
|
||||
params: ThinkingHookParams<ProviderThinkingPolicyContext>,
|
||||
) {
|
||||
return resolveActiveThinkingProvider(params.provider)?.isBinaryThinking?.(params.context);
|
||||
}
|
||||
|
||||
export function resolveProviderXHighThinking(
|
||||
params: ThinkingHookParams<ProviderThinkingPolicyContext>,
|
||||
) {
|
||||
return resolveActiveThinkingProvider(params.provider)?.supportsXHighThinking?.(params.context);
|
||||
}
|
||||
|
||||
export function resolveProviderDefaultThinkingLevel(
|
||||
params: ThinkingHookParams<ProviderDefaultThinkingPolicyContext>,
|
||||
) {
|
||||
return resolveActiveThinkingProvider(params.provider)?.resolveDefaultThinkingLevel?.(
|
||||
params.context,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user