Skip to content

Latest commit

 

History

History
62 lines (53 loc) · 3.45 KB

File metadata and controls

62 lines (53 loc) · 3.45 KB

AGENTS.md

Dev environment

This is a pnpm + Turborepo monorepo (TypeScript serving layer) plus a uv-managed Python ingestion engine (engine/). Run pnpm install at the root and uv sync in engine/ before starting. uv installs to ~/.local/bin; in a fresh non-login shell run export PATH="$HOME/.local/bin:$PATH" if uv is not found.

Services / how to run

  • @orca/api (Next.js 16 dev server) — the product runtime serving /v1/chat, /v1/search, and the /playground UI. Run with pnpm --filter @orca/api dev (pinned to http://localhost:3000). Boots fine with no secrets: env vars are optional and the DB client is lazy.
  • @orca/web (Next.js 16 admin console) — better-auth dashboard for tenant settings, usage/activity, knowledge sources, and feedback. Run with pnpm --filter @orca/web dev (pinned to http://localhost:3001 so it can run alongside @orca/api). Backed by the same Neon DB via @orca/db.
  • Python ingestion engine (engine/) — not a long-running service. Run connectors via uv run engine ingest <connector> [--source-dir DIR] [--dry-run] from engine/. --dry-run (or simply having no DATABASE_URL) uses an in-memory DryRunWriter, so it parses/chunks docs with no DB or API key.

Non-obvious caveats

  • External secrets gate the live answer path. AI_GATEWAY_API_KEY (Vercel AI Gateway, routes embeddings/rerank/generation) and DATABASE_URL (Neon serving role) are required for /v1/chat and /v1/search to return grounded answers. Without them, the server still runs and the request flows through the real request-gate → router → agent loop, then fails loud at requireEnv(...). The deterministic safety path (advice-refusal guardrail) works with no secrets.
  • The Neon serving role must be non-owner + NOBYPASSRLS. DATABASE_URL is the serving connection and ADMIN_DATABASE_URL is the owner role (migrations/role setup only). Using the owner role for serving makes RLS tenant isolation a no-op; assertServingRole fails loud at boot to catch this.
  • The @orca/db Neon driver uses the WebSocket session Pool (not the HTTP endpoint) because SET LOCAL must hold across the tenant transaction.
  • docs_mdx/openapi connectors default to a sibling boardwalk-landing repo that is NOT in this repo. For a no-credential ingestion demo, point them at the committed fixtures, e.g. uv run engine ingest docs_mdx --source-dir tests/fixtures/docs_mdx/input --dry-run.
  • Tests need no external services. TS tests use @electric-sql/pglite (in-memory Postgres); Python tests run offline. pyproject.toml sets filterwarnings = ["error"], so any new warning fails the Python suite.
  • The Python evals (Ragas/DeepEval) and pdf (Docling/torch) dependency groups are heavy and intentionally excluded from uv sync; install on demand with uv sync --group evals / --group pdf only when needed.

Lint / test / typecheck / build

Standard commands (see root package.json and README.md):

  • Typecheck: pnpm -r typecheck
  • TS tests: pnpm -r test
  • Lint + format (Biome): pnpm lint:ci is what CI runs; pnpm lint:fix / pnpm format to auto-fix locally.
  • Build (widget IIFE + both Next apps, turbo-cached): pnpm build
  • Tenant-access lint (tenant tables only reachable via withTenant): node scripts/lint-tenant-access.mjs
  • Python tests: cd engine && uv run pytest; lint: uv run ruff check . and uv run ruff format --check .