/** * Tool catalog the Strategy Decomposer agent calls during reasoning. * * Layers: * 1. Lucidly research tools — catalog, policies, verify_policy_id, addresses, families. * These let the agent confirm leaves exist on the live policy registry. The non-negotiable * "never invent a leaf" rule depends on verify_policy_id. * * 2. Strategy corpus tools — find_corpus_strategy + corpus_by_archetype + corpus_by_chain. * Nearest-neighbour lookup over the 4 reference archetypes. * * 3. Onchain read tools — read_contract proxies a JSON-RPC eth_call so the agent can inspect * pool prices, oracle staleness, market liquidity, etc. Read-only; the agent can't send tx. * * 4. Simulator dry-run tool — dry_run_plan posts to SimulatorClient.simulatePlan so the agent * can verify its candidate plan against an anvil fork BEFORE finalising. The simulator * itself has no signing key, so this is genuinely read-only at the broadcast level. * * Tool names use dotted notation (lucidly.policies); the SDK's OpenAICompatProvider already * sanitizes dots → underscores for DeepSeek's strict pattern. No special handling needed here. */ import type { Address } from "viem"; import { type CorpusStrategy } from "./strategyCorpus.js"; import { type ResearchToolsModule, type ToolDescriptor } from "./researchTools.js"; import { SimulatorClient } from "./simulatorClient.js"; export declare const CORPUS_TOOLS: ToolDescriptor[]; export declare const ONCHAIN_TOOLS: ToolDescriptor[]; /** * These let the agent answer "which deployed vault already has the policies I need?" instead of * always recommending the user deploy a new one. Useful when the user's idea matches an existing * production vault's capability set — the agent can suggest reuse + a one-click "I want to use * this vault" path. */ export declare const DISCOVERY_TOOLS: ToolDescriptor[]; /** * These let the decomposer reach beyond the corpus when the user's idea touches a protocol that * isn't in our 4 reference strategies (e.g., Euler V2, Fluid, Spark, Hyperlend, Drift). The * pattern: web_search for the protocol's docs, find_token for canonical addresses, read_protocol_abi * for verified selectors against deployed bytecode. With these, the agent stops guessing from * training data and starts grounding on current reality. */ export declare const RESEARCH_TOOLS: ToolDescriptor[]; export declare const SIMULATOR_TOOLS: ToolDescriptor[]; /** * Full tool catalog the decomposer advertises to the LLM. Combines: * - LUCIDLY_RESEARCH_TOOLS (catalog, policies, verify_policy_id, addresses, families, etc.) * - CORPUS_TOOLS (nearest-neighbour archetype lookup) * - ONCHAIN_TOOLS (raw eth_call, balance reads) * - SIMULATOR_TOOLS (dry_run_plan) * * The agent is free to call any of these in any order. The system prompt enforces the * "never-invent-a-leaf" rule: every leaf must be confirmed via verify_policy_id before * being included in the final answer. */ export declare const DECOMPOSER_TOOLS: ToolDescriptor[]; export interface DecomposerToolContext { /** ResearchToolsModule (catalog/policies/verify_policy_id/etc.). Required. */ research: ResearchToolsModule; /** Optional simulator client — when set, lucidly.dry_run_plan is functional. When unset, the * dispatcher returns a clear error telling the agent the tool isn't wired up so it can fall * back to text-only validation. */ simulator?: SimulatorClient; /** Optional onchain reader — a function that does eth_call against the requested chain. When * unset, lucidly.read_contract returns an error and the agent must rely on catalog reads. */ rpcCall?: (chainId: number, target: Address, calldata: `0x${string}`, blockTag?: string) => Promise<`0x${string}`>; /** Optional balance reader. Same shape — when unset, lucidly.read_balance errors clearly. */ rpcBalance?: (chainId: number, address: Address, blockTag?: string) => Promise; /** Optional web search adapter — injectable so callers wire Brave / Tavily / DuckDuckGo / etc. * Function shape: (query, maxResults?) → array of {title, url, snippet}. When unset, the * lucidly.web_search tool returns an error and the agent falls back to corpus + training. */ webSearch?: (query: string, maxResults?: number) => Promise>; /** Optional Etherscan v2 unified API key. When set, lucidly.read_protocol_abi works across * every chain on the same key. Get one at https://etherscan.io/apis (free tier 5 req/s). */ etherscanApiKey?: string; } /** * Dispatch a tool call from the decomposer agent's loop. Returns whatever the underlying tool * returns (already JSON-serialisable). Never throws on tool-mechanic errors — instead returns * a clear { error, hint } shape so the agent can recover (e.g., "I should call verify_policy_id * with a different policyId" rather than crashing the conversation). */ export declare function dispatchDecomposerTool(ctx: DecomposerToolContext, name: string, input: Record): Promise; export type { CorpusStrategy };