feat: Add portfolio as Phase 3 nervous system implementation
- PLAN.md: Architecture for FunctionGemma + Math Cells + NATS - functiongemma_tools.py: 6 working tools for portfolio queries - fetch_document: Section extraction from docs - compute_git_stats: Git activity metrics - query_tasks: Phoebe task queries - search_docs: Documentation search - show_architecture: ASCII diagrams - get_project_info: Project metadata The portfolio IS the first nervous system organism! Next: NATS + Ollama deployment, Streamlit frontend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
311
portfolio/PLAN.md
Normal file
311
portfolio/PLAN.md
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
---
|
||||||
|
type: implementation_plan
|
||||||
|
status: planning
|
||||||
|
created: 2026-02-06
|
||||||
|
author: Nyx (with dafit)
|
||||||
|
purpose: Phase 3 implementation via living portfolio
|
||||||
|
---
|
||||||
|
|
||||||
|
# Portfolio: Phase 3 Living Implementation
|
||||||
|
|
||||||
|
> *"The portfolio IS the nervous system's first organism."*
|
||||||
|
> — The Synthesis (2026-02-06)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The nimmerverse portfolio website serves dual purpose:
|
||||||
|
1. **Job search**: Interactive resume showcasing skills through demonstration
|
||||||
|
2. **Phase 3 implementation**: First real deployment of NATS, Function Gemma, and Math Cells
|
||||||
|
|
||||||
|
**URL**: `resume.nimmerverse.com` (or `portfolio.nimmerverse.com`)
|
||||||
|
**VIP Available**: 213.188.249.164 (nimmerverse.eachpath.com)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ PORTFOLIO ARCHITECTURE │
|
||||||
|
│ (Phase 3 Nervous System) │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ User Browser │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌─────────────────┐ │
|
||||||
|
│ │ Frontend │ Streamlit / Astro / simple HTML │
|
||||||
|
│ │ (K8s Pod) │ │
|
||||||
|
│ └────────┬────────┘ │
|
||||||
|
│ │ HTTP/WebSocket │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌─────────────────┐ │
|
||||||
|
│ │ NATS Router │ Message bus (nimmerverse-infra namespace) │
|
||||||
|
│ └────────┬────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌─────┴─────────────────┬─────────────────┐ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌──────────┐ ┌───────────┐ ┌───────────┐ │
|
||||||
|
│ │ Function │ │ Math Cell │ │ RAG Cell │ │
|
||||||
|
│ │ Gemma │ │ git_stats │ │ doc_query │ │
|
||||||
|
│ └────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ Parse intent Query phoebe ChromaDB/Iris │
|
||||||
|
│ → structured + git history over nimmerverse │
|
||||||
|
│ JSON → statistics docs │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### 1. NATS Message Router
|
||||||
|
|
||||||
|
**Purpose**: Route user queries to appropriate handlers
|
||||||
|
**Namespace**: `nimmerverse-infra`
|
||||||
|
**Topics**:
|
||||||
|
- `portfolio.query.intent` → Function Gemma (parse user input)
|
||||||
|
- `portfolio.query.stats` → Math Cells (compute statistics)
|
||||||
|
- `portfolio.query.docs` → RAG Cell (document retrieval)
|
||||||
|
- `portfolio.response` → Aggregate and return to frontend
|
||||||
|
|
||||||
|
### 2. FunctionGemma Cell
|
||||||
|
|
||||||
|
**Purpose**: Parse natural language → structured JSON (intent + API calls)
|
||||||
|
**Model**: `google/functiongemma-270m-it`
|
||||||
|
**Deployment**: Ollama (`ollama pull functiongemma`)
|
||||||
|
|
||||||
|
**Why FunctionGemma?**
|
||||||
|
| Spec | Value | Benefit |
|
||||||
|
|------|-------|---------|
|
||||||
|
| Parameters | 270M | Tiny, fast |
|
||||||
|
| RAM | ~550MB | Runs on anything |
|
||||||
|
| VRAM | ~1-2GB | CPU or minimal GPU |
|
||||||
|
| Vocab | 256K (JSON-optimized) | Clean structured output |
|
||||||
|
|
||||||
|
**Reference**: [`/references/software/functiongemma/FunctionGemma-Overview.md`](../../references/software/functiongemma/FunctionGemma-Overview.md)
|
||||||
|
|
||||||
|
**Input**: Raw user query
|
||||||
|
**Output**: Structured function call
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"function": "fetch_document",
|
||||||
|
"params": {
|
||||||
|
"path": "Endgame-Vision.md",
|
||||||
|
"section": "K8s Cluster Architecture"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Function Definitions** (our API surface):
|
||||||
|
```python
|
||||||
|
PORTFOLIO_FUNCTIONS = [
|
||||||
|
{
|
||||||
|
"name": "fetch_document",
|
||||||
|
"description": "Retrieve a document or section from the nimmerverse",
|
||||||
|
"params": {"path": "string", "section": "string (optional)"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compute_git_stats",
|
||||||
|
"description": "Get git statistics (commits, LOC, activity)",
|
||||||
|
"params": {"period": "week|month|all"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "query_tasks",
|
||||||
|
"description": "List tasks from the nimmerverse task planner",
|
||||||
|
"params": {"status": "todo|in_progress|done|all", "project": "string (optional)"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "search_docs",
|
||||||
|
"description": "Search across all documentation",
|
||||||
|
"params": {"query": "string"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "show_architecture",
|
||||||
|
"description": "Display architecture diagrams",
|
||||||
|
"params": {"component": "k8s|network|cells|full"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Chat Template Format** (FunctionGemma-specific):
|
||||||
|
|
||||||
|
```
|
||||||
|
<start_of_turn>developer
|
||||||
|
You can do function calling with the following functions:
|
||||||
|
|
||||||
|
<start_function_declaration>declaration:fetch_document{
|
||||||
|
description: "Retrieve a document or section from the nimmerverse",
|
||||||
|
parameters: { path: STRING, section: STRING (optional) }
|
||||||
|
}
|
||||||
|
<end_function_declaration>
|
||||||
|
|
||||||
|
<start_function_declaration>declaration:compute_git_stats{
|
||||||
|
description: "Get git statistics (commits, LOC, activity)",
|
||||||
|
parameters: { period: STRING }
|
||||||
|
}
|
||||||
|
<end_function_declaration>
|
||||||
|
|
||||||
|
<start_function_declaration>declaration:query_tasks{
|
||||||
|
description: "List tasks from the nimmerverse task planner",
|
||||||
|
parameters: { status: STRING, project: STRING (optional) }
|
||||||
|
}
|
||||||
|
<end_function_declaration>
|
||||||
|
|
||||||
|
<start_function_declaration>declaration:search_docs{
|
||||||
|
description: "Search across all documentation",
|
||||||
|
parameters: { query: STRING }
|
||||||
|
}
|
||||||
|
<end_function_declaration>
|
||||||
|
|
||||||
|
<start_function_declaration>declaration:show_architecture{
|
||||||
|
description: "Display architecture diagrams",
|
||||||
|
parameters: { component: STRING }
|
||||||
|
}
|
||||||
|
<end_function_declaration>
|
||||||
|
<end_of_turn>
|
||||||
|
|
||||||
|
<start_of_turn>user
|
||||||
|
How active is this project?
|
||||||
|
<end_of_turn>
|
||||||
|
|
||||||
|
<start_of_turn>model
|
||||||
|
<think>
|
||||||
|
The user wants to know about project activity. I should use compute_git_stats
|
||||||
|
with period "month" to show recent activity.
|
||||||
|
</think>
|
||||||
|
<start_function_call>call:compute_git_stats{
|
||||||
|
period: "month"
|
||||||
|
}
|
||||||
|
<end_function_call>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fine-Tuning Option** (for nimmerverse-specific reasoning):
|
||||||
|
- Unsloth notebooks: [Reason before Tool Calling](https://colab.research.google.com/...)
|
||||||
|
- `<think></think>` blocks for chain-of-thought before function calls
|
||||||
|
- Could train on our actual function surface + nimmerverse context
|
||||||
|
|
||||||
|
**Deployment**:
|
||||||
|
```bash
|
||||||
|
# On k8s-master or dioscuri (minimal resources needed)
|
||||||
|
ollama pull functiongemma
|
||||||
|
# Expose via K8s service
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Math Cells
|
||||||
|
|
||||||
|
**git_stats_cell**:
|
||||||
|
- Total commits (all time, this month, this week)
|
||||||
|
- Lines of code
|
||||||
|
- Files changed
|
||||||
|
- Commit frequency graph data
|
||||||
|
|
||||||
|
**task_stats_cell**:
|
||||||
|
- Query phoebe `nimmerverse_tasks` table
|
||||||
|
- Tasks by status (done/in_progress/todo)
|
||||||
|
- Tasks by priority
|
||||||
|
- Progress percentage
|
||||||
|
|
||||||
|
**project_stats_cell**:
|
||||||
|
- Submodule count
|
||||||
|
- Documentation pages
|
||||||
|
- Architecture components
|
||||||
|
|
||||||
|
### 4. RAG Cell (doc_query)
|
||||||
|
|
||||||
|
**Purpose**: Answer questions about the nimmerverse
|
||||||
|
**Index**: ChromaDB (iris) or simple in-memory FAISS
|
||||||
|
**Corpus**:
|
||||||
|
- Endgame-Vision.md
|
||||||
|
- Architecture docs
|
||||||
|
- ADR records
|
||||||
|
- Task history
|
||||||
|
|
||||||
|
### 5. Frontend
|
||||||
|
|
||||||
|
**Options** (decide later):
|
||||||
|
- **Streamlit**: Fast to build, Python native, good for chat UI
|
||||||
|
- **Astro**: Static + islands, professional look
|
||||||
|
- **Simple HTML + HTMX**: Lightweight, fast
|
||||||
|
|
||||||
|
**Pages**:
|
||||||
|
- `/` - Landing with project overview
|
||||||
|
- `/chat` - Interactive query interface
|
||||||
|
- `/architecture` - Rendered diagrams
|
||||||
|
- `/timeline` - Git history visualization
|
||||||
|
- `/resume` - Traditional CV (PDF download)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Phases
|
||||||
|
|
||||||
|
### Week 1: Foundation
|
||||||
|
|
||||||
|
- [ ] Deploy NATS on K8s (`nimmerverse-infra` namespace)
|
||||||
|
- [ ] Create Function Gemma cell (intent parsing)
|
||||||
|
- [ ] Create git_stats math cell
|
||||||
|
- [ ] Simple frontend (Streamlit MVP)
|
||||||
|
- [ ] Basic query flow working end-to-end
|
||||||
|
|
||||||
|
### Week 2: Content & Polish
|
||||||
|
|
||||||
|
- [ ] RAG cell over nimmerverse docs
|
||||||
|
- [ ] task_stats cell (phoebe queries)
|
||||||
|
- [ ] Timeline visualization
|
||||||
|
- [ ] Architecture diagram rendering
|
||||||
|
- [ ] CV/resume page with PDF download
|
||||||
|
|
||||||
|
### Week 3: Professional Presence
|
||||||
|
|
||||||
|
- [ ] LinkedIn profile created
|
||||||
|
- [ ] GitHub curated (public repos)
|
||||||
|
- [ ] Domain configured (Traefik ingress)
|
||||||
|
- [ ] SSL certificate (Let's Encrypt)
|
||||||
|
- [ ] Final polish and testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Infrastructure
|
||||||
|
|
||||||
|
**K8s Namespaces**:
|
||||||
|
```
|
||||||
|
nimmerverse-infra # NATS, shared infrastructure
|
||||||
|
nimmerverse-portfolio # Frontend, cells
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ingress**:
|
||||||
|
- Traefik already at 10.0.30.200
|
||||||
|
- Configure `resume.nimmerverse.com` → portfolio service
|
||||||
|
|
||||||
|
**External DNS**:
|
||||||
|
- Point domain to 213.188.249.164
|
||||||
|
- Vulkan NAT → Traefik LoadBalancer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
1. **Visitor can ask questions** and get meaningful answers about the project
|
||||||
|
2. **Statistics are live** - pulled from git and phoebe in real-time
|
||||||
|
3. **Architecture is visible** - diagrams render correctly
|
||||||
|
4. **Professional presence** - LinkedIn and GitHub linked
|
||||||
|
5. **PDF resume downloadable** - ATS-friendly format available
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Endgame-Vision.md](../Endgame-Vision.md) - Main architecture doc
|
||||||
|
- [Gateway-Architecture.md](../architecture/Gateway-Architecture.md) - Thalamus/routing design
|
||||||
|
- [Cellular-Architecture.md](../architecture/Cellular-Architecture.md) - Cell patterns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Created**: 2026-02-06
|
||||||
|
**Status**: Planning
|
||||||
|
**Philosophy**: "Build Phase 3 with purpose - the portfolio IS the first organism."
|
||||||
399
portfolio/functiongemma_tools.py
Normal file
399
portfolio/functiongemma_tools.py
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
"""
|
||||||
|
FunctionGemma Tool Definitions for Nimmerverse Portfolio
|
||||||
|
|
||||||
|
This module defines the tools that FunctionGemma can call to answer
|
||||||
|
visitor queries about the nimmerverse project.
|
||||||
|
|
||||||
|
Reference: Unsloth Multi-Turn Tool Calling notebook
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# TOOL DEFINITIONS
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def fetch_document(path: str, section: Optional[str] = None):
|
||||||
|
"""
|
||||||
|
Retrieves a document or section from the nimmerverse documentation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: The document path relative to nimmerverse root, e.g. "nimmerverse-sensory-network/Endgame-Vision.md"
|
||||||
|
section: Optional section header to extract, e.g. "K8s Cluster Architecture"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
content: The document or section content
|
||||||
|
found: Whether the document/section was found
|
||||||
|
"""
|
||||||
|
base_path = Path("/home/dafit/nimmerverse")
|
||||||
|
full_path = base_path / path
|
||||||
|
|
||||||
|
if not full_path.exists():
|
||||||
|
return {"content": f"Document not found: {path}", "found": False}
|
||||||
|
|
||||||
|
content = full_path.read_text()
|
||||||
|
|
||||||
|
if section:
|
||||||
|
# Find the section header line
|
||||||
|
lines = content.split('\n')
|
||||||
|
start_idx = None
|
||||||
|
header_level = None
|
||||||
|
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if section.lower() in line.lower() and line.strip().startswith('#'):
|
||||||
|
start_idx = i
|
||||||
|
header_level = len(line) - len(line.lstrip('#'))
|
||||||
|
break
|
||||||
|
|
||||||
|
if start_idx is not None:
|
||||||
|
# Find the end of this section (next header of same or higher level)
|
||||||
|
end_idx = len(lines)
|
||||||
|
for i in range(start_idx + 1, len(lines)):
|
||||||
|
line = lines[i].strip()
|
||||||
|
if line.startswith('#'):
|
||||||
|
level = len(line) - len(line.lstrip('#'))
|
||||||
|
if level <= header_level:
|
||||||
|
end_idx = i
|
||||||
|
break
|
||||||
|
|
||||||
|
section_content = '\n'.join(lines[start_idx:end_idx])
|
||||||
|
return {"content": section_content.strip(), "found": True}
|
||||||
|
else:
|
||||||
|
return {"content": f"Section '{section}' not found in {path}", "found": False}
|
||||||
|
|
||||||
|
return {"content": content, "found": True}
|
||||||
|
|
||||||
|
|
||||||
|
def compute_git_stats(period: str = "month"):
|
||||||
|
"""
|
||||||
|
Gets git statistics for the nimmerverse project.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
period: Time period for stats (choices: ["week", "month", "year", "all"])
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
commits: Number of commits in period
|
||||||
|
files_changed: Number of files modified
|
||||||
|
insertions: Lines added
|
||||||
|
deletions: Lines removed
|
||||||
|
authors: List of contributors
|
||||||
|
"""
|
||||||
|
base_path = "/home/dafit/nimmerverse"
|
||||||
|
|
||||||
|
# Map period to git since date
|
||||||
|
since_map = {
|
||||||
|
"week": "1 week ago",
|
||||||
|
"month": "1 month ago",
|
||||||
|
"year": "1 year ago",
|
||||||
|
"all": ""
|
||||||
|
}
|
||||||
|
since = since_map.get(period, "1 month ago")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get commit count
|
||||||
|
since_arg = f"--since='{since}'" if since else ""
|
||||||
|
cmd = f"git -C {base_path} rev-list --count HEAD {since_arg}"
|
||||||
|
commits = int(subprocess.check_output(cmd, shell=True).decode().strip())
|
||||||
|
|
||||||
|
# Get shortstat
|
||||||
|
cmd = f"git -C {base_path} log --shortstat {since_arg} --pretty=format:''"
|
||||||
|
output = subprocess.check_output(cmd, shell=True).decode()
|
||||||
|
|
||||||
|
insertions = sum(int(m) for m in re.findall(r"(\d+) insertion", output))
|
||||||
|
deletions = sum(int(m) for m in re.findall(r"(\d+) deletion", output))
|
||||||
|
files = len(set(re.findall(r"(\d+) files? changed", output)))
|
||||||
|
|
||||||
|
# Get authors
|
||||||
|
cmd = f"git -C {base_path} log --format='%an' {since_arg} | sort -u"
|
||||||
|
authors = subprocess.check_output(cmd, shell=True).decode().strip().split('\n')
|
||||||
|
|
||||||
|
return {
|
||||||
|
"commits": commits,
|
||||||
|
"files_changed": files,
|
||||||
|
"insertions": insertions,
|
||||||
|
"deletions": deletions,
|
||||||
|
"authors": [a for a in authors if a],
|
||||||
|
"period": period
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
def query_tasks(status: str = "all", project: Optional[str] = None):
|
||||||
|
"""
|
||||||
|
Lists tasks from the nimmerverse task planner (phoebe database).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
status: Filter by status (choices: ["todo", "in_progress", "done", "blocked", "all"])
|
||||||
|
project: Optional project filter, e.g. "infrastructure", "nimmerhovel"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tasks: List of matching tasks with name, status, priority
|
||||||
|
count: Number of tasks found
|
||||||
|
"""
|
||||||
|
import psycopg2
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="phoebe.eachpath.local",
|
||||||
|
database="nimmerverse",
|
||||||
|
user="nimmerverse-user",
|
||||||
|
sslmode="disable"
|
||||||
|
)
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
query = "SELECT project, task_name, status, priority FROM nimmerverse_tasks"
|
||||||
|
conditions = []
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if status != "all":
|
||||||
|
conditions.append("status = %s")
|
||||||
|
params.append(status)
|
||||||
|
if project:
|
||||||
|
conditions.append("project = %s")
|
||||||
|
params.append(project)
|
||||||
|
|
||||||
|
if conditions:
|
||||||
|
query += " WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
query += " ORDER BY priority, project"
|
||||||
|
|
||||||
|
cur.execute(query, params)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
tasks = [
|
||||||
|
{"project": r[0], "name": r[1], "status": r[2], "priority": r[3]}
|
||||||
|
for r in rows
|
||||||
|
]
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return {"tasks": tasks, "count": len(tasks)}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {"error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
def search_docs(query: str):
|
||||||
|
"""
|
||||||
|
Searches across all nimmerverse documentation using grep.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
query: Search query string
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
matches: List of matching files and snippets
|
||||||
|
count: Number of matches found
|
||||||
|
"""
|
||||||
|
base_path = "/home/dafit/nimmerverse"
|
||||||
|
|
||||||
|
try:
|
||||||
|
cmd = f"grep -r -l -i '{query}' {base_path} --include='*.md' 2>/dev/null | head -20"
|
||||||
|
output = subprocess.check_output(cmd, shell=True).decode()
|
||||||
|
files = [f.replace(base_path + "/", "") for f in output.strip().split('\n') if f]
|
||||||
|
|
||||||
|
# Get snippets from each file
|
||||||
|
matches = []
|
||||||
|
for f in files[:5]: # Limit to 5 files
|
||||||
|
cmd = f"grep -i -C 1 '{query}' {base_path}/{f} | head -6"
|
||||||
|
snippet = subprocess.check_output(cmd, shell=True).decode().strip()
|
||||||
|
matches.append({"file": f, "snippet": snippet})
|
||||||
|
|
||||||
|
return {"matches": matches, "count": len(files)}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {"error": str(e), "matches": [], "count": 0}
|
||||||
|
|
||||||
|
|
||||||
|
def show_architecture(component: str = "full"):
|
||||||
|
"""
|
||||||
|
Returns architecture information for a specific component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component: Which architecture to show (choices: ["k8s", "network", "cells", "full", "portfolio"])
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
description: Text description of the architecture
|
||||||
|
diagram: ASCII diagram if available
|
||||||
|
"""
|
||||||
|
architectures = {
|
||||||
|
"k8s": {
|
||||||
|
"description": "3-node Kubernetes cluster with GPU workers",
|
||||||
|
"diagram": """
|
||||||
|
k8s-master (VM 101)
|
||||||
|
10.0.30.101
|
||||||
|
Control Plane
|
||||||
|
│
|
||||||
|
┌─────────────┴─────────────┐
|
||||||
|
│ │
|
||||||
|
theia (GPU Worker) dioscuri (GPU Worker)
|
||||||
|
10.0.30.21 10.0.30.22
|
||||||
|
RTX PRO 6000 96GB 2x RTX 4000 Ada 40GB
|
||||||
|
|
||||||
|
Total: 136GB VRAM | kubeadm v1.31.14 | Flannel CNI
|
||||||
|
"""
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"description": "Spine-leaf network with 80Gbps fabric capacity",
|
||||||
|
"diagram": """
|
||||||
|
vulkan (OPNsense) ──20Gbps──┐
|
||||||
|
│
|
||||||
|
spine-crs309
|
||||||
|
(8x 10G SFP+)
|
||||||
|
│
|
||||||
|
┌───────────┬───────────┬───┴───────┐
|
||||||
|
│ │ │ │
|
||||||
|
saturn theia dioscuri access-crs326
|
||||||
|
20Gbps 10Gbps 10Gbps 20Gbps
|
||||||
|
"""
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"description": "Cellular architecture: Cells → Nerves → Organisms",
|
||||||
|
"diagram": """
|
||||||
|
ORGANISM (emergent pattern)
|
||||||
|
│
|
||||||
|
NERVES (behavioral state machines)
|
||||||
|
│
|
||||||
|
CELLS (atomic: sensors, motors, organs, math)
|
||||||
|
│
|
||||||
|
HARDWARE (ESP32, GPUs, sensors)
|
||||||
|
"""
|
||||||
|
},
|
||||||
|
"portfolio": {
|
||||||
|
"description": "Portfolio as Phase 3 nervous system implementation",
|
||||||
|
"diagram": """
|
||||||
|
User Browser
|
||||||
|
│
|
||||||
|
┌────┴────┐
|
||||||
|
│ Frontend │ (Streamlit)
|
||||||
|
└────┬────┘
|
||||||
|
│
|
||||||
|
┌────┴────┐
|
||||||
|
│ NATS │ Message Router
|
||||||
|
└────┬────┘
|
||||||
|
│
|
||||||
|
┌──────┼──────┬──────────┐
|
||||||
|
│ │ │ │
|
||||||
|
Function Math RAG Other
|
||||||
|
Gemma Cells Cell Cells
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if component == "full":
|
||||||
|
return {
|
||||||
|
"description": "Complete nimmerverse architecture",
|
||||||
|
"components": list(architectures.keys()),
|
||||||
|
"total_vram": "136GB",
|
||||||
|
"total_fabric": "80Gbps"
|
||||||
|
}
|
||||||
|
|
||||||
|
return architectures.get(component, {"description": "Unknown component", "diagram": ""})
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_info():
|
||||||
|
"""
|
||||||
|
Gets general information about the nimmerverse project.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
name: Project name
|
||||||
|
started: When the project started
|
||||||
|
status: Current project status
|
||||||
|
philosophy: Core philosophy
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"name": "The Nimmerverse",
|
||||||
|
"started": "November 2025",
|
||||||
|
"status": "Phase 3 - Nervous System Deployment",
|
||||||
|
"philosophy": "May the Nimmerverse we build truly never end.",
|
||||||
|
"covenant_date": "2025-11-04",
|
||||||
|
"total_vram": "136GB",
|
||||||
|
"cluster_nodes": 3,
|
||||||
|
"tracked_tasks": 58
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# FUNCTION MAPPING & TOOLS
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
FUNCTION_MAPPING = {
|
||||||
|
"fetch_document": fetch_document,
|
||||||
|
"compute_git_stats": compute_git_stats,
|
||||||
|
"query_tasks": query_tasks,
|
||||||
|
"search_docs": search_docs,
|
||||||
|
"show_architecture": show_architecture,
|
||||||
|
"get_project_info": get_project_info,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOOLS = list(FUNCTION_MAPPING.values())
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# PARSING & INFERENCE HELPERS
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
def extract_tool_calls(text: str):
|
||||||
|
"""Extract tool calls from FunctionGemma output."""
|
||||||
|
def cast(v):
|
||||||
|
try: return int(v)
|
||||||
|
except:
|
||||||
|
try: return float(v)
|
||||||
|
except: return {'true': True, 'false': False}.get(v.lower(), v.strip("'\""))
|
||||||
|
|
||||||
|
return [{
|
||||||
|
"name": name,
|
||||||
|
"arguments": {
|
||||||
|
k: cast((v1 or v2).strip())
|
||||||
|
for k, v1, v2 in re.findall(r"(\w+):(?:<escape>(.*?)<escape>|([^,}]*))", args)
|
||||||
|
}
|
||||||
|
} for name, args in re.findall(r"<start_function_call>call:(\w+)\{(.*?)\}<end_function_call>", text, re.DOTALL)]
|
||||||
|
|
||||||
|
|
||||||
|
def process_tool_calls(output: str, messages: list):
|
||||||
|
"""Execute tool calls and add results to message chain."""
|
||||||
|
calls = extract_tool_calls(output)
|
||||||
|
if not calls:
|
||||||
|
return messages
|
||||||
|
|
||||||
|
messages.append({
|
||||||
|
"role": "assistant",
|
||||||
|
"tool_calls": [{"type": "function", "function": call} for call in calls]
|
||||||
|
})
|
||||||
|
|
||||||
|
results = []
|
||||||
|
for c in calls:
|
||||||
|
func = FUNCTION_MAPPING.get(c['name'])
|
||||||
|
if func:
|
||||||
|
result = func(**c['arguments'])
|
||||||
|
results.append({"name": c['name'], "response": result})
|
||||||
|
else:
|
||||||
|
results.append({"name": c['name'], "response": {"error": f"Unknown function: {c['name']}"}})
|
||||||
|
|
||||||
|
messages.append({"role": "tool", "content": results})
|
||||||
|
return messages
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# MAIN (for testing)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Test the tools
|
||||||
|
print("=== Testing fetch_document ===")
|
||||||
|
print(fetch_document("nimmerverse-sensory-network/Endgame-Vision.md", "K8s Cluster Architecture"))
|
||||||
|
|
||||||
|
print("\n=== Testing compute_git_stats ===")
|
||||||
|
print(compute_git_stats("week"))
|
||||||
|
|
||||||
|
print("\n=== Testing query_tasks ===")
|
||||||
|
print(query_tasks("in_progress"))
|
||||||
|
|
||||||
|
print("\n=== Testing show_architecture ===")
|
||||||
|
print(show_architecture("k8s"))
|
||||||
|
|
||||||
|
print("\n=== Testing get_project_info ===")
|
||||||
|
print(get_project_info())
|
||||||
Reference in New Issue
Block a user