feat: add local-deploy (dl) setup script and documentation#1
feat: add local-deploy (dl) setup script and documentation#1felippepestana merged 3 commits intomainfrom
Conversation
Instala o dl CLI v1.2.0 (local-deploy.github.io) como ferramenta de deploy local para o ambiente de desenvolvimento AIOX. - setup-local-deploy.sh — script automatizado de instalação do dl - doc/local-deploy.md — documentação de uso, comandos e integração com AIOX Resultado da instalação no ambiente: - Docker 29.2 + Docker Compose v2 (plugin 5.0.2) verificados - dl v1.2.0 instalado em /usr/local/bin/dl (linux/amd64) https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy
Cria ambiente de conversação completo para interação com os squads AIOX. O chatbot carrega dinamicamente todos os agentes das pastas squads/*/agents/*.md e os expõe como personas conversacionais via claude-opus-4-6. Funcionalidades: - Seleção interativa de agente (8 squads, 73 agentes carregados) - Streaming de respostas token a token - Upload de arquivos via Files API (PDF, imagens, CSV, TXT, JSON) - Troca de agente em tempo real sem perder histórico - Comandos: /help /agent /upload /files /reset /status /exit - Cleanup automático de arquivos ao encerrar sessão - Adaptive thinking (claude-opus-4-6) Estrutura: chatbot/src/agents.ts — carregador de agentes dos .md chatbot/src/chat.ts — sessão de streaming com Files API chatbot/src/files.ts — upload/delete via Files API beta chatbot/src/index.ts — CLI interativa com cores ANSI chatbot/start.sh — script de inicialização Resultado de smoke test: - 8 squads carregados, 73 agentes disponíveis - Menu de seleção renderizado corretamente - TypeScript compilado sem erros https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy
- Add Express 5 web server (server.ts) with REST API + SSE chat endpoint - Mobile-first responsive UI: drawer sidebar, hamburger menu, swipe-to-close - Safe-area insets (env(safe-area-inset-*)) for notched phones - 46px touch targets, autocapitalize/autocorrect on textarea - File upload via Multer 2 + Anthropic Files API integration - Dockerfile for deployment (build context = repo root) - docker-compose.chatbot.yml for easy local/cloud deployment - web-start.sh script to start web interface https://claude.ai/code/session_01XXsrRinWBHmRBDd7X9yci8
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! Este pull request aprimora o ambiente de desenvolvimento AIOX ao introduzir o 'dl CLI' para gerenciamento de deploy local baseado em Docker Compose, simplificando a configuração de serviços e replicando ambientes de produção. Além disso, ele adiciona um novo chatbot interativo, construído em TypeScript, que permite aos usuários conversar com agentes AIOX, fazer upload de arquivos e gerenciar sessões de chat de forma eficiente, tanto via linha de comando quanto por uma interface web. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
Este pull request adiciona a configuração e documentação para o local-deploy (dl), juntamente com um novo chatbot com interfaces CLI e web. A implementação geral é de alta qualidade, especialmente os scripts de shell e a estrutura do projeto do chatbot. No entanto, identifiquei algumas questões críticas que precisam ser abordadas, principalmente um bug no tratamento de upload de arquivos na interface web que impede a análise correta de imagens, e uma falha na configuração do Dockerfile que tornará o contêiner 'unhealthy'. Também há algumas sugestões de melhoria para otimizar a imagem Docker, melhorar a manutenibilidade do código TypeScript e remover redundâncias.
| HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ | ||
| CMD wget -qO- http://localhost:3000/ || exit 1 |
There was a problem hiding this comment.
O HEALTHCHECK utiliza wget, que não está disponível na imagem base node:22-alpine. Isso fará com que a verificação de saúde falhe e o contêiner seja marcado como "unhealthy", podendo ser reiniciado em loop por orquestradores. Para corrigir, instale o wget na imagem antes da instrução HEALTHCHECK.
RUN apk add --no-cache wget
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/ || exit 1
| const pendingFiles = pendingFileIds.map((id) => ({ | ||
| fileId: id, | ||
| filename: id, | ||
| mimeType: "application/octet-stream", | ||
| sizeBytes: 0, | ||
| })); |
There was a problem hiding this comment.
Existe um bug no tratamento de arquivos na API web. Ao receber os fileIds do cliente, o servidor cria objetos UploadedFile com um mimeType genérico (application/octet-stream). Isso faz com que todos os arquivos, incluindo imagens, sejam tratados como documentos genéricos pela API da Anthropic, o que impede a análise correta de imagens.
A solução é armazenar o objeto UploadedFile completo na sessão do servidor no momento do upload e recuperá-lo usando o fileId na chamada de chat.
Sugestão de correção:
- Altere o tipo da sessão para armazenar o objeto
UploadedFilecompleto:const sessions = new Map< string, { session: ChatSession; files: UploadedFile[] } // Alterado de fileIds: string[] >();
- Em
/api/upload, armazene o objeto completo:const entry = getOrCreateSession(sessionId, agentId); entry.files.push(uploaded); // Alterado de entry.fileIds.push(uploaded.fileId)
- Em
/api/chat, recupere os objetos completos em vez de criá-los de forma fictícia:const pendingFileIds: string[] = rawFileIds ? rawFileIds.split(",").filter(Boolean) : []; const pendingFiles = entry.files.filter(f => pendingFileIds.includes(f.fileId));
| RUN npm install | ||
|
|
||
| # Copia source TypeScript e configs | ||
| COPY chatbot/tsconfig.json ./ | ||
| COPY chatbot/src/ ./src/ | ||
|
|
||
| # Compila TypeScript | ||
| RUN npx tsc && npm prune --omit=dev |
There was a problem hiding this comment.
Este Dockerfile pode ser otimizado usando um build multi-stage. Isso resulta em uma imagem final menor e mais segura, pois as devDependencies e os arquivos intermediários da compilação não são incluídos na imagem final.
Exemplo de implementação:
# Estágio de build
FROM node:22-alpine AS builder
WORKDIR /app/chatbot
COPY chatbot/package*.json ./
RUN npm install
COPY chatbot/tsconfig.json ./
COPY chatbot/src/ ./src/
RUN npx tsc
# Estágio final
FROM node:22-alpine
WORKDIR /app/chatbot
COPY chatbot/package*.json ./
RUN npm install --omit=dev
# Copia apenas os artefatos compilados do estágio de build
COPY --from=builder /app/chatbot/dist ./dist
# Copia squads para o path correto
COPY squads/ /app/squads/
EXPOSE 3000
# ... (resto do arquivo)| const stream = (this.client.beta.messages as any).stream( | ||
| { | ||
| model: MODEL, | ||
| max_tokens: 8192, | ||
| thinking: { type: "adaptive" }, | ||
| system: this.agent.systemPrompt, | ||
| messages, | ||
| }, | ||
| { headers: { "anthropic-beta": "files-api-2025-04-14" } } | ||
| ); |
There was a problem hiding this comment.
O código utiliza as any para contornar a tipagem de funcionalidades beta do SDK da Anthropic e hardcode a string do cabeçalho beta em múltiplos locais (files.ts, chat.ts). Para melhorar a manutenibilidade e segurança, sugiro:
- Extrair a string do cabeçalho para uma constante.
- Adicionar um comentário explicando a necessidade do
as anypara referência futura.
Exemplo:
// No topo do arquivo
const ANTHROPIC_BETA_HEADER = { 'anthropic-beta': 'files-api-2025-04-14' };
// ...
// Uso do 'as any' é necessário pois a API de Files ainda está em beta
// e os tipos podem não estar totalmente estáveis no SDK.
const stream = (this.client.beta.messages as any).stream(
{
// ...
},
{ headers: ANTHROPIC_BETA_HEADER }
);| const c = { | ||
| reset: "\x1b[0m", | ||
| bold: "\x1b[1m", | ||
| dim: "\x1b[2m", | ||
| cyan: "\x1b[36m", | ||
| green: "\x1b[32m", | ||
| yellow: "\x1b[33m", | ||
| blue: "\x1b[34m", | ||
| magenta: "\x1b[35m", | ||
| red: "\x1b[31m", | ||
| white: "\x1b[37m", | ||
| bgBlue: "\x1b[44m", | ||
| }; |
There was a problem hiding this comment.
O arquivo define manualmente códigos de cores ANSI, mas a dependência chalk já está incluída no package.json. Utilizar chalk tornaria o código mais legível, robusto e consistente com as dependências do projeto, além de lidar automaticamente com a detecção de suporte a cores no terminal.
Sugestão:
import chalk from 'chalk';
// Substituir o objeto 'c' por chamadas diretas ao chalk
function header(text: string): string {
return `\n${chalk.bold.cyan(text)}`;
}
function success(text: string): string {
return `${chalk.green('✓')} ${text}`;
}
// ... e assim por diante para as outras funções de cor.| healthcheck: | ||
| test: ["CMD", "wget", "-qO-", "http://localhost:3000/"] | ||
| interval: 30s | ||
| timeout: 10s | ||
| retries: 3 | ||
| start_period: 10s |
There was a problem hiding this comment.
A diretiva healthcheck neste arquivo é redundante, pois já está definida no Dockerfile. Embora não cause um erro por serem idênticas, a melhor prática é definir o healthcheck na imagem (no Dockerfile) para que seja portável. Manter a definição em apenas um lugar simplifica a manutenção. Sugiro remover a seção healthcheck deste arquivo.
Instala o dl CLI v1.2.0 (local-deploy.github.io) como ferramenta de
deploy local para o ambiente de desenvolvimento AIOX.
Resultado da instalação no ambiente:
https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy