From c5f7369772b19e0adbbec519a9967c2c564f04b3 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sat, 18 Apr 2026 09:54:15 +0000 Subject: [PATCH] fix(codegen/cli): make autoEmbedWhere/autoEmbedInput generic in embedder template The CLI codegen emits calls like `findManyArgs.where = await autoEmbedWhere(findManyArgs.where ?? {}, ['embedding'], embedder)` and `await autoEmbedInput(cleanedData, ['embedding'], embedder)` where the first argument is a concrete `*Filter` / `*Patch` type produced by `input-types.ts`. Those generated types don't have a string index signature, so under strict `tsc` every call site errors with: error TS2345: Argument of type 'XxxFilter' is not assignable to parameter of type 'Record'. Index signature for type 'string' is missing in type 'XxxFilter'. CI for consumers (agentic-db et al.) passes via `ts-jest`, which is lenient about index-signature / excess-property checks, but `makage build` on publish is strict and fails across all generated `commands/*.ts` files. Make both helpers generic (`(x: T, ...): Promise`) and cast to `Record` internally for the field-name indexing. Runtime behavior is unchanged (mutation in place, same return semantics), and call sites now type-check as-is without any generator change. Consumer-side point fix already landed in constructive-io/agentic-db#29; this PR fixes the upstream template so the next `pnpm generate:all` in any consumer emits a correctly-typed `embedder.ts`. --- .../src/core/codegen/templates/embedder.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/graphql/codegen/src/core/codegen/templates/embedder.ts b/graphql/codegen/src/core/codegen/templates/embedder.ts index 711440d44..c5321c297 100644 --- a/graphql/codegen/src/core/codegen/templates/embedder.ts +++ b/graphql/codegen/src/core/codegen/templates/embedder.ts @@ -113,13 +113,14 @@ function buildEmbedder(config: EmbedderConfig): EmbedderFunction | null { * @param embedder - The resolved embedder function * @returns The modified where clause */ -export async function autoEmbedWhere( - where: Record, +export async function autoEmbedWhere( + where: T, vectorFieldNames: string[], embedder: EmbedderFunction, -): Promise> { +): Promise { + const rec = where as unknown as Record; for (const fieldName of vectorFieldNames) { - const fieldValue = where[fieldName]; + const fieldValue = rec[fieldName]; if (fieldValue && typeof fieldValue === 'object') { const input = fieldValue as Record; // If 'vector' is a string, embed it @@ -132,7 +133,7 @@ export async function autoEmbedWhere( // Shorthand: --where.vectorEmbedding "text" with --auto-embed // becomes { vector: [embedded], metric: 'COSINE' } const embedding = await embedder(fieldValue); - where[fieldName] = { vector: embedding }; + rec[fieldName] = { vector: embedding }; } } return where; @@ -157,17 +158,18 @@ export async function autoEmbedWhere( * @param embedder - The resolved embedder function * @returns The modified data object with text values replaced by vectors */ -export async function autoEmbedInput( - data: Record, +export async function autoEmbedInput( + data: T, vectorFieldNames: string[], embedder: EmbedderFunction, -): Promise> { +): Promise { + const rec = data as unknown as Record; for (const fieldName of vectorFieldNames) { - const fieldValue = data[fieldName]; + const fieldValue = rec[fieldName]; if (typeof fieldValue === 'string') { // Text string → embed to vector array const embedding = await embedder(fieldValue); - data[fieldName] = embedding; + rec[fieldName] = embedding; } // If it's already an array (pre-computed vector), leave it as-is }