Ctrl K
ComunidadGuías…

docs/model-capabilities.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Model effort capabilities

The backend resolves thinking effort through a versioned capability declaration
before admitting a Run. The resolved provider value and transport are recorded in
the environment specification and used when constructing the model. For a model
registered in the catalog or an override, an explicitly requested unsupported
effort is rejected instead of silently becoming `medium`.

## Capability sources

Resolution uses the first applicable source:

1. A provider/model-scoped `extra_params.model_capability` override.
1. An exact provider/model entry in the catalog, except for Codex subscription
   authentication, which retains its existing adapter mapping.
1. The Codex subscription adapter or the legacy OpenAI/Azure adapter rules.
1. An unknown-model result when no capability has been registered.

The built-in catalog is
`backend/app/workspace_config/model_capabilities.json`. Set
`EIGENT_MODEL_CAPABILITY_CATALOG` to a complete replacement catalog to register
additional models without changing Python code. A replacement is not merged with
the built-in catalog. Loading the catalog does not call a provider.

Catalog entries match `model_platform` and `model_type` after trimming whitespace
and normalizing case. Azure deployment aliases need their own exact entry or
scoped override; their capabilities are not inferred from the alias.

The built-in `gpt-6-astra` and `gpt-6-luna` entries for OpenAI and Azure preserve
all five selectable effort values, including `max`. They select Responses when
tools are present, including when effort is omitted or Cloud metadata still
selects Chat Completions. Luna's provider default enables reasoning, so omitting
the effort parameter does not make Chat Completions with tools compatible. See
the [Luna API contract](https://developers.openai.com/api/docs/models/gpt-6-luna).
This does not add `none` to the application's persisted effort enum or silently
disable reasoning. Deployment aliases still need scoped declarations. These are
application declarations; the mocked tests do not establish support for a
particular live Azure deployment. Consult the provider's model/deployment contract
before registering a deployment.

The built-in `gpt-6-sol` entries for OpenAI and Azure declare `low`, `medium`,
and `high` only, with `medium` as the default and the same Responses selection
for tools. `xhigh` and `max` stay unsupported until confirmed for this model.

Do not bump the catalog's top-level `revision` when adding an entry. It is part
of every catalog entry's capability digest, so a bump would block Resume for
every interrupted attempt on an existing entry (see Revisions and resume).

Legacy OpenAI/Azure prefix rules remain compatibility fallbacks. New models should
use a catalog entry or override. Because a prefix match only infers the supported
efforts, such a model runs a requested effort outside them at the nearest
supported one (for example `xhigh` at `high`) and records both the requested and
the effective effort, instead of failing admission. The existing Codex subscription mapping of
`max` to `xhigh` is unchanged. The historical product alias `ultra` normalizes to
the product effort `max`; `ultra` is not forwarded as a provider value.

## Declaration format

The following example registers a fictitious deployment. Its supported values
must be replaced with the deployment's actual contract.

```json
{
  "schema_version": 1,
  "revision": "example-catalog-v1",
  "models": [
    {
      "schema_version": 1,
      "revision": "example-deployment-v1",
      "model_platform": "azure",
      "model_type": "example-deployment",
      "supported_efforts": ["low", "medium", "high", "xhigh", "max"],
      "default_effort": "medium",
      "provider_mapping": {
        "low": "low",
        "medium": "medium",
        "high": "high",
        "xhigh": "xhigh",
        "max": "max"
      },
      "transport_parameters": {
        "chat_completions": "reasoning_effort",
        "responses": "reasoning.effort"
      },
      "default_transport": "chat_completions",
      "tools_transport": "responses"
    }
  ]
}
```

For a request-specific override, put the individual object from `models` under
`extra_params.model_capability`. Do not include the surrounding catalog object.
This reserved initializer field is consumed locally and never forwarded to CAMEL
or the provider request body. It must match the selected provider/model. Do not put
credentials, endpoint URLs, or local paths in capability metadata.

Both catalog and entry schemas reject unknown fields. Entries require unique
supported efforts, a supported default, a complete provider mapping, and a valid
parameter name for every declared transport. Provider values are restricted to
`low`, `medium`, `high`, `xhigh`, and `max`. Revisions contain only letters, digits,
periods, underscores, and hyphens. Invalid metadata produces a configuration error
without echoing its raw values or local catalog path.

## Admission and provider requests

Task admission assumes agents can use function tools and pins a compatible
transport. The runtime capability manifest records the capability source,
revision, supported values, mapping, selected transport, and any unknown-model
diagnostic. These fields contain no credentials.

An unknown model always runs at its provider default, and the snapshot reports
`unknown_model`. An effort requested by the application (the input box, a
Session or Space setting, or a Bundle model profile) does not block the Run and
is not sent: the requested effort is recorded, while the persisted effective
`medium` enum remains a compatibility sentinel and `provider_default` with the
diagnostic indicates that no effort was established or sent. This applies to new
tasks, follow-ups, Resume, and managed Agent configurations. A model registered
in the catalog or an override still fails admission with a structured HTTP 422
`unsupported_thinking_effort` response for an effort it does not support.
Invalid capability metadata returns HTTP 422 `invalid_model_capability`.

At model construction, a registered model's admitted effort takes precedence
over conflicting effort fields in provider configuration, including
`extra_body`. The helper normalizes the supported effort locations into the
selected transport:

| Transport        | Provider request field |
| ---------------- | ---------------------- |
| Chat Completions | `reasoning_effort`     |
| Responses        | `reasoning.effort`     |

Responses-only reasoning options, such as a summary, remain in the Responses
`reasoning` object. They are rejected for Chat Completions. Responses requests drop
Chat-specific `stream_options`. An `extra_body.model` override is rejected because
it would invalidate the capability scope. Conflicting unpinned effort values are
also rejected, as are raw provider effort values outside a registered model's
mapping.

For an unknown model, an effort written into the user's own provider
configuration (`reasoning_effort`, `thinking_effort`, `reasoning.effort`, or the
same fields in `extra_body`) is sent as written in the selected transport's
field, because the user owns that endpoint; it is not checked against a mapping.
The same applies whenever the admitted value is `provider_default`, which is only
admitted for an unknown model. The structural checks above still apply. Eigent
Cloud requests for an unknown model never carry such an effort and are rejected
instead.

A custom agent model resolves its own effort. It does not inherit the task's
admitted effort; a provider/model/endpoint change also discards an inherited
capability override unless the custom agent supplied its own initializer settings.
An explicitly supplied override must still match that agent's provider/model.
Responses instruction and input/image conversion remain owned by their existing
adapters, outside the effort helper.

## Revisions and resume

The capability digest includes the selected source, provider/model, authentication
source, mappings, transport, metadata, and applicable catalog revision. Changes to
these inputs can invalidate the existing resume capability check, including for
attempts created with an older capability digest format. This change does not
rewrite historical attempts or bypass that check. Start a new Run when an older
attempt cannot satisfy the current capability contract.

One case may resume across a digest change: an attempt admitted for an
unregistered model, which sent no effort of its own, after that model gains a
catalog entry. Resume keeps the pinned provider default, including an effort
from the user's own provider configuration, so its requests do not change.
It is allowed only when the current capability comes from the catalog, the
pinned transport equals the current one, and resolving the current inputs with
no catalog entries reproduces the pinned digest. A change of authentication
source, override, or transport is still refused.

## Anthropic tool compatibility

CAMEL emits tool-level `strict` flags. The native Anthropic API supports them,
but some Anthropic Messages-compatible routes reject the field, even when its
value is `false`. The shared model and validation factories install a narrow
compatibility adapter for CAMEL's Anthropic backend:

- Send the original request first, preserving strict tools on supporting routes.
- Only when HTTP 400 explicitly rejects `tools.N.custom.strict` (or
  `tools.N.strict`) as an extra input, retry that request once with the custom
  tools' top-level `strict` fields omitted.
- Preserve tool definitions, argument schemas, messages, thinking parameters,
  and structured-output configuration. A parameter named `strict` inside a
  tool's `input_schema` is not removed.
- Remember the omission only after a successful retry, on that model instance.
  Do not modify shared SDK clients or maintain a global model-name override.
- Do not retry unrelated errors, a failed compatibility retry, or errors raised
  while consuming a response stream. Tools that were already executed are not
  replayed by this adapter.

The retry logs that strict tool constraints are unavailable. It does not supply
grammar-constrained tool arguments on the incompatible route. Structured-output
errors remain errors; this adapter does not disable output schemas. If a gateway
injects `strict` after the client's request, that gateway must be fixed: the
adapter only retries when the rejected field was present in the outgoing tool.
OpenAI-compatible and Bedrock Converse backends retain their existing adapters.

## Mock verification

Use the backend's installed Python environment and run from `backend`:

```sh
python -B tests/run_isolated.py --fast-test-mode \
  tests/app/workspace_config \
  tests/app/model/test_effort.py \
  tests/app/model/test_anthropic_tools.py \
  tests/app/model/test_model_platform.py \
  tests/app/model/test_codex_subscription_runtime.py \
  tests/app/agent/test_agent_model.py \
  tests/app/agent/test_model_effort_pipeline.py \
  tests/app/run_journal/test_model_capture.py \
  tests/app/run_journal/test_model_invocations.py \
  tests/app/controller/test_model_effort_admission.py \
  tests/app/controller/test_chat_controller.py \
  tests/app/controller/test_run_stream_lifecycle.py \
  tests/app/workspace_bundle/test_workspace_bundle_runtime.py \
  tests/app/component/test_model_validation.py \
  tests/app/controller/test_model_controller.py -q -rs
```

The runner redirects user-state lookups to a temporary directory, disables dotenv
loading and model telemetry, and blocks in-process socket connections and DNS. It
is intended for unit/mock suites and does not sandbox subprocesses. The pipeline
tests use the real CAMEL adapter and OpenAI SDK with `httpx.MockTransport`; they
check synchronous and asynchronous request serialization without live provider
calls. Live deployment behavior and human acceptance require separate validation.