forked from Rockachopa/Timmy-time-dashboard
chore: checkpoint local wip for issue 892
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Tiny auth gate for nginx auth_request. Sets a cookie after successful basic auth."""
|
||||
import hashlib, hmac, http.server, time, base64, os, sys
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import http.server
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
SECRET = os.environ.get("AUTH_GATE_SECRET", "")
|
||||
USER = os.environ.get("AUTH_GATE_USER", "")
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -8,6 +7,7 @@ sys.path.insert(0, str(Path(__file__).parent / "src"))
|
||||
|
||||
from timmy.memory_system import memory_store
|
||||
|
||||
|
||||
def index_research_documents():
|
||||
research_dir = Path("docs/research")
|
||||
if not research_dir.is_dir():
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
from logging.config import fileConfig
|
||||
|
||||
from sqlalchemy import engine_from_config
|
||||
from sqlalchemy import pool
|
||||
|
||||
from alembic import context
|
||||
from sqlalchemy import engine_from_config, pool
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
@@ -19,7 +17,7 @@ if config.config_file_name is not None:
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
from src.dashboard.models.database import Base
|
||||
from src.dashboard.models.calm import Task, JournalEntry
|
||||
|
||||
target_metadata = Base.metadata
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
|
||||
@@ -5,17 +5,16 @@ Revises:
|
||||
Create Date: 2026-03-02 10:57:55.537090
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '0093c15b4bbf'
|
||||
down_revision: Union[str, Sequence[str], None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
down_revision: str | Sequence[str] | None = None
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
@@ -5,7 +5,6 @@ Usage:
|
||||
python scripts/add_pytest_markers.py
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -93,7 +92,7 @@ def main():
|
||||
print(f"⏭️ {rel_path:<50} (already marked)")
|
||||
|
||||
print(f"\n📊 Total files marked: {marked_count}")
|
||||
print(f"\n✨ Pytest markers configured. Run 'pytest -m unit' to test specific categories.")
|
||||
print("\n✨ Pytest markers configured. Run 'pytest -m unit' to test specific categories.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import os
|
||||
|
||||
def fix_l402_proxy():
|
||||
path = "src/timmy_serve/l402_proxy.py"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
|
||||
# 1. Add hmac_secret to Macaroon dataclass
|
||||
@@ -132,7 +131,7 @@ if _MACAROON_SECRET_RAW == _MACAROON_SECRET_DEFAULT or _HMAC_SECRET_RAW == _HMAC
|
||||
def fix_xss():
|
||||
# Fix chat_message.html
|
||||
path = "src/dashboard/templates/partials/chat_message.html"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = content.replace("{{ user_message }}", "{{ user_message | e }}")
|
||||
content = content.replace("{{ response }}", "{{ response | e }}")
|
||||
@@ -142,7 +141,7 @@ def fix_xss():
|
||||
|
||||
# Fix history.html
|
||||
path = "src/dashboard/templates/partials/history.html"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = content.replace("{{ msg.content }}", "{{ msg.content | e }}")
|
||||
with open(path, "w") as f:
|
||||
@@ -150,7 +149,7 @@ def fix_xss():
|
||||
|
||||
# Fix briefing.html
|
||||
path = "src/dashboard/templates/briefing.html"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = content.replace("{{ briefing.summary }}", "{{ briefing.summary | e }}")
|
||||
with open(path, "w") as f:
|
||||
@@ -158,7 +157,7 @@ def fix_xss():
|
||||
|
||||
# Fix approval_card_single.html
|
||||
path = "src/dashboard/templates/partials/approval_card_single.html"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = content.replace("{{ item.title }}", "{{ item.title | e }}")
|
||||
content = content.replace("{{ item.description }}", "{{ item.description | e }}")
|
||||
@@ -168,7 +167,7 @@ def fix_xss():
|
||||
|
||||
# Fix marketplace.html
|
||||
path = "src/dashboard/templates/marketplace.html"
|
||||
with open(path, "r") as f:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = content.replace("{{ agent.name }}", "{{ agent.name | e }}")
|
||||
content = content.replace("{{ agent.role }}", "{{ agent.role | e }}")
|
||||
|
||||
@@ -8,8 +8,7 @@ from existing history so the LOOPSTAT panel isn't empty.
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
@@ -227,7 +226,7 @@ def generate_summary(entries: list[dict]):
|
||||
stats["avg_duration"] = round(stats["total_duration"] / stats["count"])
|
||||
|
||||
summary = {
|
||||
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"updated_at": datetime.now(UTC).isoformat(),
|
||||
"window": len(recent),
|
||||
"total_cycles": len(entries),
|
||||
"success_rate": round(len(successes) / len(recent), 2) if recent else 0,
|
||||
|
||||
@@ -17,7 +17,7 @@ import importlib.util
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
@@ -216,7 +216,7 @@ def generate_markdown(all_results: dict, run_date: str) -> str:
|
||||
lines.append(f"- **Result:** {bres.get('detail', bres.get('error', 'n/a'))}")
|
||||
snippet = bres.get("code_snippet", "")
|
||||
if snippet:
|
||||
lines.append(f"- **Generated code snippet:**")
|
||||
lines.append("- **Generated code snippet:**")
|
||||
lines.append(" ```python")
|
||||
for ln in snippet.splitlines()[:8]:
|
||||
lines.append(f" {ln}")
|
||||
@@ -287,7 +287,7 @@ def parse_args() -> argparse.Namespace:
|
||||
|
||||
def main() -> int:
|
||||
args = parse_args()
|
||||
run_date = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
||||
run_date = datetime.now(UTC).strftime("%Y-%m-%d %H:%M UTC")
|
||||
|
||||
print(f"Model Benchmark Suite — {run_date}")
|
||||
print(f"Testing {len(args.models)} model(s): {', '.join(args.models)}")
|
||||
|
||||
@@ -46,8 +46,7 @@ import argparse
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
@@ -91,7 +90,7 @@ def _epoch_tag(now: datetime | None = None) -> tuple[str, dict]:
|
||||
When the date rolls over, the counter resets to 1.
|
||||
"""
|
||||
if now is None:
|
||||
now = datetime.now(timezone.utc)
|
||||
now = datetime.now(UTC)
|
||||
|
||||
iso_cal = now.isocalendar() # (year, week, weekday)
|
||||
week = iso_cal[1]
|
||||
@@ -221,7 +220,7 @@ def update_summary() -> None:
|
||||
for k, v in sorted(by_weekday.items())}
|
||||
|
||||
summary = {
|
||||
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"updated_at": datetime.now(UTC).isoformat(),
|
||||
"current_epoch": current_epoch,
|
||||
"window": len(recent),
|
||||
"measured_cycles": len(measured),
|
||||
@@ -293,7 +292,7 @@ def main() -> None:
|
||||
truly_success = args.success and args.main_green
|
||||
|
||||
# Generate epoch turnover tag
|
||||
now = datetime.now(timezone.utc)
|
||||
now = datetime.now(UTC)
|
||||
epoch_tag, epoch_parts = _epoch_tag(now)
|
||||
|
||||
entry = {
|
||||
|
||||
@@ -11,7 +11,6 @@ Usage: python scripts/dev_server.py [--port PORT]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
@@ -81,8 +80,8 @@ def _ollama_url() -> str:
|
||||
|
||||
def _smoke_ollama(url: str) -> str:
|
||||
"""Quick connectivity check against Ollama."""
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(url, method="GET")
|
||||
@@ -101,14 +100,14 @@ def _print_banner(port: int) -> None:
|
||||
hr = "─" * 62
|
||||
print(flush=True)
|
||||
print(f" {hr}")
|
||||
print(f" ┃ Timmy Time — Development Server")
|
||||
print(" ┃ Timmy Time — Development Server")
|
||||
print(f" {hr}")
|
||||
print()
|
||||
print(f" Dashboard: http://localhost:{port}")
|
||||
print(f" API docs: http://localhost:{port}/docs")
|
||||
print(f" Health: http://localhost:{port}/health")
|
||||
print()
|
||||
print(f" ── Status ──────────────────────────────────────────────")
|
||||
print(" ── Status ──────────────────────────────────────────────")
|
||||
print(f" Backend: {ollama_url} [{ollama_status}]")
|
||||
print(f" Version: {version}")
|
||||
print(f" Git commit: {git}")
|
||||
|
||||
@@ -319,9 +319,9 @@ def main(argv: list[str] | None = None) -> int:
|
||||
print(f"Exported {count} training examples to: {args.output}")
|
||||
print()
|
||||
print("Next steps:")
|
||||
print(f" mkdir -p ~/timmy-lora-training")
|
||||
print(" mkdir -p ~/timmy-lora-training")
|
||||
print(f" cp {args.output} ~/timmy-lora-training/train.jsonl")
|
||||
print(f" python scripts/lora_finetune.py --data ~/timmy-lora-training")
|
||||
print(" python scripts/lora_finetune.py --data ~/timmy-lora-training")
|
||||
else:
|
||||
print("No training examples exported.")
|
||||
return 1
|
||||
|
||||
@@ -18,9 +18,8 @@ Called by: deep_triage.sh (before the LLM triage), timmy-loop.sh (every 50 cycle
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
@@ -52,7 +51,7 @@ def parse_ts(ts_str: str) -> datetime | None:
|
||||
try:
|
||||
dt = datetime.fromisoformat(ts_str.replace("Z", "+00:00"))
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
dt = dt.replace(tzinfo=UTC)
|
||||
return dt
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
@@ -60,7 +59,7 @@ def parse_ts(ts_str: str) -> datetime | None:
|
||||
|
||||
def window(entries: list[dict], days: int) -> list[dict]:
|
||||
"""Filter entries to the last N days."""
|
||||
cutoff = datetime.now(timezone.utc) - timedelta(days=days)
|
||||
cutoff = datetime.now(UTC) - timedelta(days=days)
|
||||
result = []
|
||||
for e in entries:
|
||||
ts = parse_ts(e.get("timestamp", ""))
|
||||
@@ -344,7 +343,7 @@ def main() -> None:
|
||||
recommendations = generate_recommendations(trends, types, repeats, outliers, triage_eff)
|
||||
|
||||
insights = {
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"generated_at": datetime.now(UTC).isoformat(),
|
||||
"total_cycles_analyzed": len(cycles),
|
||||
"trends": trends,
|
||||
"by_type": types,
|
||||
@@ -371,7 +370,7 @@ def main() -> None:
|
||||
header += f" · current epoch: {latest_epoch}"
|
||||
print(header)
|
||||
|
||||
print(f"\n TRENDS (7d vs previous 7d):")
|
||||
print("\n TRENDS (7d vs previous 7d):")
|
||||
r7 = trends["recent_7d"]
|
||||
p7 = trends["previous_7d"]
|
||||
print(f" Cycles: {r7['count']:>3d} (was {p7['count']})")
|
||||
@@ -383,14 +382,14 @@ def main() -> None:
|
||||
print(f" PRs merged: {r7['prs_merged']:>3d} (was {p7['prs_merged']})")
|
||||
print(f" Lines net: {r7['lines_net']:>+5d}")
|
||||
|
||||
print(f"\n BY TYPE:")
|
||||
print("\n BY TYPE:")
|
||||
for t, info in sorted(types.items(), key=lambda x: -x[1]["count"]):
|
||||
print(f" {t:12s} n={info['count']:>2d} "
|
||||
f"ok={info['success_rate']*100:>3.0f}% "
|
||||
f"avg={info['avg_duration']//60}m{info['avg_duration']%60:02d}s")
|
||||
|
||||
if repeats:
|
||||
print(f"\n REPEAT FAILURES:")
|
||||
print("\n REPEAT FAILURES:")
|
||||
for rf in repeats[:3]:
|
||||
print(f" #{rf['issue']} failed {rf['failure_count']}x")
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ def main(argv: list[str] | None = None) -> int:
|
||||
return rc
|
||||
|
||||
# Default: train
|
||||
print(f"Starting LoRA fine-tuning")
|
||||
print("Starting LoRA fine-tuning")
|
||||
print(f" Model: {model_path}")
|
||||
print(f" Data: {args.data}")
|
||||
print(f" Adapter path: {args.adapter_path}")
|
||||
|
||||
@@ -9,11 +9,10 @@ This script runs before commits to catch issues early:
|
||||
- Syntax errors in test files
|
||||
"""
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
import ast
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def check_imports():
|
||||
@@ -70,7 +69,7 @@ def check_test_syntax():
|
||||
|
||||
for test_file in tests_dir.rglob("test_*.py"):
|
||||
try:
|
||||
with open(test_file, "r") as f:
|
||||
with open(test_file) as f:
|
||||
ast.parse(f.read())
|
||||
print(f"✓ {test_file.relative_to(tests_dir.parent)} has valid syntax")
|
||||
except SyntaxError as e:
|
||||
@@ -86,7 +85,7 @@ def check_platform_specific_tests():
|
||||
# Check for hardcoded /Users/ paths in tests
|
||||
tests_dir = Path("tests").resolve()
|
||||
for test_file in tests_dir.rglob("test_*.py"):
|
||||
with open(test_file, "r") as f:
|
||||
with open(test_file) as f:
|
||||
content = f.read()
|
||||
if 'startswith("/Users/")' in content:
|
||||
issues.append(
|
||||
@@ -110,7 +109,7 @@ def check_docker_availability():
|
||||
|
||||
if docker_test_files:
|
||||
for test_file in docker_test_files:
|
||||
with open(test_file, "r") as f:
|
||||
with open(test_file) as f:
|
||||
content = f.read()
|
||||
has_skipif = "@pytest.mark.skipif" in content or "pytestmark = pytest.mark.skipif" in content
|
||||
if not has_skipif and "docker" in content.lower():
|
||||
|
||||
@@ -83,8 +83,8 @@ def test_tcp_connection(host: str, port: int, timeout: float) -> tuple[bool, soc
|
||||
return True, sock
|
||||
except OSError as exc:
|
||||
print(f" ✗ Connection failed: {exc}")
|
||||
print(f" Checklist:")
|
||||
print(f" - Is Bannerlord running with GABS mod enabled?")
|
||||
print(" Checklist:")
|
||||
print(" - Is Bannerlord running with GABS mod enabled?")
|
||||
print(f" - Is port {port} open in Windows Firewall?")
|
||||
print(f" - Is the VM IP correct? (got: {host})")
|
||||
return False, None
|
||||
@@ -92,7 +92,7 @@ def test_tcp_connection(host: str, port: int, timeout: float) -> tuple[bool, soc
|
||||
|
||||
def test_ping(sock: socket.socket) -> bool:
|
||||
"""PASS: JSON-RPC ping returns a 2.0 response."""
|
||||
print(f"\n[2/4] JSON-RPC ping")
|
||||
print("\n[2/4] JSON-RPC ping")
|
||||
try:
|
||||
t0 = time.monotonic()
|
||||
resp = _rpc(sock, "ping", req_id=1)
|
||||
@@ -109,7 +109,7 @@ def test_ping(sock: socket.socket) -> bool:
|
||||
|
||||
def test_game_state(sock: socket.socket) -> bool:
|
||||
"""PASS: get_game_state returns a result (game must be in a campaign)."""
|
||||
print(f"\n[3/4] get_game_state call")
|
||||
print("\n[3/4] get_game_state call")
|
||||
try:
|
||||
t0 = time.monotonic()
|
||||
resp = _rpc(sock, "get_game_state", req_id=2)
|
||||
@@ -120,7 +120,7 @@ def test_game_state(sock: socket.socket) -> bool:
|
||||
if code == -32601:
|
||||
# Method not found — GABS version may not expose this method
|
||||
print(f" ~ Method not available ({elapsed_ms:.1f} ms): {msg}")
|
||||
print(f" This is acceptable if game is not yet in a campaign.")
|
||||
print(" This is acceptable if game is not yet in a campaign.")
|
||||
return True
|
||||
print(f" ✗ RPC error ({elapsed_ms:.1f} ms) [{code}]: {msg}")
|
||||
return False
|
||||
@@ -191,7 +191,7 @@ def main() -> int:
|
||||
args = parser.parse_args()
|
||||
|
||||
print("=" * 60)
|
||||
print(f"GABS Connectivity Test Suite")
|
||||
print("GABS Connectivity Test Suite")
|
||||
print(f"Target: {args.host}:{args.port}")
|
||||
print(f"Timeout: {args.timeout}s")
|
||||
print("=" * 60)
|
||||
|
||||
@@ -150,7 +150,7 @@ def test_model_available(model: str) -> bool:
|
||||
|
||||
def test_basic_response(model: str) -> bool:
|
||||
"""PASS: model responds coherently to a simple prompt."""
|
||||
print(f"\n[2/5] Basic response test")
|
||||
print("\n[2/5] Basic response test")
|
||||
messages = [
|
||||
{"role": "user", "content": "Reply with exactly: HERMES_OK"},
|
||||
]
|
||||
@@ -188,7 +188,7 @@ def test_memory_usage() -> bool:
|
||||
|
||||
def test_tool_calling(model: str) -> bool:
|
||||
"""PASS: model produces a tool_calls response (not raw text) for a tool-use prompt."""
|
||||
print(f"\n[4/5] Tool-calling test")
|
||||
print("\n[4/5] Tool-calling test")
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
@@ -236,7 +236,7 @@ def test_tool_calling(model: str) -> bool:
|
||||
|
||||
def test_timmy_persona(model: str) -> bool:
|
||||
"""PASS: model accepts a Timmy persona system prompt and responds in-character."""
|
||||
print(f"\n[5/5] Timmy-persona smoke test")
|
||||
print("\n[5/5] Timmy-persona smoke test")
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
|
||||
@@ -26,7 +26,7 @@ import argparse
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
try:
|
||||
|
||||
@@ -16,7 +16,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
# ── Config ──────────────────────────────────────────────────────────────
|
||||
@@ -277,7 +277,7 @@ def update_quarantine(scored: list[dict]) -> list[dict]:
|
||||
"""Auto-quarantine issues that have failed >= 2 times. Returns filtered list."""
|
||||
failures = load_cycle_failures()
|
||||
quarantine = load_quarantine()
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
now = datetime.now(UTC).isoformat()
|
||||
|
||||
filtered = []
|
||||
for item in scored:
|
||||
@@ -366,7 +366,7 @@ def run_triage() -> list[dict]:
|
||||
backup_data = QUEUE_BACKUP_FILE.read_text()
|
||||
json.loads(backup_data) # Validate backup
|
||||
QUEUE_FILE.write_text(backup_data)
|
||||
print(f"[triage] Restored queue.json from backup")
|
||||
print("[triage] Restored queue.json from backup")
|
||||
except (json.JSONDecodeError, OSError) as restore_exc:
|
||||
print(f"[triage] ERROR: Backup restore failed: {restore_exc}", file=sys.stderr)
|
||||
# Write empty list as last resort
|
||||
@@ -377,7 +377,7 @@ def run_triage() -> list[dict]:
|
||||
|
||||
# Write retro entry
|
||||
retro_entry = {
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"timestamp": datetime.now(UTC).isoformat(),
|
||||
"total_open": len(all_issues),
|
||||
"scored": len(scored),
|
||||
"ready": len(ready),
|
||||
|
||||
@@ -35,9 +35,9 @@ from dashboard.routes.chat_api_v1 import router as chat_api_v1_router
|
||||
from dashboard.routes.daily_run import router as daily_run_router
|
||||
from dashboard.routes.db_explorer import router as db_explorer_router
|
||||
from dashboard.routes.discord import router as discord_router
|
||||
from dashboard.routes.energy import router as energy_router
|
||||
from dashboard.routes.experiments import router as experiments_router
|
||||
from dashboard.routes.grok import router as grok_router
|
||||
from dashboard.routes.energy import router as energy_router
|
||||
from dashboard.routes.health import router as health_router
|
||||
from dashboard.routes.hermes import router as hermes_router
|
||||
from dashboard.routes.loop_qa import router as loop_qa_router
|
||||
@@ -48,6 +48,7 @@ from dashboard.routes.models import router as models_router
|
||||
from dashboard.routes.nexus import router as nexus_router
|
||||
from dashboard.routes.quests import router as quests_router
|
||||
from dashboard.routes.scorecards import router as scorecards_router
|
||||
from dashboard.routes.self_correction import router as self_correction_router
|
||||
from dashboard.routes.sovereignty_metrics import router as sovereignty_metrics_router
|
||||
from dashboard.routes.sovereignty_ws import router as sovereignty_ws_router
|
||||
from dashboard.routes.spark import router as spark_router
|
||||
@@ -55,7 +56,6 @@ from dashboard.routes.system import router as system_router
|
||||
from dashboard.routes.tasks import router as tasks_router
|
||||
from dashboard.routes.telegram import router as telegram_router
|
||||
from dashboard.routes.thinking import router as thinking_router
|
||||
from dashboard.routes.self_correction import router as self_correction_router
|
||||
from dashboard.routes.three_strike import router as three_strike_router
|
||||
from dashboard.routes.tools import router as tools_router
|
||||
from dashboard.routes.tower import router as tower_router
|
||||
|
||||
@@ -19,7 +19,6 @@ Refs: #1009
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
@@ -24,8 +24,8 @@ from infrastructure.models.registry import (
|
||||
model_registry,
|
||||
)
|
||||
from infrastructure.models.router import (
|
||||
TierLabel,
|
||||
TieredModelRouter,
|
||||
TierLabel,
|
||||
classify_tier,
|
||||
get_tiered_router,
|
||||
)
|
||||
|
||||
@@ -27,7 +27,6 @@ References:
|
||||
- Issue #882 — Model Tiering Router: Local 8B / Hermes 70B / Cloud API Cascade
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
|
||||
@@ -20,13 +20,11 @@ Usage::
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import sqlite3
|
||||
import uuid
|
||||
from collections.abc import Generator
|
||||
from contextlib import closing, contextmanager
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -21,7 +21,6 @@ import base64
|
||||
import json
|
||||
import logging
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
@@ -22,21 +22,20 @@ import sqlite3
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from timmy.thinking._db import Thought, _get_conn
|
||||
from timmy.thinking.engine import ThinkingEngine
|
||||
from timmy.thinking.seeds import (
|
||||
SEED_TYPES,
|
||||
_SENSITIVE_PATTERNS,
|
||||
_META_OBSERVATION_PHRASES,
|
||||
_THINK_TAG_RE,
|
||||
_THINKING_PROMPT,
|
||||
)
|
||||
|
||||
# Re-export HOT_MEMORY_PATH and SOUL_PATH so existing patch targets continue to work.
|
||||
# Tests that patch "timmy.thinking.HOT_MEMORY_PATH" or "timmy.thinking.SOUL_PATH"
|
||||
# should instead patch "timmy.thinking._snapshot.HOT_MEMORY_PATH" etc., but these
|
||||
# re-exports are kept for any code that reads them from the top-level namespace.
|
||||
from timmy.memory_system import HOT_MEMORY_PATH, SOUL_PATH # noqa: F401
|
||||
from timmy.thinking._db import Thought, _get_conn
|
||||
from timmy.thinking.engine import ThinkingEngine
|
||||
from timmy.thinking.seeds import (
|
||||
_META_OBSERVATION_PHRASES,
|
||||
_SENSITIVE_PATTERNS,
|
||||
_THINK_TAG_RE,
|
||||
_THINKING_PROMPT,
|
||||
SEED_TYPES,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import logging
|
||||
from pathlib import Path
|
||||
|
||||
from config import settings
|
||||
|
||||
from timmy.thinking.seeds import _META_OBSERVATION_PHRASES, _SENSITIVE_PATTERNS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -5,11 +5,11 @@ import random
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from timmy.thinking.seeds import (
|
||||
SEED_TYPES,
|
||||
_CREATIVE_SEEDS,
|
||||
_EXISTENTIAL_SEEDS,
|
||||
_OBSERVATION_SEEDS,
|
||||
_SOVEREIGNTY_SEEDS,
|
||||
SEED_TYPES,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""System snapshot and memory context mixin for the thinking engine."""
|
||||
|
||||
import logging
|
||||
from datetime import UTC, datetime
|
||||
from datetime import datetime
|
||||
|
||||
from timmy.memory_system import HOT_MEMORY_PATH, SOUL_PATH
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ from difflib import SequenceMatcher
|
||||
from pathlib import Path
|
||||
|
||||
from config import settings
|
||||
|
||||
from timmy.thinking._db import Thought, _DEFAULT_DB, _get_conn, _row_to_thought
|
||||
from timmy.thinking._db import _DEFAULT_DB, Thought, _get_conn, _row_to_thought
|
||||
from timmy.thinking._distillation import _DistillationMixin
|
||||
from timmy.thinking._issue_filing import _IssueFilingMixin
|
||||
from timmy.thinking._seeds_mixin import _SeedsMixin
|
||||
|
||||
@@ -27,7 +27,6 @@ from infrastructure.router.cascade import (
|
||||
ProviderStatus,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -10,13 +10,13 @@ Covers:
|
||||
- "Plan the optimal path to become Hortator" → LOCAL_HEAVY
|
||||
"""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from infrastructure.models.router import (
|
||||
TierLabel,
|
||||
TieredModelRouter,
|
||||
TierLabel,
|
||||
_is_low_quality,
|
||||
classify_tier,
|
||||
get_tiered_router,
|
||||
|
||||
@@ -5,7 +5,6 @@ from __future__ import annotations
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from timmy.backlog_triage import (
|
||||
@@ -28,7 +27,6 @@ from timmy.backlog_triage import (
|
||||
score_issue,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -4,7 +4,6 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# exceeds_local_capacity
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -34,7 +34,6 @@ from timmy.quest_system import (
|
||||
update_quest_progress,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -15,7 +15,6 @@ if "serpapi" not in sys.modules:
|
||||
|
||||
from timmy.research_tools import get_llm_client, google_web_search # noqa: E402
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# google_web_search
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -6,8 +6,7 @@ Refs: #957 (Session Sovereignty Report Generator)
|
||||
import base64
|
||||
import json
|
||||
import time
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from datetime import UTC
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
@@ -18,14 +17,12 @@ from timmy.sovereignty.session_report import (
|
||||
_format_duration,
|
||||
_gather_session_data,
|
||||
_gather_sovereignty_data,
|
||||
_render_markdown,
|
||||
commit_report,
|
||||
generate_and_commit_report,
|
||||
generate_report,
|
||||
mark_session_start,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _format_duration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -7,11 +7,8 @@ from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from timmy.tools.search import _extract_crawl_content, scrape_url, web_search
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -12,9 +12,7 @@ import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
|
||||
# Add timmy_automations to path for imports
|
||||
_TA_PATH = Path(__file__).resolve().parent.parent.parent / "timmy_automations" / "daily_run"
|
||||
|
||||
@@ -7,7 +7,6 @@ falls back to the Ollama backend without crashing.
|
||||
Refs #1284
|
||||
"""
|
||||
|
||||
import sys
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -11,11 +11,9 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
|
||||
from infrastructure.energy.monitor import (
|
||||
_DEFAULT_MODEL_SIZE_GB,
|
||||
EnergyBudgetMonitor,
|
||||
InferenceSample,
|
||||
_DEFAULT_MODEL_SIZE_GB,
|
||||
_EFFICIENCY_SCORE_CEILING,
|
||||
_WATTS_PER_GB_HEURISTIC,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
"""Unit tests for infrastructure.self_correction."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -13,10 +13,9 @@ Usage:
|
||||
import argparse
|
||||
import dataclasses
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
@@ -28,12 +27,14 @@ except ImportError:
|
||||
# Add parent dir to path so levels can be imported
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from levels import level_0_coin_flip
|
||||
from levels import level_1_tic_tac_toe
|
||||
from levels import level_2_resource_mgmt
|
||||
from levels import level_3_battle_tactics
|
||||
from levels import level_4_trade_route
|
||||
from levels import level_5_mini_campaign
|
||||
from levels import (
|
||||
level_0_coin_flip,
|
||||
level_1_tic_tac_toe,
|
||||
level_2_resource_mgmt,
|
||||
level_3_battle_tactics,
|
||||
level_4_trade_route,
|
||||
level_5_mini_campaign,
|
||||
)
|
||||
|
||||
ALL_LEVELS = [
|
||||
level_0_coin_flip,
|
||||
@@ -86,7 +87,7 @@ def run_benchmark(
|
||||
levels_to_run = list(range(len(ALL_LEVELS)))
|
||||
|
||||
print(f"\n{'=' * 60}")
|
||||
print(f" Timmy Cognitive Benchmark — Project Bannerlord M0")
|
||||
print(" Timmy Cognitive Benchmark — Project Bannerlord M0")
|
||||
print(f"{'=' * 60}")
|
||||
print(f" Model: {model}")
|
||||
print(f" Levels: {levels_to_run}")
|
||||
@@ -100,7 +101,7 @@ def run_benchmark(
|
||||
"model": model,
|
||||
"skipped": True,
|
||||
"reason": f"Model '{model}' not available",
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"timestamp": datetime.now(UTC).isoformat(),
|
||||
}
|
||||
else:
|
||||
print(f" ERROR: Model '{model}' not found in Ollama.", file=sys.stderr)
|
||||
@@ -110,7 +111,7 @@ def run_benchmark(
|
||||
|
||||
results = {
|
||||
"model": model,
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"timestamp": datetime.now(UTC).isoformat(),
|
||||
"skipped": False,
|
||||
"levels": {},
|
||||
"summary": {},
|
||||
|
||||
@@ -21,11 +21,10 @@ import json
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
# ── Configuration ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -260,7 +259,7 @@ def score_issue_for_path(issue: dict) -> int:
|
||||
if updated_at:
|
||||
try:
|
||||
updated = datetime.fromisoformat(updated_at.replace("Z", "+00:00"))
|
||||
days_old = (datetime.now(timezone.utc) - updated).days
|
||||
days_old = (datetime.now(UTC) - updated).days
|
||||
if days_old < 7:
|
||||
score += 2
|
||||
elif days_old < 30:
|
||||
@@ -388,7 +387,7 @@ def build_golden_path(
|
||||
4. One more micro-fix or docs (closure)
|
||||
"""
|
||||
path = GoldenPath(
|
||||
generated_at=datetime.now(timezone.utc).isoformat(),
|
||||
generated_at=datetime.now(UTC).isoformat(),
|
||||
target_minutes=target_minutes,
|
||||
)
|
||||
|
||||
@@ -478,7 +477,7 @@ def generate_golden_path(
|
||||
if not client.is_available():
|
||||
# Return empty path with error indication
|
||||
return GoldenPath(
|
||||
generated_at=datetime.now(timezone.utc).isoformat(),
|
||||
generated_at=datetime.now(UTC).isoformat(),
|
||||
target_minutes=target_minutes,
|
||||
items=[],
|
||||
)
|
||||
|
||||
@@ -17,11 +17,11 @@ import json
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
# ── Configuration ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -327,7 +327,7 @@ def check_critical_issues(client: GiteaClient, config: dict) -> IssueSignal:
|
||||
issues=all_critical[:10], # Limit stored issues
|
||||
)
|
||||
|
||||
except (HTTPError, URLError) as exc:
|
||||
except (HTTPError, URLError):
|
||||
return IssueSignal(
|
||||
count=0,
|
||||
p0_count=0,
|
||||
@@ -419,7 +419,7 @@ def check_token_economy(config: dict) -> TokenEconomySignal:
|
||||
|
||||
try:
|
||||
# Read last 24 hours of transactions
|
||||
since = datetime.now(timezone.utc) - timedelta(hours=24)
|
||||
since = datetime.now(UTC) - timedelta(hours=24)
|
||||
|
||||
recent_mint = 0
|
||||
recent_burn = 0
|
||||
@@ -511,7 +511,7 @@ def generate_snapshot(config: dict, token: str | None) -> HealthSnapshot:
|
||||
overall = calculate_overall_status(ci, issues, flakiness)
|
||||
|
||||
return HealthSnapshot(
|
||||
timestamp=datetime.now(timezone.utc).isoformat(),
|
||||
timestamp=datetime.now(UTC).isoformat(),
|
||||
overall_status=overall,
|
||||
ci=ci,
|
||||
issues=issues,
|
||||
|
||||
@@ -19,11 +19,11 @@ import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
# ── Token Economy Integration ──────────────────────────────────────────────
|
||||
# Import token rules helpers for tracking Daily Run rewards
|
||||
@@ -31,12 +31,11 @@ from urllib.error import HTTPError, URLError
|
||||
sys.path.insert(
|
||||
0, str(Path(__file__).resolve().parent.parent)
|
||||
)
|
||||
from utils.token_rules import TokenRules, compute_token_reward
|
||||
|
||||
# Health snapshot lives in the same package
|
||||
from health_snapshot import generate_snapshot as _generate_health_snapshot
|
||||
from health_snapshot import get_token as _hs_get_token
|
||||
from health_snapshot import load_config as _hs_load_config
|
||||
from utils.token_rules import TokenRules, compute_token_reward
|
||||
|
||||
# ── Configuration ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -284,7 +283,7 @@ def generate_agenda(issues: list[dict], config: dict) -> dict:
|
||||
items.append(item)
|
||||
|
||||
return {
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"generated_at": datetime.now(UTC).isoformat(),
|
||||
"time_budget_minutes": agenda_time,
|
||||
"item_count": len(items),
|
||||
"items": items,
|
||||
@@ -322,7 +321,7 @@ def print_agenda(agenda: dict) -> None:
|
||||
def fetch_recent_activity(client: GiteaClient, config: dict) -> dict:
|
||||
"""Fetch recent issues and PRs from the lookback window."""
|
||||
lookback_hours = config.get("lookback_hours", 24)
|
||||
since = datetime.now(timezone.utc) - timedelta(hours=lookback_hours)
|
||||
since = datetime.now(UTC) - timedelta(hours=lookback_hours)
|
||||
since_str = since.isoformat()
|
||||
|
||||
activity = {
|
||||
@@ -399,7 +398,7 @@ def load_cycle_data() -> dict:
|
||||
continue
|
||||
|
||||
# Get entries from last 24 hours
|
||||
since = datetime.now(timezone.utc) - timedelta(hours=24)
|
||||
since = datetime.now(UTC) - timedelta(hours=24)
|
||||
recent = [
|
||||
e for e in entries
|
||||
if e.get("timestamp") and datetime.fromisoformat(e["timestamp"].replace("Z", "+00:00")) >= since
|
||||
@@ -426,7 +425,7 @@ def load_cycle_data() -> dict:
|
||||
def generate_day_summary(activity: dict, cycles: dict) -> dict:
|
||||
"""Generate a day summary from activity data."""
|
||||
return {
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"generated_at": datetime.now(UTC).isoformat(),
|
||||
"lookback_hours": 24,
|
||||
"issues_touched": len(activity.get("issues_touched", [])),
|
||||
"issues_closed": len(activity.get("issues_closed", [])),
|
||||
|
||||
@@ -25,7 +25,6 @@ import sys
|
||||
from collections import Counter
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ Refs: #1105
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
Reference in New Issue
Block a user