Configure 10xgraph.json
In shortTask guide for setting the common 10xgraph.json keys, wiring a checkpointer, store and auth, and keeping separate configs per environment.
- 4 min read
- 11 sections
- Updated
- v0.9.2
- Markdown
10xgraph.json tells the API server which graph to serve and how to secure it. This guide covers how to set the keys you reach for most often. For every key, type and default, see the 10xgraph.json reference.
Start with the agent key
Only agent is required. It is a module:attribute path to your compiled graph:
{
"agent": "graph.react:app",
"env": ".env"
}The module is imported when the server starts, and app must be a compiled graph (state_graph.compile()). If the import fails, the server does not start. Test it by hand:
python -c "from graph.react import app; print(type(app))"env names a dotenv file loaded before your graph module is imported. Use it for local secrets, never commit it, and in production pass variables through the container or process environment instead.
Persist conversations with a checkpointer
Pass the checkpointer to compile() in your graph module. The server uses whatever the compiled graph carries. The checkpointer key in 10xgraph.json is recognised but not applied by the API server, so setting it has no effect.
# graph/dependencies.py
from tenxgraph.storage.checkpointer import PgCheckpointer
my_checkpointer = PgCheckpointer(
postgres_dsn="postgresql://user:password@localhost/agentflow",
redis_url="redis://localhost:6379/0",
)# graph/react.py
from graph.dependencies import my_checkpointer
app = state_graph.compile(checkpointer=my_checkpointer)PgCheckpointer needs pip install "10xgraph[pg_checkpoint]". Without a checkpointer, compile() falls back to InMemoryCheckpointer: threads work while the process runs, but are lost on restart and are not shared across workers. See Set up checkpointing.
Enable the memory store endpoints
The store key points at a BaseStore instance (not a class). Without it, the /v1/store/* endpoints report that no store is configured.
# graph/dependencies.py
from tenxgraph.storage.store import QdrantStore
from tenxgraph.storage.store.embedding import OpenAIEmbedding
my_store = QdrantStore(embedding=OpenAIEmbedding(), path="./qdrant_data"){
"agent": "graph.react:app",
"store": "graph.dependencies:my_store"
}Loading fails at startup with a clear error if the attribute is not a BaseStore. For tests, tenxgraph.qa.testing.InMemoryStore satisfies the same key.
Inject your own services
The injectq key points at an InjectQ container. Use it when nodes or tools need services resolved at startup, such as a database session factory or an HTTP client:
# graph/dependencies.py
from injectq import InjectQ
container = InjectQ()
container.bind_instance(MyDatabase, MyDatabase(dsn=os.environ["DATABASE_URL"])){
"agent": "graph.react:app",
"injectq": "graph.dependencies:container"
}The container becomes the global instance on load, so the server’s own bindings land in the same container as yours. Bind a BaseRateLimitBackend here when you use "backend": "custom" for rate limiting.
Name threads
Set thread_name_generator to a module:Class path to give new threads readable names instead of raw UUIDs:
# graph/thread_name_generator.py
from agentflow_cli.src.app.utils.thread_name_generator import ThreadNameGenerator
class MyThreadNameGenerator(ThreadNameGenerator):
async def generate_name(self, messages: list[str]) -> str:
return "thoughtful-conversation"{
"agent": "graph.react:app",
"thread_name_generator": "graph.thread_name_generator:MyThreadNameGenerator"
}Turn on auth, authorization and rate limits
These keys have their own guides:
| Key | Guide |
|---|---|
auth |
Add JWT authentication |
authorization |
Auth and authorization |
rate_limit |
Configure rate limiting |
A minimal secured config looks like this:
{
"agent": "graph.react:app",
"auth": "jwt",
"authorization": "ownership",
"rate_limit": { "backend": "redis", "redis": { "url": "redis://localhost:6379/1" }, "requests": 100, "window": 60 }
}"auth": "jwt" needs JWT_SECRET_KEY in the environment. ownership makes threads owner-only. The server checks resource:action scopes on every endpoint through the authorization backend, and the rbac backend maps roles to those scopes.
Share a Redis URL
The redis key is a plain URL string used by the shared tier of the thread-ownership cache. When unset, the server falls back to the REDIS_URL environment variable. With neither, the cache is per process and the server logs a warning. It is separate from rate_limit.redis, so configure both if you want both backed by Redis.
Set defaults for test and eval
The optional test and evaluation blocks supply defaults for 10xgraph test and 10xgraph eval. CLI flags win over the file:
{
"agent": "graph.react:app",
"test": { "path": "tests", "coverage": true, "coverage_threshold": 80 },
"evaluation": { "directory": "evals", "output_dir": "eval_reports", "threshold": 0.9 }
}10xgraph test tests/unit/ # overrides test.path
10xgraph test --coverage # overrides test.coverage
10xgraph eval --output ci_reports/ # overrides evaluation.output_dir (short form: -o)
10xgraph eval --threshold 0.95
10xgraph eval --parallel --max-concurrency 16Evaluation criteria do not come from 10xgraph.json. They come from confeval.py in your evals directory. See Run evals.
Keep one config per environment
Use separate files and pick one with --config:
config/
dev.json
staging.json
prod.json10xgraph api --config config/dev.json
MODE=production 10xgraph api --config config/prod.json --no-reloadValidate before you deploy
Run 10xgraph audit to check the interpreter, packages, project config and port. Then start the server and call the health endpoint:
10xgraph audit
10xgraph api &
curl http://127.0.0.1:8000/pingCommon config issues
| Symptom | Check |
|---|---|
| Module not found | The module path is spelled correctly and the module exists in your project. |
| Attribute not found | graph.react:app needs an app variable in graph/react.py. |
| Checkpointer database connection failed | The DSN is correct and the database is reachable (psql <dsn>). |
JWT_SECRET_KEY not found |
Export it, or set "env": ".env" and add it there. |