Skip to content

Commit 4b1f9bd

Browse files
matte1782claude
andcommitted
feat(w43): revise Day 5 plan — drop MMR (not in @langchain/core), add gap analysis
- Drop W43.5d (maxMarginalRelevanceSearch): not on VectorStore prototype - Replace with similaritySearch + similaritySearchWithScore default tests - Add post-Day-4 gap analysis (101 tests delivered, dist/ not yet built) - Document actual available default methods from @langchain/core@0.3.x - Note tsup output path uncertainty for build verification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 228c6ab commit 4b1f9bd

1 file changed

Lines changed: 111 additions & 47 deletions

File tree

docs/planning/weeks/week_43/day_5.md

Lines changed: 111 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,39 @@
11
# Week 43 — Day 5: Integration Tests + Default Method Verification + Build
22

33
**Date:** 2026-03-11
4-
**Status:** [REVISED]Hostile review fixes applied (C1 config clarification)
4+
**Status:** [REVISED]Updated after Day 4 completion; removed W43.5d (MMR does not exist on installed @langchain/core)
55
**Focus:** End-to-end RAG pipeline tests, verify LangChain default method behavior, validate ESM + CJS dual build
6-
**Prerequisite:** Day 4 complete (unit tests passing)
6+
**Prerequisite:** Day 4 complete (101 tests passing: 40 metadata + 61 store)
77
**Reference:** `docs/research/LANGCHAIN_SPIKE.md` Section 1 (Default Methods)
88

99
---
1010

11+
## Gap Analysis (Post Day 4)
12+
13+
**Days 1-4 delivered:**
14+
- `pkg/langchain/src/` — 5 modules (index, store, types, metadata, init)
15+
- `pkg/langchain/tests/metadata.test.ts` — 40 tests
16+
- `pkg/langchain/tests/store.test.ts` — 61 tests (0 `as any`, hostile review APPROVED)
17+
18+
**Day 5 must deliver:**
19+
1. `pkg/langchain/tests/integration.test.ts`**NEW FILE** (does not exist yet)
20+
2. `pkg/langchain/dist/`**NOT YET BUILT** (tsup configured but never run)
21+
3. Verification of inherited LangChain methods (`similaritySearch`, `similaritySearchWithScore`, `asRetriever`)
22+
23+
**Plan correction:** `maxMarginalRelevanceSearch` does NOT exist on the installed `@langchain/core@0.3.x` VectorStore prototype. Task W43.5d is **DROPPED** and replaced with `similaritySearch` string-query test (the actual default method that calls embedQuery + similaritySearchVectorWithScore).
24+
25+
---
26+
1127
## Tasks
1228

1329
| Task | ID | Hours | Status | Dependency |
1430
|:-----|:---|:------|:-------|:-----------|
1531
| Create integration test with mock embeddings (no external API) | W43.5a | 1.5h | PENDING | Day 4 |
16-
| Test full RAG pipeline: embed store search retrieve | W43.5b | 1h | PENDING | W43.5a |
17-
| Test `addDocuments` default implementation (embeds via `this.embeddings`) | W43.5c | 0.5h | PENDING | Day 3 |
18-
| Test `maxMarginalRelevanceSearch` default with EdgeVec scores | W43.5d | 0.5h | PENDING | Day 3 |
32+
| Test full RAG pipeline: embed -> store -> search -> retrieve | W43.5b | 1h | PENDING | W43.5a |
33+
| Test `similaritySearch` default (string query -> embedQuery -> search) | W43.5c | 0.5h | PENDING | Day 3 |
34+
| Test `similaritySearchWithScore` default (string query variant) | W43.5d | 0.5h | PENDING | Day 3 |
1935
| Test `asRetriever()` returns functional `VectorStoreRetriever` | W43.5e | 0.5h | PENDING | Day 3 |
20-
| Verify build: ESM + CJS dual output | W43.5f | 1h | PENDING | Day 3 |
36+
| Verify build: ESM + CJS dual output via `tsup` | W43.5f | 1h | PENDING | Day 3 |
2137
| Verify peer dep: test with `@langchain/core@0.3.x` and `@langchain/core@0.4.x` | W43.5g | 0.5h | PENDING | W43.5f |
2238

2339
**Total Estimated Hours:** 5.5h
@@ -27,9 +43,9 @@
2743
## Critical Path
2844

2945
```
30-
W43.5a (integration setup) W43.5b (RAG pipeline)
46+
W43.5a (integration setup) -> W43.5b (RAG pipeline)
3147
W43.5c + W43.5d + W43.5e (default methods, parallel)
32-
W43.5f (build) W43.5g (peer dep compat)
48+
W43.5f (build) -> W43.5g (peer dep compat)
3349
```
3450

3551
Three independent tracks can run in parallel.
@@ -40,7 +56,7 @@ Three independent tracks can run in parallel.
4056

4157
| Artifact | Path | Description |
4258
|:---------|:-----|:------------|
43-
| Integration tests | `pkg/langchain/tests/integration.test.ts` | E2E RAG pipeline tests |
59+
| Integration tests | `pkg/langchain/tests/integration.test.ts` | E2E RAG pipeline + default method tests |
4460
| Build output | `pkg/langchain/dist/` | ESM + CJS compiled output |
4561

4662
---
@@ -49,46 +65,56 @@ Three independent tracks can run in parallel.
4965

5066
### W43.5a — Integration Test Setup
5167

68+
The integration test file uses the same mock infrastructure as `store.test.ts` but focuses on **multi-step workflows** rather than individual methods.
69+
5270
```typescript
53-
describe("EdgeVecStore Integration", () => {
54-
let store: EdgeVecStore;
55-
let embeddings: MockEmbeddings;
56-
57-
beforeAll(async () => {
58-
await initEdgeVec();
59-
embeddings = new MockEmbeddings(128);
60-
});
61-
62-
beforeEach(() => {
63-
// [C1 FIX] metric is an EdgeVecStoreConfig field, NOT IndexConfig.
64-
// EdgeVecStore constructor extracts it before passing to EdgeVecIndex.
65-
store = new EdgeVecStore(embeddings, {
66-
dimensions: 128,
67-
metric: "cosine", // EdgeVecStoreConfig.metric (default), NOT IndexConfig
71+
import { Embeddings } from "@langchain/core/embeddings";
72+
73+
class DeterministicEmbeddings extends Embeddings {
74+
constructor(private dims = 128) { super({}); }
75+
76+
async embedDocuments(texts: string[]): Promise<number[][]> {
77+
// Deterministic: hash-based vectors so similar texts get similar vectors
78+
return texts.map((text) => {
79+
let hash = 0;
80+
for (let i = 0; i < text.length; i++) hash = (hash * 31 + text.charCodeAt(i)) | 0;
81+
return Array.from({ length: this.dims }, (_, d) => Math.sin(hash + d) * 0.5 + 0.5);
6882
});
69-
});
70-
});
83+
}
84+
85+
async embedQuery(text: string): Promise<number[]> {
86+
return (await this.embedDocuments([text]))[0];
87+
}
88+
}
7189
```
7290

91+
Key difference from unit test `MockEmbeddings`: **deterministic and text-dependent** — different texts produce different vectors, enabling meaningful similarity ranking tests.
92+
7393
### W43.5b — Full RAG Pipeline
7494

7595
```
76-
Input texts Embed Add to store Query Get documents back
96+
Input texts -> Embed -> Add to store -> Query (string) -> Get documents back
7797
```
7898

7999
Verify:
80100
1. Documents returned have correct `pageContent`
81101
2. Documents returned have correct `metadata`
82102
3. Scores are in [0, 1] range
83-
4. Most similar document is ranked first
103+
4. Document IDs are preserved through the pipeline
104+
5. Results array length <= k
105+
106+
### W43.5c — Default `similaritySearch`
84107

85-
### W43.5c — Default `addDocuments`
108+
The `VectorStore` base class provides `similaritySearch(query, k, filter)` which:
109+
1. Calls `this.embeddings.embedQuery(query)` to get a vector
110+
2. Calls `this.similaritySearchVectorWithScore(vector, k, filter)` to get results
111+
3. Returns just the `Document[]` (strips scores)
86112

87-
The `VectorStore` base class provides `addDocuments` which calls `this.embeddings.embedDocuments()` then `this.addVectors()`. Verify this works correctly with `EdgeVecStore`.
113+
Verify this chain works correctly with EdgeVecStore.
88114

89-
### W43.5d — Default `maxMarginalRelevanceSearch`
115+
### W43.5d — Default `similaritySearchWithScore`
90116

91-
Verify that the MMR default implementation works with EdgeVec's score format. May return fewer results than `k` — that's expected behavior.
117+
Same as `similaritySearch` but returns `[Document, score][]` (preserves scores). Verify scores are normalized.
92118

93119
### W43.5e — `asRetriever()`
94120

@@ -98,59 +124,97 @@ const results = await retriever.invoke("test query");
98124
// results should be Document[]
99125
```
100126

127+
Verify:
128+
- `retriever.invoke()` returns `Document[]`
129+
- Results have `pageContent` and `metadata`
130+
- Result count <= k
131+
101132
### W43.5f — Build Verification
102133

103134
```bash
104135
cd pkg/langchain && npm run build
105136
```
106137

107138
Verify:
108-
- `dist/esm/index.js` exists (ESM output)
109-
- `dist/cjs/index.js` exists (CJS output)
110-
- `dist/types/index.d.ts` exists (type declarations)
139+
- `dist/index.js` or `dist/index.mjs` exists (ESM output)
140+
- `dist/index.cjs` exists (CJS output)
141+
- `dist/index.d.ts` or `dist/index.d.cts` exists (type declarations)
111142
- No TypeScript errors in strict mode
143+
- Bundle size < 10KB (excluding edgevec WASM)
144+
145+
**Note:** tsup.config.ts output structure may differ from the `dist/esm/` + `dist/cjs/` layout described in the original plan. Check actual tsup output paths.
112146

113147
### W43.5g — Peer Dep Compatibility
114148

115149
Test installation with:
116150
- `@langchain/core@0.3.0` (lower bound)
117-
- `@langchain/core@0.4.x` (latest in range)
151+
- `@langchain/core@0.4.x` (latest in range, if available)
152+
153+
Verify `npm install` succeeds and basic import works. This is a **verification task**, not a separate test suite — run in a temp directory with `npm pack` output.
154+
155+
---
156+
157+
## Implementation Notes
158+
159+
### Mock Strategy
160+
161+
Integration tests use the same WASM mock pattern as `store.test.ts`:
162+
- `vi.mock("edgevec", ...)` — mock WASM init
163+
- `vi.mock("edgevec/edgevec-wrapper.js", ...)` — mock EdgeVecIndex
164+
165+
But the mock search implementation should be **smarter** for RAG pipeline tests: return results that correspond to what was added, so the pipeline test is meaningful.
166+
167+
### Reuse from Day 4
168+
169+
- `MockEmbeddings` class pattern (extends `Embeddings`)
170+
- `testInternals()` accessor pattern
171+
- IDB cleanup in `beforeEach`
172+
- Same `vi.mock` setup (can be extracted to a shared test helper if needed)
173+
174+
### Available Default Methods (Verified)
175+
176+
From `@langchain/core@0.3.x` VectorStore prototype:
177+
- `similaritySearch(query, k, filter)` — returns `Document[]`
178+
- `similaritySearchWithScore(query, k, filter)` — returns `[Document, score][]`
179+
- `asRetriever(kOrFields, filter, callbacks, tags, metadata, verbose)` — returns `VectorStoreRetriever`
180+
- `delete(params)` — overridden by EdgeVecStore
118181

119-
Verify `npm install` succeeds and basic import works.
182+
**NOT available:** `maxMarginalRelevanceSearch` — does not exist on installed version.
120183

121184
---
122185

123186
## Acceptance Criteria
124187

125188
- [ ] Integration tests pass with mock embeddings (no external API calls)
126-
- [ ] Full RAG pipeline: text embed add query get document back with correct content
127-
- [ ] `addDocuments` default: calls `embeddings.embedDocuments`, then `addVectors` — works correctly
128-
- [ ] `maxMarginalRelevanceSearch`: returns results without error, result count <= k
189+
- [ ] Full RAG pipeline: text -> embed -> add -> query -> get document back with correct content
190+
- [ ] `similaritySearch` default: calls `embedQuery`, returns `Document[]` without scores
191+
- [ ] `similaritySearchWithScore` default: calls `embedQuery`, returns `[Document, score][]`
129192
- [ ] `asRetriever()`: returned retriever can `.invoke(query)` and get `Document[]`
130193
- [ ] `npm run build` produces both ESM and CJS output
131-
- [ ] TypeScript strict mode: zero errors
194+
- [ ] TypeScript strict mode: zero errors (`npx tsc --noEmit`)
132195
- [ ] Bundle size of langchain adapter < 10KB (excluding edgevec WASM)
133-
- [ ] Peer dep: installs cleanly with `@langchain/core@0.3.x` and `@langchain/core@0.4.x`
196+
- [ ] Peer dep: installs cleanly with `@langchain/core@0.3.x`
134197

135198
---
136199

137200
## Risk Notes
138201

139202
| Risk | Mitigation |
140203
|:-----|:-----------|
141-
| `maxMarginalRelevanceSearch` requires specific score format | Test and adapt if needed; may need to override default |
142-
| CJS build fails due to ESM-only dependencies | Use `tsup` or `unbuild` for dual output if `tsc` is insufficient |
143-
| Bundle size exceeds 10KB | Profile imports, tree-shake unused LangChain internals |
204+
| `asRetriever().invoke()` requires async chain through VectorStoreRetriever | Test with proper await chain; inspect return type |
205+
| CJS build fails due to ESM-only dependencies | tsup handles dual output; if `@langchain/core` is ESM-only, CJS may need `require()` shim |
206+
| Bundle size exceeds 10KB | Profile imports; tsup externalizes peer deps already (`edgevec`, `@langchain/core`) |
207+
| tsup output paths differ from expected `dist/esm/` + `dist/cjs/` | Check actual tsup output after first build; update package.json `exports` if needed |
144208

145209
---
146210

147211
## Exit Criteria
148212

149213
**Day 5 is complete when:**
150214
1. All 7 tasks are DONE
151-
2. `npx vitest run tests/integration.test.ts` passes
215+
2. `npx vitest run` passes (all tests: metadata + store + integration)
152216
3. `npm run build` produces ESM + CJS output
153-
4. Peer dep compatibility verified
217+
4. TypeScript strict mode: zero errors
154218
5. Bundle size < 10KB
155219

156220
**Handoff to Day 6:** Implementation and tests are complete. Day 6 writes documentation.

0 commit comments

Comments
 (0)