/** * LangChain / LangGraph tool adapter over withCodeRifts (ID632 slice 3 — same thin * pattern as OpenAI / Anthropic). * * Thin converter only. Guard logic stays in withCodeRifts; this module: * 1. calls withCodeRifts with the same input shape, * 2. maps each ProtectedTool → a framework-agnostic tool descriptor that * LangChain's tool()/StructuredTool and LangGraph's ToolNode can accept, * 3. returns those descriptors PLUS the untouched assurance objects * (registry_report, composition_assurance, receipt_thread). * * NO hard dependency on langchain / @langchain/* / langgraph packages. The host * owns the framework import and wires descriptors into tool() / ToolNode / * bind_tools / StateGraph themselves. * * Descriptor shape (dependency-free, StructuredTool-compatible for createReactAgent): * { name, description, schema, func, invoke, lc_runnable: true } * Measured against @langchain/langgraph createReactAgent tools: * ToolNode | (StructuredToolInterface | DynamicTool | RunnableToolLike)[] * (@langchain/langgraph@0.2.74 d.ts; current npm 1.4.12). Runtime isRunnable * requires lc_runnable === true; ToolNode drops non-matching tools and the * model sees "Tool not found" — NEVER return that silent shape. * - schema = JSON Schema from ProtectedTool.inputSchema (or empty object schema) * - func / invoke = the GUARDED execute (same function reference) — never the raw tool * - description always set (fallback to name) — StructuredToolInterface requires it * NO hard @langchain/* dependency: duck-type the measured surface. If a tool would * still fail that check, throw LangGraphToolsNotStructuredError (named, with the fix). * * Honesty (do not "upgrade" assurance): * - composition_assurance is passed through EXACTLY as the core reported it * (COMPOSITION_CALL_POLICY_COMPLETE may still be false; inescapable_runtime may be false). * - The adapter converts tool shape + binds guarded execute; it does not claim product-level * inescapability the core does not claim. * * Only-protected-tools (6/D at the adapter surface): * - `tools` is derived ONLY from the frozen registry's ProtectedTool list. * - Raw tools never appear in the returned table. The host may still hold a raw * reference outside this table; that boundary stays the host's responsibility. * * Ergonomics (5–10 lines): pass raw tools + client + operation → LangGraph-ready descriptors. * Mirrors src/adapters/openai.ts and anthropic.ts — only the target tool shape differs. */ import type { WithCodeRiftsInput, WithCodeRiftsResult, CompositionAssurance, ReceiptThreadHandle } from '../with-coderifts.js'; import type { CoverageObservedHandle } from '../coverage-observed.js'; import type { ProtectedTool, RegistryCoverageReport } from '../tool-registry.js'; import type { GuardOutcome } from '../types.js'; /** * Framework-agnostic LangChain/LangGraph tool descriptor (no package import). * * Host wiring (illustrative — host supplies the framework packages, e.g. * @langchain/core tools + @langchain/langgraph ToolNode): * const lcTools = tools.map((d) => * hostTool(d.func, { name: d.name, description: d.description, schema: d.schema })); * // then hostToolNode(lcTools) / hostLlm.bindTools(lcTools) */ export type LangGraphToolDescriptor = { name: string; /** Always set (fallback to name). StructuredToolInterface requires description. */ description: string; /** JSON Schema for tool args (LangChain `schema` / StructuredTool args). */ schema: Record; /** * Guarded execute — same as ProtectedTool.execute. * Pass to LangChain `tool(func, …)` or StructuredTool-style runners. */ func: (args: unknown) => Promise; /** * Alias of `func` for invoke-style APIs (StructuredTool.invoke / ToolNode). * Same guarded execute reference as `func`. Runnable.invoke also accepts a config arg. */ invoke: (args: unknown, _config?: unknown) => Promise; /** * Measured isRunnable / isStructuredTool check (@langchain/core). * Without this, createReactAgent's ToolNode drops the tool → model-visible "Tool not found". */ lc_runnable: true; }; /** * Named error — thrown instead of returning tools createReactAgent would silently drop. * Never a model-visible "Tool not found". */ export declare class LangGraphToolsNotStructuredError extends Error { constructor(message?: string); } /** * True iff `t` matches the measured createReactAgent tool surface * (StructuredToolInterface | DynamicTool | RunnableToolLike). */ export declare function isLangGraphReactAgentTool(t: unknown): t is LangGraphToolDescriptor; /** * Result of withCodeRiftsLangGraph — descriptors + core assurance, unflattened. * * `tools` is the ONLY list intended for the model/runtime tool table. `protected_tools` is the * same guarded list for host inspection — never the raw tools. */ export type WithCodeRiftsLangGraphResult = { /** LangGraph/LangChain-compatible descriptors — only protected/guarded tools. */ tools: LangGraphToolDescriptor[]; /** * Guarded ProtectedTool list from withCodeRifts (same tools as `tools`). * Host may use these for dispatch; never raw tools. */ protected_tools: ProtectedTool[]; /** Untouched registry report — registry's own truth. */ registry_report: RegistryCoverageReport; /** * Product-level assurance — deliberately narrower than the registry. * Passed through untouched; may still show inescapable_runtime:false and * residual composition_call_policy_incomplete. */ composition_assurance: CompositionAssurance; /** Per-composition receipt cursor — NOT product-truth chain evidence. */ receipt_thread: ReceiptThreadHandle; /** Observed coverage for this withCodeRifts run. Half A always; Half B via reportToolDispatch. */ coverage_observed: CoverageObservedHandle; repository?: string; }; /** * Map one ProtectedTool → LangGraph/LangChain tool descriptor. * Binds guarded execute to both `func` and `invoke` (same reference). * Prefer tool.inputSchema when it is a plain object; otherwise empty object schema. */ export declare function protectedToolToLangGraph(tool: ProtectedTool): LangGraphToolDescriptor; /** * Convert a list of ProtectedTool into LangGraph/LangChain descriptors. * Does NOT call the guard — pure map over an already-protected list. */ export declare function toLangGraphTools(protectedTools: readonly ProtectedTool[]): LangGraphToolDescriptor[]; /** * Assert (and return) tools that createReactAgent can consume. * Throws LangGraphToolsNotStructuredError — never a silent "Tool not found". */ export declare function bindLangGraphTools(tools: readonly unknown[]): LangGraphToolDescriptor[]; /** * Build LangGraph/LangChain-ready guarded tool descriptors from raw tools + client + operation. * * Calls withCodeRifts internally (guard logic stays in the core). Returns: * - `tools` — StructuredTool-compatible descriptors { name, description, schema, func, invoke, lc_runnable } * - `protected_tools` — same guarded tools * - assurance objects from the core, passed through untouched * * @param input Same shape as withCodeRifts (WithCodeRiftsInput). */ export declare function withCodeRiftsLangGraph(input: WithCodeRiftsInput): WithCodeRiftsLangGraphResult; /** * Shape adapter over an existing WithCodeRiftsResult (composition style). * Prefer withCodeRiftsLangGraph when starting from raw tools. * * Does not re-run the guard; does not invent assurance. */ export declare function langGraphToolAdapter(result: WithCodeRiftsResult): WithCodeRiftsLangGraphResult; /** * Minimal LangChain ToolMessage-shaped plain object (no @langchain/* dependency). * Host may wrap into ToolMessage: new ToolMessage({ content, tool_call_id, name? }). * @see https://js.langchain.com/docs/concepts/messages */ export type LangGraphToolMessage = { content: string; tool_call_id: string; name?: string; }; declare const __proofBoundLangGraphBrand: unique symbol; export type ProofBoundLangGraphToolMessage = LangGraphToolMessage & { readonly __proofBound: typeof __proofBoundLangGraphBrand; }; export type BindLangGraphGuardOutcomeArgs = { /** LangChain/LangGraph tool_call_id this ToolMessage answers. */ tool_call_id: string; /** Optional tool name (ToolMessage.name). */ name?: string; serialize?: (result: T) => string; /** * Attach the rendered GuardExecutionProof (S4). Default ON. * Pass `false` to opt out. */ attachProof?: boolean; }; export declare function defaultSerializeLangGraphToolResult(result: T): string; /** * Map a full GuardOutcome into a LangGraph/LangChain ToolMessage shape with proof embedded. * Same arm mapping as bindOpenAIGuardOutcome; id field is tool_call_id. */ export declare function bindLangGraphGuardOutcome(outcome: GuardOutcome, args: BindLangGraphGuardOutcomeArgs): ProofBoundLangGraphToolMessage; export {}; //# sourceMappingURL=langgraph.d.ts.map