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 docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ ANTHROPIC_API_KEY="..."
ANTHROPIC_MODEL="claude-..."
```

`ANTHROPIC_BASE_URL` and `ANTHROPIC_MAX_TOKENS` are optional. Anthropic uses the Agent Framework model client automatically.
`ANTHROPIC_BASE_URL` and `ANTHROPIC_MAX_TOKENS` are optional. Microsoft Agent Framework is the default model client for all providers starting with Co-op Translator 0.22.0. Semantic Kernel can still be selected temporarily with `CO_OP_TRANSLATOR_MODEL_CLIENT="semantic-kernel"`, but doing so emits a deprecation warning; see [configuration](configuration.md#model-client-backend) for the staged removal plan.

Required Azure AI Vision variables for image translation:

Expand Down
14 changes: 8 additions & 6 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,19 @@ The tool auto-detects providers in this order:
2. OpenAI
3. Anthropic

If no provider is configured, `translate`, `evaluate`, `migrate-links`, and `run_translation` fail during configuration checks. `co-op-review` and `run_review` are deterministic maintenance checks and do not require provider credentials.
If no provider is configured, `translate`, `evaluate`, and `run_translation` fail during configuration checks. `migrate-links`, `co-op-review`, and `run_review` are deterministic maintenance operations and do not require provider credentials.

## Model client backend

Azure OpenAI and OpenAI use Semantic Kernel by default. Anthropic uses the [Microsoft Agent Framework Anthropic integration](https://github.com/microsoft/agent-framework/tree/main/python/packages/anthropic) automatically. To select Agent Framework explicitly, set:
Starting with Co-op Translator 0.22.0, Azure OpenAI, OpenAI, and Anthropic use Microsoft Agent Framework by default. No backend setting is required for normal use.

Semantic Kernel remains available temporarily for compatibility. To select it explicitly, set:

```bash
CO_OP_TRANSLATOR_MODEL_CLIENT="agent-framework"
CO_OP_TRANSLATOR_MODEL_CLIENT="semantic-kernel"
```

Supported values are `semantic-kernel` and `agent-framework`. Anthropic requires `agent-framework`; explicitly selecting `semantic-kernel` with Anthropic fails with a configuration error. Invalid values fail during provider-backed translator initialization instead of silently falling back.
Using Semantic Kernel emits a deprecation warning. The package is planned to move Semantic Kernel to an optional dependency in 0.23.0 and remove the integration in 0.24.0, subject to compatibility results and user feedback. Anthropic requires `agent-framework`; explicitly selecting `semantic-kernel` with Anthropic fails with a configuration error. Invalid values fail during provider-backed translator initialization instead of silently falling back. Follow the rollout and report blockers in [GitHub issue #543](https://github.com/Azure/co-op-translator/issues/543).

## Azure OpenAI

Expand Down Expand Up @@ -97,7 +99,7 @@ ANTHROPIC_BASE_URL="..." # optional; omit for the Anthropic API
ANTHROPIC_MAX_TOKENS="8192" # optional; output token limit per request
```

`ANTHROPIC_API_KEY` and `ANTHROPIC_MODEL` are required. You do not need to set `CO_OP_TRANSLATOR_MODEL_CLIENT`; Anthropic selects Agent Framework automatically.
`ANTHROPIC_API_KEY` and `ANTHROPIC_MODEL` are required. You do not need to set `CO_OP_TRANSLATOR_MODEL_CLIENT`; Agent Framework is the default backend.

`ANTHROPIC_MAX_TOKENS` defaults to `8192`, which leaves room for token-dense scripts such as Meitei Mayek. Lower it if your model or Anthropic-compatible endpoint caps output below that.

Expand Down Expand Up @@ -143,7 +145,7 @@ OpenAI and Anthropic support the same suffix convention. Keep every variable in
| `translate -img` | Yes | Yes | Translates images only. |
| `translate` with no type flags | Yes | Yes | Default mode includes Markdown, notebooks, and images. |
| `evaluate` | Yes | No | Uses LLM evaluation unless `--fast` is selected. |
| `migrate-links` | Yes | No | Performs link migration, but still runs shared configuration checks. |
| `migrate-links` | No | No | Performs local link migration without provider calls. |
| `co-op-review` | No | No | Runs deterministic translation structure, freshness, Markdown, notebook, and local link checks. |
| `run_translation(markdown=True)` | Yes | No | Programmatic Markdown translation. |
| `run_translation(images=True)` | Yes | Yes | Programmatic image translation. |
Expand Down
2 changes: 2 additions & 0 deletions src/co_op_translator/core/llm/model_clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from co_op_translator.core.llm.model_clients.factory import (
MODEL_CLIENT_ENV_VAR,
ModelClientBackend,
SemanticKernelDeprecationWarning,
create_translation_model_client,
get_model_client_backend,
)
Expand All @@ -21,6 +22,7 @@
"MODEL_CLIENT_ENV_VAR",
"ModelClientBackend",
"ModelResponse",
"SemanticKernelDeprecationWarning",
"SemanticKernelModelClient",
"StructuredTranslationModelClient",
"TranslationModelClient",
Expand Down
27 changes: 16 additions & 11 deletions src/co_op_translator/core/llm/model_clients/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from enum import Enum
import os
import warnings

from co_op_translator.config.llm_config.azure_openai import AzureOpenAIConfig
from co_op_translator.config.llm_config.anthropic import AnthropicConfig
Expand All @@ -12,14 +13,18 @@
MODEL_CLIENT_ENV_VAR = "CO_OP_TRANSLATOR_MODEL_CLIENT"


class SemanticKernelDeprecationWarning(FutureWarning):
"""Warn that the Semantic Kernel model client is being phased out."""


class ModelClientBackend(str, Enum):
SEMANTIC_KERNEL = "semantic-kernel"
AGENT_FRAMEWORK = "agent-framework"


def get_model_client_backend() -> ModelClientBackend:
value = os.getenv(
MODEL_CLIENT_ENV_VAR, ModelClientBackend.SEMANTIC_KERNEL.value
MODEL_CLIENT_ENV_VAR, ModelClientBackend.AGENT_FRAMEWORK.value
).strip()
normalized = value.lower().replace("_", "-")
try:
Expand All @@ -37,21 +42,21 @@ def create_translation_model_client(
*,
backend: ModelClientBackend | None = None,
) -> TranslationModelClient:
selected_backend = backend or _default_backend_for_provider(provider)
selected_backend = backend or get_model_client_backend()
if selected_backend == ModelClientBackend.SEMANTIC_KERNEL:
warnings.warn(
"The Semantic Kernel model client is deprecated in Co-op Translator "
"0.22.0. It will become an optional dependency in 0.23.0 and is "
"planned for removal in 0.24.0. Unset "
f"{MODEL_CLIENT_ENV_VAR} or set it to "
f"'{ModelClientBackend.AGENT_FRAMEWORK.value}'.",
SemanticKernelDeprecationWarning,
stacklevel=2,
)
return _create_semantic_kernel_client(provider)
return _create_agent_framework_client(provider)


def _default_backend_for_provider(provider: LLMProvider) -> ModelClientBackend:
configured_backend = os.getenv(MODEL_CLIENT_ENV_VAR)
if configured_backend is not None:
return get_model_client_backend()
if provider == LLMProvider.ANTHROPIC:
return ModelClientBackend.AGENT_FRAMEWORK
return ModelClientBackend.SEMANTIC_KERNEL


def _create_semantic_kernel_client(
provider: LLMProvider,
) -> TranslationModelClient:
Expand Down
30 changes: 16 additions & 14 deletions tests/co_op_translator/core/llm/model_clients/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
MODEL_CLIENT_ENV_VAR,
AgentFrameworkModelClient,
ModelClientBackend,
SemanticKernelDeprecationWarning,
SemanticKernelModelClient,
create_translation_model_client,
get_model_client_backend,
)


def test_model_client_backend_defaults_to_semantic_kernel(monkeypatch):
def test_model_client_backend_defaults_to_agent_framework(monkeypatch):
monkeypatch.delenv(MODEL_CLIENT_ENV_VAR, raising=False)

assert get_model_client_backend() == ModelClientBackend.SEMANTIC_KERNEL
assert get_model_client_backend() == ModelClientBackend.AGENT_FRAMEWORK


def test_model_client_backend_accepts_agent_framework_alias(monkeypatch):
Expand All @@ -36,32 +37,33 @@ def test_model_client_backend_rejects_unknown_value(monkeypatch):
def test_factory_creates_semantic_kernel_adapters(provider, monkeypatch):
monkeypatch.setenv(MODEL_CLIENT_ENV_VAR, "semantic-kernel")
config_values = _patch_provider_config(provider)
with config_values:
with (
config_values,
pytest.warns(
SemanticKernelDeprecationWarning,
match="deprecated.*0.22.0.*optional dependency.*0.23.0.*removal.*0.24.0",
),
):
client = create_translation_model_client(provider)

assert isinstance(client, SemanticKernelModelClient)


@pytest.mark.parametrize("provider", list(LLMProvider))
def test_factory_creates_agent_framework_adapters(provider, monkeypatch):
monkeypatch.setenv(MODEL_CLIENT_ENV_VAR, "agent-framework")
def test_factory_defaults_to_agent_framework_adapters(provider, monkeypatch):
monkeypatch.delenv(MODEL_CLIENT_ENV_VAR, raising=False)
config_values = _patch_provider_config(provider)
with config_values:
client = create_translation_model_client(provider)

assert isinstance(client, AgentFrameworkModelClient)


def test_anthropic_defaults_to_agent_framework(monkeypatch):
monkeypatch.delenv(MODEL_CLIENT_ENV_VAR, raising=False)
with _patch_provider_config(LLMProvider.ANTHROPIC):
client = create_translation_model_client(LLMProvider.ANTHROPIC)

assert isinstance(client, AgentFrameworkModelClient)


def test_anthropic_rejects_semantic_kernel_backend():
with pytest.raises(ValueError, match="Agent Framework"):
with (
pytest.warns(SemanticKernelDeprecationWarning),
pytest.raises(ValueError, match="Agent Framework"),
):
create_translation_model_client(
LLMProvider.ANTHROPIC,
backend=ModelClientBackend.SEMANTIC_KERNEL,
Expand Down
Loading