# @novelpad/outreach-ai LLM access layer for the HelmDocs grant-match outreach engine. Modeled on `novelpad-desktop`'s `packages/ai`, trimmed to what this engine needs: a Vertex/Gemini client, an embeddings helper, model-tier constants, and two structured-output agents (org profiler, mission-fit judge). ## Provenance `src/gemini.ts` and `src/embeddings.ts` are copied near-verbatim from `novelpad-desktop` at commit `62c56b87` (see the header comment in each file for the exact source path). They are kept as close to the original as compiles standalone in this workspace — do not "clean up" drift between them and the source without checking whether the source has moved on too. `src/agents/*/run.ts` follow the structured-JSON-output pattern from `novelpad-desktop`'s `packages/ai/src/agents/grant/section-drafter/run.ts` (prompt builder + `generateContent` with `responseMimeType: 'application/json'` and a hand-written `responseSchema`), but are new code for this repo's domain, not copies — both are currently `NOT IMPLEMENTED` stubs pending the source-fetching / hard-gate scoring infrastructure they depend on. Each stub's doc comment shows the intended call shape. ## Never mix embedding models `generateQueryEmbedding` / `generateDocumentEmbedding` / `generateDocumentEmbeddings` are pinned to `gemini-embedding-001` at `outputDimensionality: 1536`. **Do not change either value**, and do not add a second embedding model/dimensionality into this package. Every vector this package produces has to remain comparable (same model, same dimensionality) against every other vector already stored in the HelmDocs RAG index — switching models or dimensions silently corrupts similarity search for anything embedded before the switch, with no error at write time. If a better embedding model becomes available, that's a deliberate, full-reindex migration, not a constant change here. ## Model tiering See `src/models.ts`: `BULK_MODEL` (`gemini-2.5-flash`) for high-volume mechanical work (classification, effort estimates, first-pass org-profile extraction); `JUDGE_MODEL` (`gemini-2.5-pro`) for anything a wrong answer could put in front of a real prospect (mission-fit judge, email personalization QA). ## Layout - `src/gemini.ts` — `getAi()` Vertex client singleton + `CHAT_MODEL`. - `src/embeddings.ts` — query/document embedding helpers. - `src/models.ts` — `BULK_MODEL` / `JUDGE_MODEL` constants. - `src/agents/org-profiler/` — `OrgProfileSchema` (per-field source URL + confidence) and the profiler agent stub. - `src/agents/mission-fit-judge/` — `MissionFitVerdictSchema` (`fit`, `citedOrgProgram`, `citedGrantPriority`, `reasoning`) and the judge agent stub. - `src/index.ts` — barrel export.