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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR
- Nos providers do LangChain, a tentativa seguinte a uma resposta recusada pela validação do modelo Pydantic, inclusive por validadores próprios, leva ao modelo a resposta e os erros por campo, com pedido de correção; antes, repetia o mesmo prompt. A recusa levanta `ProviderRejectedOutputError`, transitória por classe, e deixa de ser lida como erro HTTP quando o texto analisado tem números como 404. Os tokens das tentativas recusadas são somados ao uso da linha quando a resposta os traz, o que inclui a OpenAI, pela resposta HTTP anexada ao erro do SDK (#144).
- A docstring de `dataframeit()` e a mensagem de rate limit descrevem `rate_limit_delay` como a pausa de cada worker depois de cada linha processada com sucesso, com teto de `parallel_requests * 60 / rate_limit_delay` linhas por minuto.
- No provider `codex`, chaves do schema que não restringem o valor, como anotações próprias em `json_schema_extra` e os metadados `examples` e `deprecated`, são descartadas com aviso em vez de recusadas; keywords de validação fora do subconjunto do Structured Outputs continuam recusadas.
- No provider `codex`, o preflight recusa `format` fora da lista do Structured Outputs, como os de `bytes`, `Path`, `AnyUrl` e `UUID4`, e `pattern` com lookahead, lookbehind ou referência a grupo, como o de `Decimal`. Antes, o schema passava, e cada linha falhava no turno: a API recusa esse `format` e o lookaround com HTTP 400 `invalid_json_schema`, e com referência a grupo o turno gera texto até `max_output_tokens` (#158).
- No provider `codex`, o preflight recusa `format` fora da lista do Structured Outputs, como os de `bytes`, `Path`, `AnyUrl` e `UUID4`, e `pattern` com lookahead, lookbehind ou referência a grupo, como o que o pydantic anterior à 2.14 gera para `Decimal`. Antes, o schema passava, e cada linha falhava no turno: a API recusa esse `format` e o lookaround com HTTP 400 `invalid_json_schema`, e com referência a grupo o turno gera texto até `max_output_tokens` (#158).
- Com `resume=True` e `checkpoint_path` existente, rodar a mesma chamada de novo continua do checkpoint, sem carregá-lo à mão; antes, a execução recomeçava e o sobrescrevia. `<checkpoint>.dataframeit.json`, gravado a cada gravação do checkpoint, guarda a assinatura da execução, o hash do texto de cada linha e o do próprio arquivo, e o checkpoint só é retomado quando os três batem; com outra configuração ou entrada, a execução avisa e recomeça como antes. Das linhas concluídas, com sucesso ou com erro, vêm também os campos do modelo, sobre o que a entrada trazia neles.
- No provider `codex`, o app-server roda com `HOME` no diretório isolado da execução, e as skills do usuário, como as de `~/.agents/skills`, deixam de ser carregadas.
- Com `search_per_field=True`, o modo por grupo também devolve `search_provider` no uso, e o modo por campo devolve os campos na ordem do modelo, como o modo por grupo. O campo pulado por condição é registrado uma vez no log, e não duas.
Expand Down
2 changes: 1 addition & 1 deletion docs/en/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ result = dataframeit(
)
```

For this provider, `model_kwargs` accepts only `effort` and `timeout`. `effort` takes one of the values the SDK declares: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`; each model accepts only some of them. `timeout` is the deadline, in seconds, for each attempt, from opening the thread to the end of the turn, with a default of 600: a turn that does not finish in time is interrupted, the attempt fails with `ProviderTransientError`, and the row is retried according to `max_retries`. If the deadline runs out before the app-server answers the request that opens the thread or the turn, the app-server is shut down and the run stops with `ProviderAbortError`; rows without a status are left for `resume=True`. With `timeout=None`, there is no deadline. Changing `timeout` does not prevent resuming a checkpoint. `use_search=True` is not supported. The Pydantic model must have fields at the root and use the [JSON Schema subset accepted by Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas); `RootModel`, `Any`, dynamic-key `dict` fields, validation keywords outside the subset, such as those of fixed tuples, sets, and `min_length`/`max_length` on strings, `format` values outside the supported list, such as those of `bytes`, `Path`, `AnyUrl`, and `UUID4`, and `pattern` values with lookahead, lookbehind, or backreferences, such as the one of `Decimal`, are rejected during preflight. Keys that do not constrain the value, such as custom annotations in `json_schema_extra` and the `examples` and `deprecated` metadata, are dropped from the schema sent, with a warning listing them; the response is still validated by the Pydantic model. Authentication configured during installation comes from `auth.json`, so do not pass `api_key` to `dataframeit()`.
For this provider, `model_kwargs` accepts only `effort` and `timeout`. `effort` takes one of the values the SDK declares: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`; each model accepts only some of them. `timeout` is the deadline, in seconds, for each attempt, from opening the thread to the end of the turn, with a default of 600: a turn that does not finish in time is interrupted, the attempt fails with `ProviderTransientError`, and the row is retried according to `max_retries`. If the deadline runs out before the app-server answers the request that opens the thread or the turn, the app-server is shut down and the run stops with `ProviderAbortError`; rows without a status are left for `resume=True`. With `timeout=None`, there is no deadline. Changing `timeout` does not prevent resuming a checkpoint. `use_search=True` is not supported. The Pydantic model must have fields at the root and use the [JSON Schema subset accepted by Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas); `RootModel`, `Any`, dynamic-key `dict` fields, validation keywords outside the subset, such as those of fixed tuples, sets, and `min_length`/`max_length` on strings, `format` values outside the supported list, such as those of `bytes`, `Path`, `AnyUrl`, and `UUID4`, and `pattern` values with lookahead, lookbehind, or backreferences, such as the one pydantic before 2.14 generates for `Decimal`, are rejected during preflight. Keys that do not constrain the value, such as custom annotations in `json_schema_extra` and the `examples` and `deprecated` metadata, are dropped from the schema sent, with a warning listing them; the response is still validated by the Pydantic model. Authentication configured during installation comes from `auth.json`, so do not pass `api_key` to `dataframeit()`.

With `model`, the library checks at startup, through a thread with no turn, that the runtime resolved the requested model, and fails before the first row if it did not; without `model`, a warning says which model will be used. A turn that the runtime reroutes to another model is interrupted, and the row fails. `effort` is sent with each turn and does not come back in the runtime's response, so it is not checked.

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ resultado = dataframeit(
)
```

Para esse provider, `model_kwargs` aceita somente `effort` e `timeout`. O `effort` recebe um dos valores que o SDK declara: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` e `ultra`; cada modelo aceita só parte deles. O `timeout` é o prazo, em segundos, de cada tentativa, da abertura da thread ao fim do turno, com padrão de 600: o turno que não termina no prazo é interrompido, a tentativa falha com `ProviderTransientError` e a linha é repetida conforme `max_retries`. Se o prazo acaba antes de o app-server responder à abertura da thread ou do turno, o app-server é encerrado e a execução para com `ProviderAbortError`; as linhas sem status ficam para `resume=True`. Com `timeout=None`, não há prazo. Trocar o `timeout` não impede retomar um checkpoint. `use_search=True` não é suportado. O modelo Pydantic deve ter campos no nível raiz e usar o [subconjunto de JSON Schema aceito por Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas); `RootModel`, `Any`, campos `dict` com chaves dinâmicas, keywords de validação fora do subconjunto, como as de tuplas fixas, `set` e `min_length`/`max_length` em texto, `format` fora da lista suportada, como os de `bytes`, `Path`, `AnyUrl` e `UUID4`, e `pattern` com lookahead, lookbehind ou referência a grupo, como o de `Decimal`, são rejeitados no preflight. Chaves que não restringem o valor, como as anotações próprias em `json_schema_extra` e os metadados `examples` e `deprecated`, são descartadas do schema enviado, com um aviso que as lista; a resposta continua validada pelo modelo Pydantic. A autenticação configurada durante a instalação vem de `auth.json`, portanto não passe `api_key` ao `dataframeit()`.
Para esse provider, `model_kwargs` aceita somente `effort` e `timeout`. O `effort` recebe um dos valores que o SDK declara: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` e `ultra`; cada modelo aceita só parte deles. O `timeout` é o prazo, em segundos, de cada tentativa, da abertura da thread ao fim do turno, com padrão de 600: o turno que não termina no prazo é interrompido, a tentativa falha com `ProviderTransientError` e a linha é repetida conforme `max_retries`. Se o prazo acaba antes de o app-server responder à abertura da thread ou do turno, o app-server é encerrado e a execução para com `ProviderAbortError`; as linhas sem status ficam para `resume=True`. Com `timeout=None`, não há prazo. Trocar o `timeout` não impede retomar um checkpoint. `use_search=True` não é suportado. O modelo Pydantic deve ter campos no nível raiz e usar o [subconjunto de JSON Schema aceito por Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas); `RootModel`, `Any`, campos `dict` com chaves dinâmicas, keywords de validação fora do subconjunto, como as de tuplas fixas, `set` e `min_length`/`max_length` em texto, `format` fora da lista suportada, como os de `bytes`, `Path`, `AnyUrl` e `UUID4`, e `pattern` com lookahead, lookbehind ou referência a grupo, como o que o pydantic anterior à 2.14 gera para `Decimal`, são rejeitados no preflight. Chaves que não restringem o valor, como as anotações próprias em `json_schema_extra` e os metadados `examples` e `deprecated`, são descartadas do schema enviado, com um aviso que as lista; a resposta continua validada pelo modelo Pydantic. A autenticação configurada durante a instalação vem de `auth.json`, portanto não passe `api_key` ao `dataframeit()`.

Com `model`, a biblioteca confere na abertura, por uma thread sem turno, que o runtime resolveu o modelo pedido, e falha antes da primeira linha se não resolveu; sem `model`, um aviso diz qual modelo será usado. Um turno que o runtime reroteia para outro modelo é interrompido, e a linha falha. O `effort` vai em cada turno e não volta na resposta do runtime, então não é conferido.

Expand Down
18 changes: 14 additions & 4 deletions tests/test_codex.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from collections.abc import Callable
from datetime import date, datetime, timedelta
from datetime import time as time_type
from decimal import Decimal
from ipaddress import IPv4Address, IPv6Address
from pathlib import Path
from typing import Annotated, Any, Literal
Expand Down Expand Up @@ -552,11 +551,22 @@ def test_format_que_nao_e_texto_e_recusado(self, formato):
_to_strict_json_schema(schema)

def test_pattern_do_decimal_e_recusado_pelo_lookahead(self):
class Modelo(BaseModel):
valor: Decimal
# O pattern que o pydantic emite para Decimal até a 2.13, escrito aqui
# porque da 2.14 em diante o schema do tipo não traz pattern.
schema = {
"type": "object",
"properties": {
"valor": {
"anyOf": [
{"type": "number"},
{"type": "string", "pattern": r"^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$"},
]
}
},
}

with pytest.raises(ProviderConfigurationError, match="lookahead"):
_to_strict_json_schema(Modelo.model_json_schema())
_to_strict_json_schema(schema)

@pytest.mark.parametrize(
("pattern", "construcao"),
Expand Down
Loading