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 gerenciamento de modelos;
  • a API compatível com o TypeSafe em /v1/*, idêntica em nível de protocolo à do TypeSafe, para que os SDKs TypeSafe existentes funcionem sem alterações. Consulte 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 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 na memória
POST /api/pull Baixa um modelo (transmite o progresso)
DELETE /api/delete Exclui 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 requisição e resposta são objetos JSON. O corpo é analisado como JSON qualquer que seja o Content-Type, então curl -d funciona como está. As requisições têm no máximo 8 MiB.
  • Os nomes de campos usam snake_case. Campos de requisição desconhecidos são ignorados; null significa ausente.
  • Os nomes de modelos são [host/][namespace/]model[:tag], sem diferenciar maiúsculas de minúsculas. Uma tag ausente significa latest. As respostas sempre usam a forma canônica, como laya:latest.
  • Números. Probabilidades, confianças, score e noul são arredondados para 4 casas decimais. As durações são inteiros em nanossegundos; os carimbos de data e hora são RFC 3339 em UTC.
  • Streaming. /api/pull e /api/create transmitem JSON delimitado por quebras de linha, um objeto por linha, terminando com exatamente um {"status":"success"} ou uma linha de erro. Envie "stream": false para obter uma única resposta.
  • IDs de requisição. Toda resposta carrega X-Request-Id, e as respostas de /v1/* também x-typesafe-request-id. Um X-Request-Id válido enviado pelo cliente é repetido na resposta.
  • Concorrência. Um modelo carregado executa uma requisição por vez, e cada requisição responde a todas as suas perguntas em uma única passada. As requisições para o mesmo modelo entram na fila, então enviar mais de uma de cada vez não termina mais cedo; o tempo de ida e volta de cada uma passa a incluir a espera. Faça todas as perguntas sobre um estado em uma única requisição. Modelos carregados diferentes são executados em paralelo.
  • Nenhum download implícito. Nenhum endpoint baixa um modelo como efeito colateral. O ollaya run baixa 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 analise; a única mensagem congelada é model "<name>" not found, try pulling it first, como no Ollama.
code Código legível por máquina. Ramifique 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 a requisição 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 roteador) não está nesta máquina; em um download, não está no registro 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á gravando o mesmo nome de modelo depois que terminar
REQUEST_TOO_LARGE 413 Corpo acima de 8 MiB não
QUEUE_FULL 503 Já há OLLAYA_MAX_QUEUE requisições esperando; enviado com Retry-After: 1 sim
MODEL_LOAD_FAILED 500 O modelo não pôde ser carregado (arquivos 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 da requisição 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 Registro 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: trate um código desconhecido pelo seu status 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 que um stream começa, uma falha chega como última linha no mesmo formato, por exemplo {"error": "…", "code": "DIGEST_MISMATCH"}. Verifique em cada linha se há error antes de lê-la como progresso.

Perguntas

/api/decide, /v1/systemone e /api/create compartilham um único esquema de perguntas, o do TypeSafe. Uma requisição tem 1–256 perguntas, indexadas por qualquer id; as respostas voltam na mesma ordem.

type instructions criteria Resposta
choice opcional obrigatório: objeto rótulo → descrição, ou um array de rótulos; 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, então um id descritivo como is_spam funciona sozinho.
  • state é uma string, um objeto ou um array, de até 65.536 tokens. Se exceder o contexto disponível do modelo, /api/decide o trunca e reporta state_truncated: true. /v1/systemone e /v1/decisions retornam 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 roteador, valem os limites do destino.

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

type Campos
choice choice: o rótulo mais provável. confidence. probabilities: rótulo → probabilidade, na 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 ser verdadeira. 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 concentra toda a probabilidade. A fórmula é a mesma para todo modelo, mas o que uma dada confiança significa não é: os modelos são calibrados de forma diferente, então ajuste um limiar por modelo nos seus próprios dados. As probabilidades são calibradas com as temperaturas de cada modelo. Em uma GPU CUDA roda o grafo fp16, cujas respostas podem diferir do fp32 em empates apertados.

keep_alive

Por quanto tempo um modelo permanece carregado depois que uma requisição termina, com a semântica do Ollama:

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

O cronômetro começa quando uma requisição termina, e o valor da requisição mais recente prevalece. Para um roteador, ele se aplica ao destino que respondeu. O /v1/* ignora keep_alive.

Decidir

POST /api/decide

Responde perguntas tipadas sobre um estado em uma única passada direta. O corpo é o corpo de /v1/systemone mais opções nativas; a resposta é a resposta do TypeSafe mais campos nativos, então um cliente TypeSafe também consegue analisá-la.

Campo Tipo Obrigatório Notas
model string sim Nome do modelo
state string, objeto ou array sim para decidir Sem ele, a requisição carrega ou descarrega o modelo (abaixo)
questions objeto sim, a menos que o modelo tenha perguntas integradas Substitui por completo as perguntas do próprio modelo
preset string não O nome de uma predefinição, integrada 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. Consulte Imagens
keep_alive string ou number não Consulte 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 roteador, seu destino (laya:en para uma requisição de laya)
answers Id de pergunta → resposta, na ordem das perguntas
usage input_tokens lidos; output_tokens é sempre 0
routing Para um roteador: 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 o recebimento da requisição até a resposta, incluindo a fila
load_duration Nanossegundos gastos esperando o modelo carregar; 0 quando ele já estava quente
eval_duration Nanossegundos no runner: tokenização, passada direta, calibração

Com "extras": ["laya"], cada resposta também tem 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 perguntas sobre uma imagem além do estado. Envie a imagem em images, codificada em base64, do mesmo modo que 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 requisição, apenas PNG. O pré-processamento do modelo é reproduzido valor a valor, então os pixels precisam corresponder ao que os autores do modelo decodificam. Os decodificadores de JPEG do Rust diferem do libjpeg-turbo em até 4 níveis em alguns pixels, então o JPEG ainda não é aceito: converta-o para PNG primeiro.
  • Decider: A imagem é redimensionada para múltiplos de 32 pixels, como o modelo espera, e pode ter no máximo 4.096 patches de 16x16 pixels depois disso, cerca de um megapixel (1024x1024). Uma imagem maior recebe um 422 que diz isso; reduza-a antes.
  • Decider: As perguntas aceitam no máximo 10 opções. O mesmo modelo também responde a requisições apenas de texto.
  • Winnow E4B vision: até 16 PNGs 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 tags de texto existentes da Winnow não o carregam.
  • Um modelo que não lê imagens responde a uma requisição 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. Uma requisição sem state e questions nunca decide. Sem keep_alive, ou com um valor positivo ou negativo, ela carrega o modelo (todos os destinos, no caso de um roteador) e retorna done_reason: "load". Com keep_alive: 0 ela o descarrega ("unload"). O ollaya run pré-carrega desse 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 colateral sobre dados armazenados, então é seguro tentar de novo.

Predefinições

Uma predefinição é um conjunto nomeado de perguntas. Seis são integradas (triage, email, guard, moderation, router, agent), e você pode salvar as suas próprias. Envie "preset": "NAME" para /api/decide no lugar 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 integradas, depois as personalizadas: name, builtin, description, ids de pergunta, modified_at
POST /api/presets/create name, questions, description (opcional) Salva 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 Exclui uma predefinição personalizada

Os nomes têm de 1 a 64 caracteres de letras minúsculas, dígitos, - e _. Um nome integrado não pode ser reutilizado (422) nem excluído (403), e um nome desconhecido é um 404. As predefinições personalizadas são armazenadas junto dos modelos, então todo cliente do servidor vê as mesmas.

Roteadores

Um roteador como laya (laya:latest) não tem pesos: para cada requisição ele escolhe um de seus destinos, que então 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 (o padrão) laya:en

Textos curtos em maiúsculas e sem letras acentuadas, como nomes de comerciantes em uma fatura de cartão (MIGROS KADIKOY ISTANBUL TR), SKUs ou nomes de usuário, geralmente não podem ser identificados e vão para laya:en. Se você sabe o idioma, peça laya:multilingual ou laya:en diretamente; o model da resposta diz qual checkpoint respondeu.

O roteamento custa microssegundos. Ramifique com base em route, nunca em reason, cujo texto pode mudar. O laya:typed-decisions nunca é escolhido pelo roteador; peça-o diretamente.

Listar modelos locais

GET /api/tags

Os modelos nesta máquina, do mais novo para o mais antigo. Cada entrada tem name, model (o mesmo), modified_at, size em bytes, digest (sha256 do manifesto, em hex puro) e details: parent_model, format (onnx, gguf ou router), family, families, parameter_size e quantization_level (as precisões que ele carrega, 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 integradas, ou null
router Para um roteador: 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 multilíngue ainda pode ler outros idiomas, então meça nos seus dados.
capabilities Tipos de pergunta que ele responde (choice, score, noul), mais act se tiver uma cabeça de ato
modified_at Como em /api/tags

Um roteador é 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 roteadores nunca aparecem; 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 ele será descarregado, ou null quando mantido carregado), size_vram, context_length e device (cpu, cuda:0, metal, …).

Baixar um modelo

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

Baixa o modelo para o armazenamento local e verifica cada blob em relação ao seu sha256. Baixar um roteador também baixa todos os modelos para os quais ele roteia. Só as camadas de que esta máquina precisa são baixadas, blobs compartilhados entre modelos são baixados uma vez, e downloads interrompidos são retomados.

A resposta transmite o progresso, com as strings de status 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 roteador há um único success, no final. Um nome que não é analisado, um modelo que não está no registro e um registro inacessível são erros HTTP comuns (422, 404, 502) antes de o stream começar, então curl --fail funciona. Com "stream": false a resposta é {"status": "success"} quando termina. Um segundo download do mesmo nome se junta ao que está em andamento. Seguro tentar de novo.

Excluir um modelo

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

Remove o nome, e os blobs que nenhum outro modelo usa. Um modelo carregado é descarregado assim que suas requisições terminam; excluir um roteador mantém seus destinos. A resposta é 200 com corpo vazio, e 404 MODEL_NOT_FOUND quando o nome não existe; após um timeout, trate isso como sucesso.

Copiar um modelo

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

Copia um modelo para um novo nome, sobrescrevendo 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 arquivos que ele nomeia e envia seus conteúdos como JSON.

Campo Tipo Obrigatório Notas
model string sim Nome a criar
from string sim Um modelo local, possivelmente um roteador. Ele nunca é baixado.
questions objeto não Perguntas integradas, validadas como uma requisição 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 Padrã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, então 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 Requisição: 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. Consulte Compatibilidade com o TypeSafe.

Segurança

O servidor se liga a 127.0.0.1:11435 e, como o Ollama, confia nos chamadores locais. Vinculá-lo a outro endereço (OLLAYA_HOST=0.0.0.0) permite que todos que conseguem alcançar a porta executem decisões e baixem, excluam e criem modelos, então:

  • OLLAYA_API_KEY faz toda requisição, exceto GET /, HEAD / e o preflight de CORS, exigir Authorization: Bearer <key>; caso contrário, a resposta é 401 UNAUTHORIZED. O SDK TypeSafe envia sua chave desse modo, e a CLI ollaya envia $OLLAYA_API_KEY. O servidor registra um aviso quando escuta além do loopback sem uma chave.
  • O TLS não é terminado pelo servidor; coloque um proxy reverso na frente para acesso remoto.
  • Navegadores. Requisições com um cabeçalho Origin são permitidas apenas de localhost, 127.0.0.1, 0.0.0.0 e [::1] (qualquer porta), de webviews de aplicativos e editores, e das origens em OLLAYA_ORIGINS (separadas por vírgulas, curingas *). Um servidor em loopback também rejeita cabeçalhos Host inesperados, o que bloqueia DNS rebinding.
  • Seus dados. Os estados e as perguntas nunca são registrados nem repetidos 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], então 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 adicionais
OLLAYA_KEEP_ALIVE 5m keep_alive padrão
OLLAYA_MAX_LOADED_MODELS 3 Limite de modelos carregados
OLLAYA_MAX_QUEUE 512 Requisições em andamento 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 registro padrão nos nomes