Skip to content

Commit c5f7369

Browse files
committed
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<string, unknown>'. 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 (`<T extends object>(x: T, ...): Promise<T>`) and cast to `Record<string, unknown>` 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`.
1 parent da90c33 commit c5f7369

1 file changed

Lines changed: 12 additions & 10 deletions

File tree

graphql/codegen/src/core/codegen/templates/embedder.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,14 @@ function buildEmbedder(config: EmbedderConfig): EmbedderFunction | null {
113113
* @param embedder - The resolved embedder function
114114
* @returns The modified where clause
115115
*/
116-
export async function autoEmbedWhere(
117-
where: Record<string, unknown>,
116+
export async function autoEmbedWhere<T extends object>(
117+
where: T,
118118
vectorFieldNames: string[],
119119
embedder: EmbedderFunction,
120-
): Promise<Record<string, unknown>> {
120+
): Promise<T> {
121+
const rec = where as unknown as Record<string, unknown>;
121122
for (const fieldName of vectorFieldNames) {
122-
const fieldValue = where[fieldName];
123+
const fieldValue = rec[fieldName];
123124
if (fieldValue && typeof fieldValue === 'object') {
124125
const input = fieldValue as Record<string, unknown>;
125126
// If 'vector' is a string, embed it
@@ -132,7 +133,7 @@ export async function autoEmbedWhere(
132133
// Shorthand: --where.vectorEmbedding "text" with --auto-embed
133134
// becomes { vector: [embedded], metric: 'COSINE' }
134135
const embedding = await embedder(fieldValue);
135-
where[fieldName] = { vector: embedding };
136+
rec[fieldName] = { vector: embedding };
136137
}
137138
}
138139
return where;
@@ -157,17 +158,18 @@ export async function autoEmbedWhere(
157158
* @param embedder - The resolved embedder function
158159
* @returns The modified data object with text values replaced by vectors
159160
*/
160-
export async function autoEmbedInput(
161-
data: Record<string, unknown>,
161+
export async function autoEmbedInput<T extends object>(
162+
data: T,
162163
vectorFieldNames: string[],
163164
embedder: EmbedderFunction,
164-
): Promise<Record<string, unknown>> {
165+
): Promise<T> {
166+
const rec = data as unknown as Record<string, unknown>;
165167
for (const fieldName of vectorFieldNames) {
166-
const fieldValue = data[fieldName];
168+
const fieldValue = rec[fieldName];
167169
if (typeof fieldValue === 'string') {
168170
// Text string → embed to vector array
169171
const embedding = await embedder(fieldValue);
170-
data[fieldName] = embedding;
172+
rec[fieldName] = embedding;
171173
}
172174
// If it's already an array (pre-computed vector), leave it as-is
173175
}

0 commit comments

Comments
 (0)