A starter template for building AI agents that run on Vertex AI Agent Engine and serve users through The Forum — Comites.ai's open-source middleware that bridges Slack, Google Chat, Telegram, and Discord to your agent.
You are reading the template's README. Once you run
./get_started_linux.sh, this file is rewritten to be about your agent. The "what is this template" content you're reading is only here for first-time setup and for people who want to contribute changes to the template itself.
This README has two audiences:
- You want to build a new agent. → See Building an agent with this template.
- You want to change something about the template itself. → See Modifying the template.
Comites.ai is a platform for building specialized AI agents — "a council, not a chatbot." Instead of one general-purpose assistant, you build narrow domain experts (a wine sommelier, a growth coach, a legal advisor, etc.) that users reach through the messaging apps they already live in. The name comes from the Roman comites — the trusted companions of an emperor's inner circle.
Three open-source pieces fit together:
- The Forum (AGPL-3.0) — middleware that bridges Slack, Google Chat, Telegram, and Discord to agents running on Vertex AI. One Forum deployment routes to many agents.
- This template (MIT) — scaffolding for building one of those agents. The output is a Vertex AI Reasoning Engine that registers itself with a Forum and starts receiving traffic on whichever platforms you enable.
- The Marketplace — curated directory where verified agents can be published and adopted into other people's Forums (launching soon).
For a higher-level tour, see comites.ai/developers and comites.ai/architecture.
┌──────────────────────────────────────────────────────┐
│ Messaging platforms │
│ (Slack · Google Chat · Telegram · Discord) │
└──────────────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ The Forum (Cloud Run) │
│ github.com/Comites-ai/the-forum │
│ · Routes messages to the right agent (via Firestore)│
│ · Manages sessions, identity, scheduled jobs │
│ · Hosts the scheduler MCP server │
└──────────────────────────┬───────────────────────────┘
│ (cross-project call)
▼
┌──────────────────────────────────────────────────────┐
│ YOUR AGENT (Vertex AI Reasoning Engine) │
│ Lives in this repo · Deployed by deploy_and_update │
│ · Conducts conversations using your prompt + tools │
│ · Reads secrets / accesses Google Workspace via its │
│ own service account │
└──────────────────────────────────────────────────────┘
The template gives you:
- An ADK agent stub (
agent.py) that replies with a recognizable greeting until you replace its instruction with real logic — so the first deploy proves the full pipeline works before you write any agent code. terraform/for the agent's dedicated GCP project (service account, secrets per platform, IAM bindings to The Forum, ADK staging bucket, Workspace API enablements). Platform sections commented out until you select them.deploy_and_update.sh— blue/green deploy + smoke test + Firestore registration + stale-session cleanup.register_agent.py— auto-detects enabled platforms by probing Secret Manager and writes the agent record to The Forum's Firestore.get_started_linux.sh— interactive bootstrap that asks you a handful of questions, generates.env+terraform.tfvars, uncomments the right terraform sections, provisions the state bucket, optionally runsterraform apply+ populates secrets, optionally wires up a Google Doc for persistent memory, rewrites this README to be about your agent, and self-deletes.AGENTS.md— hard rules for AI coding agents working in the repo (and equally useful for humans).
Before running ./get_started_linux.sh:
-
A local clone of The Forum with its own
.envandterraform/terraform.tfvarsalready populated, AND The Forum already deployed at least once.get_started_linux.shreads from these to figure out what project The Forum runs in and what its public URL is. The Forum also needs a currentgoogle-cloud-aiplatformto invoke the Reasoning Engines this template deploys — if Forum→agent calls fail right after you stand up your first agent, an out-of-date aiplatform SDK in the Forum is worth ruling out.The "deployed at least once" part matters because this template's terraform creates IAM bindings that reference the Forum project's Vertex AI service agents (
service-${FORUM_PROJECT_NUMBER}@gcp-sa-aiplatform[.|-re|-cc].iam.gserviceaccount.com— three of them, all needed), which only auto-exist once Vertex AI has been used in that project.get_started_linux.shhandles this automatically by runninggcloud beta services identity create --service=aiplatform.googleapis.com --project=$FORUM_PROJECT_IDduring its API-bootstrap phase — a single call provisions all three sub-agents and is idempotent (no-op if they already exist). You only need to know about this if you're applying terraform by hand, or if you don't haveroles/serviceusage.serviceUsageAdminon the Forum project — in which case the bootstrap will print a warning and ask the Forum's admin to run that one command before you re-try.Whoever runs
terraform applyfor this template also needs two roles on the Forum's project (not just the agent's project):roles/resourcemanager.projectIamAdmin(to grant the per-agent SA its runtime roles —aiplatform.user,logging.logWriter, etc. — without which the Reasoning Engine deploys cleanly but 500s on the first message) and read access via something likeroles/viewer(so the Vertex AI list/create API calls work). The Forum's admin typically has both of these. If you don't, you can either ask them to grant you the roles temporarily, or have them apply the equivalent gcloud commands once — both are documented inline interraform/main.tfnext to the relevant resources.Separately, the Forum project needs the org policy
constraints/iam.disableCrossProjectServiceAccountUsagedisabled (so it accepts your per-agent SA as the Reasoning Engine's runtime identity). That policy lives in the Forum's own terraform, not in this template — seeAGENTS.mdrule #3 for the exact snippet to give the Forum operator if it isn't already in place. If it's missing, the symptom is an engine that deploys cleanly and then 500s on the first user message. -
A GCP project for this agent (separate from The Forum's project) with billing linked. Create with:
gcloud projects create YOUR_AGENT_PROJECT \ --name="Your Agent Name" \ --organization=YOUR_ORG_ID gcloud beta billing projects link YOUR_AGENT_PROJECT \ --billing-account=YOUR_BILLING_ACCTget_started_linux.shverifies the project exists and offers helpful errors if billing or APIs are missing — but it does not create the project for you (deliberate: project creation is one-time and not really a fit for an idempotent bootstrap script). -
CLI tools installed and on
$PATH:gcloud,terraform(≥ 1.2),python3,pip,adk(pip install google-adk). -
gcloudauthenticated: bothgcloud auth loginandgcloud auth application-default login. -
For at least one messaging platform you intend to test with: the bot is already created on the platform's side (Slack app, Telegram BotFather, etc.), so you can paste the token into
get_started_linux.shwhen it prompts you. See The Forum'sFOR_AGENT_DEVELOPERS.mdfor per-platform bot creation steps.
# 1. Clone this template (rename the directory to something that's a
# valid Python identifier — no hyphens — since ADK uses the directory
# name as the agent package name).
git clone <this-repo> my_agent
cd my_agent
# 2. Run the bootstrap. It walks you through everything and self-deletes
# on success.
./get_started_linux.sh
# 3. Once it finishes, deploy.
./deploy_and_update.sh
# 4. DM your bot on any platform you enabled. You should get the stub
# greeting back, confirming the pipeline works end-to-end.After that, the repo is about your agent. Edit agent.py with your real prompt and tools, then redeploy with ./deploy_and_update.sh. The post-setup README.md (which get_started writes) has a "Next steps" section that walks through adding tools, sub-agents, MCP servers, and external API integrations.
- Verifies prerequisites and
gcloudauth. - Locates your local clone of The Forum and reads its config.
- Asks you for: agent display name,
bot_account_id, GCP project, region, models, which platforms to enable. - Generates
.envandterraform/terraform.tfvars. - Uncomments the platform sections you selected in
terraform/main.tf. - Creates the GCS bucket for terraform state and wires up the
backend "gcs"block interraform/providers.tf. - Optionally: runs
terraform apply(two-phase: secret containers first, then prompts silently for each platform token andgcloud secrets versions add, then full apply). - Optionally: wires up a Google Doc for persistent agent memory (prompts for the doc ID, sets
AGENT_MEMORY_DOC_IDin.env, prints the SA email to share the doc with). - Rewrites this README for your agent. (
AGENTS.mdis left as-is — its hard rules apply to deployed agents unchanged.) - Deletes the template-only files (
test.md,MAINTAINER_SETUP.md,.readme_template_post_setup.md,tests/) and itself. - Prints what to do next: configure platform webhooks (per-platform instructions for whichever you selected), then
./deploy_and_update.sh.
.
├── agent.py # ADK root agent (Junius Rusticus stub persona until you replace)
├── __init__.py
├── custom_functions.py # Your FunctionTool implementations
├── custom_agents.py # Your sub-agents (used via AgentTool)
├── secret_utilities.py # Secret Manager + retry helpers
├── requirements.txt
├── .env / .env.example # Runtime config (.env is gitignored)
├── deploy_and_update.sh # Blue/green deploy + smoke test + register
├── register_agent.py # Auto-detects platforms, writes Firestore record
├── get_started_linux.sh # One-shot bootstrap (self-deletes)
├── AGENTS.md # Hard rules for AI agents working in this repo
├── terraform/
│ ├── main.tf # All resources (platform sections commented)
│ ├── variables.tf
│ ├── terraform.tfvars # Your config (gitignored)
│ ├── terraform.tfvars.example
│ ├── providers.tf # GCS backend wired by get_started
│ └── README.md
├── LICENSE.txt # MIT
├── TRADEMARK.md
├── THIRD_PARTY_LICENSES
├── CONTRIBUTING.md # CLA flow (same as The Forum)
└── .github/ # CODEOWNERS, PR template, issue templates, CI
# Template-only files (deleted by get_started_linux.sh on first run):
# test.md, MAINTAINER_SETUP.md, tests/, .readme_template_post_setup.md
If you want to change something about the scaffolding itself (the bootstrap script, the terraform, the deploy script, etc.) and contribute it back, this section is for you.
This repo is the scaffolding for new Comites.ai agents. Changes here affect every new agent created with the template, so testing is more rigorous than a typical app: a change can pass shell lint and terraform lint and still break a real bootstrap end-to-end. There are two tiers of testing:
- Fast local unit tests — run in seconds, no GCP needed, catch the most common heuristic regressions.
- End-to-end GCP smoke test — required for any PR that touches
get_started_linux.sh,terraform/,deploy_and_update.sh, orregister_agent.py. Creates real cloud resources, deploys a real Reasoning Engine, sends a real message through a real Slack workspace.
Both tiers are documented in test.md.
See CONTRIBUTING.md for the full development setup, but in short:
git clone https://github.com/YOUR_USERNAME/agent-template.git
cd agent-template
# Optional: python venv if you want to run register_agent.py locally
python -m venv venv && source venv/bin/activate && pip install -r requirements.txtRun these in order:
# 1. Fast unit test — catches uncomment_section regressions
./tests/test_uncomment_section.sh
# 2. Local lint checks (same checks CI runs)
bash -n *.sh
shellcheck -S error *.sh # apt install shellcheck
terraform fmt -check -recursive terraform/
python -m py_compile agent.py custom_functions.py custom_agents.py secret_utilities.py register_agent.py
# 3. If your PR touches get_started_linux.sh, terraform/,
# deploy_and_update.sh, or register_agent.py:
# Walk through test.md end-to-end against a real GCP project.
# Read test.md for the full sequence.CI runs the lint checks automatically on every PR. The unit test and the GCP test are NOT automated — the unit test should be (TODO), and the GCP test can't be (requires credentials).
Most changes touch one or two of these:
get_started_linux.sh— the interactive bootstrap. 16 phases, mirroring The Forum'sinstall.shpatterns. The trickiest piece is theuncomment_sectionfunction, which uses a brace-balanced block detector to selectively uncomment platform sections interraform/main.tf. The unit test intests/test_uncomment_section.shexists specifically because this heuristic is the most likely thing to silently break.terraform/main.tf— all GCP infrastructure for the agent's dedicated project. Section 1 (common) is always active; sections 2-6 (Slack, Google Chat, Telegram, Discord, Scheduler MCP) are commented blocks thatuncomment_sectionselectively enables. If you add a new platform or rename resources, update the expected-resource lists intests/test_uncomment_section.sh.deploy_and_update.sh— blue/green deploy + smoke test + Firestore registration + stale-session cleanup. Reads config from.env.register_agent.py— auto-detects platforms from Secret Manager and writes the agent's Firestore record. Validates each token via the platform's native API before writing.agent.py— the stub agent that the template ships. Replaces operator-facing logic inSTUB_INSTRUCTIONanddescription. The default persona is Junius Rusticus (Stoic teacher of Marcus Aurelius — namesake inspiration for the project). If you change the stub persona, update the expected keywords intest.mdstep 7.AGENTS.md— hard rules for AI agents (and humans) working in repos created from the template. Add a new rule when there's a way to break an agent that's not obvious from the code.
Every PR runs three jobs (see .github/workflows/ci.yml):
| Job | What it does |
|---|---|
| Shell lint | bash -n syntax check + shellcheck -S error on *.sh |
| Terraform lint | terraform fmt -check -recursive terraform/ |
| Python syntax | python -m py_compile on *.py |
CI does NOT run the unit test in tests/ or the GCP test in test.md yet — those are manual gates. The unit test is a near-term TODO to wire into CI (it doesn't need GCP credentials, just terraform and python3).
See CONTRIBUTING.md for the CLA process. Briefly:
- Fork, branch from
main, make your changes. - Run the testing sequence above.
- Open a PR. CLA Assistant will prompt you to sign the CLA on your first PR; do so and email
cla@comites.aiwith the supplemental info described inCONTRIBUTING.md. - A maintainer will review. For PRs touching infrastructure files, the maintainer will spot-check the GCP test result you describe in your PR body.
Two files exist for template work and don't ship to end users:
MAINTAINER_SETUP.md— One-time setup steps for publishing this repo as OSS on GitHub (CLA Assistant, branch protection, etc.) and for pointing The Forum repo at this template. Read once when first standing up the repo, then ignore.test.md— The GCP smoke-test sequence (a required manual gate for PRs that touch infrastructure files). Walks through bootstrap + deploy + end-to-end message flow against a real GCP project.
Both are deleted by get_started_linux.sh so they never appear in an end user's agent repo.
MIT. See LICENSE.txt and TRADEMARK.md. The template's MIT license means you can use, modify, and redistribute it freely — including as the basis for closed-source agents. The trademark policy in TRADEMARK.md still applies separately: you can't name your project "Comites", "The Forum", or anything that implies it's a Comites.ai product.
(Note: The Forum itself is AGPL-3.0 — a deliberate choice for a deployed service. This template is permissive scaffolding, so picking the same license made less sense.)
This template is the convergence of patterns developed across The Forum and the existing Comites.ai agents (Growth Coach, Sommelier). It packages those patterns up so creating a new agent doesn't require excavating five years of decisions from five different repos.