Pular para o conteúdo principal

Configuração do Cordis

O mecanismo Cordis/DSH incorporado é configurado por dois documentos e variáveis de ambiente. Por padrão, ambos os documentos ficam ao lado do backend; LIBRE_CORDIS_CONFIG e LIBRE_CORDIS_SETTINGS alteram suas localizações.

DocumentoResponsávelEstruturaFinalidade
cordis.patch.ymlCordis LoaderArray YAML no nível superiorEntradas dos plugins que montam o mecanismo
cordis.config.ymlHost do Libre WebUIMapeamento YAMLProvedor, origem das credenciais e controles de recursos

São dois documentos porque o componente Include do Cordis lê a própria composição e rejeita arquivos cujo nível superior não seja um array. As configurações do host não podem compartilhar esse arquivo.

Como ativar

Opção de ativação do Motor Cordis nas Configurações, ao lado da ativação de Agentes.

Um administrador ativa o mecanismo em Configurações → Gerenciamento de Usuários → Acesso e políticas → Motor Cordis. A alteração é imediata: ativar inicia o mecanismo na próxima solicitação; desativar o descarta. Não é necessário reiniciar.

Duas fontes no nível da implantação podem fixar o valor. Ambas bloqueiam o controle da interface, em vez de serem substituídas silenciosamente:

FonteEfeito
Variável LIBRE_CORDIS_ENABLEDtrue/false fixa o recurso para a implantação
features.enabled em cordis.config.ymlUm valor explícito fixa a opção; omitir a chave deixa a escolha com o administrador

O mecanismo também precisa de uma composição. Comece pelos exemplos incluídos:

cd backend
cp cordis.patch.example.yml cordis.patch.yml
cp cordis.config.example.yml cordis.config.yml

O host lê cordis.patch.yml, mescla seus padrões na entrada da ponte e grava o resultado em <DATA_DIR>/cordis-runtime/cordis.composed.yml. Esse arquivo gerado é descartável e não deve ser editado. O documento autoritativo é o cordis.patch.yml do operador.

cordis.config.yml

trace: false

model:
provider: libre-webui
# Empty selects the authenticated caller's configured default/fallback route.
model: ''

features:
# Omit enabled to let the administrator use the Settings toggle.
streaming: true
tools: true
persistence: true

# Optional absolute paths; defaults live under Libre WebUI's data directory.
# workspacePath: /absolute/path/to/workspace
# sessionStorePath: /absolute/path/to/sessions

Chaves de nível superior

ChaveTipoPadrãoSignificado
tracebooleanofalseRegistrar todas as transições de ativação do Cordis
modelmapeamentoSeleção do adaptador de modelos; veja abaixo
featuresmapeamentoControles das capacidades; veja abaixo

features

ChaveTipoPadrãoSignificado
enabledbooleanofalseMontar o mecanismo. Quando false, todas as rotas retornam 503
streamingbooleanotrueAceitar turnos que transmitem a saída do modelo
toolsbooleanotruePermitir ferramentas do mecanismo e expor seu registro
persistencebooleanotrueAtivar persistência JSONL e exigir seu serviço, preservando sessões após reiniciar

features.enabled é o único controle que precisa ser definido para ativar a ponte. Uma chave enabled no nível superior não é lida. Manter todos os controles em features deixa um único lugar para consultar o que está ativo.

model

ChaveTipoPadrãoSignificado
providerstringlibre-webuilibre-webui, deepseek, pi-ai ou none
apiKeyEnvstringOPENAI_API_KEYNome da variável de ambiente que contém a chave
routestringlibre-webuiRota do provedor usada pelo mecanismo nas solicitações
modelstring''ID do modelo solicitado. Defina-o para rotas declaradas manualmente
baseUrlstring''Substituição do endpoint; vazio usa o padrão do adaptador
providersmapeamento{}Rotas declaradas manualmente, indexadas pelo nome da rota

De onde vêm os modelos do mecanismo

O mecanismo não tem uma configuração própria de provedores. Ele chama os provedores já disponíveis no Libre WebUI pela rota libre-webui, registrada pela entrada libre-webui-llm-adapter da composição. O que funciona no chat da interface também pode ser usado pelo mecanismo: ao baixar um modelo pela UI, ele passa a enxergá-lo com as credenciais e o endpoint já configurados.

Defina model.provider: libre-webui para usar esse modo. Esse é o padrão incluído; credenciais e endpoints continuam nas configurações existentes do Libre WebUI.

model identifica o modelo solicitado. Vazio significa usar o padrão do aplicativo. Se a implantação não tiver um padrão, o mecanismo escolhe o primeiro modelo de chat informado pela camada de provedores, priorizando modelos locais disponíveis. Modelos de embeddings são excluídos. As rotas internas mantêm provedor e modelo: lwui:ollama:<encoded-model> ou lwui:plugin:<encoded-provider>:<encoded-model>. Isso impede que nomes coincidentes ou uma falha do Ollama redirecionem uma solicitação local a um provedor remoto. Uma escolha explícita indisponível falha, sem substituir silenciosamente o provedor.

Um model vazio só é seguro na rota libre-webui. Uma rota atendida por um pacote de provedor precisa de um modelo explícito. dsh-llm-pi-ai resolve o catálogo para consultas, mas não usa sua primeira entrada como alternativa. Uma rota manual sem model não atende nenhum turno e falha com:

provider "<route>" resolves no models; the installed catalog does not describe
this route, so its models must be listed in configuration

Defina model com um ID da lista models dessa rota. O exemplo incluído combina route: ollama com model: llama3.2, correspondendo à entrada llama3.2 declarada.

provider escolhe qual pacote de adaptador será montado:

  • libre-webui atende ao mecanismo pela camada de provedores da própria implantação. É o modo padrão e suportado.
  • none inicia o mecanismo sem acesso a modelos. A lista de ferramentas e as sessões funcionam, mas os turnos não podem ser respondidos. É útil para exercitar a composição.
  • deepseek e pi-ai montam diretamente um pacote de provedor. Esses pacotes não são dependências deste backend: incluir todos os SDKs adicionava 59 dependências transitivas, inclusive pacotes obsoletos de funções que o mecanismo não usa. Instale o pacote desejado e monte sua entrada na composição. O host informa o nome do pacote se ele não estiver presente.

Uma rota de provedor é descrita por:

CampoSignificado
displayNameNome legível
apiProtocolo de comunicação, como openai-completions
baseURLBase do endpoint
apiKeyEnvVariável de ambiente que contém a chave
modelsLista de modelos; cada entrada aceita id, name, contextWindow, maxTokens

Credenciais nunca são gravadas em nenhum dos documentos. apiKeyEnv indica uma variável de ambiente, resolvida pelo adaptador a cada solicitação. Assim, a rotação da chave não exige reiniciar.

cordis.patch.yml

É um array de entradas do Cordis Loader no nível superior. O exemplo incluído monta nove entradas e é o ponto de partida recomendado.

- id: llm
name: '@deepseek-ai/dsh-llm'

- id: session
name: '@deepseek-ai/dsh-session'

- id: session-projection
name: '@deepseek-ai/dsh-session-projection'

- id: session-persistence
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
# The host supplies the resolved sessionStorePath.

- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
personaPrefix: ''

- id: tools
name: '@deepseek-ai/dsh-tools'

- id: agent
name: '@deepseek-ai/dsh-agent'

- id: agent-loop
name: '@deepseek-ai/dsh-agent-loop'
config:
agents: []

- id: libre-webui-bridge
name: './dist/cordis/dsh/engine-plugin.js'

Campos das entradas

CampoObrigatórioSignificado
idnãoID estável para localizar a entrada; derivado de name quando omitido
namesimEspecificador do módulo importado pelo Loader; deve ser uma string literal
confignãoConfiguração do plugin; expressões !!js são permitidas
disablednãoIgnorar a entrada sem apagá-la; aceita !!js
injectnãoServiços extras obrigatórios ou configuração de interceptação da entrada

name é importado diretamente e nunca avaliado, portanto não pode ser uma expressão !!js. Os valores de config podem usar !!js; essas expressões são avaliadas depois, na fibra da entrada, com acesso ao contexto do Loader. process.env e ctx.get(...) funcionam; import.meta não.

Especificadores relativos são resolvidos a partir do diretório do próprio arquivo de composição. Especificadores de pacote passam pelo backend, de modo que @deepseek-ai/dsh-tools encontra a cópia em backend/node_modules.

A ordem das entradas não determina o carregamento. O Cordis ativa uma entrada quando os serviços declarados ficam disponíveis; o agrupamento acima serve apenas à leitura.

Entradas obrigatórias

Um mecanismo que responde ao chat precisa de todas estas entradas:

EntradaForneceNecessário para
dsh-llmllmciclo do agente
dsh-sessionsessionsciclo do agente, ponte
dsh-session-projectionsessionProjectionsciclo do agente
dsh-system-promptsystemPromptferramentas, ciclo do agente
dsh-toolstoolsciclo do agente, ponte
dsh-agentagentsponte
dsh-agent-loopdriver do agenteresposta aos turnos
entrada da pontelibreDshEnginetodas as rotas

Montar também entradas de ferramentas, como @deepseek-ai/dsh-fs-sandbox e @deepseek-ai/dsh-tool-fs, faz GET /api/cordis/tools retornar itens. Um registro sem plugins de ferramentas pode estar legitimamente vazio.

Variáveis de ambiente

Todos os valores têm uma substituição por ambiente. A variável prevalece sobre o documento, e o documento sobre o padrão incorporado.

VariávelSubstituiPadrão
LIBRE_CORDIS_ENABLEDfeatures.enabledfalse
LIBRE_CORDIS_STREAMINGfeatures.streamingtrue
LIBRE_CORDIS_TOOLSfeatures.toolstrue
LIBRE_CORDIS_PERSISTENCEfeatures.persistencetrue
LIBRE_CORDIS_TRACEtracefalse
LIBRE_CORDIS_MODEL_PROVIDERmodel.providerlibre-webui
LIBRE_CORDIS_MODEL_ROUTEmodel.routelibre-webui
LIBRE_CORDIS_MODELmodel.model''
LIBRE_CORDIS_API_KEY_ENVmodel.apiKeyEnvOPENAI_API_KEY
LIBRE_CORDIS_BASE_URLmodel.baseUrl''
LIBRE_CORDIS_CONFIGCaminho do documento de composição<cwd>/cordis.patch.yml
LIBRE_CORDIS_SETTINGSCaminho do documento de configuraçõesao lado da composição
LIBRE_CORDIS_WORKSPACEEspaço de trabalho padrão do mecanismo<DATA_DIR>/cordis-workspace
LIBRE_CORDIS_SESSION_STOREDiretório das sessões persistidas<DATA_DIR>/cordis-sessions

Variáveis booleanas aceitam 1/true/yes/on e 0/false/no/off. Um valor não reconhecido recorre ao documento, sem tentar adivinhar.

LIBRE_CORDIS_SESSION_STORE e LIBRE_CORDIS_WORKSPACE também são lidas pelas expressões !!js da composição incluída. Por isso, o host as exporta antes de montar a árvore.

Exemplos completos

Ollama local, totalmente offline

features:
enabled: true
model:
provider: pi-ai
route: ollama
model: llama3.2
apiKeyEnv: OLLAMA_API_KEY
providers:
ollama:
api: openai-completions
baseURL: http://127.0.0.1:11434/v1
apiKeyEnv: OLLAMA_API_KEY
models:
- id: llama3.2
contextWindow: 131072
maxTokens: 4096

O Ollama ignora a chave, mas o cliente OpenAI exige que uma esteja definida. Exporte OLLAMA_API_KEY=ollama para atender à exigência sem criar um segredo. Nada sai da máquina.

Um gateway compatível com OpenAI

features:
enabled: true
model:
provider: pi-ai
route: gateway
model: acme-large
apiKeyEnv: ACME_GATEWAY_API_KEY
providers:
gateway:
displayName: Acme Gateway
api: openai-completions
baseURL: https://gateway.acme.example/v1
apiKeyEnv: ACME_GATEWAY_API_KEY
models:
- id: acme-large
contextWindow: 65536
maxTokens: 4096

DeepSeek oficial

features:
enabled: true
model:
provider: deepseek
route: deepseek
apiKeyEnv: DEEPSEEK_API_KEY

Defina DEEPSEEK_API_KEY no ambiente do backend.

Sem provedor, apenas ferramentas

features:
enabled: true
model:
provider: none

O mecanismo inicia, sessões podem ser criadas e GET /api/cordis/tools lista os plugins de ferramentas configurados. Enviar uma mensagem falha porque nenhum adaptador pode atender à solicitação.

Notas de migração

A ponte Cordis é um recurso adicional. Vem desligada por padrão e não altera o comportamento existente enquanto estiver desligada.

Atualização de uma implantação existente. Nenhuma ação é necessária. Os exemplos são distribuídos como cordis.patch.example.yml e cordis.config.example.yml, portanto só são usados depois de copiá-los e ativar o recurso. Nenhuma migração é executada, tabela é criada ou diretório de dados existente é alterado.

Primeira ativação. Copie os dois exemplos e defina features.enabled: true. Não instale mais nada: os pacotes do mecanismo já são dependências do backend. Na primeira solicitação, o mecanismo cria <DATA_DIR>/cordis-workspace, <DATA_DIR>/cordis-sessions e <DATA_DIR>/cordis-runtime. Os três são novos diretórios dentro do diretório de dados existente e ficam cobertos por backups e restaurações que incluam esse diretório.

Atualização do mecanismo. As versões resolvidas estão em package-lock.json. backend/package.json declara intervalos compatíveis com a versão alpha. Atualize deliberadamente e valide os contratos de provedor e sessão depois de executar npm install. Se um pacote DSH adicionar uma dependência peer, o npm a informa na instalação, não na montagem. Os formatos de modelo e sessão pertencem ao DSH; uma alteração de formato é tratada nas notas do DSH, não como migração do Libre WebUI.

Reversão. Defina features.enabled: false e reinicie, ou remova a entrada da ponte de cordis.patch.yml. O serviço libreDshEngine é retirado, seu listener liberado e os agentes criados são descartados. Arquivos de sessão permanecem como dados no disco; exclua sessionStorePath para recuperar o espaço. Desinstalar os pacotes é opcional e não afeta outras funções do Libre WebUI.

Implantações existentes de Chat e Work. O Chat ganha uma opção DeepSeek Harness exclusiva de administradores, com sessões transitórias e o histórico existente do Chat. O Work ganha uma seleção independente de mecanismo DeepSeek Harness, com driver isolado e a estrutura atual de sandbox e aprovação. Seleções de modelo existentes mantêm seu comportamento.

Com o adaptador padrão libre-webui, o seletor Agentes inclui escolhas explícitas de provedor e modelo DSH, além do perfil básico. Escolhas explícitas mantêm sua identidade qualificada; o perfil básico usa o padrão da composição em execução. Títulos e resumos de raciocínio chamam diretamente o provedor subjacente, sem ferramentas de agente. Uma rota de adaptador personalizada mantém apenas a entrada básica de Chat e exige um modelo de tarefa Ollama ou de plugin separado para títulos e resumos.

O DSH respeita o controle administrativo do Ollama. Quando desativado, seus modelos não são listados nem sondados, e uma escolha explícita falha sem mudar de provedor. Nomes não qualificados fixados pelo operador também exigem o catálogo do Ollama para uma resolução segura. Em uma implantação apenas com plugins, use lwui:plugin:<plugin>:<model>.

Limites operacionais

  • Mecanismo do host e Chat são exclusivos de administradores e do modo solo. A página é um console administrativo compartilhado com armazenamento JSONL local e não pode ser montada em team. O Work em sandbox usa os repositórios SQL existentes.
  • Chamadas de modelo usam o solicitante autenticado. Turnos interativos do host usam suas credenciais e preferência de modelo. Uma composição confiável não interativa pode definir explicitamente LIBRE_CORDIS_USER com o ID de um administrador ativo. Não há escolha implícita do administrador mais antigo.
  • Ferramentas de arquivos do host ficam restritas ao espaço configurado. Leituras e gravações verificam o destino canônico; sessões não escolhem diretórios fora da raiz. Restrições de alteração do DSH continuam valendo. Plugins extras instalados pelo operador são código confiável do servidor.
  • Ferramentas do host seguem as políticas do DSH. A página oferece modos por sessão de leitura e escrita e cartões de aprovação única. Nenhum ignora o limite do espaço de trabalho. O Chat sem interface rejeita aprovações que não pode exibir. O driver do Work usa aprovações do Work e isolamento de contêineres, sem ferramentas de arquivos do host.
  • Streams contêm texto ao vivo e raciocínio exposto. Mensagens duráveis preservam a conversa concluída; o cliente não recebe uma segunda cópia do texto ao vivo.
  • Reiniciar e excluir usa as sessões armazenadas. Sessões vazias e concluídas sobrevivem a reinicializações. Excluir uma sessão JSONL criada pela ponte interrompe seu gravador e remove o artefato. Outras implementações precisam fornecer um adaptador de exclusão apropriado.
  • Logs antigos malformados exigem reparo explícito. Versões anteriores gravavam mensagens sem os IDs obrigatórios. O leitor estrito rejeita os logs em vez de descartá-los. Consulte a recuperação em Solução de problemas.
  • Títulos são derivados localmente. O resumo usa a primeira mensagem humana como título curto; sessões vazias não têm título derivado.

Conectar modelos de uma instância DSH em execução

O plugin opcional dsh-native-provider expõe modelos e conexões já configurados em outra instância DSH, como a aplicação web local na porta 3080. Instale-o no perfil existente dessa instância. Ele chama apenas ctx.llm: chaves permanecem no DSH, e a conexão não pode criar sessões, executar agentes, ler anexos nativos ou executar ferramentas nativas.

Ambos os processos precisam executar no mesmo host Unix e na mesma conta do sistema. O transporte usa um socket Unix configurado explicitamente. Seu diretório físico deve pertencer à conta e ter modo 0700; o socket usa 0600. Nenhum listener TCP é adicionado, e a autenticação do navegador DSH não é reutilizada nem enfraquecida. Windows e hosts DSH remotos não são suportados.

A conta do sistema é o limite de acesso local: outros processos dessa conta podem usar o socket. A conexão não oferece credenciais nativas separadas nem isolamento entre aplicações que compartilham a conta.

Instalar o plugin independente

Em DSH → Plugins → Add plugin, cole esta URL pública em Package name or address e clique em Install:

https://github.com/libre-webui/dsh-native-provider

Ative o componente quando o DSH solicitar. O pacote público é a versão 0.1.1, licenciado sob Apache-2.0, com runtime pré-compilado e patch de bundle. Não exige compilação local, scripts de instalação nem dependências npm de runtime. O nome @libre-webui/dsh-native-provider não está publicado no npm; use a URL do GitHub no diálogo.

O bundle usa <DSH home>/lwui-provider/llm.sock, normalmente $HOME/.dsh/lwui-provider/llm.sock. Uma configuração DSH_HOME tem prioridade. O diretório privado é criado se não existir. Use uma única ponte ativa por diretório DSH ou substitua o caminho no cordis.patch.yml do usuário para perfis adicionais. O caminho completo deve caber em 100 bytes UTF-8 e não conter links simbólicos. Consulte o guia de configuração do pacote independente para substituições.

O comando CLI equivalente é opcional:

dsh plugin --profile web add https://github.com/libre-webui/dsh-native-provider

Troque web pelo perfil que realmente executa sua instância, se for outro. Reinicie esse perfil após a instalação via CLI; a instalação pela UI em execução pode ativar o plugin imediatamente. Siga qualquer aviso de reinicialização do DSH. Não são necessárias alterações no código nativo nem cópias das chaves dos provedores.

Preparar um bundle pelo Libre WebUI

O Libre WebUI também inclui um script de preparação. Em um checkout do código, compile o backend e prepare um novo diretório de saída:

npm run build:backend
node scripts/prepare-dsh-provider.mjs /absolute/dsh-provider-bundle /absolute/private-directory/provider.sock
dsh plugin --profile web add /absolute/dsh-provider-bundle

Distribuições instaladas pelo npm já contêm o backend compilado e o script. Execute os últimos dois comandos a partir do diretório de instalação, sem a compilação. Depois, reinicie o perfil DSH escolhido. As duas formas recusam diretórios existentes e incluem metadados do pacote, licença e orientações de instalação.

Conectar o Libre WebUI

Aponte o cordis.config.yml do Libre WebUI para o mesmo caminho absoluto do socket. Para o padrão do bundle público, substitua /absolute/home pelo diretório pessoal real:

nativeProvider:
socketPath: /absolute/home/.dsh/lwui-provider/llm.sock

Outra opção é definir LIBRE_DSH_PROVIDER_SOCKET com esse caminho absoluto. Um valor vazio desativa a conexão mesmo quando o arquivo contém um caminho. Ative Motor Cordis no LWUI. Administradores ativos podem selecionar modelos nativos no mecanismo DeepSeek Harness do Work, na página do mecanismo e em Agentes no Chat. O Chat também exige Modelos de agentes CLI. O Work conserva o modelo nativo e ID do provedor originais com providerType: dsh; tarefas DSH existentes que usam provedores LWUI mantêm sua identidade e marcador de mecanismo.

A lista de modelos nativos é lida ao vivo. Alterações de provedor ou credenciais invalidam a geração da conexão e cancelam chamadas nativas em andamento. Socket, modelo ou provedor indisponível interrompe a solicitação, sem alternativa para Ollama ou outro provedor. Títulos e resumos chamam diretamente o LLM selecionado, sem ferramentas. Esta conexão inicial aceita texto, raciocínio e mensagens de ferramentas, mas rejeita referências nativas a imagens ou arquivos.

As credenciais nativas pertencem ao operador DSH, portanto a conexão é exclusiva de administradores, mesmo quando o Work normal está aberto a mais usuários. Conforme o provedor configurado no DSH, solicitações podem sair do host; o Work mostra a indicação de provedor remoto. Em team, todo worker que atende essas tarefas precisa acessar a conexão local configurada. Se ela faltar, a execução é recusada. Desativar Cordis ou remover o socket revoga o acesso nativo e preserva as tarefas. Se uma falha do DSH deixar um socket, pare a instância proprietária e remova apenas esse socket obsoleto antes de reiniciar. O plugin não substitui entradas existentes do sistema de arquivos.

Atualizar ou remover o plugin

Conclua ou cancele solicitações nativas antes da alteração. Para substituir o antigo bundle local 0.0.0/0.1.0 pela UI do DSH, use Uninstall, volte a Add plugin e instale a URL pública acima. Preserve caminhos de socket personalizados por uma substituição de perfil de usuário suportada. Sessões e credenciais nativas são mantidas.

Uma instalação já proveniente do GitHub pode ser atualizada pela CLI:

dsh plugin --profile web update @libre-webui/dsh-native-provider

Reinicie após atualizar pela CLI e verifique a versão. Um plugin desativado permanece assim; confira seu estado antes de testar a conexão. Para fixar ou reverter, use github:libre-webui/dsh-native-provider#<commit>. Para bundles preparados localmente, compile um novo diretório e adicione-o novamente. Atualizar uma dependência local não busca alterações no GitHub.

Para remover a conexão, primeiro exclua nativeProvider.socketPath do LWUI ou defina LIBRE_DSH_PROVIDER_SOCKET vazio. Em seguida, execute:

dsh plugin --profile web remove @libre-webui/dsh-native-provider

Reinicie o perfil DSH após remover. As tarefas salvas continuam existindo, mas suas solicitações nativas falham até que a mesma conexão explícita seja restaurada. Remover o plugin não apaga provedores nem credenciais configurados no DSH. Exclua diretórios de bundles antigos apenas quando eles não estiverem mais instalados.

Uso do provedor nativo

Solicitações nativas aparecem em Uso de Fornecedores, sob DeepSeek Harness · provedor, com o modelo original escolhido. Cada solicitação real é contada uma vez, incluindo rodadas de ferramentas, títulos e resumos de raciocínio. O painel inclui chamadas bem-sucedidas, falhas e canceladas, latência e tokens informados pelo DSH. A entrada em cache entra uma vez no total; uso ausente permanece não medido, sem estimativa. IDs usam dsh-native:<percent-encoded-native-provider-id> nas regras existentes de tarifas e custos. Tarifas desconhecidas continuam sem preço calculado.

Solicitações DSH pelos provedores configurados no LWUI mantêm os registros desses provedores. Consultas ao catálogo e rejeições anteriores à inferência nativa não criam registros extras. A medição começa na instalação desta versão da conexão, sem inventar uso histórico. Os registros contêm identidade, estado, horário e contadores, sem prompts, respostas, credenciais, endpoints ou texto de erro do provedor.

Como verificar uma configuração

curl -s http://127.0.0.1:3001/api/cordis/health | jq
{
"success": true,
"enabled": true,
"ready": true,
"services": [
{ "name": "llm", "state": "ready" },
{ "name": "systemPrompt", "state": "ready" },
{ "name": "sessions", "state": "ready" },
{ "name": "tools", "state": "ready" },
{ "name": "agents", "state": "ready" }
]
}

Um 503 com code: CORDIS_UNAVAILABLE significa que a composição não foi montada. O campo error informa o motivo, e LIBRE_CORDIS_TRACE=true adiciona o log de ativação. Veja causas comuns em Solução de problemas.