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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ Confirm the following limitations before use:

- The built-in LLM call chain is uniformly exposed as an OpenAI adaptation layer.
- The LLM prompt resources are built in and do not support custom extension (`prompts` and `errors` are always read from the built-in resources).
- Negotiation session state travels in the message metadata (the SDK is stateless) and no negotiation state store is provided; the legacy state-machine negotiation APIs (`start_negotiation` / `receive_negotiation` / `continue_negotiation`) are deprecated since 1.1.0.
- Negotiation session state travels in the message metadata (the SDK is stateless) and no negotiation state store is provided; the legacy state-machine negotiation APIs (`start_negotiation` / `receive_negotiation` / `continue_negotiation`) were deprecated since v1.1.0 and removed in v1.2.0.
- Bundled resources and language coverage are limited, and remote resource loading such as `registry-center` (the registry center) is not included.
- This document mainly introduces the SDK itself and does not cover CLI tools, hosted services, deployment flows, or ready-to-use application solutions.

Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ uv run mypy src # 类型检查

- 内置 LLM 调用链对外统一为 OpenAI 适配层。
- 大模型提示词资源已内置,不支持自定义扩展(`prompts` 与 `errors` 始终从内置资源加载)。
- 协商会话状态随消息 metadata 往返(SDK 无状态),不提供协商状态存储;旧的状态机协商 API(`start_negotiation` / `receive_negotiation` / `continue_negotiation`)自 1.1.0 起废弃。
- 协商会话状态随消息 metadata 往返(SDK 无状态),不提供协商状态存储;旧的状态机协商 API(`start_negotiation` / `receive_negotiation` / `continue_negotiation`)自 v1.1.0 起废弃,已在 v1.2.0 版本删除。
- 随包资源与语言覆盖有限,不包含 `registry-center`(注册中心)等远程资源加载能力。
- 本文档主要介绍 SDK 本身,不涉及 CLI、托管服务、部署流程或可直接使用的应用方案。

Expand Down
3 changes: 0 additions & 3 deletions a2a-t-sample/env.example
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,3 @@ A2AT_LLM_SESSION_MAX_PER_PROVIDER=100
# the dedicated logger a2a_t.llm.call is enabled for DEBUG; where the lines are printed is
# decided by the embedding application's logging framework.
A2AT_LLM_DETAIL_LOG_ENABLED=false

# Negotiation
A2AT_NEGOTIATION_STATE_STORE_TYPE=in_memory
2 changes: 1 addition & 1 deletion docs/en/API_Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The A2A-T SDK exposes only two entry points: the client entry `A2ATClient` (prom

- Some APIs involve LLM calls. When using them, control the call frequency and concurrency based on the concurrency the connected model service can provide and your business latency requirements.
- APIs involving LLM calls apply length protection to `text` inputs: when the input exceeds `A2AT_INPUT_TEXT_MAX_CHARS` configured in `.env` (the `package_data/.env` or the file pointed to by `env_path`), the error code `input.text_too_long` is reported; the default of this configuration item is 16384 (16×1024). Structured data that does not involve LLM calls is not limited.
- The SDK is stateless: negotiation session state travels with the A2A-T metadata (`negotiationContext`) of each message and is not stored inside the SDK; the legacy `start_negotiation` / `receive_negotiation` / `continue_negotiation` state-machine negotiation APIs are deprecated since 1.1.0, emit a `DeprecationWarning` when called, and will be removed in the next release.
- The SDK is stateless: negotiation session state travels with the A2A-T metadata (`negotiationContext`) of each message and is not stored inside the SDK; the legacy `start_negotiation` / `receive_negotiation` / `continue_negotiation` state-machine negotiation APIs were deprecated since v1.1.0, emitted a `DeprecationWarning` when called, and were removed in v1.2.0.

## 1.3 API Descriptions

Expand Down
3 changes: 1 addition & 2 deletions docs/en/developer_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ flowchart TD
1. Python 3.12+ is required.
2. Complete multi-agent protocol interaction development also requires the `a2a-sdk`, version 1.1.0+.
3. The SDK is stateless: negotiation session state travels with the A2A-T metadata (`negotiationContext`) of each message and is not stored inside the SDK.
4. The legacy state-machine negotiation demo (`start_negotiation` / `receive_negotiation` / `continue_negotiation` and the `negotiation/{types,store,runtime,handling}` packages) is deprecated since 1.1.0 (calls emit a `DeprecationWarning`) and will be removed in the next release.
4. The legacy state-machine negotiation demo (`start_negotiation` / `receive_negotiation` / `continue_negotiation` and the `negotiation/{types,store,runtime,handling}` packages): the state-machine negotiation APIs were deprecated since v1.1.0, emitted a `DeprecationWarning` when called, and were removed in v1.2.0.
5. The A2A-T SDK does not provide an agent HTTP service framework, a registry-center client, or authentication and key management capabilities; these must be integrated by the business system.

## 1.3 Environment Preparation
Expand Down Expand Up @@ -1521,4 +1521,3 @@ The sample configuration file provided by the SDK is `env.example`; copy it to `
| `A2AT_LLM_SESSION_MAX_PER_PROVIDER` | Maximum number of tracked sessions per provider, default `100` |
| `A2AT_LLM_MAX_ATTEMPTS` | Maximum number of attempts for retryable LLM steps, range 1-10 (out-of-range values are clipped), default `3` |
| `A2AT_LLM_DETAIL_LOG_ENABLED` | Whether to print the complete LLM request/response messages (not truncated), default `false`; enabling it may print sensitive information or consume log space, use only in the DEBUG phase and keep it off in production; time/token/elapsed-time summary logs are emitted at DEBUG level by the dedicated logger `a2a_t.llm.call`, see 1.6 |
| `A2AT_NEGOTIATION_STATE_STORE_TYPE` | Negotiation state store of the deprecated state-machine negotiation demo (`in_memory`); the 1.1.0 negotiation content API is stateless and does not use this key |
2 changes: 1 addition & 1 deletion docs/zh/API参考.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ A2A-T SDK 对外仅提供两个入口:客户端入口 `A2ATClient`(提示词

- 部分接口涉及到LLM调用,使用时需根据对所接模型服务可提供的并发能力,结合业务时限要求,控制使用API时的调用频率和并发。
- 涉及到LLM调用的API针对文本`text`输入会做长度防护,在输入超过`.env`(`package_data/.env` 或 `env_path` 指向的文件)中配置的 `A2AT_INPUT_TEXT_MAX_CHARS` 字符时,会报错误码 `input.text_too_long` ,该配置项默认配置为 16384(16×1024);不涉及LLM调用的结构化数据不受此限制。
- SDK 无状态:协商会话状态随每条消息的 A2A-T metadata(`negotiationContext`)往返,不保存在 SDK 内部;旧的 `start_negotiation` / `receive_negotiation` / `continue_negotiation` 状态机协商 API 自 1.1.0 起废弃,调用时发出 `DeprecationWarning`,将在下一版本删除。
- SDK 无状态:协商会话状态随每条消息的 A2A-T metadata(`negotiationContext`)往返,不保存在 SDK 内部;旧的 `start_negotiation` / `receive_negotiation` / `continue_negotiation` 状态机协商 API 自 v1.1.0 起废弃,调用时发出 `DeprecationWarning`,已在 v1.2.0 版本删除。

## 1.3 API说明

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/开发指南.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ flowchart TD
1. Python 版本要求为 3.12+。
2. 完整的多智能体协议交互开发需要同时引入`a2a-sdk`,要求版本为 1.1.0+。
3. SDK 无状态:协商会话状态随每条消息的 A2A-T metadata(`negotiationContext`)往返,不保存在 SDK 内部。
4. 旧的状态机协商 demo(`start_negotiation` / `receive_negotiation` / `continue_negotiation` 以及 `negotiation/{types,store,runtime,handling}` 包):状态机协商 API 自 v1.1.0 起废弃,调用时发出 `DeprecationWarning`,已在 v1.2.0 版本删除。
5. A2A-T SDK 不提供 Agent HTTP 服务框架、注册中心客户端、鉴权和密钥管理能力,需由业务系统集成。

## 1.3 环境准备
Expand Down Expand Up @@ -1512,4 +1513,3 @@ SDK提供的样例配置文件为`env.example`,复制为 `package_data/.env`
| `A2AT_LLM_SESSION_MAX_PER_PROVIDER` | 单提供方会话跟踪数上限,默认 `100` |
| `A2AT_LLM_MAX_ATTEMPTS` | 可重试 LLM 步骤的最大尝试次数,取值范围 1-10(越界自动裁剪),默认 `3` |
| `A2AT_LLM_DETAIL_LOG_ENABLED` | 是否打印 LLM 请求/响应的完整报文(不截断),默认 `false`;开启后可能打印敏感信息或占用日志空间,仅限 DEBUG 阶段使用、正式运行必须关闭;时间/Token/耗时等摘要日志由专用 logger `a2a_t.llm.call` 以 DEBUG 级输出,详见 1.6 |
| `A2AT_NEGOTIATION_STATE_STORE_TYPE` | 已废弃状态机协商 demo 的协商状态存储(`in_memory`);1.1.0 协商内容 API 无状态,不使用该键 |
4 changes: 0 additions & 4 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ A2AT_LLM_MAX_ATTEMPTS=3
# decided by the embedding application's logging framework.
A2AT_LLM_DETAIL_LOG_ENABLED=false

# Negotiation
# Selects the negotiation state store implementation (legacy state-machine demo, deprecated).
A2AT_NEGOTIATION_STATE_STORE_TYPE=in_memory

# Live-LLM corpus tests (dev only; fully decoupled from the production A2AT_LLM_* keys)
# Base URL of the live endpoint used by the live corpus family; the family skips when unset.
A2AT_TEST_LLM_BASE_URL=
Expand Down
4 changes: 0 additions & 4 deletions package_data/env.example
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,3 @@ A2AT_LLM_MAX_ATTEMPTS=3
# the dedicated logger a2a_t.llm.call is enabled for DEBUG; where the lines are printed is
# decided by the embedding application's logging framework.
A2AT_LLM_DETAIL_LOG_ENABLED=false

# Negotiation
# Selects the negotiation state store implementation (legacy state-machine demo, deprecated).
A2AT_NEGOTIATION_STATE_STORE_TYPE=in_memory
92 changes: 8 additions & 84 deletions src/a2a_t/client/a2at_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@
twelve negotiation content methods
of the shared :class:`~a2a_t.negotiation.generation.content_service.NegotiationContentService`
(eight generation plus four validation methods) and the extension-agnostic template queries of the
:class:`~a2a_t.common.prompt_resources.catalog.TemplateQueryService`. The three legacy
``start/receive/continue_negotiation`` methods of the deprecated state-machine negotiation demo
are kept for one release with a :class:`DeprecationWarning` and will be removed in the next
release (port decision D1).
:class:`~a2a_t.common.prompt_resources.catalog.TemplateQueryService`.
"""

from __future__ import annotations

import logging
import warnings
from collections.abc import Mapping
from pathlib import Path
from typing import Any
Expand All @@ -27,7 +23,6 @@
from a2a_t.core.validation_pipeline import FilledParamData
from a2a_t.llm.config_loader import LLMConfigLoader
from a2a_t.llm.factory import LLMClientFactory
from a2a_t.negotiation.common.models import ContinueNegotiationInput, StartNegotiationInput
from a2a_t.negotiation.content.models import (
NegotiationAbortData,
NegotiationEndingData,
Expand All @@ -37,7 +32,6 @@
from a2a_t.observability.llm_decorator import A2ATLLMClientDecorator
from a2a_t.observability.negotiation_metrics import report_terminal_negotiation_rounds

from .negotiation.negotiation_orchestrator_builder import ClientNegotiationOrchestratorBuilder
from .prompt_generation.models import PromptGenerationResult
from .prompt_generation.prompt_generation_orchestrator_builder import PromptGenerationOrchestratorBuilder

Expand All @@ -60,17 +54,6 @@ def _default_env_path() -> Path:
return Path(__file__).resolve().parents[3] / "package_data" / ".env"


def _deprecation_message(method: str) -> str:
"""Return the D1 deprecation message of one legacy negotiation facade method."""
return (
f"A2ATClient.{method} is deprecated since 1.1.0 and will be removed in the next release; "
"the state-machine negotiation demo it belongs to is retired. Use the negotiation content "
"API instead: generate_negotiation_{propose,accept,reject,abort}_prompt_from_data / "
"..._from_text and validate_{propose,accept,reject,abort}_prompt_and_data_filling, backed "
"by a2a_t.negotiation.generation.NegotiationContentService."
)


def _parse_template_uri(template_uri: str | TemplateUri | None) -> TemplateUri:
"""Parse the raw template URI string boundary fail-fast (D16, Java ``parseTemplateUri``).

Expand Down Expand Up @@ -111,10 +94,6 @@ class A2ATClient:
hand-written URI strings. Business failures are raised as catalog-coded exceptions of the
:mod:`a2a_t.core.errors.exceptions` tree (catch :class:`~a2a_t.core.errors.exceptions.A2ATError`
and branch on ``code_str``); programming errors stay ``TypeError`` / ``ValueError``.

The three legacy ``start/receive/continue_negotiation`` methods of the retired state-machine
negotiation demo are kept for one release with a :class:`DeprecationWarning` and will be
removed in the next release.
"""

def __init__(
Expand All @@ -125,18 +104,18 @@ def __init__(
) -> None:
"""Create one client facade from a ``.env`` file.

The configuration, the LLM client and both orchestrators are resolved eagerly so that a
misconfiguration surfaces at construction instead of on the first call. The negotiation
content service and the template query service are assembled lazily on first use: both
capture resource snapshots at that point, so constructing the facade stays side-effect free
for the prompt-only flows.
The configuration and the LLM client are resolved eagerly so that a misconfiguration
surfaces at construction instead of on the first call. The negotiation content service and
the template query service are assembled lazily on first use: both capture resource
snapshots at that point, so constructing the facade stays side-effect free for the
prompt-only flows.

Args:
env_path: path of the ``.env`` file carrying the SDK configuration; ``None`` uses the
packaged ``package_data/.env`` default. The resolved file must exist — copy
``env.example`` to ``.env`` first (every key is optional, an empty file works).
logger: optional logger injected into the LLM client and the orchestrators; ``None``
uses each component's module-level logger.
logger: optional logger injected into the LLM client and the prompt generation
orchestrator; ``None`` uses each component's module-level logger.

Raises:
ConfigFileNotFoundError: when the resolved ``.env`` path does not exist.
Expand All @@ -155,10 +134,6 @@ def __init__(
llm_client=self._llm_client,
logger=logger,
)
self._negotiation_orchestrator = ClientNegotiationOrchestratorBuilder().build(
env_path=resolved_env_path,
logger=logger,
)
# Lazily assembled negotiation content service and template query service: both capture
# resource snapshots at first use, so constructing the facade stays side-effect free for
# the prompt-only flows. Tests may inject either seam before the first call.
Expand Down Expand Up @@ -381,57 +356,6 @@ def generate_notification_prompt_from_data_with_schema(
data, schema, _parse_template_uri(template_uri)
)

def start_negotiation(self, input: StartNegotiationInput) -> dict[str, object]:
"""Start a client-side negotiation round.

Deprecated (D1): the state-machine negotiation demo is retired; this method emits a
:class:`DeprecationWarning`, forwards to the legacy orchestrator unchanged, and will be
removed in the next release. Use the negotiation content API instead —
:meth:`generate_negotiation_propose_prompt_from_data` and its siblings.

Args:
input: legacy negotiation start input.

Returns:
the legacy orchestrator's round result as a plain mapping.
"""
warnings.warn(_deprecation_message("start_negotiation"), DeprecationWarning, stacklevel=2)
return self._negotiation_orchestrator.start_negotiation(input)

def receive_negotiation(self, message: str, context: dict[str, object]) -> dict[str, object]:
"""Process a negotiation message received from the remote peer.

Deprecated (D1): the state-machine negotiation demo is retired; this method forwards to the
legacy orchestrator unchanged and will be removed in the next release. Use the negotiation
content API instead — :meth:`validate_propose_prompt_and_data_filling` and its siblings.

Args:
message: received negotiation message text.
context: legacy negotiation context mapping.

Returns:
the legacy orchestrator's round result as a plain mapping.
"""
warnings.warn(_deprecation_message("receive_negotiation"), DeprecationWarning, stacklevel=2)
return self._negotiation_orchestrator.receive_negotiation(message, context)

def continue_negotiation(self, input: ContinueNegotiationInput) -> dict[str, object]:
"""Continue an existing negotiation with a local response.

Deprecated (D1): the state-machine negotiation demo is retired; this method forwards to the
legacy orchestrator unchanged and will be removed in the next release. Use the negotiation
content API instead — :meth:`generate_negotiation_accept_prompt_from_data` and its
siblings.

Args:
input: legacy negotiation continuation input.

Returns:
the legacy orchestrator's round result as a plain mapping.
"""
warnings.warn(_deprecation_message("continue_negotiation"), DeprecationWarning, stacklevel=2)
return self._negotiation_orchestrator.continue_negotiation(input)

# ------------------------------------------------------------------
# Negotiation content generation (from data: deterministic, zero LLM)
# ------------------------------------------------------------------
Expand Down
7 changes: 0 additions & 7 deletions src/a2a_t/client/negotiation/__init__.py

This file was deleted.

17 changes: 0 additions & 17 deletions src/a2a_t/client/negotiation/negotiation_orchestrator.py

This file was deleted.

Loading
Loading