Lattice
연구를 위한 작업공간
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기KAZER — espaço web/PWA de conversa com IA, pesquisa, workspace e integrações seguras.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Assistente de IA em português, feito como app web instalável (PWA). Conversa, pesquisa na internet em tempo real, cria arquivos, sites, jogos, PDFs e apresentações, lê anexos e oferece os principais modelos de IA do mercado nos planos pagos.
| Pasta | O que tem |
|---|---|
kazer/interfaces/web/ | App web (Starlette) e a tela inteira em static/ (HTML, CSS e JS sem build) |
kazer/chat/ | Conversa: serviço, geração em streaming, pesquisa (prefetch.py, web_tools.py), arquivos, PDFs |
kazer/brain/ | Provedores de modelo (Groq, Anthropic, OpenAI-compatível) e o governador de limites da Groq |
kazer/billing/ | Planos, divisão de cada assinatura, modelos premium, créditos e webhook do Stripe |
kazer/auth/ | Contas (Supabase Auth ou local), sessões e recuperação de senha |
kazer/security/ | Segredos por escopo, limites de taxa, guardas de entrada e saída |
kazer/integrations/ | Serviços externos (pagamento) |
kazer/core, memory, runtime, tools, observability | Contratos do agente (base para evoluções) |
supabase/migrations/ | Esquema do banco, com RLS em todas as tabelas |
tests/ | Testes automáticos (make test) |
docs/ | Documentação: veja o índice abaixo |
| Documento | Assunto |
|---|---|
| ARCHITECTURE.md | Princípios, fronteiras e fluxo do agente |
| SECURITY.md | Riscos e controles |
| docs/NEGOCIO.md | Planos, margem, créditos, Stripe e chaves das IAs |
| docs/ESCALA.md | Como o KAZER aguenta mais gente na Groq grátis |
| docs/supabase-chat-storage.md | Banco do chat no Supabase |
| CONTRIBUTING.md | Como mexer no código sem quebrar nada |
| CHANGELOG.md | O que mudou em cada versão |
Requer Python 3.11 ou superior. Na raiz do repositório:
make setup
make test
make run
main.py é apenas um ponto de composição mínimo e ainda não inicia um agente funcional. Os módulos de produto permanecem como stubs intencionais.
make web # http://127.0.0.1:8000 (KAZER_HOST/KAZER_PORT alteram o endereço)
A tela abre quase toda preta: partículas convergem das bordas e formam o símbolo e o nome KAZER, que se abrem para revelar o início (≈1,9 s; qualquer toque ou tecla pula). O início cabe numa única tela, sem rolagem: uma cena em pixel art de um quarto à noite (janela com a cidade ao lado do computador; o programador digita, toma café e às vezes olha para quem está na tela; no monitor, o KAZER em versão "coder" programa, testa, constrói e publica), a frase "Você imagina. O KAZER executa_", os botões Criar conta e Entrar e os links para os Termos de Uso e a Política de Privacidade. A interface está em português do Brasil. Tudo é HTML, CSS e Canvas sem build nem dependências de frontend, servido pelo próprio app em kazer/interfaces/web/static/.
No PC e no notebook (telas a partir de 960 × 560 px) o layout muda: a cena vira um palco de cinema em plano aberto à esquerda (scene-desktop.js, 288 × 240 pixels) e a entrada fica num painel à direita, sem esconder a cena. Esse palco tem chuva escorrendo na janela, gato dormindo no peitoril, vela, varal de luzes, segundo monitor com logs, poeira na luz da luminária, brilho (bloom) só nas fontes de luz e uma leve inclinação 3D que segue o mouse. O módulo só é baixado em telas grandes; o celular continua com a versão leve.
O símbolo do KAZER (Fenda) e seus estados estão em docs/brand.md. Com o manifesto (/manifest.webmanifest), o site pode ser adicionado à tela inicial e abre em modo app, sem barra de endereço.
O que funciona de verdade, ponta a ponta:
/termos) e Política de Privacidade (/privacidade) que descrevem o tratamento real de dados;Em desenvolvimento os e-mails são gravados em data/outbox/*.eml; abra o arquivo e use o link. Em produção (KAZER_ENV=production) o app exige HTTPS em KAZER_PUBLIC_URL, cookies Secure e SMTP configurado, e se recusa a iniciar sem eles. Dados coletados, retenção e exclusão: docs/privacy-data-map.md.
Cada push na main gera um deploy de produção pela integração Git da Vercel. O vercel.json fixa o preset python e o pyproject.toml aponta a entrada ASGI (kazer.interfaces.web.asgi:app), então a configuração não depende do preset salvo no painel. Uma única função Python serve a tela, os assets e a API; arquivos do repositório não são publicados como estáticos.
Funções serverless não têm disco persistente, e o SQLite local perderia contas entre execuções. Por isso, na Vercel a tela fica no ar com as contas fechadas (a API responde 503 auth_unavailable e o botão aparece desativado com aviso) até existir um banco persistente e SMTP configurados. Nada de login simulado. Com SUPABASE_URL e SUPABASE_PUBLISHABLE_KEY cadastradas, as contas passam a usar o Supabase Auth (também na Vercel). O chat guarda as conversas no Postgres do Supabase quando ele está configurado (inclusive na Vercel), e no SQLite local no desenvolvimento; sem nenhum dos dois ele responde chat_unavailable e avisa na tela, em vez de fingir que gravou. Estado detalhado: docs/supabase-integration-status.md; esquema, migrações e reversão: docs/supabase-chat-storage.md.
Login, confirmação de e-mail e sessão já válida levam direto ao chat (sem tela intermediária). O chat é HTML, CSS e módulos JavaScript sem build, carregado só depois do login (chat.js, chat.css):
squares.js). Na primeira mensagem aceita pelo servidor o campo some, o laço para e o canvas é liberado; se o envio falhar antes, o estado vazio continua.+, o pill KAZ 1.1 Baixo (modelo e esforço numa folha só; cada nível de esforço troca o modelo por trás, ver Groq abaixo), o microfone e enviar/parar. Enter envia no computador (Shift+Enter pula linha); no celular, Enter pula linha. O rascunho fica guardado na aba e volta se o envio falhar. Digitar / abre a lista das suas Skills: dá para escrever para filtrar ou escolher (setas e Enter, ou toque); a escolhida vira uma pastilha acima do campo e vale para aquela mensagem (até 3).+ → Adicionar à conversa: Câmera (celular), Fotos e Arquivos de verdade, com prévia, progresso e remoção. Fotos grandes são reduzidas no aparelho e regravadas sem metadados de localização. Pesquisa, Busca na web e Memória mostram o estado real. GitHub aparece como um botão redondo, já de início: toque para conectar (cola o token uma vez), toque de novo para ligar ou desligar nesta conversa.library.js + library.css, baixados quando a aba abre): tela própria na gaveta. A Biblioteca reúne o que você enviou (fotos, documentos, arquivos) e o que o KAZER produziu, com filtros (Tudo, Do KAZER, Imagens, Docs), uma página por vez ao rolar e miniatura carregada só quando o item chega perto da tela.No computador o KAZER faz o que o celular não tem como fazer, sem tirar nada de lá:
palette.js, baixada no primeiro atalho): Ctrl K (⌘K no Mac) abre uma caixa que faz tudo pelo teclado — ir para qualquer seção, começar conversa, abrir o KZ Code, os planos ou as configurações, e buscar entre as conversas pelo servidor. Setas navegam, Enter executa, Esc fecha. O atalho fica à vista, dentro da busca da gaveta.Ctrl K paleta, Ctrl B gaveta, Ctrl Shift O nova conversa, Ctrl Shift F nova conversa no KZ Code, Esc fecha o que estiver aberto. Enquanto você escreve num campo, o atalho é do campo — o app não rouba a tecla.No celular nada disso aparece: não há teclado físico, a gaveta está a um toque e a paleta nunca é baixada.
Sem um modelo configurado, o chat abre, mostra o histórico e explica que o KAZ 1.1 ainda não está conectado: nenhuma resposta é inventada.
O comando kazer abre o KAZER no terminal (kazer/interfaces/terminal/). Conectar leva dois comandos — pipx install git+https://github.com/jeanvicen/KAZER e kazer entrar <endereço do site> —, e a tela Configurações › Terminal já mostra o endereço certo, com botão de copiar. Não é um KAZER paralelo: ele fala com o mesmo servidor pela mesma API do site, então as conversas são as mesmas, as habilidades instaladas entram no contexto, os conectores ligados viram ferramentas, o plano limita e a memória lembra. Quando o servidor ganha um recurso, o terminal ganha junto — e não tem como divergir.
kazer entrar <endereço> entra com a conta do site e já guarda o servidor (a senha não aparece nem fica no histórico)
kazer abre uma conversa (na primeira vez, o próprio kazer pede o login)
kazer "sua pergunta" responde e sai
cat erro.log | kazer a pergunta (ou o contexto) vem pelo cano
kazer conversas [busca] lista as conversas; `kazer continuar 2` volta para uma
kazer habilidades as Skills instaladas na conta
kazer conectores o que está ligado, e quantas ferramentas cada um trouxe
kazer status conta, plano e quanto resta da janela
kazer servidor https://… troca de servidor (ou a variável `KAZER_URL`)
kazer sair encerra a sessão deste computador
Na conversa: /nova, /conversas, /continuar <n>, /habilidades, /conectores, /biblioteca, /status, /code (KZ Code, planos pagos), /pensamento, /sair. A resposta chega em streaming, os passos das ferramentas aparecem enquanto acontecem, e Ctrl-C interrompe no servidor, não só na tela.
Decisões que valem explicar:
~/.kazer/sessao.json com permissão 600 dentro de uma pasta 700. Ela nunca entra em argumento de linha de comando (que o ps de qualquer um mostra), nunca é impressa e nunca aparece em erro. A senha só existe durante o kazer entrar: ela não é guardada em lugar nenhum. Quando o servidor renova a sessão, o arquivo é regravado — e sessão inválida é apagada em vez de ficar para trás.localhost, só https. Em http o cookie iria em claro, então o terminal recusa o endereço.kazer "pergunta" > resposta.txt grava a resposta, sem moldura, sem recuo e sem cor — dá para usar em script e em atalho de editor. Com NO_COLOR=1 ou num terminal sem cor, tudo continua legível.KAZER_HOME muda a pasta de configuração (útil em máquina compartilhada e em teste). O servidor padrão é http://localhost:8000, o mesmo padrão do app.
O navegador só conhece o nome público KAZ 1.1. Qual provedor e qual modelo atendem esse nome é decisão do servidor, por variáveis de ambiente. As chaves são lidas apenas por kazer/security/secrets.py (allowlist do escopo model) e nunca vão para o navegador, para logs, para respostas de erro ou para o repr dos objetos.
KAZER_MODEL_PROVIDER | Chave (variável secreta) | Observação |
|---|---|---|
xai (Grok) | XAI_API_KEY | API compatível com OpenAI, imagens ligadas |
openai | OPENAI_API_KEY | imagens ligadas |
gemini | GEMINI_API_KEY | endpoint compatível com OpenAI |
groq | GROQ_API_KEY | o esforço escolhido troca o modelo (ver abaixo); sem KAZER_MODEL |
deepseek, mistral, together | DEEPSEEK_API_KEY, MISTRAL_API_KEY, TOGETHER_API_KEY | só texto por padrão |
openrouter | OPENROUTER_API_KEY | vários modelos por uma chave |
ollama | (sem chave) | servidor local em http://127.0.0.1:11434/v1 |
custom | KAZER_MODEL_API_KEY (opcional) | qualquer API compatível com OpenAI em KAZER_MODEL_BASE_URL |
anthropic (Claude) | ANTHROPIC_API_KEY | SDK oficial: pip install "kazer[anthropic]"; padrão claude-opus-5-5 |
Com KAZER_MODEL_PROVIDER=groq e a GROQ_API_KEY no servidor, o KAZ 1.1 roda na API da Groq e cada nível de esforço aponta para um modelo diferente. O navegador manda só baixo, medio, alto, extra ou max — nunca um ID de modelo: quem mapeia é o servidor, e esforço fora da oferta é recusado (invalid_effort), não só escondido.
| Esforço | Cadeia padrão (o primeiro que existir responde; os seguintes são reserva) |
|---|---|
| Baixo | llama-3.1-8b-instant, openai/gpt-oss-20b:low |
| Médio | openai/gpt-oss-20b:medium, llama-3.1-8b-instant |
| Alto | llama-3.3-70b-versatile, openai/gpt-oss-120b:medium |
| Extra | openai/gpt-oss-120b:medium, llama-3.3-70b-versatile |
| Máx | openai/gpt-oss-120b:high, openai/gpt-oss-120b:medium |
O que vem depois dos dois-pontos é o reasoning_effort do modelo. Os IDs da Groq mudam com o tempo (modelos são aposentados e renomeados) e este ambiente não alcança a documentação deles, então confira a lista em console.groq.com e, se precisar, troque um nível sem mexer no código: KAZER_GROQ_MODEL_BAIXO, _MEDIO, _ALTO, _EXTRA, _MAX (mesmo formato modelo:raciocínio,reserva). Se a Groq responder que um modelo foi aposentado ou não existe, o KAZER passa sozinho para o próximo da cadeia; se a cadeia inteira sumir, a resposta falha com o erro genérico e o log diz model.chain_exhausted.
Segurança: a chave só é lida por secrets.py e só vai no cabeçalho Authorization — nunca no corpo, no log, no repr nem em erro. A URL base é a da Groq, fixa. O raciocínio cru do modelo é pedido escondido (include_reasoning: false) e descartado no servidor mesmo se vier. Esforço maior pesa mais na franquia (Baixo +0, Médio +1, Alto +2, Extra +3, Máx +4 unidades). Para aceitar imagens, defina KAZER_GROQ_VISION_MODEL com um modelo com visão da Groq; sem ele, imagens ficam desligadas.
Exemplo com o Grok, num .env local (nunca versionado):
KAZER_MODEL_PROVIDER=xai
KAZER_MODEL=grok-4 # o identificador do modelo no painel do provedor
XAI_API_KEY=... # só no servidor
Na Vercel, cadastre as mesmas variáveis em Settings → Environment Variables (a chave como Sensitive). Opcionais:
KAZER_MODEL_DEEP: modelo usado quando Pensamento profundo está ligado (por exemplo, a versão "reasoning" do provedor). Sem ele, o botão aparece indisponível. KAZER_MODEL_REASONING=effort envia também reasoning_effort (low no esforço Baixo, high no profundo) para provedores que aceitam.KAZER_MODEL_VISION=true|false: força o suporte a imagens.KAZER_MODEL_WEB_SEARCH=true: liga a busca na web do servidor da Anthropic (só nesse provedor; tem custo).KAZER_MODEL_MAX_TOKENS, KAZER_MODEL_TIMEOUT: limites da resposta.KAZER_CHAT_HOURLY_UNITS (60) e KAZER_CHAT_DAILY_UNITS (300): cota por conta, contada no servidor, com o horário exato de liberação mostrado quando acaba. O custo acompanha a complexidade do pedido: mensagem = 1, pensamento profundo +2, busca +1, cada imagem +1, cada PDF +2, prompt longo +1 e histórico longo +1, com teto de 12 por envio. O que foi cobrado fica gravado na própria mensagem, então o consumo é auditável.KAZER_CHAT_MAX_CONVERSATIONS (100): histórico leve. Quando a conta chega no limite e uma conversa nova nasce, a mais antiga sai junto com os anexos dela, na mesma transação.Na Anthropic, o esforço Baixo vira output_config.effort: "low", o pensamento profundo vira "high" com pensamento adaptativo e resumo do raciocínio, e as recusas usam o fallbacks: "default" do servidor nos modelos que suportam.
Mais provedores: crie um adaptador em kazer/brain/model_provider.py que implemente ModelProvider.stream() e registre a chave na allowlist de secrets.py.
Copie .env.example para .env somente em ambiente local e preencha apenas credenciais necessárias, fora do controle de versão; make web carrega o .env se ele existir. A autenticação usa as variáveis KAZER_* e SMTP_*; a senha SMTP só é lida por security/secrets.py. As chaves de provedores de modelo (seção acima) também só são lidas por security/secrets.py, pelo adaptador do modelo; as das demais integrações continuam ilustrativas. Leia SECURITY.md antes de adicionar segredos.
kazer/tools/ e derive de BaseTool.read, write, network, shell, filesystem, admin).security/tool_guard.py.security/secrets.py através do guard.Crie um adaptador específico em kazer/integrations/, sem misturar credenciais ou lógica de domínio com o core. Declare escopos, limites de rede e operações de leitura/escrita; conecte apenas por contratos de ferramentas autorizados. Nunca registre tokens nem conteúdo pessoal. Inclua testes com doubles locais, política de retries/limites e documentação de revogação.
.env e dados locais estão ignorados.Consulte ROADMAP.md para as sete fases. A tela de entrada e o chat principal foram antecipados a pedido (fase 7); pesquisa, conectores e voz seguem pendentes.
As decisões iniciais refletem recomendações públicas da Anthropic: começar com a solução mais simples que funciona, compor padrões explícitos, tratar contexto como recurso finito, criar ferramentas claras e avaliá-las, além de usar permissões e sandbox. Fontes: Building effective AI agents, Effective context engineering for AI agents, Writing effective tools for AI agents e Claude Code security. São princípios consultados, não uma alegação de que KAZER replica sistemas internos da Anthropic/Claude.
kazer/chat/artifacts.pyforja.js + forja.css; o nome antigo era Forja): a oficina de código, na gaveta, com o nome em pixel discreto. Nos planos pagos abre uma tela como a do Claude Code: campo para descrever a tarefa, ideias para começar, e as sessões recentes (a conversa em modo código, guardada só no servidor). Nele o modelo recebe instruções para entregar arquivos inteiros, com nome na própria cerca, o que alimenta os artefatos. No gratuito aparece só a tela de compra, sem mostrar a oficina; a trava é do servidor (402 plan_required), não da interface.https://api.githubcopilot.com/mcp/, endereço fixo no servidor — ninguém digita URL, então não há como apontar o KAZER para um endereço interno). Você cola um token fine-grained uma vez; ele vai direto ao servidor do KAZER, nunca volta para a tela e só é lido por kazer_connection_secret() (exige auth.uid()). O plano decide o que o GitHub pode fazer, nos dois lados: no gratuito o cabeçalho X-MCP-Readonly pede só leitura e o KAZER filtra qualquer ferramenta que não seja readOnlyHint; no Pro e no Ultra a escrita (abrir PR, enviar commit) é liberada. As ferramentas vão ao modelo e o resultado volta como resultado de ferramenta, nunca como instrução do sistema.loader.js): quando uma tela demora, aparece o Kazinho levantando um halter — o mesmo personagem da tela sem internet, em pixel, com gotinha de suor. Só entra depois de 420 ms (carregamento rápido não pisca boneco na cara de ninguém), desenha a 20 quadros por segundo e para quando a aba fica escondida.content-visibility para pular o que está fora dela e o streaming desenhado no máximo uma vez por quadro. Cada tela extra (configurações, planos, biblioteca, KZ Code, carregador, microfone) só baixa seu módulo e seu CSS quando a pessoa a abre: o caminho da conversa não engorda com o que ninguém usou ainda.plans.js + plans.css, baixados só no clique): Configurações › Planos mostra o plano da conta e quanto resta da janela; o botão abre a tela cheia com os três planos (KAZER, KAZER Pro a R$ 59,99/mês e KAZER Ultra a R$ 179,99/mês), mensal ou anual, com a Fenda pulsando, os cartões entrando em cascata e o contador de unidades subindo. Quando o limite acaba, a mensagem diz quanto falta para liberar e oferece o plano de cima com quantas vezes mais uso ele dá. A cobrança ainda não está ligada: a tela guarda o interesse na conta e diz isso, em vez de simular uma compra.settings.js, carregado sob demanda): Conta (trocar senha, sair dos outros dispositivos), Planos, Personalização (apelido com prévia da saudação, estilo das respostas com exemplo ao vivo, instruções pessoais), Memória, Interface (tema escuro, claro ou do sistema; idioma português ou inglês; animações, tamanho do texto, fundo animado, Enter), Dados e privacidade (exportar JSON, apagar conversas e excluir a conta segurando o botão), Conectores, Skills, Terminal e Sobre. Tudo salva sozinho no servidor.i18n.js traduz a interface a partir de um dicionário (i18n-en.js, baixado só em inglês) e nunca toca no que você escreveu nem no que o modelo respondeu. Texto sem tradução fica em português, não some. O modelo também passa a responder no idioma escolhido, a menos que você escreva em outro. Ficam em português por enquanto: as páginas legais, a tela de entrada, o texto do terminal e as instruções das Skills oficiais.skills.js, slash.js): Configurações › Skills tem Suas e Catálogo. O catálogo traz as Skills oficiais (escritas pela equipe, fixas no código) e as da comunidade (publicadas por quem as criou). Instalar faz uma cópia sua, congelada: quem publicou não consegue alterar depois. Toda Skill, no salvar, no publicar e a cada instalação, passa pela guarda de segurança (skill_guard.py): caracteres invisíveis (largura zero, bidi, Tags Unicode), pedido para ignorar regras ou revelar o prompt do sistema, envio de dados para fora por link ou imagem e pedido de segredo são recusados. Mesmo assim o texto da comunidade entra no contexto como texto de terceiros, e, enquanto uma Skill da comunidade está em uso, os conectores ficam só em leitura. Publicar tem limite (5 por hora).net.js + offline.js): pedidos com prazo, novas tentativas com espera crescente e uma sonda real (/api/health), porque o navigator.onLine sozinho mente. Quando a rede cai aparece a tela "Ops, parece que tamo sem internet, fi.", com o Kazinho, um personagem em pixel com a cabeça da Fenda, que varre a casa, cochila, brinca de bola, treina e mostra o muque. Quando a conexão volta ele comemora e a tela some. O service worker (/sw.js) guarda só a casca do app, nunca /api/, para essa tela abrir até sem rede.