Files · Auto-Takeoff Agent for Small GC Bid Prep
84 (1 binary, 680.5 kB total)attempt 1
README.md·5306 B·markdown
markdown
# Auto-Takeoff Agent for Small GC Bid Prep
> Convert plan sets to BOM + sub RFPs in minutes, not days.
A General Contractor estimator spends days manually measuring plan sets and spec docs to produce a bill of materials and subcontractor RFPs. Errors in takeoff lead to underbid losses or overbid rejections. This recipe automates extraction of quantities, materials, and specs from PDFs and images, then generates structured RFPs for subs.
**Target provider:** agnostic (Vercel AI SDK)
**Archetype:** document-pipeline
**Vertical:** construction-trades
**Stack:** Next.js 16 App Router + Fastify standalone server
## Architecture
The pipeline processes plan sets in 7 stages:
1. **Load** — Accept plan set documents via `POST /api/takeoff`
2. **OCR** — Extract text from each document using `@reaatech/media-pipeline-mcp-doc-extraction`
3. **Tables** — Extract structured tables (schedules, material lists)
4. **Fields** — Extract typed fields (material names, quantities, specs)
5. **Interpret** — Vercel AI SDK (`ai` + `@ai-sdk/openai`) converts extracted data into structured material line items
6. **BOM** — Generate a validated Bill of Materials
7. **Persist** — Store the job result via `@reaatech/a2a-reference-persistence`
After takeoff, `POST /api/rfp` generates one subcontractor RFP per trade, each containing a natural-language scope of work written by the LLM.
## REAA Packages
| Package | Version | Role |
|---------|---------|------|
| [`@reaatech/media-pipeline-mcp-doc-extraction`](https://www.npmjs.com/package/@reaatech/media-pipeline-mcp-doc-extraction) | 0.3.0 | Document OCR, table extraction, field extraction, summarization |
| [`@reaatech/agent-mesh`](https://www.npmjs.com/package/@reaatech/agent-mesh) | 1.0.0 | Request/response schemas and type validation |
| [`@reaatech/llm-cache`](https://www.npmjs.com/package/@reaatech/llm-cache) | 0.1.0 | Semantic + exact-match caching for LLM calls |
| [`@reaatech/agent-budget-engine`](https://www.npmjs.com/package/@reaatech/agent-budget-engine) | 0.1.1 | Per-scope budget enforcement with state machine |
| [`@reaatech/a2a-reference-persistence`](https://www.npmjs.com/package/@reaatech/a2a-reference-persistence) | 0.2.0 | In-memory and filesystem task stores |
| [`@reaatech/agents-markdown`](https://www.npmjs.com/package/@reaatech/agents-markdown) | 1.0.1 | Validation result types and utilities |
## Third-Party Packages
- `ai@6.0.202` — Vercel AI SDK (`generateText`, `Output`)
- `@ai-sdk/openai@3.0.70` — OpenAI provider
- `zod@4.4.3` — Schema validation
- `langfuse@3.38.20` — LLM tracing (optional)
- `fastify@5.2.2` — Standalone HTTP server
## Environment Variables
| Variable | Description |
|----------|-------------|
| `OPENAI_API_KEY` | OpenAI API key for LLM calls |
| `LANGFUSE_PUBLIC_KEY` | Langfuse public key (optional) |
| `LANGFUSE_SECRET_KEY` | Langfuse secret key (optional) |
| `LANGFUSE_HOST` | Langfuse host URL (optional) |
| `FASTIFY_PORT` | Fastify server port (default: 3001) |
| `MODEL_ID` | LLM model identifier (optional — defaults to gpt-5.2) |
## API Reference
### `POST /api/takeoff`
Submit a plan set for automated takeoff. Returns a job result with BOM.
### `GET /api/takeoff/:id`
Get the status and result of a takeoff job.
### `DELETE /api/takeoff/:id`
Cancel and remove a takeoff job.
### `POST /api/rfp`
Generate subcontractor RFPs from a Bill of Materials.
### `GET /api/rfp/:id`
Retrieve a generated RFP document.
### `GET /api/budget`
View current budget status for all scopes.
### `GET /api/health`
Health check — returns `{ "status": "ok", "version": "0.1.0" }`.
## Getting Started
```bash
pnpm install
cp .env.example .env.local
# Edit .env.local with your OPENAI_API_KEY
pnpm dev # Next.js dev server on port 3000
```
To start the standalone Fastify server:
```bash
pnpm tsx src/server.ts
```
## Testing
```bash
pnpm test # vitest run with coverage
pnpm typecheck # tsc --noEmit
pnpm lint # eslint .
```
Tests mock all external dependencies (`vi.mock` for LLM calls, package adapters). No live HTTP calls are made during test execution.
## Project Layout
```
app/ Next.js App Router pages + API routes
api/
takeoff/ POST / (create), GET /[id] (status), DELETE /[id] (cancel)
rfp/ POST / (generate), GET /[id] (fetch)
budget/ GET / (budget status)
health/ GET / (health check)
src/
types/ Zod schemas and TypeScript interfaces
services/
document-extraction.ts Wraps @reaatech/media-pipeline-mcp-doc-extraction
cache-manager.ts Wraps @reaatech/llm-cache
budget-manager.ts Wraps @reaatech/agent-budget-engine
task-persistence.ts Wraps @reaatech/a2a-reference-persistence
llm-processor.ts Vercel AI SDK LLM integration
takeoff-engine.ts Pipeline orchestrator
rfp-generator.ts RFP generation from BOM
server.ts Standalone Fastify server entrypoint
index.ts Public API barrel exports
tests/ Vitest suite mirroring src/
packages/ API references for every dependency
DEV_PLAN.md Build plan for this recipe
```
## License
MIT — see [LICENSE](./LICENSE).