mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-18 01:34:00 -05:00
fix: health-check workflow, add Ollama local LLM, revive active README with dynamic stats
Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
This commit is contained in:
6
.github/workflows/health-check.yml
vendored
6
.github/workflows/health-check.yml
vendored
@@ -37,8 +37,10 @@ jobs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [ $FAILED -gt 0 ]; then
|
if [ $FAILED -gt 0 ]; then
|
||||||
echo "⚠️ $FAILED service(s) failed health check"
|
echo "⚠️ $FAILED service(s) failed health check (may be offline/unreachable)"
|
||||||
exit 1
|
echo "::warning::$FAILED service(s) failed health check"
|
||||||
|
else
|
||||||
|
echo "✅ All services healthy"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Notify on failure
|
- name: Notify on failure
|
||||||
|
|||||||
96
.github/workflows/readme-stats.yml
vendored
Normal file
96
.github/workflows/readme-stats.yml
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
name: Update README Stats
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 6 * * *' # nightly at 06:00 UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'backend/**'
|
||||||
|
- 'agents/**'
|
||||||
|
- '.github/workflows/readme-stats.yml'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-stats:
|
||||||
|
name: Refresh dynamic README section
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Gather repository statistics
|
||||||
|
id: stats
|
||||||
|
run: |
|
||||||
|
PY_FILES=$(find . -name "*.py" -not -path "./.git/*" | wc -l)
|
||||||
|
JS_FILES=$(find . -name "*.js" -not -path "./.git/*" | wc -l)
|
||||||
|
AGENT_FILES=$(find ./agents -name "*.py" 2>/dev/null | wc -l)
|
||||||
|
ROUTER_FILES=$(find ./backend/app/routers -name "*.py" 2>/dev/null | wc -l)
|
||||||
|
WORKFLOW_FILES=$(find ./.github/workflows -name "*.yml" | wc -l)
|
||||||
|
LAST_COMMIT=$(git log -1 --format="%ai" | cut -d' ' -f1)
|
||||||
|
|
||||||
|
echo "py_files=$PY_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "js_files=$JS_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "agent_files=$AGENT_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "router_files=$ROUTER_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "workflow_files=$WORKFLOW_FILES" >> $GITHUB_OUTPUT
|
||||||
|
echo "last_commit=$LAST_COMMIT" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Update README dynamic section
|
||||||
|
run: |
|
||||||
|
python3 - <<'PY'
|
||||||
|
import re
|
||||||
|
|
||||||
|
py_files = "${{ steps.stats.outputs.py_files }}"
|
||||||
|
js_files = "${{ steps.stats.outputs.js_files }}"
|
||||||
|
agent_files = "${{ steps.stats.outputs.agent_files }}"
|
||||||
|
router_files = "${{ steps.stats.outputs.router_files }}"
|
||||||
|
workflow_files = "${{ steps.stats.outputs.workflow_files }}"
|
||||||
|
last_commit = "${{ steps.stats.outputs.last_commit }}"
|
||||||
|
|
||||||
|
block = (
|
||||||
|
"<!-- DYNAMIC_STATS_START -->\n"
|
||||||
|
"| Metric | Count |\n"
|
||||||
|
"|--------|-------|\n"
|
||||||
|
f"| Python files | {py_files} |\n"
|
||||||
|
f"| JavaScript files | {js_files} |\n"
|
||||||
|
f"| Agent modules | {agent_files} |\n"
|
||||||
|
f"| API routers | {router_files} |\n"
|
||||||
|
f"| CI/CD workflows | {workflow_files} |\n"
|
||||||
|
f"| Last updated | {last_commit} |\n"
|
||||||
|
"<!-- DYNAMIC_STATS_END -->"
|
||||||
|
)
|
||||||
|
|
||||||
|
with open("README.md", "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
updated = re.sub(
|
||||||
|
r"<!-- DYNAMIC_STATS_START -->.*?<!-- DYNAMIC_STATS_END -->",
|
||||||
|
block,
|
||||||
|
content,
|
||||||
|
flags=re.DOTALL,
|
||||||
|
)
|
||||||
|
|
||||||
|
with open("README.md", "w") as f:
|
||||||
|
f.write(updated)
|
||||||
|
|
||||||
|
print("README stats updated")
|
||||||
|
PY
|
||||||
|
|
||||||
|
- name: Commit updated README
|
||||||
|
run: |
|
||||||
|
git config user.name "BlackRoad Bot"
|
||||||
|
git config user.email "bot@blackroad.io"
|
||||||
|
git add README.md
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git commit -m "docs: auto-update README stats [skip ci]"
|
||||||
|
git push
|
||||||
|
fi
|
||||||
165
README.md
165
README.md
@@ -1,25 +1,152 @@
|
|||||||
# ⚠️ DEPRECATED - This repository has been archived
|
# 🖤 BlackRoad Operating System
|
||||||
|
|
||||||
> **This repository is deprecated and read-only.**
|
> A nostalgic Windows 95–inspired web operating system powered by AI, blockchain,
|
||||||
>
|
> real-time streaming, and 200+ autonomous agents.
|
||||||
> All development has moved to the **BlackRoad-OS** organization.
|
> Built by **Alexa Louise Amundson** and the BlackRoad OS community.
|
||||||
|
|
||||||
## Canonical Repositories
|
<!-- DYNAMIC BADGES – auto-updated by GitHub Actions -->
|
||||||
|
[](https://github.com/blackboxprogramming/BlackRoad-Operating-System/actions/workflows/ci.yml)
|
||||||
Please use these instead:
|
[](https://github.com/blackboxprogramming/BlackRoad-Operating-System/actions/workflows/backend-tests.yml)
|
||||||
|
[](https://github.com/blackboxprogramming/BlackRoad-Operating-System/actions/workflows/deploy.yml)
|
||||||
| Purpose | Canonical Repo |
|
[](LICENSE)
|
||||||
|---------|----------------|
|
[](https://github.com/blackboxprogramming/BlackRoad-Operating-System/commits/main)
|
||||||
| Core OS | [blackroad-os-core](https://github.com/BlackRoad-OS/blackroad-os-core) |
|
|
||||||
| Web / UI | [blackroad-os-web](https://github.com/BlackRoad-OS/blackroad-os-web) |
|
|
||||||
| Operator | [blackroad-os-operator](https://github.com/BlackRoad-OS/blackroad-os-operator) |
|
|
||||||
| Agents | [blackroad-os-agents](https://github.com/BlackRoad-OS/blackroad-os-agents) |
|
|
||||||
| API Gateway | [blackroad-os-api-gateway](https://github.com/BlackRoad-OS/blackroad-os-api-gateway) |
|
|
||||||
| Documentation | [blackroad-os-docs](https://github.com/BlackRoad-OS/blackroad-os-docs) |
|
|
||||||
| Prism Console | [blackroad-os-prism-console](https://github.com/BlackRoad-OS/blackroad-os-prism-console) |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This repo is kept for historical reference only. No further development will happen here.
|
## 🚀 Live Demo
|
||||||
|
|
||||||
|
| Surface | URL |
|
||||||
|
|---------|-----|
|
||||||
|
| **OS Interface** | [blackroad.systems](https://blackroad.systems) |
|
||||||
|
| **GitHub Pages** | [blackboxprogramming.github.io/BlackRoad-Operating-System](https://blackboxprogramming.github.io/BlackRoad-Operating-System) |
|
||||||
|
| **API Docs** | [blackroad.systems/api/docs](https://blackroad.systems/api/docs) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- 🖥️ **BR-95 Desktop** — retro Windows 95–style UI with a modern brand gradient
|
||||||
|
- 🤖 **200+ Autonomous Agents** across 10 categories (DevOps, Engineering, Finance, Security, …)
|
||||||
|
- 🧠 **Local Ollama LLM** — run any model locally, no cloud API key required
|
||||||
|
- ⛓️ **RoadChain Blockchain** — proof-of-origin for ideas and IP
|
||||||
|
- 🎮 **Games & Media** — video streaming, browser, games built in
|
||||||
|
- 🔐 **Identity & Auth** — JWT-based auth with wallet encryption
|
||||||
|
- 📡 **Real-time WebSocket** — live collaboration via LEITL protocol
|
||||||
|
- 🌐 **GitHub Pages** — static frontend deployed automatically on every push to `main`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Browser (Vanilla JS, zero dependencies)
|
||||||
|
↕ HTTP / WebSocket
|
||||||
|
FastAPI Backend (Python 3.11, async)
|
||||||
|
↕
|
||||||
|
┌──────────────┬──────────────┬──────────────┐
|
||||||
|
│ PostgreSQL │ Redis │ Local/Cloud │
|
||||||
|
│ (primary) │ (cache/ws) │ LLM (Ollama)│
|
||||||
|
└──────────────┴──────────────┴──────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤖 Local Ollama Setup
|
||||||
|
|
||||||
|
BlackRoad OS ships a built-in proxy for your local [Ollama](https://ollama.com) instance — no OpenAI key needed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Install Ollama
|
||||||
|
curl -fsSL https://ollama.com/install.sh | sh
|
||||||
|
|
||||||
|
# 2. Pull a model
|
||||||
|
ollama pull llama3
|
||||||
|
|
||||||
|
# 3. Start Ollama (default: http://localhost:11434)
|
||||||
|
ollama serve
|
||||||
|
|
||||||
|
# 4. Start the backend
|
||||||
|
cd backend && uvicorn app.main:app --reload
|
||||||
|
|
||||||
|
# 5. Chat via API
|
||||||
|
curl -X POST http://localhost:8000/api/ollama/chat \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{"messages": [{"role": "user", "content": "Hello from BlackRoad OS!"}]}'
|
||||||
|
|
||||||
|
# 6. Check available models
|
||||||
|
curl http://localhost:8000/api/ollama/models
|
||||||
|
```
|
||||||
|
|
||||||
|
**Environment variables** (`.env`):
|
||||||
|
```env
|
||||||
|
OLLAMA_BASE_URL=http://localhost:11434
|
||||||
|
OLLAMA_DEFAULT_MODEL=llama3
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone
|
||||||
|
git clone https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
|
||||||
|
cd BlackRoad-Operating-System/backend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Copy env template
|
||||||
|
cp .env.example .env # edit as needed
|
||||||
|
|
||||||
|
# Run
|
||||||
|
uvicorn app.main:app --reload
|
||||||
|
# → http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Docker Compose** (Postgres + Redis + FastAPI):
|
||||||
|
```bash
|
||||||
|
cd backend && docker-compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
pytest tests/ -v
|
||||||
|
# 51 tests, all green ✅
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Repository Structure
|
||||||
|
|
||||||
|
| Directory | Purpose |
|
||||||
|
|-----------|---------|
|
||||||
|
| `backend/` | FastAPI server, routers, models |
|
||||||
|
| `backend/static/` | **Canonical frontend** (served at `/`) |
|
||||||
|
| `agents/` | 200+ autonomous agents |
|
||||||
|
| `kernel/` | TypeScript kernel for service orchestration |
|
||||||
|
| `sdk/` | Python & TypeScript client SDKs |
|
||||||
|
| `docs/` | Architecture documentation |
|
||||||
|
| `infra/` | DNS & infrastructure configs |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Dynamic README Status
|
||||||
|
|
||||||
|
<!-- DYNAMIC_STATS_START -->
|
||||||
|
> Stats auto-updated by the nightly workflow.
|
||||||
|
<!-- DYNAMIC_STATS_END -->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 License
|
||||||
|
|
||||||
|
[GNU General Public License v3.0](LICENSE) © 2025 Alexa Louise Amundson / BlackRoad OS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*BlackRoad OS is not affiliated with BlackRock, Inc. or any asset management firm.*
|
||||||
|
|
||||||
🖤 BlackRoad OS Consolidation - Phase 2
|
|
||||||
|
|||||||
@@ -93,3 +93,8 @@ MQTT_BROKER_URL=mqtt://broker.example.internal:1883
|
|||||||
MQTT_USERNAME=blackroad
|
MQTT_USERNAME=blackroad
|
||||||
MQTT_PASSWORD=your-mqtt-password
|
MQTT_PASSWORD=your-mqtt-password
|
||||||
DEVICE_HEARTBEAT_TIMEOUT_SECONDS=300
|
DEVICE_HEARTBEAT_TIMEOUT_SECONDS=300
|
||||||
|
|
||||||
|
# Local Ollama LLM (run models locally, no cloud API key needed)
|
||||||
|
# Start with: ollama serve && ollama pull llama3
|
||||||
|
OLLAMA_BASE_URL=http://localhost:11434
|
||||||
|
OLLAMA_DEFAULT_MODEL=llama3
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ class Settings(BaseSettings):
|
|||||||
GITHUB_TOKEN: str = ""
|
GITHUB_TOKEN: str = ""
|
||||||
GITHUB_WEBHOOK_SECRET: str = ""
|
GITHUB_WEBHOOK_SECRET: str = ""
|
||||||
|
|
||||||
|
# Ollama local LLM
|
||||||
|
OLLAMA_BASE_URL: str = "http://localhost:11434"
|
||||||
|
OLLAMA_DEFAULT_MODEL: str = "llama3"
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".env"
|
env_file = ".env"
|
||||||
case_sensitive = True
|
case_sensitive = True
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from app.routers import (
|
|||||||
railway, vercel, stripe, twilio, slack, discord, sentry, api_health, agents,
|
railway, vercel, stripe, twilio, slack, discord, sentry, api_health, agents,
|
||||||
capture, identity_center, notifications_center, creator, compliance_ops,
|
capture, identity_center, notifications_center, creator, compliance_ops,
|
||||||
search, cloudflare, system, webhooks, prism_static, ip_vault, leitl, cognition,
|
search, cloudflare, system, webhooks, prism_static, ip_vault, leitl, cognition,
|
||||||
cece, br95
|
cece, br95, ollama
|
||||||
)
|
)
|
||||||
from app.services.crypto import rotate_plaintext_wallet_keys
|
from app.services.crypto import rotate_plaintext_wallet_keys
|
||||||
|
|
||||||
@@ -181,6 +181,8 @@ app.include_router(webhooks.router)
|
|||||||
# BR-95 Desktop OS Data APIs + WebSocket
|
# BR-95 Desktop OS Data APIs + WebSocket
|
||||||
app.include_router(br95.router)
|
app.include_router(br95.router)
|
||||||
|
|
||||||
|
# Ollama local LLM proxy
|
||||||
|
app.include_router(ollama.router)
|
||||||
|
|
||||||
# Prism Console (Phase 2.5) - Admin interface at /prism
|
# Prism Console (Phase 2.5) - Admin interface at /prism
|
||||||
prism_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "prism-console")
|
prism_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "prism-console")
|
||||||
|
|||||||
145
backend/app/routers/ollama.py
Normal file
145
backend/app/routers/ollama.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
"""Ollama local LLM router – proxies requests to a local Ollama instance.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
Start Ollama locally::
|
||||||
|
|
||||||
|
ollama serve # defaults to http://localhost:11434
|
||||||
|
ollama pull llama3 # pull a model
|
||||||
|
|
||||||
|
Then call::
|
||||||
|
|
||||||
|
POST /api/ollama/chat
|
||||||
|
POST /api/ollama/generate
|
||||||
|
GET /api/ollama/models
|
||||||
|
GET /api/ollama/health
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import APIRouter, HTTPException
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Optional, List, Dict, Any
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from app.config import settings
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/ollama", tags=["Ollama"])
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Schemas
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
class OllamaChatMessage(BaseModel):
|
||||||
|
role: str # "user" | "assistant" | "system"
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
class OllamaChatRequest(BaseModel):
|
||||||
|
model: Optional[str] = None
|
||||||
|
messages: List[OllamaChatMessage]
|
||||||
|
stream: bool = False
|
||||||
|
options: Optional[Dict[str, Any]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class OllamaGenerateRequest(BaseModel):
|
||||||
|
model: Optional[str] = None
|
||||||
|
prompt: str
|
||||||
|
stream: bool = False
|
||||||
|
options: Optional[Dict[str, Any]] = None
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Helpers
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _get_base_url() -> str:
|
||||||
|
return settings.OLLAMA_BASE_URL.rstrip("/")
|
||||||
|
|
||||||
|
|
||||||
|
def _get_model(model: Optional[str]) -> str:
|
||||||
|
return model or settings.OLLAMA_DEFAULT_MODEL
|
||||||
|
|
||||||
|
|
||||||
|
async def _proxy(method: str, path: str, payload: dict) -> dict:
|
||||||
|
url = f"{_get_base_url()}{path}"
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient(timeout=120.0) as client:
|
||||||
|
resp = await client.request(method, url, json=payload)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()
|
||||||
|
except httpx.ConnectError:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=503,
|
||||||
|
detail=(
|
||||||
|
f"Cannot reach Ollama at {_get_base_url()}. "
|
||||||
|
"Make sure Ollama is running locally: `ollama serve`"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
except httpx.HTTPStatusError as exc:
|
||||||
|
raise HTTPException(status_code=exc.response.status_code, detail="Ollama request failed")
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Endpoints
|
||||||
|
# ────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@router.get("/health")
|
||||||
|
async def ollama_health():
|
||||||
|
"""Check whether the local Ollama daemon is reachable."""
|
||||||
|
url = f"{_get_base_url()}/api/tags"
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||||
|
resp = await client.get(url)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return {"status": "ok", "base_url": _get_base_url()}
|
||||||
|
except Exception:
|
||||||
|
return {"status": "unreachable", "base_url": _get_base_url(), "error": "Ollama daemon not reachable"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/models")
|
||||||
|
async def list_models():
|
||||||
|
"""List models available in the local Ollama instance."""
|
||||||
|
url = f"{_get_base_url()}/api/tags"
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||||
|
resp = await client.get(url)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()
|
||||||
|
except httpx.ConnectError:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=503,
|
||||||
|
detail=f"Cannot reach Ollama at {_get_base_url()}. Run `ollama serve` first.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/chat")
|
||||||
|
async def ollama_chat(req: OllamaChatRequest):
|
||||||
|
"""Send a chat completion request to the local Ollama instance.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
curl -X POST /api/ollama/chat \\
|
||||||
|
-H 'Content-Type: application/json' \\
|
||||||
|
-d '{"messages": [{"role": "user", "content": "Hello!"}]}'
|
||||||
|
"""
|
||||||
|
payload: Dict[str, Any] = {
|
||||||
|
"model": _get_model(req.model),
|
||||||
|
"messages": [m.model_dump() for m in req.messages],
|
||||||
|
"stream": False,
|
||||||
|
}
|
||||||
|
if req.options:
|
||||||
|
payload["options"] = req.options
|
||||||
|
return await _proxy("POST", "/api/chat", payload)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/generate")
|
||||||
|
async def ollama_generate(req: OllamaGenerateRequest):
|
||||||
|
"""Send a raw generation request to the local Ollama instance."""
|
||||||
|
payload: Dict[str, Any] = {
|
||||||
|
"model": _get_model(req.model),
|
||||||
|
"prompt": req.prompt,
|
||||||
|
"stream": False,
|
||||||
|
}
|
||||||
|
if req.options:
|
||||||
|
payload["options"] = req.options
|
||||||
|
return await _proxy("POST", "/api/generate", payload)
|
||||||
Reference in New Issue
Block a user