Compare commits
3 Commits
main
...
gemini/iss
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2e1366795 | ||
|
|
15fee6bef2 | ||
|
|
b6f8f7d67b |
75
scripts/update_ollama_models.py
Executable file
75
scripts/update_ollama_models.py
Executable file
@@ -0,0 +1,75 @@
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import glob
|
||||
|
||||
def get_models_from_modelfiles():
|
||||
models = set()
|
||||
modelfiles = glob.glob("Modelfile.*")
|
||||
for modelfile in modelfiles:
|
||||
with open(modelfile, 'r') as f:
|
||||
for line in f:
|
||||
if line.strip().startswith("FROM"):
|
||||
parts = line.strip().split()
|
||||
if len(parts) > 1:
|
||||
model_name = parts[1]
|
||||
# Only consider models that are not local file paths
|
||||
if not model_name.startswith('/') and not model_name.startswith('~') and not model_name.endswith('.gguf'):
|
||||
models.add(model_name)
|
||||
break # Only take the first FROM in each Modelfile
|
||||
return sorted(list(models))
|
||||
|
||||
def update_ollama_model(model_name):
|
||||
print(f"Checking for updates for model: {model_name}")
|
||||
try:
|
||||
# Run ollama pull command
|
||||
process = subprocess.run(
|
||||
["ollama", "pull", model_name],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
timeout=900 # 15 minutes
|
||||
)
|
||||
output = process.stdout
|
||||
print(f"Output for {model_name}:\n{output}")
|
||||
|
||||
# Basic check to see if an update happened.
|
||||
# Ollama pull output will contain "pulling" or "downloading" if an update is in progress
|
||||
# and "success" if it completed. If the model is already up to date, it says "already up to date".
|
||||
if "pulling" in output or "downloading" in output:
|
||||
print(f"Model {model_name} was updated.")
|
||||
return True
|
||||
elif "already up to date" in output:
|
||||
print(f"Model {model_name} is already up to date.")
|
||||
return False
|
||||
else:
|
||||
print(f"Unexpected output for {model_name}, assuming no update: {output}")
|
||||
return False
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error updating model {model_name}: {e}")
|
||||
print(f"Stderr: {e.stderr}")
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
print("Error: 'ollama' command not found. Please ensure Ollama is installed and in your PATH.")
|
||||
return False
|
||||
|
||||
def main():
|
||||
models_to_update = get_models_from_modelfiles()
|
||||
print(f"Identified models to check for updates: {models_to_update}")
|
||||
|
||||
updated_models = []
|
||||
for model in models_to_update:
|
||||
if update_ollama_model(model):
|
||||
updated_models.append(model)
|
||||
|
||||
if updated_models:
|
||||
print("\nSuccessfully updated the following models:")
|
||||
for model in updated_models:
|
||||
print(f"- {model}")
|
||||
else:
|
||||
print("\nNo models were updated.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -5,6 +5,7 @@ to swarm agents. Inspired by OpenClaw-RL's multi-model orchestration.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -59,6 +60,23 @@ class SetActiveRequest(BaseModel):
|
||||
# ── API endpoints ─────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@api_router.post("/update-ollama")
|
||||
async def update_ollama_models():
|
||||
"""Trigger the Ollama model update script."""
|
||||
logger.info("Ollama model update triggered")
|
||||
script_path = Path(__file__).parent.parent.parent.parent / "scripts" / "update_ollama_models.py"
|
||||
try:
|
||||
subprocess.Popen(
|
||||
["python", str(script_path)],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
return {"message": "Ollama model update started in the background."}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to start Ollama model update: {e}")
|
||||
raise HTTPException(status_code=500, detail="Failed to start model update script.") from e
|
||||
|
||||
|
||||
@api_router.get("")
|
||||
async def list_models(role: str | None = None) -> dict[str, Any]:
|
||||
"""List all registered custom models."""
|
||||
|
||||
@@ -53,7 +53,12 @@
|
||||
|
||||
<!-- Registered Models -->
|
||||
<div class="mc-section" style="margin-top: 1.5rem;">
|
||||
<h2>Registered Models</h2>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<h2>Registered Models</h2>
|
||||
<button class="mc-btn" hx-post="/api/v1/models/update-ollama" hx-swap="none">
|
||||
Update Ollama Models
|
||||
</button>
|
||||
</div>
|
||||
{% if models %}
|
||||
<table class="mc-table">
|
||||
<thead>
|
||||
|
||||
@@ -13,8 +13,8 @@ from dataclasses import dataclass
|
||||
import httpx
|
||||
|
||||
from config import settings
|
||||
from timmy.research_tools import get_llm_client, google_web_search
|
||||
from timmy.research_triage import triage_research_report
|
||||
from timmy.research_tools import google_web_search, get_llm_client
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import logging
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from config import settings
|
||||
from serpapi import GoogleSearch
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -10,14 +10,12 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import socket
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from integrations.bannerlord.gabs_client import GabsClient, GabsError
|
||||
|
||||
|
||||
# ── GabsClient unit tests ─────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import scripts.export_trajectories as et
|
||||
|
||||
|
||||
# ── Fixtures ──────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from timmy.dispatcher import (
|
||||
AGENT_REGISTRY,
|
||||
AgentType,
|
||||
@@ -21,7 +19,6 @@ from timmy.dispatcher import (
|
||||
wait_for_completion,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Agent registry
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -9,19 +9,15 @@ Refs: #1105
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from timmy_automations.retrain.quality_filter import QualityFilter, TrajectoryQuality
|
||||
from timmy_automations.retrain.retrain import RetrainOrchestrator
|
||||
from timmy_automations.retrain.training_dataset import TrainingDataset
|
||||
from timmy_automations.retrain.training_log import CycleMetrics, TrainingLog
|
||||
from timmy_automations.retrain.trajectory_exporter import Trajectory, TrajectoryExporter
|
||||
|
||||
|
||||
# ── Fixtures ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user