A step-by-step walkthrough of building, inspecting, and running an agent entirely from the Chronos CLI — driven by a YAML config, no application code required for the basics. It also shows the supported way to give an agent a custom tool with real behavior (a small Go program), since custom tools declared in YAML are placeholders.
Every command below uses the actual Chronos CLI verbs
(go run ./cli/main.go <command>). Run go run ./cli/main.go help to see them.
| File | Purpose |
|---|---|
agents.yaml |
Declarative agent + team config the CLI loads. |
custom_tool.go |
A Go program that registers a real custom tool handler. |
The CLI looks for a config in this order: $CHRONOS_CONFIG, then
.chronos/agents.yaml, agents.yaml, and finally ~/.chronos/agents.yaml.
Use the environment variable to load this example's config:
export CHRONOS_CONFIG=examples/cli_agent/agents.yamlOr place it at the project-default location instead of setting the variable:
mkdir -p .chronos
cp examples/cli_agent/agents.yaml .chronos/agents.yamlThe config reads the model API key from the environment via ${OPENAI_API_KEY}
expansion, so export your key before any command that actually talks to the
model (agent chat, run, repl, team run):
export OPENAI_API_KEY=sk-...Commands that only read the config (agent list, agent show, team list,
team show) work without a key.
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go agent listID NAME PROVIDER MODEL DESCRIPTION
-------------------------------------------------------------------------------------
assistant CLI Assistant openai gpt-4o A concise general-purpose a...
repo-explorer Repository Explorer openai gpt-4o Answers questions about the...
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go agent show repo-explorerShows the resolved provider, model, storage, system prompt, instructions, and capabilities.
run sends a single message and prints the response. Choose an agent with
--agent (alias -a); omit it to use the first agent in the config.
# default (first) agent
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go run "Give me one tip for writing clear commit messages"
# a specific agent
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go run --agent assistant "Summarize what a durable agent is in one sentence"CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go agent chat assistantOpens an interactive REPL bound to that agent. Type messages; the conversation is persisted to the configured SQLite database.
repl starts the interactive shell and loads the first agent from the config:
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go replserve starts the HTTP control plane (default :8420):
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go serve :8420The config defines a sequential team named review:
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go team list
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go team show review
CHRONOS_CONFIG=examples/cli_agent/agents.yaml go run ./cli/main.go team run review "Summarize the README in this directory"Chronos resolves built-in tool names in YAML to real handlers automatically
(file_read, file_write, file_list, file_glob, file_grep, shell,
shell_auto). The repo-explorer agent uses several of these.
A custom tool in YAML (a name + description that is not a built-in) is
registered as a no-op placeholder: the model can see the tool, but calling
it just echoes the arguments. In agents.yaml the word_count tool is such a
placeholder.
To give a custom tool real behavior, register a tool.Definition with a
Handler programmatically in Go. custom_tool.go shows the supported
pattern — it wires a real word_count handler onto the repo-explorer agent
and invokes it two ways (direct execution and a model-driven tool call). It uses
a deterministic mock provider, so it runs with no API key:
go run ./examples/cli_agent/━━━ Direct tool execution ━━━
word_count("the quick brown fox") = map[words:4]
━━━ Model-driven tool call ━━━
Assistant: That text contains 7 words.
In production you would build the agent from agents.yaml
(agent.BuildAgent), then AddTool your real handler for any custom tool name
before serving it.
| Variable | Purpose |
|---|---|
CHRONOS_CONFIG |
Path to the agents YAML config file. |
CHRONOS_DB_PATH |
SQLite database path (default chronos.db). |
OPENAI_API_KEY |
Consumed by ${OPENAI_API_KEY} in agents.yaml. |
go run ./cli/main.go help # full command list
go run ./cli/main.go version # build/version info
go run ./cli/main.go sessions # session management (list/resume/export)
go run ./cli/main.go config # show resolved configuration