Documentation Index
Fetch the complete documentation index at: https://docs.dzap.io/llms.txt
Use this file to discover all available pages before exploring further.
The loop
1. User prompt + metadata (wallet, chain) arrive
└─ Vercel AI SDK generateText() with tools[]
2. Model produces a plan
└─ Either: textual answer, OR tool calls
3. Tool calls execute in sequence
└─ Each tool wraps a DZap API or external service
4. Tool results feed back into model
└─ Model decides: another tool? answer? clarification?
5. Final text + structured tool calls return
└─ result.finalText, result.toolCalls
Reasoning trace
For a query like “Swap 100 USDC for WETH on Arbitrum”:
[1] BalanceTool: confirm USDC balance ≥ 100
→ 100 USDC available
[2] TokenAddressTool: resolve symbols
→ USDC: 0xaf88..., WETH: 0x82aF...
[3] ZapCallDataGeneratorTool: build the trade
→ quote: 100 USDC → 0.041 WETH, fee 0.05%, slippage 1%
[4] (with confirmation) PerformZapTool: execute
→ tx hash: 0xabc...
[5] Final answer with tx link
You see the structured trace in result.toolCalls; the user sees result.finalText.
Tools have descriptions. The model picks based on description match. To bias selection:
- Make user intent explicit — “show top pools” reaches for
PoolTool; “what’s my balance” reaches for BalanceTool.
- Use metadata —
accountInfo in metadata anchors BalanceTool and DefiPositionsTool automatically.
- Custom system prompt — pass
systemPrompt at SDK init to nudge selection (e.g. “always check balance before swap”).
Errors
When a tool fails, ZapBot retries with backoff (default 2 retries). On exhaustion, it surfaces the error to the model — which usually picks a different tool or asks the user for clarification.
You can inspect retry behavior in result.toolCalls[i].error.
Streaming
sdk.ask() streams events when onStep is provided:
await sdk.ask({
userQuery: "...",
metadata: { ... },
onStep: (event) => {
console.log(event.type, event); // 'tool_call' | 'tool_result' | 'text_delta'
},
});
Use this to render real-time progress in a UI.
Memory
ZapBot reads ChatHistory at the start of each turn and writes the new turn back. For multi-turn conversations:
const sdk = new DZapSDK();
await sdk.initialize({ /* ... */ });
await sdk.ask({ userQuery: "What's the price of ETH?", sessionId: 'user-123' });
await sdk.ask({ userQuery: "Same question for BTC.", sessionId: 'user-123' });
// Second call sees the first turn's history.
Reset by passing a new sessionId or clearing memory explicitly.