diff --git a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md index 9b2139f7..c519f477 100644 --- a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md +++ b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md @@ -2122,6 +2122,27 @@ Notes: - `cd ts && bun run lint` - `git diff --check` +### 2026-06-04: Retrieval RAG Effect.fn Helper Slice + +- Status: migrated and package-verified. +- Completed: + - `ts/packages/flow/src/retrieval/document-rag.ts` now defines its reusable + document RAG query program with `Effect.fn` instead of a function returning + `Effect.gen`. + - `ts/packages/flow/src/retrieval/graph-rag.ts` now defines the graph RAG + query, concept extraction, vector lookup, entity lookup, edge traversal, + edge scoring, and synthesis helpers with named `Effect.fn` providers. + - Public Promise facades and requestor compatibility surfaces are unchanged. + - The focused scan for retrieval `return Effect.gen(...)` helper patterns is + clean. +- Verification: + - `cd ts/packages/flow && bunx --bun vitest run src/__tests__/retrieval-rag.test.ts` + - `cd ts && bun run check:tsgo` + - `cd ts && bun run build` + - `cd ts && bun run test` + - `cd ts && bun run lint` + - `git diff --check` + ## Subagent Findings To Preserve - MCP/workbench: @@ -2281,8 +2302,8 @@ Notes: slices found no production normal `Error`, raw `try`/`catch`, native `switch`, or Effect-focused type assertions under `ts/packages`. - Remaining real helper-normalization targets from the fresh sweep are - retrieval/document-rag, retrieval/graph-rag, embeddings/ollama, base - processor flow helpers, and one workbench atom helper. + embeddings/ollama, base processor flow helpers, and one workbench atom + helper. - Remaining real long-lived native collection targets include base processor registries, Librarian service / collection manager state, prompt template cache, and a workbench module cache. Local traversal sets and test fakes diff --git a/ts/packages/flow/src/retrieval/document-rag.ts b/ts/packages/flow/src/retrieval/document-rag.ts index 409e38c8..6e5b6be9 100644 --- a/ts/packages/flow/src/retrieval/document-rag.ts +++ b/ts/packages/flow/src/retrieval/document-rag.ts @@ -93,12 +93,11 @@ export function makeDocumentRag(clients: DocumentRagClients): DocumentRag { }; } -function queryDocumentRag( +const queryDocumentRag = Effect.fn("DocumentRagEngine.queryDocumentRag")(function* ( clients: DocumentRagClients, queryText: string, options?: DocumentRagQueryOptions, -): Effect.Effect { - return Effect.gen(function* () { +) { const collection = options?.collection ?? "default"; const embResp = yield* clients.embeddings.request({ text: [queryText] }).pipe( @@ -139,4 +138,3 @@ function queryDocumentRag( return resp.response; }); -} diff --git a/ts/packages/flow/src/retrieval/graph-rag.ts b/ts/packages/flow/src/retrieval/graph-rag.ts index ea4d1b9c..76a7838b 100644 --- a/ts/packages/flow/src/retrieval/graph-rag.ts +++ b/ts/packages/flow/src/retrieval/graph-rag.ts @@ -149,13 +149,12 @@ export function makeGraphRag( }; } -function queryGraphRag( +const queryGraphRag = Effect.fn("GraphRagEngine.queryGraphRag")(function* ( clients: GraphRagClients, queryText: string, options?: GraphRagQueryOptions, rawConfig?: GraphRagConfig, -): Effect.Effect { - return Effect.gen(function* () { +) { const config = normalizeGraphRagConfig(rawConfig); yield* Effect.log(`[GraphRag] Query: "${queryText.slice(0, 80)}..."`); @@ -185,10 +184,11 @@ function queryGraphRag( return { answer, subgraph: scoredEdges }; }); -} -function extractConcepts(clients: GraphRagClients, query: string): Effect.Effect { - return Effect.gen(function* () { +const extractConcepts = Effect.fn("GraphRagEngine.extractConcepts")(function* ( + clients: GraphRagClients, + query: string, +) { const promptResp = yield* requestClient( clients.prompt, "extract-concepts-prompt", @@ -212,22 +212,21 @@ function extractConcepts(clients: GraphRagClients, query: string): Effect.Effect .map((concept) => concept.trim()) .filter((concept) => concept.length > 0); }); -} -function getVectors(clients: GraphRagClients, concepts: string[]): Effect.Effect { - return Effect.gen(function* () { +const getVectors = Effect.fn("GraphRagEngine.getVectors")(function* ( + clients: GraphRagClients, + concepts: string[], +) { const resp = yield* requestClient(clients.embeddings, "get-vectors", { text: concepts }); return resp.vectors; }); -} -function getEntities( +const getEntities = Effect.fn("GraphRagEngine.getEntities")(function* ( clients: GraphRagClients, config: NormalizedGraphRagConfig, vectors: number[][], collection?: string, -): Effect.Effect { - return Effect.gen(function* () { +) { const resp = yield* requestClient( clients.graphEmbeddings, "get-entities", @@ -240,15 +239,13 @@ function getEntities( ); return resp.entities; }); -} -function followEdges( +const followEdges = Effect.fn("GraphRagEngine.followEdges")(function* ( clients: GraphRagClients, config: NormalizedGraphRagConfig, entities: Term[], collection?: string, -): Effect.Effect { - return Effect.gen(function* () { +) { const visited = new Set(); const subgraph: Triple[] = []; let currentLevel = new Set( @@ -301,15 +298,13 @@ function followEdges( return subgraph.slice(0, config.maxSubgraphSize); }); -} -function scoreEdges( +const scoreEdges = Effect.fn("GraphRagEngine.scoreEdges")(function* ( clients: GraphRagClients, config: NormalizedGraphRagConfig, query: string, triples: Triple[], -): Effect.Effect { - return Effect.gen(function* () { +) { if (triples.length === 0) return []; if (triples.length <= 500) { @@ -372,15 +367,13 @@ function scoreEdges( return result; }); -} -function synthesize( +const synthesize = Effect.fn("GraphRagEngine.synthesize")(function* ( clients: GraphRagClients, query: string, edges: Triple[], chunkCallback?: ChunkCallback, -): Effect.Effect { - return Effect.gen(function* () { +) { const context = edges .map((triple) => `${termToString(triple.s)} -> ${termToString(triple.p)} -> ${termToString(triple.o)}`) .join("\n"); @@ -431,7 +424,6 @@ function synthesize( return resp.response; }); -} const ScoredEdge = S.Struct({ id: S.String,