From 8a9a120d1ffddd72baa0e44e47c514e77bd5178c Mon Sep 17 00:00:00 2001 From: avi Date: Mon, 20 Apr 2026 13:13:41 -0500 Subject: [PATCH] Initial local AI stack --- .gitignore | 6 +++ bootstrap.sh | 17 ++++++++ scripts/probe.sh | 31 ++++++++++++++ scripts/render-config.py | 92 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 .gitignore create mode 100755 bootstrap.sh create mode 100755 scripts/probe.sh create mode 100755 scripts/render-config.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..87d1934 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +*.pyc +*.log +.env +.env.* +generated/ diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..e2ef928 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +BASE_DIR="$(cd "$(dirname "$0")" && pwd)" + +"$BASE_DIR/scripts/probe.sh" +python3 "$BASE_DIR/scripts/render-config.py" + +sudo systemctl daemon-reload +sudo systemctl restart ollama + +echo +echo "=== machine profile ===" +cat "$BASE_DIR/generated/machine-profile.json" +echo +echo "=== continue config ===" +echo "~/.continue/config.yaml updated" diff --git a/scripts/probe.sh b/scripts/probe.sh new file mode 100755 index 0000000..43453bf --- /dev/null +++ b/scripts/probe.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail + +BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)" +mkdir -p "$BASE_DIR/generated" + +THREADS="$(nproc)" +RAM_GB="$(free -g | awk '/^Mem:/{print $2}')" +CPU_MODEL="$(lscpu | awk -F: '/Model name/{gsub(/^[ \t]+/, "", $2); print $2; exit}')" + +GPU_VENDOR="none" +GPU_VRAM_GB="0" + +if command -v nvidia-smi >/dev/null 2>&1; then + GPU_VENDOR="nvidia" + GPU_VRAM_GB="$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | head -n1 | awk '{printf "%.0f", $1/1024}')" +elif command -v rocm-smi >/dev/null 2>&1; then + GPU_VENDOR="amd" +fi + +cat > "$BASE_DIR/generated/machine-profile.json" <= 8: + planner_context = 8192 + +if ram < 16: + planner_model = "qwen2.5-coder:7b" + critic_model = "qwen2.5-coder:7b" + planner_context = 4096 + critic_context = 4096 + +config = f"""name: local-cursor-open +version: 1.0.0 +schema: v1 + +models: + - name: Builder + provider: ollama + model: {builder_model} + roles: [chat, edit, apply] + capabilities: + - tool_use + defaultCompletionOptions: + contextLength: {builder_context} + maxTokens: 1200 + temperature: 0.1 + keepAlive: 300 + + - name: Autocomplete + provider: ollama + model: {autocomplete_model} + roles: [autocomplete] + defaultCompletionOptions: + contextLength: {autocomplete_context} + maxTokens: 160 + temperature: 0.05 + keepAlive: 180 + + - name: Planner + provider: ollama + model: {planner_model} + roles: [chat] + capabilities: + - tool_use + - image_input + defaultCompletionOptions: + contextLength: {planner_context} + maxTokens: 1400 + temperature: 0.2 + keepAlive: 120 + + - name: Critic + provider: ollama + model: {critic_model} + roles: [chat] + defaultCompletionOptions: + contextLength: {critic_context} + maxTokens: 1200 + temperature: 0.1 + keepAlive: 120 + +rules: + - Keep changes minimal. + - Reuse existing patterns. + - Do not refactor unrelated code. + - Prefer plain-English answers unless asked for code. +""" + +out_path.write_text(config) +print(f"Wrote {{out_path}}")