Skip to content

Commit 17e1c8e

Browse files
committed
fix: clean template state and skip stale push mappings
Reset the template repo to an empty Vapi baseline and make apply skip stale state UUIDs instead of forcing a pull or recreating remote resources.
1 parent 236f25f commit 17e1c8e

16 files changed

Lines changed: 867 additions & 826 deletions

.vapi-state.dev.json

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
{
2-
"assistants": {
3-
"inbound-customer-support": "88d807a0-854a-4a95-960f-6b69921ff877",
4-
"company-1/inbound-customer-support": "0a2c0df1-1ec8-424b-8081-12498771e536"
5-
},
6-
"structuredOutputs": {
7-
"customer-sentiment": "7fd0fbf1-4309-49b7-8560-bec9e0237f95"
8-
},
9-
"tools": {
10-
"transfer-call": "0a0df4e7-ee96-4e0b-95dd-e534bbcb04c6",
11-
"get-user": "4e7b31f8-9c2b-4032-88f3-e86f10d95e28",
12-
"company-1/transfer-call": "4ebfe4bb-6887-4295-b598-30c008bb948c",
13-
"handoff": "b1429fc9-45f6-4289-ba48-96ac892e65d7"
14-
}
2+
"credentials": {},
3+
"assistants": {},
4+
"structuredOutputs": {},
5+
"tools": {},
6+
"squads": {},
7+
"personalities": {},
8+
"scenarios": {},
9+
"simulations": {},
10+
"simulationSuites": {}
1511
}

.vapi-state.prod.json

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
{
2-
"assistants": {
3-
"inbound-customer-support": "0bbfdf02-c01a-46a9-86a8-0d0eb0b8e14a",
4-
"company-1/inbound-customer-support": "260405e4-34ee-4aed-9251-80443d8a6e64"
5-
},
6-
"structuredOutputs": {
7-
"customer-sentiment": "549ae835-2155-44ec-a557-664c669372db"
8-
},
9-
"tools": {
10-
"get-user": "745f28e0-e99f-4d2f-aa27-bb661a807b87",
11-
"transfer-call": "311b547d-ee68-4372-abbc-e8b1e0ae1958",
12-
"handoff": "e8ad4961-0484-457c-a420-19f90f1d65ba",
13-
"company-1/transfer-call": "49ac1e9c-64c7-4c05-8104-5036cb9a667e"
14-
}
2+
"credentials": {},
3+
"assistants": {},
4+
"structuredOutputs": {},
5+
"tools": {},
6+
"squads": {},
7+
"personalities": {},
8+
"scenarios": {},
9+
"simulations": {},
10+
"simulationSuites": {}
1511
}

AGENTS.md

Lines changed: 119 additions & 95 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 78 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ Manage Vapi resources via Git using YAML/Markdown as the source-of-truth.
44

55
## Why GitOps?
66

7-
| | Dashboard / Ad-hoc API | GitOps |
8-
|---|---|---|
9-
| **History** | Limited visibility of who changed what | Full git history with blame |
10-
| **Review** | Changes go live immediately (can break things) | PR review before deploy |
11-
| **Rollback** | Manual recreation | `git revert` + push |
12-
| **Environments** | Tedious to copy-paste between envs | Same config, different state files |
13-
| **Collaboration** | One person at a time. Need to duplicate assistants, tools, etc. | Team can collaborate and use git branching |
14-
| **Reproducibility** | "It worked on my assistant!" | Declarative, version-controlled |
15-
| **Disaster Recovery** | Hope you have backups | Re-apply from git |
7+
| | Dashboard / Ad-hoc API | GitOps |
8+
| --------------------- | --------------------------------------------------------------- | ------------------------------------------ |
9+
| **History** | Limited visibility of who changed what | Full git history with blame |
10+
| **Review** | Changes go live immediately (can break things) | PR review before deploy |
11+
| **Rollback** | Manual recreation | `git revert` + push |
12+
| **Environments** | Tedious to copy-paste between envs | Same config, different state files |
13+
| **Collaboration** | One person at a time. Need to duplicate assistants, tools, etc. | Team can collaborate and use git branching |
14+
| **Reproducibility** | "It worked on my assistant!" | Declarative, version-controlled |
15+
| **Disaster Recovery** | Hope you have backups | Re-apply from git |
1616

1717
### Key Benefits
1818

@@ -24,16 +24,16 @@ Manage Vapi resources via Git using YAML/Markdown as the source-of-truth.
2424

2525
### Supported Resources
2626

27-
| Resource | Status | Format |
28-
|----------|--------|--------|
29-
| **Assistants** || `.md` (with system prompt) or `.yml` |
30-
| **Tools** || `.yml` |
31-
| **Structured Outputs** || `.yml` |
32-
| **Squads** || `.yml` |
33-
| **Personalities** || `.yml` |
34-
| **Scenarios** || `.yml` |
35-
| **Simulations** || `.yml` |
36-
| **Simulation Suites** || `.yml` |
27+
| Resource | Status | Format |
28+
| ---------------------- | ------ | ------------------------------------ |
29+
| **Assistants** | | `.md` (with system prompt) or `.yml` |
30+
| **Tools** | | `.yml` |
31+
| **Structured Outputs** | | `.yml` |
32+
| **Squads** | | `.yml` |
33+
| **Personalities** | | `.yml` |
34+
| **Scenarios** | | `.yml` |
35+
| **Simulations** | | `.yml` |
36+
| **Simulation Suites** | | `.yml` |
3737

3838
---
3939

@@ -45,6 +45,7 @@ Manage Vapi resources via Git using YAML/Markdown as the source-of-truth.
4545
4. **Promote by environment** (`dev` -> `stg` -> `prod`) by copying files between `resources/dev/`, `resources/stg/`, and `resources/prod/`.
4646

4747
Use:
48+
4849
- `pull` when Vapi might have changed
4950
- `push` for explicit deploys
5051
- `apply` (`pull -> merge -> push`) when you want one command for sync + deploy
@@ -78,26 +79,26 @@ cp .env.example .env.prod
7879

7980
### Commands
8081

81-
| Command | Description |
82-
|---------|-------------|
83-
| `npm run build` | Type-check the codebase |
84-
| `npm run pull:dev` | Pull platform state, preserve local changes |
85-
| `npm run pull:stg` | Pull staging state, preserve local changes |
86-
| `npm run pull:dev:force` | Pull platform state, overwrite everything |
87-
| `npm run pull:stg:force` | Pull staging state, overwrite everything |
88-
| `npm run pull:prod` | Pull from prod, preserve local changes |
89-
| `npm run pull:prod:force` | Pull from prod, overwrite everything |
90-
| `npm run push:dev` | Push local files to Vapi (dev) |
91-
| `npm run push:stg` | Push local files to Vapi (staging) |
92-
| `npm run push:prod` | Push local files to Vapi (prod) |
93-
| `npm run apply:dev` | Pull → Merge → Push in one shot (dev) |
94-
| `npm run apply:stg` | Pull → Merge → Push in one shot (staging) |
95-
| `npm run apply:prod` | Pull → Merge → Push in one shot (prod) |
96-
| `npm run push:dev assistants` | Push only assistants (dev) |
97-
| `npm run push:dev tools` | Push only tools (dev) |
98-
| `npm run call:dev -- -a <name>` | Start a WebSocket call to an assistant (dev) |
99-
| `npm run call:dev -- -s <name>` | Start a WebSocket call to a squad (dev) |
100-
| `npm run mock:webhook` | Run local webhook receiver for Vapi server messages |
82+
| Command | Description |
83+
| ------------------------------- | --------------------------------------------------- |
84+
| `npm run build` | Type-check the codebase |
85+
| `npm run pull:dev` | Pull platform state, preserve local changes |
86+
| `npm run pull:stg` | Pull staging state, preserve local changes |
87+
| `npm run pull:dev:force` | Pull platform state, overwrite everything |
88+
| `npm run pull:stg:force` | Pull staging state, overwrite everything |
89+
| `npm run pull:prod` | Pull from prod, preserve local changes |
90+
| `npm run pull:prod:force` | Pull from prod, overwrite everything |
91+
| `npm run push:dev` | Push local files to Vapi (dev) |
92+
| `npm run push:stg` | Push local files to Vapi (staging) |
93+
| `npm run push:prod` | Push local files to Vapi (prod) |
94+
| `npm run apply:dev` | Pull → Merge → Push in one shot (dev) |
95+
| `npm run apply:stg` | Pull → Merge → Push in one shot (staging) |
96+
| `npm run apply:prod` | Pull → Merge → Push in one shot (prod) |
97+
| `npm run push:dev assistants` | Push only assistants (dev) |
98+
| `npm run push:dev tools` | Push only tools (dev) |
99+
| `npm run call:dev -- -a <name>` | Start a WebSocket call to an assistant (dev) |
100+
| `npm run call:dev -- -s <name>` | Start a WebSocket call to a squad (dev) |
101+
| `npm run mock:webhook` | Run local webhook receiver for Vapi server messages |
101102

102103
### Basic Workflow
103104

@@ -242,11 +243,13 @@ ngrok http 8787
242243
```
243244

244245
Then set your assistant `server.url` to the ngrok HTTPS URL and include event types like:
246+
245247
- `speech-update`
246248
- `status-update`
247249
- `end-of-call-report`
248250

249251
The mock server exposes:
252+
250253
- `POST /webhook` (or `POST /`)
251254
- `GET /health`
252255
- `GET /events`
@@ -319,19 +322,23 @@ firstMessage: Hello! How can I help you?
319322
---
320323

321324
# Identity & Purpose
322-
You are a helpful assistant for Acme Corp.
325+
326+
You are a helpful assistant for the business you represent.
323327

324328
# Conversation Flow
329+
325330
1. Greet the user
326331
2. Ask how you can help
327332
3. Resolve their issue
328333

329334
# Rules
335+
330336
- Always be polite
331337
- Never make up information
332338
```
333339

334340
**Benefits:**
341+
335342
- System prompts are readable Markdown (not escaped YAML strings)
336343
- Proper syntax highlighting in editors
337344
- Easy to write headers, lists, tables
@@ -405,13 +412,15 @@ members:
405412
### Simulations
406413

407414
**Personality** (`simulations/personalities/`):
415+
408416
```yaml
409417
name: Skeptical Sam
410418
description: A doubtful caller who questions everything
411419
prompt: You are skeptical and need convincing before trusting information.
412420
```
413421

414422
**Scenario** (`simulations/scenarios/`):
423+
415424
```yaml
416425
name: Happy Path - New Customer
417426
description: New customer calling to schedule an appointment
@@ -421,13 +430,15 @@ prompt: |
421430
```
422431

423432
**Simulation** (`simulations/tests/`):
433+
424434
```yaml
425435
name: Booking Test Case 1
426436
personalityId: skeptical-sam
427437
scenarioId: happy-path-new-customer
428438
```
429439

430440
**Simulation Suite** (`simulations/suites/`):
441+
431442
```yaml
432443
name: Booking Flow Tests
433444
simulationIds:
@@ -460,6 +471,7 @@ model:
460471
---
461472
462473
# Your System Prompt Here
474+
463475
Instructions for the assistant...
464476
```
465477

@@ -511,23 +523,23 @@ Use the **filename without extension** as the resource ID:
511523
# In an assistant
512524
model:
513525
toolIds:
514-
- my-tool # → resources/<env>/tools/my-tool.yml
515-
- utils/helper-tool # → resources/<env>/tools/utils/helper-tool.yml
526+
- my-tool # → resources/<env>/tools/my-tool.yml
527+
- utils/helper-tool # → resources/<env>/tools/utils/helper-tool.yml
516528
artifactPlan:
517529
structuredOutputIds:
518-
- call-summary # → resources/<env>/structuredOutputs/call-summary.yml
530+
- call-summary # → resources/<env>/structuredOutputs/call-summary.yml
519531
```
520532

521533
```yaml
522534
# In a squad
523535
members:
524-
- assistantId: intake-agent # → resources/<env>/assistants/intake-agent.md
536+
- assistantId: intake-agent # → resources/<env>/assistants/intake-agent.md
525537
```
526538

527539
```yaml
528540
# In a simulation
529-
personalityId: skeptical-sam # → resources/<env>/simulations/personalities/skeptical-sam.yml
530-
scenarioId: happy-path # → resources/<env>/simulations/scenarios/happy-path.yml
541+
personalityId: skeptical-sam # → resources/<env>/simulations/personalities/skeptical-sam.yml
542+
scenarioId: happy-path # → resources/<env>/simulations/scenarios/happy-path.yml
531543
```
532544

533545
### How to Delete a Resource
@@ -537,27 +549,28 @@ scenarioId: happy-path # → resources/<env>/simulations/scenarios/hap
537549
3. **Push**: `npm run push:dev`
538550

539551
The engine will:
552+
540553
- Detect the resource is in state but not in filesystem
541554
- Check for orphan references (will error if still referenced)
542555
- Delete from Vapi
543556
- Remove from state file
544557

545558
### How to Organize Resources into Folders
546559

547-
Create subdirectories for multi-tenant or feature organization:
560+
Create subdirectories only when they help organize related resources by feature or workflow:
548561

549562
```
550563
resources/<env>/
551564
├── assistants/
552565
│ ├── shared/
553566
│ │ └── fallback.md
554-
│ └── client-a/
555-
│ └── support.md
567+
│ └── support/
568+
│ └── intake.md
556569
├── tools/
557570
│ ├── shared/
558571
│ │ └── transfer-call.yml
559-
│ └── client-a/
560-
│ └── custom-api.yml
572+
│ └── support/
573+
│ └── lookup-customer.yml
561574
```
562575

563576
Reference using full paths:
@@ -566,7 +579,7 @@ Reference using full paths:
566579
model:
567580
toolIds:
568581
- shared/transfer-call
569-
- client-a/custom-api
582+
- support/lookup-customer
570583
```
571584

572585
---
@@ -597,6 +610,7 @@ files
597610
### Processing Order
598611

599612
**Pull** (dependency order):
613+
600614
1. Tools
601615
2. Structured Outputs
602616
3. Assistants
@@ -607,12 +621,14 @@ files
607621
8. Simulation Suites
608622

609623
**Push** (dependency order):
624+
610625
1. Tools → 2. Structured Outputs → 3. Assistants → 4. Squads
611-
5. Personalities → 6. Scenarios → 7. Simulations → 8. Simulation Suites
626+
2. Personalities → 6. Scenarios → 7. Simulations → 8. Simulation Suites
612627

613628
**Delete** (reverse dependency order):
629+
614630
1. Simulation Suites → 2. Simulations → 3. Scenarios → 4. Personalities
615-
5. Squads → 6. Assistants → 7. Structured Outputs → 8. Tools
631+
2. Squads → 6. Assistants → 7. Structured Outputs → 8. Tools
616632

617633
### Reference Resolution
618634

@@ -642,7 +658,7 @@ Credentials (API keys, JWT secrets, etc.) are environment-specific and managed a
642658
# Resource file stores credential NAME (environment-agnostic)
643659
server:
644660
url: https://my-api.com/endpoint
645-
credentialId: my-server-credential # ← human-readable name
661+
credentialId: my-server-credential # ← human-readable name
646662
```
647663

648664
```json
@@ -696,10 +712,10 @@ Tracks mapping between resource IDs and Vapi UUIDs:
696712

697713
### Environment Variables
698714

699-
| Variable | Required | Description |
700-
|----------|----------|-------------|
701-
| `VAPI_TOKEN` | ✅ | API authentication token |
702-
| `VAPI_BASE_URL` | ❌ | API base URL (defaults to `https://api.vapi.ai`) |
715+
| Variable | Required | Description |
716+
| --------------- | -------- | ------------------------------------------------ |
717+
| `VAPI_TOKEN` | ✅ | API authentication token |
718+
| `VAPI_BASE_URL` | ❌ | API base URL (defaults to `https://api.vapi.ai`) |
703719

704720
### Excluded Fields
705721

@@ -716,6 +732,7 @@ Some fields are excluded when writing to files (server-managed):
716732
### "Reference not found" warnings
717733

718734
The referenced resource doesn't exist. Check:
735+
719736
1. File exists in correct folder
720737
2. Filename matches exactly (case-sensitive)
721738
3. Using filename without extension
@@ -731,13 +748,15 @@ The referenced resource doesn't exist. Check:
731748
### Resource not updating
732749

733750
Check the state file has correct UUID:
751+
734752
1. Open `.vapi-state.{env}.json`
735753
2. Find the resource entry
736754
3. If incorrect, delete entry and re-run push
737755

738756
### "Credential with ID not found" errors
739757

740758
The credential UUID doesn't exist in the target environment. Fix:
759+
741760
1. Run `npm run pull:{env}` to fetch credentials into the state file
742761
2. If the credential doesn't exist in the target org, create it in the Vapi dashboard with the same name
743762
3. Pull again — the mapping will be auto-populated

0 commit comments

Comments
 (0)