Fork enxuto de withcatai/node-llama-cpp v3.18.1, mantido apenas com o necessário para rodar o Gemma 4 dentro do servidor gemma-llama.
A lib upstream é genérica e suporta dezenas de arquiteturas, downloaders, embeddings, ranking, infill e templates de projeto. Nosso uso é bem mais estreito: carregar um único .gguf Gemma e expor via API OpenAI-compatível. Este fork remove o que não usamos, aplica os patches necessários para a build atual e publica os binários prontos por plataforma como GitHub Releases.
- CLI: comandos
chat,complete,infill,init,pull,debug,inspect. Mantidos apenaspostinstallesource(build/download/clear) para o pipeline de compilação nativa. - Templates de projeto (
templates/— scaffolds Electron/Node, ~390 KB). - Avaliadores não usados:
LlamaEmbedding,LlamaEmbeddingContext,LlamaRankingContext, token predictors (speculative decoding). - Model downloader:
createModelDownloader,resolveModelFile(consumimos GGUF de path local). - Métodos públicos de
LlamaModel:createEmbeddingContext,createRankingContext. - Outros:
experimentalChunkDocument,docs/,test/,assets/,scripts/,eslint.config.js,vitest.config.ts, dependências e devDependências relacionadas.
- Núcleo de inferência:
LlamaModel,LlamaContext,LlamaChatSession,LlamaChat,LlamaCompletion,LlamaSampler. - Gramáticas:
LlamaGrammar,LlamaJsonSchemaGrammar,utils/gbnfJson/— não dá para remover sem reescrever metade doLlamaChat/LlamaSampler. - Todos os chat wrappers:
Gemma,General,Empty,Llama2/3/3.1/3.2,Mistral,Qwen,DeepSeek,Functionary,Falcon,Alpaca,ChatML,Harmony,Seed,Jinja/Template. OresolveChatWrapperusa todos para detecção automática a partir da metadata GGUF — remover quebra a resolução de templates. bindings/,gguf/,ChatWrapper.ts,utils/LlamaText.ts.
llama/CMakeLists.txt:target_link_libraries(${PROJECT_NAME} "llama-common")(era"common", quebrava com a versão atual dollama.cpp).llama/addon/addon.cpp:static std::atomic_bool loaded{false};(sintaxe correta de inicialização para C++20 atomic).
A versão neste repositório (3.18.1-gemma.1) é distribuída como GitHub Release com um .tgz por plataforma. O workflow .github/workflows/pack.yml faz tudo:
- Roda em paralelo nos runners
windows-latest,ubuntu-latest,macos-14(arm64). - Em cada plataforma:
npm install --ignore-scripts→npm run build→ compila o binding nativo viacmake-js(download da source dollama.cpp+ build). - Remove o
postinstalldopackage.json(binário já está embutido) e adiciona sufixo de plataforma na versão. - Faz prune de tudo que não é runtime:
llama/llama.cpp/,llama/addon/,llama/cmake/,llama/toolchains/,llama/xpack/,llama/CMakeLists.txtetc. Sobra sóllama/localBuilds/<plataforma>/...node+llama/binariesGithubRelease.json. npm pack→ upload do.tgzcomo artifact.- Job
releasebaixa os 3 artifacts, cria/atualiza a releasev3.18.1-gemma.1e anexa todos os.tgz.
gh workflow run pack.yml
gh run watchOu pela UI: Actions → Pack per platform → Run workflow → main.
| Arquivo | Plataforma alvo | Aceleração |
|---|---|---|
node-llama-cpp-3.18.1-gemma.1-win-x64.tgz |
Windows x64 | CPU |
node-llama-cpp-3.18.1-gemma.1-linux-x64.tgz |
Linux x64 | CPU |
node-llama-cpp-3.18.1-gemma.1-mac-arm64-metal.tgz |
macOS arm64 (Apple Silicon) | Metal |
Atenção: cada tarball é específico de uma plataforma. Instalar o .tgz de Windows num Mac não funciona — o .node embutido é incompatível.
Funciona para repo público. Para repo privado, npm precisa de auth (token) ou use a opção 2.
gh release download v3.18.1-gemma.1 -p '*mac-arm64-metal.tgz' -D packages/// package.json
{
"dependencies": {
"node-llama-cpp": "file:packages/node-llama-cpp-3.18.1-gemma.1-mac-arm64-metal.tgz"
}
}Em ambas as opções, npm install no gemma-llama apenas descompacta — não recompila, porque o postinstall foi removido do tarball pelo workflow.
Para gerar um .tgz no seu Mac sem CI:
cd /Users/rafaelcaires/Dev/02_WEB/node-llama-cpp
npm install # roda postinstall: compila o .node localmente
npm run build # tsc
npm pack # gera node-llama-cpp-3.18.1-gemma.1.tgz na raizO .tgz resultante inclui o postinstall (porque você não passou pelo workflow), então será recompilado em qualquer máquina onde for instalado. Para um tarball "binary-baked" como os da release, use o workflow.
src/ # fonte TypeScript (já enxuta)
bindings/ # ponte para o addon C++ (Llama, getLlama)
evaluator/ # LlamaModel, LlamaContext, LlamaChat, LlamaChatSession, ...
chatWrappers/ # detectores de template (Gemma + restante para fallback)
gguf/ # leitor de metadata GGUF
cli/ # CLI mínima: postinstall + source build/download/clear
utils/ # LlamaText, gbnfJson, helpers
llama/ # build do addon C++
CMakeLists.txt # já com patch llama-common aplicado
addon/ # código C++ do binding (já com patch atomic_bool)
cmake/ # módulos cmake
toolchains/ # toolchains cross-compile
.github/workflows/
pack.yml # nosso pipeline (matriz Win/Linux/Mac + release)
build.yml # upstream — não dispara em main
test.yml # upstream — não dispara em main
prLint.yml # upstream — só em PRs
git remote add upstream https://github.com/withcatai/node-llama-cpp.git
git fetch upstream
git merge upstream/master # resolva conflitos em CMakeLists.txt e addon.cpp;
# se os patches já não forem necessários, remova do nosso códigoDepois bumpe version em package.json (ex: 3.19.0-gemma.1), commit, push, e o workflow gera novas releases automaticamente.
MIT — herdada do upstream withcatai/node-llama-cpp.