This is an automated email from the ASF dual-hosted git repository. kaxil pushed a commit to branch anthropic-agent-config-docs in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 087b040a5be177e57aa908ff6a4fe4720f03af89 Author: Kaxil Naik <[email protected]> AuthorDate: Wed Aug 12 01:10:27 2026 +0530 Document Anthropic advisor rosters and pinned inference regions Anthropic SDK 0.121.0 adds two agent-level settings: an ``advisor`` entry for a coordinator's multiagent roster, and ``inference_geo`` on the model config for pinning which region serves inference. Both reach the API through ``AnthropicHook.create_agent``'s existing keyword passthrough, so they need no provider code -- only documentation, since nothing in the guide says they are available. Both payload shapes are verified against the live API rather than read off the SDK types. That mattered: the first attempt omitted ``multiagent.type: "coordinator"`` and was rejected with ``multiagent.type: Field required``, so documenting from the type definitions alone would have shipped a payload that 400s. Also records the roster constraints the API enforces (1-20 distinct entries, at most one advisor, referenced agents may not themselves set ``multiagent``) and that ``model`` is whole-object replacement on update, so omitting ``inference_geo`` clears it instead of preserving it. The measured budget-overshoot range in the session-budget warning widens to $0.32-$0.61 across four runs, now that the deferrable end-to-end run has added a fourth data point. --- providers/anthropic/docs/operators/anthropic.rst | 59 ++++++++++++++++++++++ .../airflow/providers/anthropic/hooks/anthropic.py | 12 +++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/providers/anthropic/docs/operators/anthropic.rst b/providers/anthropic/docs/operators/anthropic.rst index 0537ed42408..23c64e79f43 100644 --- a/providers/anthropic/docs/operators/anthropic.rst +++ b/providers/anthropic/docs/operators/anthropic.rst @@ -283,6 +283,65 @@ task's real outcome is preserved and a warning is logged. session records instead. This is the same scenario as the retry warning above, so ``retries=0`` keeps both problems away. +Configuring the agent +""""""""""""""""""""" + +Agent-level settings are not operator arguments: they belong to the agent, which is created +once and referenced by ID on every run. +:meth:`~airflow.providers.anthropic.hooks.anthropic.AnthropicHook.create_agent` forwards +keyword arguments to the API unchanged, so these need no provider support. + +**Pinning the inference region.** Pass ``model`` as a config object instead of a bare id to +confine inference to one region: + +.. code-block:: python + + hook.create_agent( + name="us-only-analyst", + model={"id": "claude-opus-5", "inference_geo": "us"}, + ) + +An unsupported value is rejected with a 400 naming the accepted set; see `Data residency +<https://platform.claude.com/docs/en/manage-claude/data-residency>`__ for the regions +Anthropic currently serves and the workspace-level controls. When ``inference_geo`` is unset, +requests fall through to the workspace's +``default_inference_geo``. On an update, ``model`` is whole-object replacement, so omitting +``inference_geo`` clears it rather than preserving it. + +The pin is re-checked against the workspace allowlist when the agent is saved, when a +session is created, and on every turn a session serves -- so narrowing the allowlist stops +running sessions, not just new ones. + +In a ``multiagent`` configuration the coordinator's pin and every roster member's must all +be set to the same value, or all be unset -- a mismatch is rejected. Following both this and +the roster example below on one agent is the easy way to trip that. + +**Adding an advisor.** A coordinator agent can consult a second model mid-turn by adding an +``advisor`` entry to its ``multiagent`` roster: + +.. code-block:: python + + hook.create_agent( + name="coordinator", + model="claude-opus-5", + multiagent={ + "type": "coordinator", + "agents": [ + worker_agent_id, + {"type": "advisor", "model": "claude-opus-5"}, + ], + }, + ) + +``type: "coordinator"`` on the ``multiagent`` object is required and the request is rejected +without it. The roster takes 1 to 20 entries, each an agent ID +string, a versioned ``{"type": "agent", "id": ..., "version": ...}`` reference, +``{"type": "self"}`` for recursive self-invocation, or an ``advisor``. Referenced agents +must exist, must be distinct, must not be archived, and must not themselves set +``multiagent`` (depth limit 1); at most one ``self`` and at most one ``advisor``. The +advisor occupies the roster name ``anthropic.advisor``, and its model must be permitted as +an advisor for the coordinator's own model. + .. exampleinclude:: /../tests/system/anthropic/example_anthropic_agent.py :language: python :dedent: 4 diff --git a/providers/anthropic/src/airflow/providers/anthropic/hooks/anthropic.py b/providers/anthropic/src/airflow/providers/anthropic/hooks/anthropic.py index f3e250c572c..0096b95ff12 100644 --- a/providers/anthropic/src/airflow/providers/anthropic/hooks/anthropic.py +++ b/providers/anthropic/src/airflow/providers/anthropic/hooks/anthropic.py @@ -57,6 +57,7 @@ if TYPE_CHECKING: BetaManagedAgentsAgent, BetaManagedAgentsBudgetLimitParam, BetaManagedAgentsSession, + agent_create_params, environment_create_params, ) from anthropic.types.beta.sessions import BetaManagedAgentsEventParams @@ -589,16 +590,21 @@ class AnthropicHook(BaseHook): # (these helpers, the ``ant`` CLI, or a setup script) and store the IDs. The # operator references those IDs; it never creates an agent per run. - def create_agent(self, name: str, model: str | None = None, **kwargs: Any) -> BetaManagedAgentsAgent: + def create_agent( + self, name: str, model: str | dict[str, Any] | None = None, **kwargs: Any + ) -> BetaManagedAgentsAgent: """ Create a (reusable, versioned) Managed Agents agent. One-time setup. ``model`` defaults to :attr:`default_model` (the connection's ``extra['model']`` - or :data:`DEFAULT_MODEL`). + or :data:`DEFAULT_MODEL`). Pass a mapping instead of a bare id to set the model + config, e.g. ``{"id": "claude-opus-5", "inference_geo": "us"}``. """ self._require_first_party("Managed Agents") agent = self._first_party_conn.beta.agents.create( - name=name, model=model or self.default_model, **kwargs + name=name, + model=cast("agent_create_params.Model", model or self.default_model), + **kwargs, ) self.log.debug("Created agent %s (name=%r, model=%s)", agent.id, name, model or self.default_model) return agent
