Skip to content

Feature/agent cache adding OpenAI anthropic llamaindex adapters#115

Merged
KIvanow merged 12 commits intomasterfrom
feature/agent-cache-adding-openai-anthropic-llamaindex-adapters
Apr 20, 2026
Merged

Feature/agent cache adding OpenAI anthropic llamaindex adapters#115
KIvanow merged 12 commits intomasterfrom
feature/agent-cache-adding-openai-anthropic-llamaindex-adapters

Conversation

@KIvanow
Copy link
Copy Markdown
Member

@KIvanow KIvanow commented Apr 20, 2026

Summary

Adds multi-modal support to @betterdb/agent-cache via three new SDK adapters (OpenAI Chat, Anthropic, LlamaIndex), a new OpenAI Responses adapter, a pluggable binary normalizer for content-addressed image/audio/document hashing,
and a storeMultipart() method on the LLM cache tier. All four adapters normalize to a shared intermediate representation, so the same cached response can be served regardless of which SDK the caller uses.

Changes

  • src/normalizer.ts - New pluggable binary normalizer API: hashBase64, hashBytes, hashUrl, fetchAndHash, passthrough, composeNormalizer, defaultNormalizer. Allows callers to control how image/audio/document bytes are reduced to
    a stable cache key ref.
  • src/adapters/openai-chat.ts - prepareParams() for OpenAI Chat Completions. Handles all 6 message roles, image/audio/file content parts, parallel tool calls, and __raw fallback for malformed tool arguments.
  • src/adapters/anthropic.ts - prepareParams() for Anthropic Messages API. Splits tool_result blocks into separate IR tool messages, preserves cache_control as hints.anthropicCacheControl, maps thinking/redacted-thinking to
    ReasoningBlock.
  • src/adapters/llamaindex.ts - prepareParams() for LlamaIndex ChatMessage[]. Dispatches on options.toolCall / options.toolResult, maps memory role to system.
  • src/adapters/openai-responses.ts - prepareParams() for OpenAI Responses API. State machine groups consecutive function_call items into one assistant block, handles reasoning items with encrypted_content.
  • src/utils.ts - Widened llmCacheHash with new optional params (toolChoice, seed, stop, responseFormat, reasoningEffort, promptCacheKey). Added ContentBlock union and sub-types (TextBlock, BinaryBlock, ToolCallBlock,
    ToolResultBlock, ReasoningBlock, BlockHints). Backward compatible - text-only callers produce identical hashes to v0.2.0.
  • src/tiers/LlmCache.ts - Added contentBlocks? to stored entries and new storeMultipart() method. check() now surfaces contentBlocks on hits.
  • src/types.ts - Added LlmCacheMessage, widened LlmCacheParams with 6 new optional fields, extended LlmCacheResult with contentBlocks, model, storedAt, tokens, cost.
  • package.json - Added openai, @anthropic-ai/sdk, @llamaindex/core as optional peer dependencies. Added ./openai, ./anthropic, ./llamaindex, ./openai-responses export paths.
  • examples/openai/, examples/anthropic/, examples/llamaindex/ - Runnable examples with standalone + cluster support, vision, tool calls, and cost savings display.
  • 29 new tests across hash-backcompat, normalizer, openai-chat, anthropic, llamaindex, openai-responses, and cross-provider test files.

Checklist

  • Unit / integration tests added
  • Docs added / updated
  • Roborev review passed — run roborev review --branch or /roborev-review-branch in Claude Code (internal)
  • Competitive analysis done / discussed (internal)
  • Blog post about it discussed (internal)

Note

Medium Risk
Moderate risk because it expands the public API and changes the LLM cache entry shape/hashing logic (new optional fields and contentBlocks), which could affect cache hit rates and interoperability across SDKs.

Overview
Adds multi-modal LLM caching to @betterdb/agent-cache by introducing a shared content-block IR (text/binary/tool_call/reasoning), a pluggable binary normalizer (composeNormalizer, hashBase64/hashUrl/etc.), and a new llm.storeMultipart() path that stores both flattened text and structured contentBlocks (with check() now returning them on hits).

Introduces new provider adapters and exports for OpenAI Chat, OpenAI Responses, Anthropic, and LlamaIndex (prepareParams), plus cross-provider fixtures/tests to ensure these adapters normalize to the same params+hash. Updates package exports/peers, bumps version to 0.3.0, adds runnable examples for the new adapters, and extends the release workflow build verification to include the new adapter artifacts.

Reviewed by Cursor Bugbot for commit 1989dc4. Bugbot is set up for automated code reviews on this repo. Configure here.

KIvanow and others added 7 commits April 17, 2026 22:32
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…3/4)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ase 4/4)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Comment thread packages/agent-cache/src/tiers/LlmCache.ts
Comment thread packages/agent-cache/src/adapters/openai-chat.ts Outdated
Comment thread packages/agent-cache/src/adapters/anthropic.ts Outdated
Comment thread packages/agent-cache/src/tiers/LlmCache.ts
Comment thread packages/agent-cache/src/adapters/anthropic.ts
Comment thread packages/agent-cache/src/tiers/LlmCache.ts
Comment thread packages/agent-cache/src/adapters/openai-responses.ts Outdated
Comment thread packages/agent-cache/src/adapters/openai-responses.ts Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 53ff629. Configure here.

}
}
return input;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local parseInput duplicates shared parseToolCallArgs utility

Low Severity

The private parseInput function in llamaindex.ts duplicates the logic of the exported parseToolCallArgs in utils.ts. Both parse a JSON string with a { __raw: ... } fallback, but they differ subtly for empty-string inputs: parseToolCallArgs coalesces "" to "{}" yielding {}, while parseInput would let JSON.parse("") throw and return { __raw: "" }. This hidden inconsistency means empty tool-call arguments hash differently depending on which adapter produced them. The LlamaIndex adapter could delegate to parseToolCallArgs for string inputs and only add the pass-through for non-string inputs.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 53ff629. Configure here.

throw err;
}
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storeMultipart missing cache.model span attribute

Low Severity

The storeMultipart method doesn't set span.setAttribute('cache.model', params.model) like the existing store method does (which sets it at line 169). This omission causes the OpenTelemetry span for multipart stores to lack the model attribute, making traces harder to filter and analyze. The fallback value for the TTL attribute also differs: store uses ttl ?? -1 while storeMultipart uses ttl ?? 0, creating an inconsistent sentinel for "no TTL."

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 53ff629. Configure here.

@KIvanow KIvanow merged commit da4bc44 into master Apr 20, 2026
3 checks passed
@KIvanow KIvanow deleted the feature/agent-cache-adding-openai-anthropic-llamaindex-adapters branch April 20, 2026 18:59
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant