|
1 | | -# Project Rules For Claude |
| 1 | +# Instructions for Claude Code |
2 | 2 |
|
3 | | -This repository uses two instruction sources for Claude: |
| 3 | +@AGENTS.md |
4 | 4 |
|
5 | | -1. `AGENTS.md` is the primary, comprehensive guide for this codebase. |
6 | | -2. `CLAUDE.md` contains Claude-specific reinforcement and policy reminders. |
7 | | - |
8 | | -When both files exist, follow both. If guidance overlaps, treat `AGENTS.md` as the canonical project playbook and use this file to reinforce Claude-specific behavior. |
9 | | - |
10 | | ---- |
11 | | - |
12 | | -## ⚠️ CRITICAL SAFETY RULES — read before any direct Vapi API call |
13 | | - |
14 | | -### Vapi PATCH on nested objects is REPLACE, not deep-merge |
15 | | - |
16 | | -**The Vapi PATCH API does NOT deep-merge nested objects. When you PATCH a nested object (`model`, `voice`, `transcriber`, `messagePlan`, `analysisPlan`, `artifactPlan`, `voicemailDetection`, `startSpeakingPlan`, `stopSpeakingPlan`) with a partial body, the API REPLACES the entire object — wiping every field you didn't include.** |
17 | | - |
18 | | -This wiped three live-production assistants' system prompts in a customer fork on 2026-05-13. The PATCH was `{"model": {"model": "gpt-4.1", "provider": "openai", "maxTokens": 260, "temperature": 0.3, "toolIds": [...]}}` — looked complete, but did NOT include `model.messages`. Result: prompts gone, live calls ran with empty system prompt until the operator forced a restore. |
19 | | - |
20 | | -**Mandatory workflow for any direct API PATCH against a nested object:** |
21 | | - |
22 | | -```bash |
23 | | -# 1. GET the full resource first |
24 | | -ASSISTANT=$(curl -H "Authorization: Bearer $VAPI_PRIVATE_API_KEY" https://api.vapi.ai/assistant/$id) |
25 | | - |
26 | | -# 2. Modify in place — keep every other field |
27 | | -MODEL=$(echo "$ASSISTANT" | jq '.model | .model = "gpt-4.1"') |
28 | | - |
29 | | -# 3. PATCH the COMPLETE nested object back |
30 | | -curl -X PATCH -H "Content-Type: application/json" \ |
31 | | - -d "{\"model\": $MODEL}" \ |
32 | | - https://api.vapi.ai/assistant/$id |
33 | | - |
34 | | -# 4. Re-GET and verify EVERY field you cared about — not just the one you changed |
35 | | -``` |
36 | | - |
37 | | -**The "I patched X and X came back correct" check is NOT sufficient.** Vapi can replace the rest of the nested object even when X looks right in the response. Verify the fields you DIDN'T touch survived too — especially `model.messages` (system prompt), `model.toolIds`, `model.knowledgeBase`, and any nested config under `voice` / `transcriber`. |
38 | | - |
39 | | -**When in doubt, use `npm run push -- <env>` instead of direct API PATCH.** The gitops engine constructs the full payload from local YAML automatically. Only fall back to direct curl PATCH when the engine is silently dropping specific fields (the 2026-04-26 `eagerEotThreshold` engine bug and the 2026-05-13 silent-push class). Even then, GET-modify-PATCH-verify. |
40 | | - |
41 | | -See `docs/learnings/voice-providers.md` for related "property X should not exist" 400 gotchas (e.g. `voice.enableSsmlParsing` is rejected on `provider: vapi` voices) — those failures are loud; the PATCH-is-REPLACE failure is silent and far more dangerous. |
42 | | - |
43 | | ---- |
44 | | - |
45 | | -## Required Reading Order |
46 | | - |
47 | | -1. Read `AGENTS.md` first. |
48 | | -2. Then read this file (`CLAUDE.md`) for additional policy constraints. |
49 | | -3. When configuring or debugging any resource, load only the relevant learnings file — not the whole folder: |
50 | | - - Assistants → `docs/learnings/assistants.md` |
51 | | - - Tools → `docs/learnings/tools.md` (also covers tool/SO dedup behavior on push) |
52 | | - - Squads → `docs/learnings/squads.md` |
53 | | - - Transfers not working → `docs/learnings/transfers.md` |
54 | | - - Structured outputs → `docs/learnings/structured-outputs.md` |
55 | | - - Simulations → `docs/learnings/simulations.md` |
56 | | - - Webhooks → `docs/learnings/webhooks.md` |
57 | | - - Latency issues → `docs/learnings/latency.md` |
58 | | - - Fallbacks / error handling → `docs/learnings/fallbacks.md` |
59 | | - - Azure OpenAI BYOK → `docs/learnings/azure-openai-fallback.md` |
60 | | - - Multilingual agents → `docs/learnings/multilingual.md` |
61 | | - - WebSocket transport → `docs/learnings/websocket.md` |
62 | | - - Outbound calling agents → `docs/learnings/outbound-agents.md` |
63 | | - - Outbound Call Campaigns (CSV bulk-dial) → `docs/learnings/outbound-campaigns.md` |
64 | | - - Voicemail detection → `docs/learnings/voicemail-detection.md` |
65 | | - - Call time limits / graceful ending → `docs/learnings/call-duration.md` |
66 | | - - Voice provider field cheat-sheet → `docs/learnings/voice-providers.md` |
67 | | - - YAML authoring conventions, .vapi-ignore lifecycle → `docs/learnings/yaml-conventions.md` |
68 | | - - Pull/push/apply behavior per drift & existence scenario → `docs/learnings/sync-behavior.md` |
69 | | - |
70 | | -This list mirrors the "Learnings & recipes" table in `AGENTS.md`. Keep both in sync — if you add a new learnings file, update both files plus `docs/learnings/README.md`. |
71 | | - |
72 | | -## Where new knowledge goes |
73 | | - |
74 | | -Per-resource tips/recipes/troubleshooting → `docs/learnings/<topic>.md`. Engine-friction log (push/pull/state/cleanup pain points + their fixes) → `improvements.md`. Code-level rationale → comments only when the *why* is non-obvious; never reference PR/issue numbers in code comments (they rot). One-time onboarding/install → `README.md`. When unsure, default to `docs/learnings/`. The full convention table lives in `AGENTS.md` under "Where new knowledge goes" — read it once, then this reminder is enough. |
75 | | - |
76 | | -## Improvements log |
77 | | - |
78 | | -This repo maintains an upstream-only running log at `improvements.md` (repo |
79 | | -root). It tracks engine friction, footguns, and improvement ideas surfaced |
80 | | -during real customer work — both before and after fixes land. |
81 | | - |
82 | | -**When you (Claude or human) hit something that makes you go "this should be |
83 | | -better," append or update an entry in `improvements.md` in the same change.** |
84 | | -The format is **Problem → Current behavior → Risk → Current mitigation → |
85 | | -Possible fix → Status**, ordered by severity / blast radius. Cite source |
86 | | -file paths with line numbers so future readers can verify your claims. |
87 | | - |
88 | | -When a fix lands, mark the entry `[RESOLVED YYYY-MM-DD] (#<PR-number>)` at |
89 | | -the top — don't delete it. The history is the point. |
90 | | - |
91 | | -Customer forks' own `improvements.md` logs feed upstream: when an entry there is |
92 | | -generic enough to apply across customers, surface it here in the same |
93 | | -revision. |
94 | | - |
95 | | -## Test-Call CLI Notes |
96 | | - |
97 | | -When debugging a customer issue with `npm run call -- <org> -s <squad>`: |
98 | | - |
99 | | -- Assistant utterances render as one coalesced line per turn (chunked TTS finals are buffered for 600 ms before flushing). If you need to see every raw final fragment for a transcriber/TTS investigation, lower or zero out `COALESCE_TIMEOUT_MS` in `src/call.ts`. |
100 | | -- `mpg123` `buffer underflow` stderr warnings are filtered out by the npm script wrapper. They are normal operational noise on macOS, not errors. |
101 | | -- Tool calls, handoffs (`handoff_to_*`), tool results, status transitions, hang warnings, and transfer events render as distinct emoji-prefixed lines (`🔧`, `🔀`, `✅`, `❌`, `📞`, `⚠️`). Use these to trace squad routing without leaving the terminal for the dashboard. |
102 | | -- High-frequency events (`conversation-update`, `model-output`, `function-call`, `user-interrupted`) are silently dropped by default. Set `VAPI_CALL_DEBUG=1` to surface them as `🔍 [debug] <type>: <preview>` lines when enumerating new event shapes. |
| 5 | +`AGENTS.md` (imported above) is the single guide for every coding agent in |
| 6 | +this repository: Claude Code, Codex and Cursor read the same rules. Put new |
| 7 | +guidance there, not here, so the agents can't drift apart. Add something to |
| 8 | +this file only if it applies to Claude Code alone. |
0 commit comments