first commit
This commit is contained in:
commit
0bde6a4808
7
.gitea/actions/setup/action.yml
Normal file
7
.gitea/actions/setup/action.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: "Install UV"
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||||
48
.gitea/workflows/code-quality.yml
Normal file
48
.gitea/workflows/code-quality.yml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
name: Python Code Quality
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
lock_file:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uv lock --locked
|
||||||
|
linting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lock_file]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uvx ruff check .
|
||||||
|
formatting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lock_file]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uvx ruff format --check .
|
||||||
|
type_consistency:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lock_file]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uv run pyright .
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lock_file]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uv run pytest -v --durations=0 --cov --cov-report=xml
|
||||||
|
- name: Upload Coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
build:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
needs: [linting, formatting, type_consistency, tests]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: uv build
|
||||||
60
.gitignore
vendored
Normal file
60
.gitignore
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# === sub-módulos clonados ===
|
||||||
|
src/modules/
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# === Autotools build artefacts ===
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
aclocal.m4
|
||||||
|
autom4te.cache/
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
configure
|
||||||
|
depcomp
|
||||||
|
install-sh
|
||||||
|
missing
|
||||||
|
py-compile
|
||||||
|
stamp-h1
|
||||||
|
|
||||||
|
# === Build & dist directories ===
|
||||||
|
/build/
|
||||||
|
/dist/
|
||||||
|
!/dist/releases/
|
||||||
|
!/dist/releases/*
|
||||||
|
*.tar.gz
|
||||||
|
*.tar.bz2
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# === Python cache & venv ===
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
*.egg-info/
|
||||||
|
.eggs/
|
||||||
|
venv/
|
||||||
|
.env/
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# === Editor / OS junk ===
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# === Logs ===
|
||||||
|
*.log
|
||||||
|
nohup.out
|
||||||
|
|
||||||
|
# === IDE / workspace ===
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# === Backup copies ===
|
||||||
|
*.old
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
125
Makefile.am
Normal file
125
Makefile.am
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
SUBDIRS = src
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Caminhos e artefactos
|
||||||
|
# ===========================
|
||||||
|
TOP_DIR = $(shell pwd)
|
||||||
|
DIST_DIR = $(TOP_DIR)/dist
|
||||||
|
BUILD_DIR = $(TOP_DIR)/build
|
||||||
|
GIT_VER = $(shell git describe --tags --always --dirty 2>/dev/null || echo "0.1-dev")
|
||||||
|
SRC_TAR = $(DIST_DIR)/myhomelab-$(GIT_VER)-src.tar.gz
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Configurações de Git
|
||||||
|
# ===========================
|
||||||
|
GIT_USER ?= "neo.webmaster.2@gmail.com"
|
||||||
|
GIT_EMAIL ?= "neo.webmaster.2@gmail.com"
|
||||||
|
GIT_REMOTE ?= "origin"
|
||||||
|
GIT_BRANCH ?= "main"
|
||||||
|
COMMIT_MSG ?= "Auto-commit via make git"
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Alvos principais
|
||||||
|
# ===========================
|
||||||
|
.PHONY: all tarball git release run clean-local check-remote
|
||||||
|
|
||||||
|
all: $(DIST_DIR)
|
||||||
|
|
||||||
|
$(DIST_DIR):
|
||||||
|
@mkdir -p $(DIST_DIR)
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Empacotamento do código-fonte
|
||||||
|
# ===========================
|
||||||
|
tarball: $(SRC_TAR)
|
||||||
|
|
||||||
|
$(SRC_TAR):
|
||||||
|
@echo "[TAR] Empacotando código-fonte (versão $(GIT_VER))..."
|
||||||
|
@mkdir -p "$(DIST_DIR)" "$(BUILD_DIR)"
|
||||||
|
cd "$(TOP_DIR)" && tar \
|
||||||
|
--exclude="$(notdir $(SRC_TAR))" \
|
||||||
|
--exclude="$(DIST_DIR)" \
|
||||||
|
--exclude="$(BUILD_DIR)" \
|
||||||
|
--exclude='*/__pycache__' \
|
||||||
|
--exclude='*/.venv' \
|
||||||
|
--exclude='*/venv' \
|
||||||
|
--exclude='*.pyc' \
|
||||||
|
--exclude='*.pyo' \
|
||||||
|
--exclude='*.o' \
|
||||||
|
--exclude='*.a' \
|
||||||
|
--exclude='*.so' \
|
||||||
|
-czf "$(SRC_TAR)" .
|
||||||
|
@echo "[✔] Tarball gerado em $(SRC_TAR)"
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Git (commit + push)
|
||||||
|
# ===========================
|
||||||
|
git: check-remote
|
||||||
|
@echo "📦 Commit automático → Gitea"
|
||||||
|
@git config user.name $(GIT_USER)
|
||||||
|
@git config user.email $(GIT_EMAIL)
|
||||||
|
@git rev-parse --abbrev-ref HEAD >/dev/null 2>&1 || true
|
||||||
|
@git add -A
|
||||||
|
@git commit -m "$$(echo '$(COMMIT_MSG)')" || echo "Nenhuma modificação para commitar."
|
||||||
|
@git push $(GIT_REMOTE) $(GIT_BRANCH)
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Release (Tarball + Tag)
|
||||||
|
# ===========================
|
||||||
|
release: tarball check-remote
|
||||||
|
@echo "🚀 Publicando build em dist/releases (versão: $(GIT_VER))"
|
||||||
|
@mkdir -p $(DIST_DIR)/releases
|
||||||
|
@cp $(SRC_TAR) $(DIST_DIR)/releases/ 2>/dev/null || echo "⚠️ Nenhum tarball encontrado. Execute 'make tarball' primeiro."
|
||||||
|
@echo "📦 Adicionando releases ignoradas (forçado)"
|
||||||
|
@git add -f $(DIST_DIR)/releases/* 2>/dev/null || echo "⚠️ Nenhum artefato novo para adicionar."
|
||||||
|
@git commit -m "Build automático: release $(GIT_VER)" || echo "Nenhum ficheiro novo para commitar."
|
||||||
|
@git push origin main
|
||||||
|
@TAG="$(GIT_VER)"; \
|
||||||
|
if git rev-parse "$$TAG" >/dev/null 2>&1; then \
|
||||||
|
echo "⚠️ Tag $$TAG já existente."; \
|
||||||
|
else \
|
||||||
|
echo "🏷 Criando tag $$TAG"; \
|
||||||
|
git tag -a "$$TAG" -m "Release automática $$TAG"; \
|
||||||
|
git push origin "$$TAG"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Git Remote (HTTPS → SSH Auto-Fix)
|
||||||
|
# ===========================
|
||||||
|
check-remote:
|
||||||
|
@REMOTE_URL=$$(git remote get-url $(GIT_REMOTE)); \
|
||||||
|
if echo $$REMOTE_URL | grep -q '^https://gitea\.neoricalex\.com'; then \
|
||||||
|
echo "⚠️ Repositório configurado com HTTPS:"; \
|
||||||
|
echo " $$REMOTE_URL"; \
|
||||||
|
echo "🔄 Convertendo para SSH (porta 2222)..."; \
|
||||||
|
SSH_URL=$$(echo $$REMOTE_URL | sed -E 's|https://gitea\.neoricalex\.com[:/]+|ssh://git@gitea.neoricalex.com:2222/|'); \
|
||||||
|
git remote set-url $(GIT_REMOTE) $$SSH_URL; \
|
||||||
|
echo "✅ Remote atualizado para:"; \
|
||||||
|
git remote -v; \
|
||||||
|
else \
|
||||||
|
echo "✅ Remote SSH já configurado:"; \
|
||||||
|
git remote -v | grep $(GIT_REMOTE); \
|
||||||
|
fi; \
|
||||||
|
echo "🔍 Testando conectividade SSH com Gitea..."; \
|
||||||
|
if ssh -T git@gitea.neoricalex.com -p 2222 2>&1 | grep -q "successfully authenticated"; then \
|
||||||
|
echo "✅ Conexão SSH funcional com Gitea."; \
|
||||||
|
else \
|
||||||
|
echo "❌ Falha na autenticação SSH com Gitea."; \
|
||||||
|
echo " Verifique a chave em ~/.ssh/id_ed25519.pub e nas SSH Keys do Gitea."; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Teste
|
||||||
|
# ===========================
|
||||||
|
run:
|
||||||
|
@python3 src/root/__main__.py
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Limpeza
|
||||||
|
# ===========================
|
||||||
|
clean-local:
|
||||||
|
@echo "[CLEAN] Removendo diretórios temporários..."
|
||||||
|
@rm -rf $(BUILD_DIR)
|
||||||
|
@find $(DIST_DIR) -maxdepth 1 -type f ! -path "$(DIST_DIR)/releases/*" -delete 2>/dev/null || true
|
||||||
|
@echo "[✔] Limpeza concluída (releases preservadas)"
|
||||||
50
README.md
Normal file
50
README.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
```
|
||||||
|
myhomelab/
|
||||||
|
├─ configure.ac
|
||||||
|
├─ Makefile.am
|
||||||
|
├─ README.md
|
||||||
|
├─ pyproject.toml # uv + ruff + (pytest)
|
||||||
|
├─ uv.lock
|
||||||
|
├─ src/
|
||||||
|
│ └─ neuro/
|
||||||
|
│ ├─ __init__.py
|
||||||
|
│ ├─ cli.py # entrypoints (tui / bench / repl)
|
||||||
|
│ │
|
||||||
|
│ ├─ tui/
|
||||||
|
│ │ ├─ app.py # Textual App
|
||||||
|
│ │ ├─ screens.py # screens/modals
|
||||||
|
│ │ ├─ widgets.py # componentes reutilizáveis
|
||||||
|
│ │ └─ state.py # estado e store (sem IA aqui)
|
||||||
|
│ │
|
||||||
|
│ ├─ engine/
|
||||||
|
│ │ ├─ __init__.py
|
||||||
|
│ │ ├─ session.py # Session, Chat/Prompt state
|
||||||
|
│ │ └─ runtime.py # “orquestração” do loop (streaming, cancel)
|
||||||
|
│ │
|
||||||
|
│ ├─ ai/
|
||||||
|
│ │ ├─ __init__.py
|
||||||
|
│ │ ├─ config.py # dataclasses: dims, vocab, layers, seed
|
||||||
|
│ │ ├─ tokenizer.py # tokenize/detokenize
|
||||||
|
│ │ ├─ embeddings.py # tok->vec, pos enc
|
||||||
|
│ │ ├─ transformer.py # forward() (minimo)
|
||||||
|
│ │ ├─ head.py # logits/probs
|
||||||
|
│ │ ├─ sampling.py # greedy, top-k, top-p, temp
|
||||||
|
│ │ └─ model.py # Model = cola tudo (tokenize->sample)
|
||||||
|
│ │
|
||||||
|
│ ├─ utils/
|
||||||
|
│ │ ├─ logging.py
|
||||||
|
│ │ ├─ rng.py
|
||||||
|
│ │ └─ perf.py
|
||||||
|
│ │
|
||||||
|
│ └─ data/
|
||||||
|
│ ├─ vocab.json # opcional no MVP
|
||||||
|
│ └─ tiny_weights.npz # opcional (se quiseres pesos fixos)
|
||||||
|
│
|
||||||
|
├─ tests/
|
||||||
|
│ ├─ test_tokenizer.py
|
||||||
|
│ ├─ test_sampling.py
|
||||||
|
│ └─ test_transformer_shapes.py
|
||||||
|
└─ tools/
|
||||||
|
├─ bench.py # microbench do forward/sampling
|
||||||
|
└─ export_vocab.py
|
||||||
|
```
|
||||||
37
configure.ac
Normal file
37
configure.ac
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
AC_INIT([MYHOMELAB], [NEO_VERSION], [https://gitea.neoricalex.com/neo/myhomelab.git])
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Diretórios base
|
||||||
|
# ===========================
|
||||||
|
AC_CONFIG_AUX_DIR([.])
|
||||||
|
AC_SUBST([TOP_DIR], ['$(CURDIR)'])
|
||||||
|
AC_SUBST([BUILD_DIR], ['$(CURDIR)/build'])
|
||||||
|
AC_SUBST([DIST_DIR], ['$(CURDIR)/dist'])
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Versão dinâmica (Git)
|
||||||
|
# ===========================
|
||||||
|
m4_define([NEO_VERSION],
|
||||||
|
m4_esyscmd_s([git describe --tags --always --dirty 2>/dev/null || echo "0.1-dev"]))
|
||||||
|
AC_SUBST([NEO_VERSION])
|
||||||
|
|
||||||
|
# Caminho do tarball dinâmico (protegido contra M4 expansion)
|
||||||
|
AC_SUBST([SRC_TAR],
|
||||||
|
['$(CURDIR)/dist/myhomelab-@NEO_VERSION@-src.tar.gz'])
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Automake + Python
|
||||||
|
# ===========================
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
|
||||||
|
AM_PATH_PYTHON([3.0])
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Arquivos Makefile
|
||||||
|
# ===========================
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
src/Makefile
|
||||||
|
src/neuro/Makefile
|
||||||
|
])
|
||||||
|
AC_OUTPUT
|
||||||
24
pyproject.toml
Normal file
24
pyproject.toml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[project]
|
||||||
|
name = "neuro"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
authors = [
|
||||||
|
{ name = "neoricalex", email = "neo.webmaster.2@gmail.com" }
|
||||||
|
]
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
neuro = "neuro:main"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["uv_build>=0.10.8,<0.11.0"]
|
||||||
|
build-backend = "uv_build"
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"pyright>=1.1.408",
|
||||||
|
"pytest>=9.0.2",
|
||||||
|
"pytest-cov>=7.0.0",
|
||||||
|
]
|
||||||
18
src/Makefile.am
Normal file
18
src/Makefile.am
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
SUBDIRS = root
|
||||||
|
|
||||||
|
bin_SCRIPTS = neuro
|
||||||
|
CLEANFILES = $(bin_SCRIPTS)
|
||||||
|
EXTRA_DIST = neuro.in
|
||||||
|
|
||||||
|
# ===========================
|
||||||
|
# Substituição dinâmica
|
||||||
|
# ===========================
|
||||||
|
neuro: neuro.in Makefile
|
||||||
|
@which git >/dev/null || { echo "⚠️ Git não encontrado — instale-o manualmente."; exit 1; }
|
||||||
|
sed \
|
||||||
|
-e 's,[@]pythondir[@],$(pythondir),g' \
|
||||||
|
-e 's,[@]PACKAGE[@],$(PACKAGE),g' \
|
||||||
|
-e 's,[@]VERSION[@],$(VERSION),g' \
|
||||||
|
< $(srcdir)/neuro.in > neuro
|
||||||
|
chmod +x neuro
|
||||||
|
|
||||||
11
src/neuro.in
Normal file
11
src/neuro.in
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.insert(1, '@pythondir@')
|
||||||
|
|
||||||
|
from bootstrap import Application
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = Application(package="@PACKAGE@", version="@VERSION@")
|
||||||
|
app.run()
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user