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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to this project are documented in this file.

## 0.3.6

- A session that loads the history while a turn runs, with a page that starts after that turn's
question, no longer adds the question again at the end of `history` when the box sends the
running turn's `stepStart` on connecting. The question is one of the older rows, and `loadOlder`
brings it in its place, once. Before, it showed at the end in the middle of the turn and, after
`loadOlder`, twice (mitra-core-sdk#140).

## 0.3.5

- A tab that sends a message to the queue of a chat whose turn runs, before its socket said a turn
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Em `functionsAdmin`, `FunctionVersion.code` pode ser `null` quando o token permi
- Turno e tempo de entrega: quem decide se a mensagem entra no turno em andamento ou ganha turno próprio é a box, não o tempo local da SDK. Um `stepStart` com `turnId` sem turno rodando abre o turno com o `content` limpo, e o `accepted` sai no frame que nomeia a mensagem. Frames que chegam juntos num tick dão os mesmos eventos que frames espaçados.
- Pergunta do agente no meio do turno: o T3 pode pedir uma resposta à pessoa. O pedido chega como evento `raw` de tipo `user_input_request`, com o item do T3 no `payload` (perguntas e `requestId`); o turno fica esperando, sem prazo da SDK. Responda com `session.respondUserInput(requestId, answers, attachmentsByQuestionId?)`, que vai direto para a box. Se a box recusar a resposta, sai um `error` e o turno continua; com o canal direto fora (reconectando ou chat sem box), a resposta não é enviada e sai um `error` dizendo isso, para o app mandar de novo depois do `channelConnected`.
- Provedores e uso: `agentCredentials.providers(agentId?, options?)` devolve os provedores em que o próximo turno pode rodar, como o Copilot monta numa chamada só (`GET /api/v1/models/providers`, com `MODEL_READ` e `CREDENTIAL_READ`): um por provedor nativo e um por provedor personalizado de `listModels(agentId)`, na ordem do catálogo, cada um com `provider`, `providerName` (o nome do personalizado, `null` no nativo), `models` e `usage` (a mesma leitura de `usage(provider)`, só nos nativos). A SDK devolve a lista como veio. `usage` vem `null` no provedor personalizado, sem janela reportada, com chave de API e quando o Copilot não conseguiu ler a assinatura: a falha dessa leitura não derruba a lista. Com `agentId`, os modelos são os da conexão do agente e a leitura continua sendo a do login da pessoa. Precisa do Copilot com a mitra-copilot#549; um Copilot sem a rota responde 404, que rejeita a chamada.
- Conversa anterior: `agentTasks.listMessages(id, { before })` lê só as linhas gravadas antes da mensagem `before` (o id dela), então a página de trás não anda quando chegam linhas novas. `session.hasOlder` diz se o Copilot tem linhas antes da linha mais antiga do `history`, pela última página lida (a do `loadHistory` também), e `session.loadOlder()` lê a página de trás dela com o tamanho que o `loadHistory` usou e põe antes do `history`, na ordem da box. Resolve com os itens que acrescentou (nenhum quando não há mais, sem chamar o Copilot) e emite `historyLoaded`. Um `loadOlder` que ainda estava lendo quando o `history` foi trocado (um `loadHistory`, a recuperação de turno) descarta o que leu; a recuperação relê as linhas mais novas e o `loadOlder` volta a ler a partir delas. O Copilot diz que há mais quando a página tem outra depois dela (`totalPages > number + 1`), e responde 404 a um `before` de outra conversa ou que não existe, que rejeita a chamada. Precisa do Copilot com a mitra-copilot#549; um Copilot sem ela ignora o `before` e devolve as linhas mais novas.
- Conversa anterior: `agentTasks.listMessages(id, { before })` lê só as linhas gravadas antes da mensagem `before` (o id dela), então a página de trás não anda quando chegam linhas novas. `session.hasOlder` diz se o Copilot tem linhas antes da linha mais antiga do `history`, pela última página lida (a do `loadHistory` também), e `session.loadOlder()` lê a página de trás dela com o tamanho que o `loadHistory` usou e põe antes do `history`, na ordem da box. Resolve com os itens que acrescentou (nenhum quando não há mais, sem chamar o Copilot) e emite `historyLoaded`. Um `loadOlder` que ainda estava lendo quando o `history` foi trocado (um `loadHistory`, a recuperação de turno) descarta o que leu; a recuperação relê as linhas mais novas e o `loadOlder` volta a ler a partir delas. O Copilot diz que há mais quando a página tem outra depois dela (`totalPages > number + 1`), e responde 404 a um `before` de outra conversa ou que não existe, que rejeita a chamada. A fala de um turno que já rodava quando o `history` foi carregado, e que ficou antes da página, não volta no fim quando a box reenvia o `stepStart` desse turno ao conectar: ela é uma das linhas de trás e entra pelo `loadOlder`, no lugar dela (#140). Precisa do Copilot com a mitra-copilot#549; um Copilot sem ela ignora o `before` e devolve as linhas mais novas.
- Portão de rollout da 0.3.0: ela só entra nas SDKs de app (`platform-sdk` e SDK de Functions) quando o ambiente tiver zero box antiga (template do fork `experimental`). A box antiga trata a mensagem do meio do turno como início de turno novo, zera o uso e a identidade do turno, e nada disso aparece como erro. A SDK não distingue box antiga de box nova; o portão é o bump nas SDKs de app, que fixam a versão exata desta.
- Abrir o chat no meio de uma run (F5): o `session({ taskId })` carrega o histórico e pede à box o replay a partir de onde ele termina, o maior `lastSequence` (ou `sequence`, quando a linha não traz `lastSequence`) do `boxLog` mais novo, com o mesmo pedido que o redial já faz e antes de qualquer frame ao vivo. O que o Copilot ainda não gravou chega no replay, e nada do histórico vem duas vezes. No socket, a decisão é a mesma do redial, pelo `hello` da box: se o `boxLog` do canal for outro que o do histórico (o Copilot sobe o `boxLog` quando a box troca de thread) ou o `lastSequence` do `hello` for menor que esse ponto, o log é outro e o replay começa do início dele. No HTTP, decide só pelo `boxLog`, antes de abrir o stream. O cursor do canal começa no ponto do replay, então uma queda no meio dele pede de novo só o que faltou. Histórico sem `sequence` não pede replay, como antes.
- O `open()` do seu `eventSource` só deve resolver depois que o stream estiver conectado, para nenhum evento do turno se perder.
Expand Down
5 changes: 5 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ publishes.

## Versions

- `0.3.6` is the `0.3.5` parity surface with a fix in the agent session: the question of a turn
that runs while the history loads no longer comes back at the end of a page that starts after it.
Same parity cases; the version exists so a consumer pinning the package can pin a corpus with the
same number.

- `0.3.5` is the `0.3.4` parity surface with a fix in the agent session: a tab that sends to the
queue of a chat whose turn runs ends that turn, and `FunctionVersion.code` accepts `null` when the
Functions API redacts source. Same parity cases; the version exists so a
Expand Down
7 changes: 6 additions & 1 deletion contracts/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract": "SDK-PARITY-001",
"current": "0.3.5",
"current": "0.3.6",
"versions": [
{
"version": "0.1.0",
Expand Down Expand Up @@ -160,6 +160,11 @@
"version": "0.3.5",
"path": "v0.3.5/sdk-parity.json",
"sha256": "e67d7b52b81cd1dca0958b60c72976015567773e6ed8dc6e7dc7dba55af047e4"
},
{
"version": "0.3.6",
"path": "v0.3.6/sdk-parity.json",
"sha256": "d1ca3c736deba9cb5c91c8dcb342821d942b424e1394b3edd0a59833e4ee294c"
}
]
}
Loading
Loading