Config as code
Your assistants, tools, squads and knowledge bases live in git as declarative YAML, and the CLI reconciles them against an organization.
callagent init
callagent validate
callagent plan
callagent applyLayout
callagent.yaml environments and their variables
assistants/*.yaml
tools/*.yaml
squads/*.yaml
knowledge/*.yaml
policies/*.yaml
.callagent/state.<env>.json remote ids from the last apply — gitignore thisEnvironments (DEV/UAT/PROD)
One set of resource files describes every environment. The differences live in callagent.yaml and are substituted as ${name}:
version: 1
defaultEnvironment: dev
environments:
dev:
apiUrl: http://localhost:8000
variables:
serverUrl: http://localhost:8080/webhooks/callagent
prod:
apiUrl: https://api.callagent.dev
protected: true # `apply --auto-approve` refuses here without --force
variables:
serverUrl: https://example.com/webhooks/callagent${env:NAME} reads a process environment variable instead, for anything that must not be committed.
Field names
Files use the @callagent/contracts vocabulary — camelCase — because that is the schema they are validated against. The CLI converts to the API's snake_case on the way out. Key spaces you own (metadata, variableValues, HTTP headers, tool parameters) are passed through untouched, so a order_id metadata key stays order_id.
Files are partial: whatever a file does not mention, the server keeps. That is what lets you manage the system prompt in git while leaving the analysis plan to the dashboard.
What a plan looks like
Plan for Production (https://api.callagent.dev)
~ assistants.Support Line (01JQASSISTANT00000000000001)
~ model.temperature: 0.4 -> 0.9
~ firstMessage: "Hi, how can I help?" -> "Hi! How can I help today?"
+ endCallPhrases = ["goodbye"]
1 to create, 1 to update, 0 to delete, 3 unchangedField-level, with the actual before and after. "Assistant changed" is not a plan.
Matching, renames and pruning
Local files match remote records by, in order:
- an explicit
id:in the file, - the id recorded in
.callagent/state.<env>.jsonby the last apply, - the
name.
Because of (2), renaming an assistant in git updates the existing record rather than deleting it and creating a new one — which would lose its call history.
--prune proposes deleting resources this project created and no longer declares. Resources somebody built in the dashboard are never proposed for deletion.
Adopting it on an existing organization
callagent init
callagent login
callagent export # pulls everything down as files
callagent plan # reports: No changesIn CI
- run: callagent validate # exits 2 on a bad file
- run: callagent plan --detailed-exitcode # exits 2 when config has drifted
- run: callagent apply --auto-approve --force
env:
CALLAGENT_API_KEY: ${{ secrets.CALLAGENT_API_KEY }}apply continues past individual failures and reports exactly what did and did not apply, so re-running finishes the job. Applying twice changes nothing the second time.
Not yet synced
policies/ is validated locally but never pushed: the control plane has no /api/v1/policies endpoint yet. plan and apply say so rather than pretending.