Skip to content

DOC-7228 Port the Lettuce semantic-cache and memory-layer demos to the typed FT.* and JSON.* API - #4398

Open
andy-stark-redis wants to merge 2 commits into
mainfrom
DOC-7228-lettuce-ft-port
Open

andy-stark-redis wants to merge 2 commits into
mainfrom
DOC-7228-lettuce-ft-port

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Jira: DOC-7228. Second PR for DOC-7228, after #4397 (recommendation engine and feature store). Based on main, independent of #4397 and #4396.

The semantic-cache and agent-memory demos sent every FT.* and JSON.* command through dispatch() with hand-built CommandArgs, and parsed the replies by position. Their pages said "Lettuce 6.7 doesn't ship first-class FT.* or JSON.* bindings", which stopped being true in 7.0. Both now use the typed API on Lettuce 7.9.0.

Changes

  • semantic-cache (pom 6.7.1 to 7.9.0): RedisSemanticCache uses ftCreate, ftSearch and ftDropindex with CreateArgs, FieldArgs and SearchArgs. The hand-written reply parser is gone.
  • memory-layer (pom 6.7.1 to 7.9.0): LongTermMemory uses the same typed search calls plus jsonSet and jsonNumincrby. JSON.SET still runs inside MULTI/EXEC under the shared lock.
  • FT.INFO stays on dispatch() in both: 7.9.0 has no typed ftInfo. The helpers keep a single-entry ProtocolKeyword for it.
  • RESP2 pin removed from both DemoServers and the pages. It existed so the hand-written parser saw the flat RESP2 shape. The typed parser handles RESP2 and RESP3, and the drivers gave identical results under RESP2, RESP3 and the default protocol (including the FT.INFO dispatch).
  • dropIndex fix: both helpers tolerated a missing index only for "no such index" and "unknown index name". Redis 8.10 says SEARCH_INDEX_NOT_FOUND Index not found, so dropIndex threw on a fresh 8.10. A shared isMissingIndex helper covers all three wordings.
  • Pages rewritten around the typed calls: the overview, the lookup and recall steps, the connection snippets and the query snippets.

Verification

  • Both demos build with mvn compile on 7.9.0 with no deprecation warnings.
  • A throwaway driver per demo against Redis 8.10.2 with synthetic vectors, under RESP2, RESP3 and the default protocol:
    • semantic cache: dropIndex on a missing index, idempotent createIndex, put, a hit with hit_count increment and TTL refresh, tenant isolation, a far-vector miss, an empty-tenant miss, listEntries, indexInfo and clear.
    • agent memory: dropIndex, idempotent createIndex, remember (new write, same-vector dedupe that bumps hit_count, other user not deduped), recall with its TTL, scope isolation, listMemories, indexInfo, deleteMemory and clear.
  • MONITOR shows the typed calls send the same FT.SEARCH as before (same RETURN, SORTBY, LIMIT, PARAMS and DIALECT 2), and FT.CREATE with the same schema (the vector attributes are sent in a different order, which is equivalent). Memory-layer also sends JSON.SET and JSON.NUMINCRBY $.hit_count as before.

Not verified

  • The embedding model (DJL with PyTorch) was not available offline, so LocalEmbedder and the DemoServer HTTP endpoints of both demos have not run on 7.9.0. Only RedisSemanticCache and LongTermMemory were exercised.
  • For memory-layer, AgentSession and AgentEventLog were not exercised.

Still open in DOC-7228

Not in this PR: the manual jar recipes (Netty 4.2.17 and reactor-core 3.8.7) and the remaining pin bumps.

Not squashing yet: /finalize waits for approval.

🤖 Generated with Claude Code


Note

Low Risk
Documentation demo code only; behavior is intended to stay wire-equivalent with broader Redis version compatibility for idempotent index drops.

Overview
Both java-lettuce demos bump Lettuce 6.7.1 → 7.9.0 and stop hand-building Redis Search/JSON via dispatch() and RESP2-shaped reply parsers.

LongTermMemory and RedisSemanticCache now use typed ftCreate, ftSearch, ftDropindex, and (memory-layer only) jsonSet / jsonNumincrby with CreateArgs, FieldArgs, and SearchArgs. FT.INFO alone stays on dispatch() because 7.9 has no typed helper. Hand-written parseAllHits / fieldsToMap logic is replaced by SearchReply and FieldValue.

RESP2 pinning is removed from both DemoServer classes and the walkthrough pages; the typed client handles RESP2 and RESP3. dropIndex tolerates Redis 8.10 missing-index wording via shared isMissingIndex.

Doc pages for semantic-cache and memory-layer are updated to match (connection snippets, query examples, and the section formerly about sending commands through dispatch()).

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

andy-stark-redis and others added 2 commits October 30, 2026 15:50
The demo now pins Lettuce 7.9.0 (was 6.7.1) and uses ftCreate, ftSearch and ftDropindex
instead of dispatch() with hand-built CommandArgs, and SearchArgs instead of an alternating
reply parsed by position. FT.INFO is the one search command with no typed method in 7.9.0,
so indexInfo() still dispatches it. The page said Lettuce 6.7 has no FT.* bindings; that
paragraph, the query snippet and the connection snippet are rewritten, and the class
javadoc now says which commands are typed.

The explicit RESP2 pin is removed. It existed so the hand-written parser saw the flat
RESP2 shape, and the typed API parses either protocol. I ran the same driver under RESP2,
RESP3 and the default protocol and the results were identical, including the FT.INFO
dispatch, which NestedMultiOutput handles in both. MONITOR shows the typed calls send the
same FT.SEARCH as before (same RETURN, SORTBY, LIMIT, PARAMS and DIALECT 2). FT.CREATE sends
the vector attributes in a different order, which is equivalent.

dropIndex tolerates a missing index by message text, and Redis 8.10 words it
"SEARCH_INDEX_NOT_FOUND Index not found", so isMissingIndex now covers that wording too.

Verified with mvn compile (no deprecation warnings) and a throwaway driver against Redis 8.10.2
with synthetic vectors: dropIndex on a missing index, idempotent createIndex, put, hit,
hit_count increment, tenant isolation, far-vector miss, empty-tenant miss, listEntries,
indexInfo and clear. The embedding model was not available offline, so LocalEmbedder and the
DemoServer HTTP endpoints have not run on 7.9.0.

Learned: Lettuce 7.9.0's typed ftSearch replaces the hand-parsed FT.SEARCH reply and works under RESP2 and RESP3, so the RESP2 pin is unnecessary
Constraint: FT.INFO has no typed method in Lettuce 7.9.0, so indexInfo() must keep dispatch() with FtCommand.FT_INFO
Gaps: LocalEmbedder and the DemoServer endpoints have not run on 7.9.0; only RedisSemanticCache was exercised
Recheck: when Lettuce adds a typed ftInfo, replace the FT.INFO dispatch
Ticket: DOC-7228
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…SON APIs

The demo now pins Lettuce 7.9.0 (was 6.7.1). LongTermMemory uses ftCreate, ftSearch and
ftDropindex for Redis Search and jsonSet and jsonNumincrby for Redis JSON, instead of
dispatch() with hand-built CommandArgs and a parser that walked the nested reply. JSON.SET
still runs inside MULTI/EXEC under the shared txLock, and the typed call queues like any
other command. FT.INFO has no typed method in 7.9.0, so indexInfo() still dispatches it.

The page claimed Lettuce 6.7 has no FT.* or JSON.* bindings; the overview, the recall and
remember steps, the connection snippet and the "Sending FT.* / JSON.* commands" section are
rewritten around the typed calls. The explicit RESP2 pin is removed from DemoServer and the
page: the typed parser handles both protocols, which I confirmed by running the same driver
under RESP2, RESP3 and the default protocol with identical results, and by recording the
wire commands with MONITOR (FT.CREATE on a JSON index with the same aliased schema,
FT.SEARCH with the same KNN query, RETURN list, SORTBY, LIMIT and DIALECT 2, JSON.SET with
the document and JSON.NUMINCRBY on $.hit_count).

dropIndex tolerated a missing index only by two message texts, and Redis 8.10 words it
"SEARCH_INDEX_NOT_FOUND Index not found", so isMissingIndex now covers that wording too.

Verified with mvn compile (no deprecation warnings) and a throwaway driver against Redis
8.10.2 with synthetic vectors: dropIndex on a missing index, idempotent createIndex,
remember (new write, same-vector dedupe that bumps hit_count, other user not deduped),
recall with its TTL, scope isolation, listMemories, indexInfo, deleteMemory and clear. The
embedding model was not available offline, so LocalEmbedder, AgentSession, AgentEventLog and
the DemoServer endpoints have not run on 7.9.0.

Learned: Lettuce 7.9.0 has typed ftSearch, ftCreate, ftDropindex, jsonSet and jsonNumincrby that work inside MULTI/EXEC and under RESP2 and RESP3
Constraint: FT.INFO has no typed method in Lettuce 7.9.0, so indexInfo() must keep dispatch() with ModuleCommand.FT_INFO
Gaps: only LongTermMemory was exercised; LocalEmbedder, AgentSession, AgentEventLog and the DemoServer endpoints have not run on 7.9.0
Recheck: when Lettuce adds a typed ftInfo, replace the FT.INFO dispatch
Ticket: DOC-7228
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7228

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

Found 5 related items from repository history (5 new this commit):

Memory updated at 3433472

@dwdougherty dwdougherty left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Skimmed. Approved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clients Client library docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants