/** * Backend-availability guard for MCP tool handlers. * * PROBLEM (the bug this prevents): several tool families are wired here AHEAD of * their Frihet-ERP backend Cloud Functions shipping (fiscal `/v1/fiscal/*`, bank * rules `/v1/banking/rules`, gestoria `/v1/gestoria/*`, GL audit `/v1/gl/*`, * portal domain/onboard, IGIC, IS, VIES onboarding, and webhook test). Until a * staged CF deploys, the API returns a genuine HTTP 404. Live HR, payroll-read, * and period-read tools also retain this guard as workspace-rollout safety. * * If that raw 404 reaches `handleToolError` it is mapped to the generic message * "Resource not found. / Recurso no encontrado." — which an LLM reads as "the * thing you asked about does not exist" and then HALLUCINATES a confident answer * ("you have no Modelo 303 to file", "this workspace has no permissions matrix"). * That is a Trust-Area failure: the model invents fiscal/compliance facts. * * FIX: wrap the client call in `withBackendGuard`. A genuine 404 is converted into * an explicit STRUCTURED tool error that names the tool and states the backend is * not available yet — never a value the LLM can mistake for real business data. * Any other error (401/403/429/5xx/network) is RE-THROWN unchanged so the normal * `withToolLogging` → `handleToolError` path still surfaces it. * * NOTE: this is intentionally a SEPARATE module from `shared.ts` (owned elsewhere) * and `client.ts`. It only depends on the public content-block shape. */ import { type AnnotatedTextContent } from "./shared.js"; /** Structured-content payload returned alongside a backend-unavailable error. */ export interface BackendUnavailableStructured { error: "backend_unavailable"; tool: string; message: string; /** The planned REST endpoint, if known — aids ops/debugging, not the LLM. */ endpoint?: string; /** Machine flag so downstream agents can branch without parsing prose. */ _backendUnavailable: true; } export interface BackendGuardErrorResult { /** Index signature mirrors the MCP `ToolResult` shape so this is assignable to it. */ [x: string]: unknown; content: AnnotatedTextContent[]; structuredContent: Record; isError: true; } /** * True when an error is a genuine HTTP 404 (FrihetApiError-like or fetch-shaped). * Duck-typed so it works regardless of which client implementation threw. */ export declare function isBackendNotFound(error: unknown): boolean; /** * Builds the explicit, LLM-safe "backend not available" tool error. */ export declare function backendUnavailableError(toolName: string, endpoint?: string): BackendGuardErrorResult; /** * Wraps a tool's client call. On a genuine 404 (backend not deployed) returns a * structured backend-unavailable error instead of letting the raw 404 surface as * a generic "resource not found" that the LLM would treat as real data. Any other * error is re-thrown so `withToolLogging`/`handleToolError` handle it normally. * * Usage: * ```ts * async ({ period }) => withToolLogging("get_modelo_303_summary", () => * withBackendGuard("get_modelo_303_summary", "/v1/fiscal/303", async () => { * const result = await client.getFiscalModeloSummary("303", period); * return { content: [getContent(formatRecord("Modelo 303 Summary", result))], * structuredContent: result as unknown as Record }; * }), * ) * ``` */ export declare function withBackendGuard(toolName: string, endpoint: string | undefined, fn: () => Promise): Promise; //# sourceMappingURL=backend-availability.d.ts.map