deliberate-lab / functions
AGENTS.md97 starsChanged 57 days agoApache-2.0View on GitHub
Firebase Cloud Functions backend (built with esbuild): HTTP callable endpoints and Firestore document triggers. All functions are registered in src/index.ts. See also: root AGENTS.md for monorepo-wide conventions. From the repository root: Emulator tests require Java 21 for the Firebase emulator. The test runner uses firebase-test.json (in the repo root) as the emulator config. Unit-only tests (no emulator): The integration test in cohort_definitions.integration.test.ts is large and slow; it exercises full experiment lifecycle flows. Stage backend logic lives in src/stages/ and follows…
In this repository10 other files it gives its agents.
- AGENTS.mdAGENTS.md
- frontend/AGENTS.mdAGENTS.md
- scripts/AGENTS.mdAGENTS.md
- utils/AGENTS.mdAGENTS.md
- eval-prSkill
- ghSkill
- pr-test-planSkill
- retrospectiveSkill
- workspace-overviewSkill
- workspace-syncSkill
The file
Files
AGENTS.md — functions
Firebase Cloud Functions backend (built with esbuild): HTTP callable
endpoints and Firestore document triggers. All functions are registered in
src/index.ts.
See also: root AGENTS.md for monorepo-wide conventions.
Build & test
From the repository root:
npm run build -w functions # Build with esbuild
npm test -w functions # Run all tests (unit + emulator)
npm run typecheck -w functionsEmulator tests require Java 21 for the Firebase emulator. The test
runner uses firebase-test.json (in the repo root) as the emulator config.
Unit-only tests (no emulator):
npm run test:unit -w functionsThe integration test in cohort_definitions.integration.test.ts is large
and slow; it exercises full experiment lifecycle flows.
File naming conventions
| Pattern | Purpose |
<entity>.endpoints.ts | HTTP callable functions (registered in src/index.ts) |
<entity>.utils.ts | Business logic and helpers |
<entity>.utils.test.ts | Unit tests for business logic |
Stage-specific files (src/stages/)
Stage backend logic lives in src/stages/ and follows these patterns:
| Pattern | Purpose |
<stage_type>.endpoints.ts | Callable endpoints for the stage |
<stage_type>.utils.ts | Stage-specific business logic |
<stage_type>.utils.test.ts | Tests |
New stage endpoints must be exported from src/index.ts.
Source directory overview
| Directory | Purpose |
src/stages/ | Stage-specific backend logic |
src/triggers/ | Firestore document triggers (see src/triggers/README.md) |
src/chat/ | Chat-specific utilities |
src/dl_api/ | External REST API layer (see below) |
src/api/ | Internal API utilities (LLM provider integrations) |
src/utils/ | Shared backend helper functions |
Key files
| File | Role |
src/index.ts | Registers all Cloud Functions (callables + triggers) |
src/app.ts | Initializes StageManager — maps stage types to handlers |
src/data.ts | Firestore data access layer (reads/exports) |
src/participant.utils.ts | Participant lifecycle — stage progression, transfers, cohort assignment |
[!CAUTION]
participant.utils.tsis ~1400 lines and the most complex backend file. It handles Firestore transaction chains for stage progression, cohort assignment, and participant transfers. Changes here carry a high risk of subtle race conditions. Proceed with extra care and test thoroughly.
Trigger system
Firestore document triggers live in src/triggers/. See
src/triggers/README.md for the full list of triggers and the Firestore
document paths they listen on.
Key trigger files:
| File | Listens to |
participant.triggers.ts | Participant document create/update |
stage.triggers.ts | Participant stage data and public stage data updates |
chat.triggers.ts | Public and private chat message creation |
chip.triggers.ts | Chip transaction creation |
agent_participant.triggers.ts | Agent participant lifecycle events |
presence.triggers.ts | Realtime Database presence changes |
Agent (LLM) participants
agent.utils.ts— core agent orchestration logicagent_participant.utils.ts— manages how LLM agents participate in experiments (stage completion, API calls, answer extraction)structured_prompt.utils.ts— prompt construction for agent participants and mediators
Data access
src/data.ts is the Firestore data access layer. It provides functions
like getExperimentDownload and getExperimentLogs using the Firebase
Admin SDK. Do not write raw Firestore calls in endpoint files — use or
extend the data access layer instead.
Endpoint conventions
- Endpoints are defined in
*.endpoints.tsfiles and exported fromsrc/index.ts - Each endpoint returns structured responses
src/app.tsinitializes theStageManager(fromutils) which maps stage types to their handler logic- The
src/dl_api/directory contains the external REST API layer (key-authenticated HTTP endpoints for programmatic access)
REST API structure (src/dl_api/)
The REST API is an Express app exposed as a single Cloud Function. It uses API key authentication (not Firebase Auth) for server-to-server access.
| File | Purpose |
dl_api.endpoints.ts | Express app setup, middleware, route registration |
experiments.dl_api.ts | /v1/experiments/ route handlers |
cohorts.dl_api.ts | /v1/experiments/:id/cohorts/ route handlers |
dl_api.utils.ts | Auth middleware and request validation |
dl_api_key.utils.ts | API key creation, verification, and revocation |
dl_api.test.utils.ts | Shared test setup utilities |
How to add a new REST API endpoint
Adding a REST API endpoint touches multiple files across workspaces:
- Implement the route handler — add a function in the appropriate
*.dl_api.tsfile (or create a new one for a new resource type) - Register the route — add the Express route in
dl_api.endpoints.ts - Update the OpenAPI spec — add the endpoint to
docs/assets/api/openapi.yaml - Add a Python client method — update
scripts/deliberate_lab/client.pyso the SDK exposes the new endpoint - Write integration tests — add tests in
*.dl_api.integration.test.ts
[!NOTE] REST API endpoints (
/v1/...) use API key auth and are for server-to-server use. Frontend callables (used by the web app) are separate — they are FirebaseonCallfunctions registered insrc/index.tswith corresponding wrappers infrontend/src/shared/callables.ts.
How to add a new callable endpoint
Callable endpoints are Firebase onCall functions invoked by the
frontend. This is the most common type of new endpoint.
- Implement the function — create or update a
*.endpoints.tsfile with the newonCallfunction - Export from
src/index.ts— add the export so Firebase registers the function - Add a frontend wrapper — add a typed callable wrapper in
frontend/src/shared/callables.ts(the frontend calls endpoints exclusively through these wrappers) - Wire up the UI — call the new wrapper from the appropriate service or component
Firestore data model
The Firestore document hierarchy (derived from trigger paths and the data access layer):
experiments/{experimentId}
├── participants/{participantId}
│ └── stageData/{stageId} # participant answers
│ └── privateChats/{chatId} # private chat messages
├── cohorts/{cohortId}
│ └── publicStageData/{stageId} # public stage data
│ ├── chats/{chatId} # group chat messages
│ └── transactions/{transactionId} # chip transactions
└── stages/{stageId} # stage configTriggers listen on these paths — see src/triggers/README.md for the
full list of trigger functions and the specific paths they watch.
Common pitfalls
- Writing raw Firestore calls in endpoint files — use or extend the
data access layer in
src/data.tsinstead. - Forgetting to export new endpoints from
src/index.ts— Cloud Functions will silently ignore unregistered functions. - Forgetting to add a
callables.tswrapper — the frontend calls all callable endpoints through typed wrappers infrontend/src/shared/callables.ts. A new endpoint without a wrapper is unreachable from the UI. - Missing Java 21 for emulator tests — use
npm run test:unit -w functionsto run unit tests without the emulator. - Firestore race conditions — concurrent writes to the same document (e.g., multiple participants updating public stage data simultaneously) are a recurring source of bugs. Use Firestore transactions for read-modify-write operations on shared documents.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

