Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/content/docs/concepts/agents-and-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ agent = Agent(
# OFF
reasoning_config=None

# On, medium effort (default for Google: thinking_budget=8192)
# On, lowest effort per provider (the default; Google thinking_budget=512)
reasoning_config=True

# Medium effort (Google thinking_budget=8192)
reasoning_config={"effort": "medium"}

# High effort, Google
Expand All @@ -141,7 +144,7 @@ reasoning_config={"thinking_budget": 5000}
reasoning_config={"effort": "low", "summary": "auto"}
```

Default is `{"effort": "medium"}`, so thinking is **on by default** for Google models.
Default is `True`: thinking is **on by default** at each provider's lowest effort (OpenAI `"minimal"`, Anthropic `"low"`, Google `"low"`). Pass a dict for more.

---

Expand Down
8 changes: 4 additions & 4 deletions src/content/docs/get-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ The `all` extra installs every other extra at once and is useful for local devel
Version pinning still matters. From 1.0 the public API is stable under a deprecation policy: breaking changes arrive only in a major release, after at least one minor release of deprecation. The three packages share major.minor, and patch versions are independent. While 1.0 is a release candidate, install it with `--pre`:

```bash
pip install --pre "10xgraph==1.0.0rc1" "10xgraph-api==1.0.0rc1"
pip install --pre "10xgraph==1.0.0rc2" "10xgraph-api==1.0.0rc2"
```

Drop `--pre` once 1.0.0 is out. Read the [changelog](/changelog) before upgrading, and see the [upgrade guide](/docs/project/upgrade-to-1.0) if you come from 0.x.
Expand All @@ -132,9 +132,9 @@ Example output (the exact formatting and versions vary by release):
```text
$ 10xgraph version
10xgraph-api
Version: 1.0.0rc1
Version: 1.0.0rc2
10xgraph (core)
Version: 1.0.0rc1
Version: 1.0.0rc2

$ python -c "import tenxgraph; print(tenxgraph.__file__)"
/path/to/.venv/lib/python3.12/site-packages/tenxgraph/__init__.py
Expand Down Expand Up @@ -193,7 +193,7 @@ If you are building a JavaScript or TypeScript application that calls the 10xGra
npm install 10xgraph-client@next
```

The `next` tag points at the 1.0 release candidate (`1.0.0-rc.1`); use plain `npm install 10xgraph-client` once 1.0.0 is out. The main class is `TenxGraphClient`, and the package requires Node.js 18 or newer. See the [client documentation](/docs/client) for usage.
The `next` tag points at the 1.0 release candidate (`1.0.0-rc.2`); use plain `npm install 10xgraph-client` once 1.0.0 is out. The main class is `TenxGraphClient`, and the package requires Node.js 18 or newer. See the [client documentation](/docs/client) for usage.

The client talks to a running 10xGraph API server (`10xgraph dev` locally) over HTTP, and you pass a thread ID to keep conversation history across runs. Use `10xgraph-api` 0.7.0 or newer with client 0.6.0 or newer: the client authenticates WebSockets with the `10xgraph-bearer` subprotocol, which older servers do not accept. HTTP calls work with either. See the [Quickstart](/docs/get-started/first-agent) for a complete example.

Expand Down
8 changes: 4 additions & 4 deletions src/content/docs/guides/configure-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,12 @@ Multiple tags are supported; the agent can call any tool matching at least one t

## Reasoning configuration

10xGraph provides a unified `reasoning_config` across all providers that support reasoning. By default, reasoning is enabled at medium effort for models that support it (like OpenAI's o-series, Google's Gemini, and Anthropic's Claude).
10xGraph provides a unified `reasoning_config` across all providers that support reasoning. By default, reasoning is enabled at each provider's lowest effort for models that support it (OpenAI `"minimal"`, Anthropic `"low"`, Google `"low"`; pass a dict such as `{"effort": "medium"}` for more) (like OpenAI's o-series, Google's Gemini, and Anthropic's Claude).

You can control reasoning mode with the `effort` key, which applies consistently across providers. Each provider translates this to its native settings. For providers without reasoning support, this parameter is safely ignored.

```python
# Default: medium effort (ON for reasoning models)
# Default: lowest effort per provider (ON for reasoning models)
agent = Agent(model="gpt-4o")

# High effort reasoning
Expand All @@ -282,7 +282,7 @@ agent = Agent(model="claude-opus-5", reasoning_config={"effort": "high"})
| `effort` | OpenAI | Google `thinking_budget` | Anthropic |
|---|---|---|---|
| `"low"` | Low effort | 512 | Adaptive (conservative) |
| `"medium"` (default) | Medium effort | 8192 | Adaptive (balanced) |
| `"medium"` | Medium effort | 8192 | Adaptive (balanced) |
| `"high"` | High effort | 24576 | Adaptive (thorough) |

When you pass `effort`, Google's equivalent `thinking_budget` is computed automatically. The `summary` key (OpenAI-only) controls how extended thinking is summarized in the response.
Expand Down Expand Up @@ -614,7 +614,7 @@ Agent(
extra_messages: list[Message] | None = None,
trim_context: bool = False,
tools_tags: set[str] | None = None,
reasoning_config: dict | bool | None = {"effort": "medium"},
reasoning_config: dict | bool | None = True,
skills: SkillConfig | None = None,
memory: MemoryConfig | None = None,
retry_config: RetryConfig | bool | None = True,
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/guides/graceful-shutdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ stats = await graph.aclose(grace=10, stop_timeout=5, timeout=5)
5. Background tasks (publisher events, memory writes) are drained for the rest of `timeout`, then cancelled.
6. The checkpointer, publisher and store are released, following the resource ownership rules (`compile(owns_resources=...)`).

Without arguments, the times split `compile(shutdown_timeout=...)` (default 30 seconds): 50% for `grace`, 25% for `stop_timeout`, 25% for `timeout`. The result is a stats dict with `runs` (`active`, `finished`, `stopped`, `cancelled`), `background_tasks` and one entry per released component. A second call returns `{"status": "already_closed"}`. `async with graph:` calls `aclose()` on exit.
Without arguments, the times split `compile(shutdown_timeout=...)` (default 30 seconds): 50% for `grace`, 25% for `stop_timeout`, 25% for `timeout`. The result is a stats dict with `runs` (`active`, `finished`, `stopped`, `cancelled`), `background_tasks`, `cleanup_tasks` (cancel saves and run-marker releases that outlived their run, waited for within the drain budget) and one entry per released component. A second call returns `{"status": "already_closed"}`. `async with graph:` calls `aclose()` on exit.

### Signals

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/integrations/anthropic.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ agent = Agent(

## Extended thinking and reasoning

Claude supports extended thinking (internal reasoning before responding) through the `reasoning_config` parameter. It is on by default with `{"effort": "medium"}`; pass `None` or `False` to turn it off:
Claude supports extended thinking (internal reasoning before responding) through the `reasoning_config` parameter. It is on by default at effort `"low"` (the lowest); pass a dict such as `{"effort": "medium"}` for more, or pass `None` or `False` to turn it off:

```python
agent = Agent(
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/integrations/google.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ config = EvalConfig(
## Thinking Models

Gemini thinking models support extended thinking. Control it via `reasoning_config`
(the default is `{"effort": "medium"}`). Thinking is not applied when `output_schema` is set
(the default is effort `"low"`, which is `thinking_budget=512`; pass a dict for more). Thinking is not applied when `output_schema` is set
or `output_type` is not text or json.

```python
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/integrations/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ Here `app` is your compiled graph.

Some models include explicit reasoning or thinking capabilities:

`reasoning_config` is on by default with `{"effort": "medium"}`. Pass `None` or `False` to turn it off.
`reasoning_config` is on by default at each provider's lowest effort (OpenAI `"minimal"`, Anthropic `"low"`, Google `"low"`). Pass a dict such as `{"effort": "medium"}` for more, or pass `None` or `False` to turn it off.

- **OpenAI:** `effort` is sent as `reasoning_effort` (Chat Completions) or `reasoning` (Responses API).
- **Anthropic:** `effort` becomes `thinking={"type": "adaptive"}` plus `output_config={"effort": ...}`.
Expand Down
17 changes: 11 additions & 6 deletions src/content/docs/integrations/openai.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ cache still fires automatically when the judge prompt prefix is stable (same rub
## Reasoning Models

Reasoning models such as `o4-mini` are controlled via `reasoning_config`. The default is
`{"effort": "medium"}`.
effort `"minimal"` (the lowest); pass a dict for more.

```python
# Enable with defaults (effort="medium")
# Enable with defaults (effort="minimal")
agent = Agent(model="o4-mini", reasoning_config=True)

# Set effort level
Expand All @@ -264,8 +264,12 @@ agent = Agent(model="o4-mini", reasoning_config=False)
```

On Chat Completions, `effort` is sent as `reasoning_effort`; on the Responses API the whole
dict is sent as `reasoning` (so `summary` is also allowed). Because the default is on, pass
`reasoning_config=None` when using a model that does not accept reasoning parameters.
dict is sent as `reasoning` (so `summary` is also allowed). When reasoning is on and you set no
`summary`, the Responses request asks for `summary: "auto"`. If the reasoning came from the default
and the model answers with a 400 that names the reasoning parameter (for example `gpt-4o`), the
call is retried once without it and the model is remembered for the process. An explicit
`reasoning_config` dict is never dropped and still raises, so pass `reasoning_config=None` for a
model that does not accept reasoning parameters.

---

Expand Down Expand Up @@ -309,8 +313,9 @@ agent = Agent(

When `base_url` is set and you do not pass `api_style`, the Agent uses Chat Completions,
because most local servers only support it. If you pass `api_style="responses"` with a
`base_url`, the Agent tries the Responses API on the first call. If the server rejects it,
the Agent logs one warning and uses Chat Completions for the rest of its lifetime.
`base_url`, the Agent tries the Responses API on the first call. If the server answers 404,
405 or 501 (no Responses API), the Agent logs one warning and uses Chat Completions for the rest
of its lifetime. Other errors, such as a 429 or a timeout, are raised and do not switch it.

Prompt caching params (`prompt_cache_key`, `prompt_cache_retention`) have no effect on
local servers unless the server explicitly implements them.
Expand Down
1 change: 1 addition & 0 deletions src/content/docs/integrations/postgres-and-redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ You must supply one Postgres source (`postgres_dsn` or `pg_pool`) and one Redis
| `redis` | Redis client | `None` | Existing `redis.asyncio.Redis` instance |
| `redis_pool` | `ConnectionPool` | `None` | Existing Redis connection pool |
| `redis_pool_config` | `dict` | `None` | Extra keyword arguments for the Redis pool, merged over the defaults. The pool is capped at `max_connections=50`, and a caller past the cap waits up to `timeout=5.0` seconds for a free connection. Override either key. |
| `redis_breaker_cooldown` | `float` (kwarg) | `5.0` | Seconds to skip Redis after a connection failure. The checkpointer falls back to Postgres (or no cache) at once during the cool-down, so a Redis outage does not slow every run step. `0` disables it. |
| `schema` | `str` | `"public"` | Postgres schema for the tables. Must match `^[a-zA-Z_][a-zA-Z0-9_]*$` |
| `cache_ttl` | `int` (kwarg) | `86400` | Redis cache lifetime in seconds |
| `state_history_limit` | `int` (kwarg) | `20` | State snapshots kept per thread; older ones are pruned on each durable write |
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/project/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ label: Overview
updated: "2026-10-28"
---

This section covers 10xGraph as a project: who maintains it, how releases are announced, how to report a security problem, where to get help and how to contribute. It is MIT licensed, maintained by 10xScale, and at the 1.0 release candidate stage (1.0.0rc1, 2026-10-28) after its October 2026 rename from Agentflow.
This section covers 10xGraph as a project: who maintains it, how releases are announced, how to report a security problem, where to get help and how to contribute. It is MIT licensed, maintained by 10xScale, and at the 1.0 release candidate stage (1.0.0rc2, 2026-10-30) after its October 2026 rename from Agentflow.

## Start here

Expand Down
31 changes: 29 additions & 2 deletions src/content/docs/project/upgrade-to-1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ read [Upgrade to 0.9](/docs/project/upgrade-to-0.9) first.
client candidate is published under the `next` dist-tag.

```bash
pip install -U --pre "10xgraph==1.0.0rc1" "10xgraph-api==1.0.0rc1"
pip install -U --pre "10xgraph==1.0.0rc2" "10xgraph-api==1.0.0rc2"
npm install 10xgraph-client@next
```

Expand Down Expand Up @@ -52,6 +52,17 @@ npm install 10xgraph-client@next
only if you set `reasoning_config` yourself. With a `base_url` and `api_style="responses"`, a
server that rejects the Responses API is probed once and the Agent then stays on Chat
Completions.
- **Default reasoning is each provider's lowest effort.** `reasoning_config` left unset or set to
`True` used to mean `{"effort": "medium"}` (Google `thinking_budget=8192`). It now resolves per
request to OpenAI `"minimal"`, Anthropic `"low"` and Google `"low"` (`thinking_budget=512`); the
values are in `DEFAULT_REASONING_EFFORT_BY_PROVIDER`. Pass `{"effort": "medium"}` to keep the
old depth. `None` or `False` still turns reasoning off.
- **OpenAI Responses asks for a reasoning summary and retries models without reasoning.** With
reasoning on and no `summary` set, the request sends `summary: "auto"`. If the reasoning came
from the default and the model answers 400 naming the reasoning parameter (for example
`gpt-4o`), the call is retried once without it. An explicit `reasoning_config` dict is never
dropped. With a custom `base_url`, only 404, 405 and 501 switch the Agent to Chat Completions;
other errors are raised.
- **The `openai` extra is `openai>=1.93.1,<4`.** openai 3.x uses httpx2, so an `http_client`
passed through `llm_kwargs` must be an `httpx2.AsyncClient` there.

Expand Down Expand Up @@ -92,6 +103,10 @@ npm install 10xgraph-client@next
- **`aforget_memory` differs by store.** `QdrantStore` applies `memory_type`, `category` and
`filters`. `Mem0Store` raises `ValueError` if any of them is passed. The `qdrant` extra needs
`qdrant-client>=1.10.0` and a Qdrant server 1.10 or newer.
- **`GoogleEmbedding` sends Gemini task types.** `RETRIEVAL_DOCUMENT` when storing and
`RETRIEVAL_QUERY` when searching (`BaseEmbedding.aembed_query`, used by `QdrantStore.asearch`).
Set `document_task_type` and `query_task_type` to change them, or `None` to send none. Vectors
stored earlier stay searchable.

### Tools and handoffs

Expand Down Expand Up @@ -154,6 +169,10 @@ npm install 10xgraph-client@next
- **There are no default node or tool timeouts.** `node_timeout` and `tool_timeout` are off until
you set them, and a value you set applies to both invoke and stream. Streaming runs also use
the tool ledger now.
- **A failing eval judge is an error, not a 0.5 score.** The LLM judge and
`SimulationGoalsCriterion` now report an error with the real exception message when every
sample fails. Reports that relied on the 0.5 placeholder will show errors until the judge
model and key are fixed. `aclose()` stats also include `cleanup_tasks`.
- **Realtime tool calls are deduplicated per thread.** A call replayed after a reconnect, or repeated by a new session on the same thread, returns the recorded result and does not run the tool again. The key is the thread id, a hash of the tool name and arguments, and the provider call id. This needs a checkpointer on the session. `GeminiLiveClient` also takes `connect_timeout` (default 30 s), so a connect that hangs fails after 30 seconds. See [Tool call deduplication](/docs/reference/python/realtime#tool-call-deduplication).
- **New opt-in LLM limits, all off by default:** `stream_idle_timeout` (per agent, `set_default_stream_idle_timeout()` or `TENXGRAPH_LLM_STREAM_IDLE_TIMEOUT`; a stalled stream raises `LLMStreamIdleTimeoutError`) and the cross-process cap on `RetryConfig` (`distributed_max_concurrent_calls` and related fields; it fails open with a WARNING when Redis is down). See [Errors and limits](/docs/concepts/errors-and-limits).
- **`LiveAgent.arun()` raises `RuntimeError` when the same instance already runs a session.** `arealtime()` runs each connection on its own copy (`LiveAgent.new_session()`). If you call `arun()` yourself, give each concurrent session its own `new_session()`.
Expand Down Expand Up @@ -210,6 +229,10 @@ npm install 10xgraph-client@next
- **The checkpointer's Redis pool is capped at 50 connections** and a caller past the cap waits up
to 5 s for a free one, instead of opening a new connection. Raise `max_connections` or
`timeout` through `redis_pool_config` if a busy worker needs more.
- **`PgCheckpointer` skips Redis for a cool-down after a connection failure.** The new kwarg
`redis_breaker_cooldown` (seconds, default `5.0`, `0` disables) makes it use its Postgres
fallback at once instead of waiting for the connect timeout on every Redis call. Checkpointers
also gain `aput_cache_value_if_absent`; a custom checkpointer inherits a get-then-put fallback.
- **A thread stored at a node the graph no longer has fails with `StoredNodeMissingError`**
(`GRAPH_NODE_MISSING_001`, API 409), naming the node and the thread. After renaming a node, add
`compile(node_aliases={"old": "new"})`. Stored state written by a newer version raises
Expand All @@ -235,6 +258,10 @@ npm install 10xgraph-client@next
make their own ids (CopilotKit does by default) must set `"runs": {"thread_ids": "client"}`.
The TypeScript client reads the live id into `session.threadId`, which is `string | null`
until `session_started` arrives.
- **Writes during a run return 409.** `PUT` and `DELETE /v1/threads/{thread_id}/state`,
`POST /v1/threads/{thread_id}/messages`, `DELETE` of a thread message or a thread, and
`POST /v1/graph/fix` are refused at once while a run holds the thread. Retry after the run ends
or stop it first.
- **Client dicts and lists have size caps:** 1000 keys per object, 10000 items per list and
200000 values in all, beside the 64-level depth cap. A larger body gets 422. The thread id
rule now also covers the WebSocket `config.thread_id`, the live init frame and the AG-UI
Expand Down Expand Up @@ -371,7 +398,7 @@ The extras raise these floors. A fresh install resolves them; an existing enviro

After upgrading, before sending production traffic:

1. `10xgraph version` reports 1.0.0rc1 for core and the CLI.
1. `10xgraph version` reports 1.0.0rc2 for core and the CLI.
2. The server starts with `MODE=production` and explicit `ALLOWED_HOST` and `ORIGINS`.
3. A new conversation without a `thread_id` succeeds, and a client-invented id for a new thread
gets 403 (unless you set `runs.thread_ids` to `"client"`).
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/reference/error-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ The server maps exceptions to responses in `tenxgraph_api/src/app/core/exception

A `429` is not a core exception either. The server returns it when the `rate_limit` window is used up (`error.code` `RATE_LIMIT_EXCEEDED`, with a `Retry-After` header) or when one user has more than `runs.max_concurrent_per_user` runs in flight (standard body, code `HTTPException`, no `Retry-After`).

In production the message of a 5xx response is replaced by a generic text and the real error goes to the server log. Messages of 4xx `HTTPException` errors are kept. Handled 4xx errors are logged at `WARNING` with no traceback, and 5xx errors at `ERROR` with the traceback, so alert rules for 4xx traffic must match `WARNING` (`10xgraph-api` 1.0.0rc1). A missing checkpointer answers `503` (`Checkpointer is not configured`), a thread state update with a bad `context` answers `422`, and a message id missing from a thread answers `404`.
In production the message of a 5xx response is replaced by a generic text and the real error goes to the server log. Messages of 4xx `HTTPException` errors are kept. Handled 4xx errors are logged at `WARNING` with no traceback, and 5xx errors at `ERROR` with the traceback, so alert rules for 4xx traffic must match `WARNING` (`10xgraph-api` 1.0.0rc2). A missing checkpointer answers `503` (`Checkpointer is not configured`), a thread state update with a bad `context` answers `422`, and a message id missing from a thread answers `404`.

A `409` with the message `thread is busy` is not a core exception. The server returns it when another run is still active on the thread after 30 seconds. It uses the standard error body (`error.code` `HTTPException`), not the `state_conflict` shape.

Expand Down
Loading
Loading