Files
grant-outreach-engine/packages/outreach-ai/README.md
Croissant Le Doux 14200edb60 feat: scaffold outreach engine monorepo on the novelpad-desktop stack
Workspaces: config (copied), outreach-core (schema + actions/queries +
hard gates), outreach-ai (Gemini client + embeddings copies, profiler and
mission-fit-judge agent stubs), outreach-worker (DBOS executor with
nightly ingest + hourly expiry workflows), outreach-review (RR7 review
queue v0). Initial drizzle migration incl. pgvector extension.

Stack contract: Yarn 4.5.0 + Turbo, Node 22.16, Drizzle 0.44.6 +
pgvector, DBOS 4.17.6, @google/genai on Vertex, gemini-embedding-001
@1536, React Router v7. Files copied from novelpad-desktop carry
provenance headers @ 62c56b87.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:08:24 -04:00

55 lines
2.7 KiB
Markdown

# @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.