/** * Tool-discovery cache — extracted from {@link ZaiMcpClient} (Ticket 02). * * Owns its filesystem I/O directly against the `tools/` subdirectory * under the unified cache root (D1 revised — does NOT reuse * `ResponseCache` for storage). Stores {@link redactTool}-scrubbed tools * (B2 fix) under a single TTL check (H2 fix). * * # Enable check (preserves v0.4.0 granularity — D3 deviation) * * ```text * isToolCacheEnabled = isCacheEnabled() && ZAI_MCP_TOOL_CACHE != "0"/"false" * ``` * * - `SCOUTLINE_CACHE=0` (or legacy `ZAI_CACHE=0`) disables BOTH caches * because `isCacheEnabled()` returns false. * - `ZAI_MCP_TOOL_CACHE=0` disables ONLY the tool cache; the response * cache stays enabled because `isCacheEnabled()` does NOT consult * this var. This preserves the four `mcp-client.test.js` suites that * set `ZAI_MCP_TOOL_CACHE=0` per-suite while relying on * response-cache hits. * * # Versioning * * {@link TOOL_CACHE_VERSION} is stamped into every cache envelope. A * mismatch (e.g. an old `tools-*.json` written by a future or past * release) yields a clean miss — never a throw — so an upgrade cannot * break tool discovery. */ import type { Tool } from "@utcp/sdk"; import { type CacheDirEnvironment } from "./cache.js"; /** * Cache envelope version. Bumped when the on-disk shape of * {@link ToolCachePayload} changes; old envelopes are ignored. * * v2 (1.2 review fix): invalidates pre-fix v1 entries that may contain * un-redacted file-only API keys. `writeToolCache` now threads resolved * secrets into `redactTool`, so v2 entries are safe — but old v1 * envelopes must not be served. */ export declare const TOOL_CACHE_VERSION = 2; /** * Inputs to the tool-cache key. Captures every dimension that affects * WHICH tools the MCP servers return: mode + baseUrl (ZAI vs ZHIPU), * the three HTTP endpoints, and whether the stdio vision server is * registered. The ZaiMcpClient adapter builds this from {@link loadConfig} * + {@link getMcpEndpoints} + its private `resolveEnableVision()`. */ export interface ToolCacheConfig { mode: string; baseUrl: string; endpoints: Record; enableVision: boolean; } /** * Tool-cache enable check (preserves v0.4.0 granularity — D3 * deviation). The tool cache is enabled only when BOTH: * - the response cache is enabled (`isCacheEnabled()` honours * `SCOUTLINE_CACHE` / `ZAI_CACHE`); AND * - the tool-specific `ZAI_MCP_TOOL_CACHE` env var is not "0"/"false". * * Read at call time (H1 fix) so per-suite env mutations in tests remain * observable. */ export declare function isToolCacheEnabled(): boolean; /** * Build the 16-char cache key for a config. Mirrors the v0.4.0 algorithm * in the extracted `ZaiMcpClient.getToolCacheKey`: SHA-256 of the * JSON-stringified config, first 16 hex chars. Two configs that produce * the same JSON yield the same key; distinct configs yield distinct keys. */ export declare function buildToolCacheKey(config: ToolCacheConfig): string; /** * Build the absolute on-disk path for a config's tool-cache envelope. * Always lands under the `tools/` subdirectory (or `tools/isolated/` * under `--isolated`). */ export declare function buildToolCachePath(config: ToolCacheConfig, envOrDir?: CacheDirEnvironment | string): string; /** * Read the tool cache for a config. Returns `null` on miss, version * mismatch, TTL expiry, corruption (invalid JSON, missing file), or when * the tool cache is disabled. NEVER throws — a miss degrades cleanly to * discovery. * * On a version mismatch the legacy envelope is unlinked best-effort * (B1-U2 / #45): pre-redaction v1 entries may carry plaintext Provider * credentials, so leaving them on disk after we detect they are unsafe * would let the secret linger until manual cleanup. `fs.unlink` is * wrapped — a failure to remove the file (race, permissions) degrades to * a clean miss; it never surfaces as an error from the read path. */ export declare function readToolCache(config: ToolCacheConfig, envOrDir?: CacheDirEnvironment | string): Promise; /** * Write the tool cache for a config. Applies {@link redactTool} to every * tool before serialization (B2 fix) so the on-disk envelope never * contains raw Provider credentials. Best-effort: I/O failures are * swallowed (cache is disposable). * * The optional `secrets` argument lets a caller thread the credentials * resolved from an injected environment (e.g. `ZaiMcpClient.options.env`) * into redaction, so a secret that exists only in the injected env — and * not in ambient `process.env` — is still redacted. When omitted, * `redactTool` falls back to `configuredSecrets()` from `process.env`, * which may miss file-only configured keys (1.1.a). */ export declare function writeToolCache(config: ToolCacheConfig, tools: Tool[], secrets?: string[], envOrDir?: CacheDirEnvironment | string): Promise; //# sourceMappingURL=tool-cache.d.ts.map