Documentação

Referência da API

O ollaya serve expõe duas APIs em http://localhost:11435:

  • a API nativa em /api/*, modelada na do Ollama, para decisões e gestão de modelos;
  • a API compatível com o TypeSafe em /v1/*, idêntica ao nível do protocolo à do TypeSafe, para que os SDKs TypeSafe existentes funcionem sem alterações. Vê Compatibilidade com o TypeSafe.
Método Caminho Finalidade
GET, HEAD / Verificação de atividade (liveness): Ollaya is running
GET /api/version Versão do servidor
POST /api/decide Responde a perguntas tipadas sobre um estado; também carrega e descarrega um modelo
GET /api/tags Modelos nesta máquina
POST /api/show Detalhes de um modelo
GET /api/ps Modelos carregados em memória
POST /api/pull Descarrega um modelo (transmite o progresso)
DELETE /api/delete Elimina um modelo
POST /api/copy Copia um modelo para um novo nome
POST /api/create Cria um modelo a partir de outro (transmite o progresso)
POST /v1/systemone System One do TypeSafe
POST /v1/decisions Alias de /v1/systemone
GET /v1/models Lista de modelos do TypeSafe

/api/push e /api/blobs/:digest estão reservados e respondem 501 NOT_IMPLEMENTED. Os endpoints de texto do Ollama (/api/generate, /api/chat, /api/embed) respondem 404: os modelos de decisão nunca geram texto.

Convenções

  • JSON. Os corpos de pedido e resposta são objetos JSON. O corpo é analisado como JSON independentemente do Content-Type, por isso curl -d funciona tal como está. Os pedidos têm no máximo 8 MiB.
  • Os nomes dos campos usam snake_case. Campos de pedido desconhecidos são ignorados; null significa ausente.
  • Os nomes dos modelos são [host/][namespace/]model[:tag], sem distinção de maiúsculas e minúsculas. Uma tag em falta significa latest. As respostas usam sempre a forma canónica, como laya:latest.
  • Números. Probabilidades, confianças, score e noul são arredondados a 4 casas decimais. As durações são inteiros em nanossegundos; as marcas temporais são RFC 3339 em UTC.
  • Streaming. /api/pull e /api/create transmitem JSON delimitado por novas linhas, um objeto por linha, terminando com exatamente um {"status":"success"} ou uma linha de erro. Envia "stream": false para obteres uma única resposta.
  • IDs de pedido. Todas as respostas transportam X-Request-Id, e as respostas de /v1/* também x-typesafe-request-id. Um X-Request-Id válido enviado pelo cliente é ecoado.
  • Concorrência. Um modelo carregado executa um pedido de cada vez, e cada pedido responde a todas as suas perguntas numa única passagem. Os pedidos para o mesmo modelo ficam em fila, por isso enviar mais de um de cada vez não termina mais cedo; o tempo de ida e volta de cada um passa então a incluir a espera. Faz todas as perguntas sobre um estado num único pedido. Modelos carregados diferentes são executados em paralelo.
  • Nenhum download implícito. Nenhum endpoint descarrega um modelo como efeito secundário. O ollaya run descarrega primeiro; as aplicações chamam /api/pull.

Erros

Todo erro, em qualquer endpoint, tem este corpo:

{
  "error": "model \"laya:xl\" not found, try pulling it first",
  "code": "MODEL_NOT_FOUND"
}
Campo Significado
error Mensagem legível por humanos. Não a analises; a única mensagem congelada é model "<name>" not found, try pulling it first, como no Ollama.
code Código legível por máquina. Ramifica com base nele.
detail Apenas para INVALID_REQUEST, TOO_MANY_OPTIONS, INPUT_TOO_LONG e STATE_TRUNCATED: cada problema de validação, no formato ValidationError do TypeSafe (do FastAPI): loc, msg, type e às vezes ctx.
Código HTTP Quando Nova tentativa
INVALID_JSON 400 Corpo ausente, não é JSON ou não é um objeto não
INVALID_REQUEST 422 O corpo não passa na validação; detail lista cada problema não
TOO_MANY_OPTIONS 422 As opções de uma pergunta não cabem no orçamento de opções do modelo não
INPUT_TOO_LONG 422 O state tem mais de 65.536 tokens não
STATE_TRUNCATED 422 /v1/systemone ou /v1/decisions descartaria parte do state para caber no contexto do modelo não
UNAUTHORIZED 401 OLLAYA_API_KEY está definida e o pedido não traz a chave não
FORBIDDEN 403 Cabeçalho Origin ou Host do navegador não permitido não
MODEL_NOT_FOUND 404 Modelo (ou o destino de um router) não está nesta máquina; num download, não está no registo não
NOT_FOUND 404 Não existe esse endpoint não
METHOD_NOT_ALLOWED 405 O endpoint existe, o método não não
OPERATION_IN_PROGRESS 409 Um download ou uma criação está a escrever o mesmo nome de modelo depois de terminar
REQUEST_TOO_LARGE 413 Corpo acima de 8 MiB não
QUEUE_FULL 503 Já há OLLAYA_MAX_QUEUE pedidos à espera; enviado com Retry-After: 1 sim
MODEL_LOAD_FAILED 500 O modelo não pôde ser carregado (ficheiros corrompidos, memória, OLLAYA_LOAD_TIMEOUT) raramente
INFERENCE_FAILED 500 O runner falhou durante uma decisão sim
STORAGE_ERROR 500 Disco cheio, permissões ou I/O não
INTERNAL 500 Um bug; o log do servidor tem detalhes sob o ID do pedido sim
UNSUPPORTED_MODEL 501 Esta compilação não consegue executar o formato do modelo não
NOT_IMPLEMENTED 501 Endpoint reservado não
REGISTRY_ERROR 502 Registo inacessível ou inválido sim
DIGEST_MISMATCH 502 Um download não correspondeu ao seu sha256 e foi descartado sim

O conjunto de códigos é aberto: trata um código desconhecido pelo seu estado HTTP. Um erro de validação lista todos os problemas de uma vez:

{
  "error": "state: Field required; questions.urgency.score.criteria: List should have at least 2 items after validation, not 1",
  "code": "INVALID_REQUEST",
  "detail": [
    {"loc": ["body", "state"], "msg": "Field required", "type": "missing"},
    {
      "loc": ["body", "questions", "urgency", "score", "criteria"],
      "msg": "List should have at least 2 items after validation, not 1",
      "type": "too_short",
      "ctx": {"field_type": "List", "min_length": 2, "actual_length": 1}
    }
  ]
}

Depois de um stream começar, uma falha chega como última linha com o mesmo formato, por exemplo {"error": "…", "code": "DIGEST_MISMATCH"}. Verifica em cada linha se há error antes de a leres como progresso.

Perguntas

/api/decide, /v1/systemone e /api/create partilham um único esquema de perguntas, o do TypeSafe. Um pedido tem 1–256 perguntas, indexadas por qualquer id; as respostas voltam pela mesma ordem.

type instructions criteria Resposta
choice opcional obrigatório: objeto etiqueta → descrição, ou um array de etiquetas; 2–255 opções choice, confidence, probabilities
score opcional obrigatório: array de descrições de níveis, o nível 0 primeiro; 2–10 níveis score, confidence, legend, probabilities
noul opcional opcional: {"true": "…", "false": "…"} noul
  • instructions pode ser uma string, um objeto, um array ou null. Quando está ausente ou é null, o modelo lê o id da pergunta, por isso um id descritivo como is_spam funciona por si só.
  • state é uma string, um objeto ou um array, até 65.536 tokens. Se exceder o contexto disponível do modelo, /api/decide trunca-o e reporta state_truncated: true. /v1/systemone e /v1/decisions devolvem 422 STATE_TRUNCATED com o modelo que respondeu em detail[0].ctx.model.
  • Limites do modelo. Cada opção precisa de espaço no contexto do modelo: cerca de 125 opções para laya:en (512 tokens) e 250 para laya:multilingual (1.024). Mais do que isso é 422 TOO_MANY_OPTIONS. Para um router, aplicam-se os limites do destino.

As respostas têm os formatos do TypeSafe, nesta ordem de campos:

type Campos
choice choice: a etiqueta mais provável. confidence. probabilities: etiqueta → probabilidade, pela ordem de criteria.
score score: o nível esperado Σ i·pᵢ, que pode cair entre níveis. confidence. legend: "0"… → a descrição do nível. probabilities: "0"… → probabilidade.
noul noul: a probabilidade de a afirmação se verificar. Sem confidence, como no TypeSafe.

confidence é a probabilidade máxima normalizada do TypeSafe, (K · pmax − 1) / (K − 1) para K opções: 0 quando todas as opções são igualmente prováveis, 1 quando uma opção tem toda a probabilidade. A fórmula é a mesma para todos os modelos, mas o que uma dada confiança significa não é: os modelos são calibrados de forma diferente, por isso ajusta um limiar por modelo nos teus próprios dados. As probabilidades são calibradas com as temperaturas de cada modelo. Numa GPU CUDA corre o grafo fp16, cujas respostas podem diferir do fp32 em empates apertados.

keep_alive

Durante quanto tempo um modelo permanece carregado depois de um pedido terminar, com a semântica do Ollama:

Valor Significado
"5m", "1h30m", "300ms", 300, "300" Permanece carregado esse tempo após o pedido
0, "0", "0s" Descarrega assim que o pedido termina
-1, "-5m", qualquer valor negativo Permanece carregado até o servidor parar ou um descarregamento explícito
em falta ou null OLLAYA_KEEP_ALIVE, predefinição 5m

O cronómetro começa quando um pedido termina, e o valor do pedido mais recente prevalece. Para um router, aplica-se ao destino que respondeu. O /v1/* ignora keep_alive.

Decidir

POST /api/decide

Responde a perguntas tipadas sobre um estado numa única passagem direta. O corpo é o corpo de /v1/systemone mais opções nativas; a resposta é a resposta do TypeSafe mais campos nativos, por isso um cliente TypeSafe também a consegue analisar.

Campo Tipo Obrigatório Notas
model string sim Nome do modelo
state string, objeto ou array sim para decidir Sem ele, o pedido carrega ou descarrega o modelo (abaixo)
questions objeto sim, a menos que o modelo tenha perguntas incorporadas Substitui por completo as perguntas do próprio modelo
preset string não O nome de uma predefinição, incorporada ou personalizada, em vez de questions
images array de strings não Para um modelo de visão: imagens PNG, em base64 ou URLs data: em base64. Decider aceita uma; winnow:e4b-vision aceita até 16. Vê Imagens
keep_alive string ou number não Vê keep_alive
extras array de strings não ["laya"] adiciona a confiança própria e a probabilidade de ato do laya a cada resposta
stream boolean não Reservado; true é rejeitado
curl http://localhost:11435/api/decide -d '{
  "model": "laya",
  "state": "I was charged twice for my subscription this month. Please refund the second charge.",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this ticket?",
      "criteria": {
        "billing": "Payments, invoices and refunds",
        "technical": "Bugs, errors and outages",
        "account": "Login, profile and settings"
      }
    },
    "urgency": {
      "type": "score",
      "instructions": "How urgent is this ticket?",
      "criteria": ["Can wait", "Needs attention this week", "Needs attention today"]
    },
    "refund": {
      "type": "noul",
      "instructions": "The customer asks for money back.",
      "criteria": {"true": "Asks for a refund", "false": "Does not ask for a refund"}
    }
  },
  "keep_alive": "10m"
}'
{
  "model": "laya:en",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.7781,
      "probabilities": {"billing": 0.8521, "technical": 0.0611, "account": 0.0868}
    },
    "urgency": {
      "type": "score",
      "score": 1.1982,
      "confidence": 0.3418,
      "legend": {"0": "Can wait", "1": "Needs attention this week", "2": "Needs attention today"},
      "probabilities": {"0": 0.1203, "1": 0.5612, "2": 0.3185}
    },
    "refund": {"type": "noul", "noul": 0.9127}
  },
  "usage": {"input_tokens": 118, "output_tokens": 0},
  "routing": {
    "router": "laya:latest",
    "model": "laya:en",
    "route": "english",
    "reason": "English Latin text"
  },
  "state_truncated": false,
  "done_reason": "decide",
  "created_at": "2026-09-24T09:30:12.418Z",
  "total_duration": 18734512,
  "load_duration": 0,
  "eval_duration": 16302117
}
Campo Significado
model O modelo que respondeu: para um router, o seu destino (laya:en para um pedido de laya)
answers Id de pergunta → resposta, pela ordem das perguntas
usage input_tokens lidos; output_tokens é sempre 0
routing Para um router: router, o model escolhido, uma chave route estável e um reason informativo. null caso contrário.
state_truncated true se parte do estado foi descartada para caber no contexto do modelo
done_reason "decide", "load" ou "unload"
created_at Quando a resposta foi produzida
total_duration Nanossegundos desde a receção do pedido até à resposta, incluindo a fila
load_duration Nanossegundos gastos à espera que o modelo carregue; 0 quando já estava quente
eval_duration Nanossegundos no runner: tokenização, passagem direta, calibração

Com "extras": ["laya"], cada resposta tem também um objeto laya: confidence (a confiança do laya baseada em entropia) e act_probability (da cabeça de ato do modelo, ou null).

Imagens

Um modelo de visão (decider:2b-vision ou winnow:e4b-vision) responde a perguntas sobre uma imagem, além do estado. Envia a imagem em images, codificada em base64, tal como o images do Ollama funciona:

curl http://localhost:11435/api/decide -d '{
  "model": "decider:2b-vision",
  "state": "A photo from the warehouse camera.",
  "images": ["'"$(base64 -w0 shelf.png)"'"],
  "questions": {
    "blocked": {"type": "noul", "instructions": "Is the aisle blocked?"},
    "fill": {"type": "score", "instructions": "How full is the shelf?", "criteria": ["empty", "half full", "full"]}
  }
}'
  • Decider: Uma imagem por pedido, apenas PNG. O pré-processamento do modelo é reproduzido valor a valor, por isso os píxeis têm de corresponder ao que os autores do modelo descodificam. Os descodificadores de JPEG do Rust diferem do libjpeg-turbo até 4 níveis em alguns píxeis, por isso o JPEG ainda não é aceite: converte-o primeiro para PNG.
  • Decider: A imagem é redimensionada para múltiplos de 32 píxeis, como o modelo espera, e pode ter no máximo 4.096 patches de 16x16 píxeis depois disso, cerca de um megapíxel (1024x1024). Uma imagem maior recebe um 422 que o indica; reduz-a primeiro.
  • Decider: As perguntas aceitam no máximo 10 opções. O mesmo modelo também responde a pedidos só de texto.
  • Winnow E4B vision: até 16 PNG ordenados, 2–64 opções por pergunta, dentro do contexto combinado de imagem/estado/pergunta. O projetor correspondente é descarregado separadamente da mesma revisão do autor. As etiquetas de texto existentes do Winnow não o carregam.
  • Um modelo que não lê imagens responde a um pedido com images com um 422.

/v1/systemone e /v1/decisions permanecem idênticos à API do TypeSafe, que não tem campo de imagem.

Carregar e descarregar. Um pedido sem state e questions nunca decide. Sem keep_alive, ou com um valor positivo ou negativo, carrega o modelo (todos os destinos, no caso de um router) e devolve done_reason: "load". Com keep_alive: 0 descarrega-o ("unload"). O ollaya run pré-carrega deste modo, e o ollaya stop descarrega.

curl http://localhost:11435/api/decide -d '{"model": "laya:en", "keep_alive": -1}'
curl http://localhost:11435/api/decide -d '{"model": "laya:en", "keep_alive": 0}'

Uma decisão não tem efeito secundário sobre dados armazenados, por isso é seguro tentar de novo.

Predefinições

Uma predefinição é um conjunto nomeado de perguntas. Seis são incorporadas (triage, email, guard, moderation, router, agent), e podes guardar as tuas próprias. Envia "preset": "NAME" para /api/decide em vez de questions.

curl http://localhost:11435/api/presets/create -d '{
  "name": "billing-check",
  "description": "Billing, and how upset the customer is",
  "questions": {
    "billing": {"type": "noul", "instructions": "The message is about a charge, an invoice or a refund."},
    "tone": {"type": "choice", "instructions": "How does the customer sound?", "criteria": {"calm": null, "annoyed": null, "angry": null}}
  }
}'
curl http://localhost:11435/api/decide -d '{"model": "winnow:e4b", "state": "I was charged twice this month.", "preset": "billing-check"}'
Endpoint Corpo Efeito
GET /api/presets – Predefinições incorporadas, depois as personalizadas: name, builtin, description, ids de pergunta, modified_at
POST /api/presets/create name, questions, description (opcional) Guarda uma predefinição personalizada, substituindo uma com o mesmo nome
POST /api/presets/show name Uma predefinição com as suas perguntas
DELETE /api/presets/delete name Elimina uma predefinição personalizada

Os nomes têm de 1 a 64 caracteres de letras minúsculas, dígitos, - e _. Um nome incorporado não pode ser reutilizado (422) nem eliminado (403), e um nome desconhecido é um 404. As predefinições personalizadas são guardadas junto dos modelos, por isso todos os clientes do servidor veem as mesmas.

Routers

Um router como laya (laya:latest) não tem pesos: para cada pedido escolhe um dos seus destinos, que depois responde. O laya lê apenas o state:

Estado route Respondido por
Inglês english laya:en
Predominantemente escrita não latina (árabe, cirílico, CJK, …) multilingual laya:multilingual
Escrita latina, mas não inglês (turco, alemão, …) multilingual laya:multilingual
Nenhuma letra english (a predefinição) laya:en

Textos curtos em maiúsculas e sem letras acentuadas, como nomes de comerciantes num extrato de cartão (MIGROS KADIKOY ISTANBUL TR), SKUs ou nomes de utilizador, normalmente não podem ser identificados e vão para laya:en. Se sabes o idioma, pede laya:multilingual ou laya:en diretamente; o model da resposta diz qual checkpoint respondeu.

O encaminhamento custa microssegundos. Ramifica com base em route, nunca em reason, cujo texto pode mudar. O laya:typed-decisions nunca é escolhido pelo router; pede-o diretamente.

Listar modelos locais

GET /api/tags

Os modelos nesta máquina, do mais recente para o mais antigo. Cada entrada tem name, model (o mesmo), modified_at, size em bytes, digest (sha256 do manifesto, em hex simples) e details: parent_model, format (onnx, gguf ou router), family, families, parameter_size e quantization_level (as precisões que transporta, como F16/F32, ou a quantização de um modelo GGUF, como Q8_0).

{
  "models": [
    {
      "name": "laya:en",
      "model": "laya:en",
      "modified_at": "2026-09-24T08:11:02.117Z",
      "size": 853634822,
      "digest": "bf30e4654e9483ff1e6a4fe6fb21b8a71baff6c8a01013046e7d13339020efd7",
      "details": {
        "parent_model": "",
        "format": "onnx",
        "family": "laya",
        "families": ["laya"],
        "parameter_size": "421M",
        "quantization_level": "F16/F32"
      }
    }
  ]
}

Mostrar detalhes de um modelo

POST /api/show
curl http://localhost:11435/api/show -d '{"model": "laya:en"}'
Campo Significado
license Texto da licença
modelfile Um Modelfile que recria o modelo
parameters Parâmetros definidos no modelo, um name value por linha, como precision fp32
questions Perguntas incorporadas, ou null
router Para um router: strategy, default e routes (rota → modelo). null caso contrário.
details Como em /api/tags
model_info general.architecture, general.languages, general.source (o repositório fixado do Hugging Face), mais chaves específicas da família, como laya.context_length. general.languages lista os idiomas para os quais o modelo foi treinado e avaliado (multilingual para muitos); um modelo construído sobre uma base multilingue ainda pode ler outros idiomas, por isso mede nos teus dados.
capabilities Tipos de pergunta a que responde (choice, score, noul), mais act se tiver uma cabeça de ato
modified_at Como em /api/tags

Um router é mostrado como ele mesmo, não resolvido para um destino.

Listar modelos em execução

GET /api/ps

Os modelos carregados, ordenados por nome. Os routers nunca aparecem; os seus destinos carregados, sim. Cada entrada tem name, model, size (memória, RAM mais VRAM), digest, details (com a precisão realmente carregada: F16 ou F32, ou a quantização de um modelo GGUF), expires_at (quando será descarregado, ou null quando mantido carregado), size_vram, context_length e device (cpu, cuda:0, metal, …).

Descarregar um modelo

POST /api/pull
{"model": "laya:en"}

Descarrega o modelo para o armazenamento local e verifica cada blob em relação ao seu sha256. Descarregar um router descarrega também todos os modelos para os quais ele encaminha. Só são descarregadas as camadas de que esta máquina precisa, os blobs partilhados entre modelos são descarregados uma vez, e os downloads interrompidos são retomados.

A resposta transmite o progresso, com as cadeias de estado do Ollama:

{"status":"pulling manifest"}
{"status":"pulling 891102d37268","digest":"sha256:891102d372688fc2a094dac56a384bc537b87c63f21f9f3dac0be2b7cbc8d86c","total":842609210,"completed":420557117}
{"status":"pulling 891102d37268","digest":"sha256:891102d372688fc2a094dac56a384bc537b87c63f21f9f3dac0be2b7cbc8d86c","total":842609210,"completed":842609210}
{"status":"verifying sha256 digest"}
{"status":"writing manifest"}
{"status":"success"}

Um modelo só aparece em /api/tags depois de writing manifest. Para um router há um único success, mesmo no fim. Um nome que não é analisado, um modelo que não está no registo e um registo inacessível são erros HTTP comuns (422, 404, 502) antes de o stream começar, por isso curl --fail funciona. Com "stream": false a resposta é {"status": "success"} quando termina. Um segundo download do mesmo nome junta-se ao que está em curso. Seguro tentar de novo.

Eliminar um modelo

DELETE /api/delete
{"model": "triage"}

Elimina o nome, e os blobs que nenhum outro modelo usa. Um modelo carregado é descarregado assim que os seus pedidos terminam; eliminar um router mantém os seus destinos. A resposta é 200 com corpo vazio, e 404 MODEL_NOT_FOUND quando o nome não existe; após um timeout, trata isso como sucesso.

Copiar um modelo

POST /api/copy
{"source": "laya:en", "destination": "my-guardrail"}

Copia um modelo para um novo nome, substituindo um destino existente. A resposta é 200 com corpo vazio.

Criar um modelo

POST /api/create

A API por trás de ollaya create -f Modelfile: a CLI lê o Modelfile e os ficheiros que nomeia e envia os seus conteúdos como JSON.

Campo Tipo Obrigatório Notas
model string sim Nome a criar
from string sim Um modelo local, possivelmente um router. Nunca é descarregado.
questions objeto não Perguntas incorporadas, validadas como um pedido de decisão
calibration objeto não temperature: até 3 números (choice, score, noul). temperature_by_options: "<type>:<2|3-5|6-10|11+>" → number.
parameters objeto não precision: "fp16" ou "fp32", para fixar um grafo
license string ou array não Texto(s) da licença
description string não Uma linha, mostrada por /v1/models e ollaya show
stream boolean não Predefinição true
curl http://localhost:11435/api/create -d '{
  "model": "triage",
  "from": "laya:en",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this ticket?",
      "criteria": ["billing", "technical", "account"]
    }
  },
  "parameters": {"precision": "fp32"},
  "description": "Support ticket triage"
}'

O stream reporta using existing layer sha256:… para cada camada herdada, creating new layer sha256:… para cada nova, depois writing manifest e success. As camadas são endereçadas por conteúdo, por isso repetir uma criação produz o mesmo modelo.

Versão

GET /api/version
{"version": "0.1.0"}

Endpoints compatíveis com o TypeSafe

Endpoint Descrição
POST /v1/systemone Pedido: model, state (obrigatório) e questions. Resposta: exatamente model, answers e usage.
POST /v1/decisions Alias de /v1/systemone
GET /v1/models Os modelos locais, como {"models": [{"name", "description", "release_date"}]}

O /v1/* ignora campos nativos como keep_alive e extras, e nunca adiciona campos nativos às suas respostas. Os erros usam o mesmo corpo que /api/*, que o SDK TypeSafe lê corretamente. Vê Compatibilidade com o TypeSafe.

Segurança

O servidor liga-se a 127.0.0.1:11435 e, tal como o Ollama, confia nos chamadores locais. Ligá-lo a outro endereço (OLLAYA_HOST=0.0.0.0) deixa que todos os que conseguem alcançar a porta executem decisões e descarreguem, eliminem e criem modelos, por isso:

  • OLLAYA_API_KEY faz com que todos os pedidos, exceto GET /, HEAD / e o preflight de CORS, exijam Authorization: Bearer <key>; caso contrário, a resposta é 401 UNAUTHORIZED. O SDK TypeSafe envia a sua chave deste modo, e a CLI ollaya envia $OLLAYA_API_KEY. O servidor regista um aviso quando escuta para além do loopback sem uma chave.
  • O TLS não é terminado pelo servidor; coloca um proxy reverso à frente para acesso remoto.
  • Navegadores. Pedidos com um cabeçalho Origin são permitidos apenas de localhost, 127.0.0.1, 0.0.0.0 e [::1] (qualquer porta), de webviews de aplicações e editores, e das origens em OLLAYA_ORIGINS (separadas por vírgulas, wildcards *). Um servidor em loopback também rejeita cabeçalhos Host inesperados, o que bloqueia DNS rebinding.
  • Os teus dados. Os estados e as perguntas nunca são registados nem ecoados nos erros.
Variável Padrão Efeito
OLLAYA_HOST 127.0.0.1:11435 Endereço de bind; o destino do cliente. Um endereço de loopback também escuta em [::1], por isso programas do Windows alcançam um servidor no WSL em localhost sem atraso
OLLAYA_API_KEY não definida Exige Authorization: Bearer <key>
OLLAYA_ORIGINS não definida Origens de navegador permitidas extra
OLLAYA_KEEP_ALIVE 5m keep_alive predefinido
OLLAYA_MAX_LOADED_MODELS 3 Limite de modelos carregados
OLLAYA_MAX_QUEUE 512 Pedidos em curso antes de 503 QUEUE_FULL
OLLAYA_LOAD_TIMEOUT 5m Prazo de carregamento antes de 500 MODEL_LOAD_FAILED
OLLAYA_DEVICE auto auto, cpu, cuda ou cuda:<n>
OLLAYA_MODELS ~/.ollaya/models Armazenamento de modelos
OLLAYA_REGISTRY ollaya.dev Host de registo predefinido nos nomes