Spaces:
Sleeping
Sleeping
File size: 4,001 Bytes
8dc575c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | """
database.py — SQLite Hardware Abstraction Layer.
Persists all system component states across steps within a session.
"""
from __future__ import annotations
import sqlite3
import json
import threading
import tempfile
from pathlib import Path
from typing import Any, Dict, Optional
import tempfile
DB_PATH = Path(tempfile.gettempdir()) / "quest_openenv.db"
_local = threading.local()
def get_conn() -> sqlite3.Connection:
"""Return a thread-local SQLite connection."""
if not hasattr(_local, "conn") or _local.conn is None:
_local.conn = sqlite3.connect(str(DB_PATH), check_same_thread=False)
_local.conn.row_factory = sqlite3.Row
_local.conn.execute("PRAGMA journal_mode=WAL")
_local.conn.execute("PRAGMA synchronous=NORMAL")
return _local.conn
def init_db() -> None:
"""Initialize all required tables."""
conn = get_conn()
conn.executescript("""
CREATE TABLE IF NOT EXISTS env_state (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS action_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
step INTEGER NOT NULL,
task_id TEXT NOT NULL,
action TEXT NOT NULL,
reward REAL NOT NULL,
success INTEGER NOT NULL,
message TEXT NOT NULL,
timestamp REAL NOT NULL DEFAULT (unixepoch('now', 'subsec'))
);
CREATE TABLE IF NOT EXISTS session_backup (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
""")
conn.commit()
def set_state(key: str, value: Any) -> None:
conn = get_conn()
conn.execute(
"INSERT OR REPLACE INTO env_state (key, value) VALUES (?, ?)",
(key, json.dumps(value))
)
conn.commit()
def get_state(key: str, default: Any = None) -> Any:
conn = get_conn()
row = conn.execute(
"SELECT value FROM env_state WHERE key = ?", (key,)
).fetchone()
if row is None:
return default
return json.loads(row["value"])
def set_state_bulk(data: Dict[str, Any]) -> None:
conn = get_conn()
conn.executemany(
"INSERT OR REPLACE INTO env_state (key, value) VALUES (?, ?)",
[(k, json.dumps(v)) for k, v in data.items()]
)
conn.commit()
def get_all_state() -> Dict[str, Any]:
conn = get_conn()
rows = conn.execute("SELECT key, value FROM env_state").fetchall()
return {row["key"]: json.loads(row["value"]) for row in rows}
def log_action(step: int, task_id: str, action: str, reward: float,
success: bool, message: str) -> None:
conn = get_conn()
conn.execute(
"""INSERT INTO action_log (step, task_id, action, reward, success, message)
VALUES (?, ?, ?, ?, ?, ?)""",
(step, task_id, action, reward, int(success), message)
)
conn.commit()
def backup_session(data: Dict[str, Any]) -> None:
"""Save session data snapshot (simulates persistent workspace)."""
conn = get_conn()
conn.executemany(
"INSERT OR REPLACE INTO session_backup (key, value) VALUES (?, ?)",
[(k, json.dumps(v)) for k, v in data.items()]
)
conn.commit()
def restore_session() -> Dict[str, Any]:
"""Restore session data from backup."""
conn = get_conn()
rows = conn.execute("SELECT key, value FROM session_backup").fetchall()
return {row["key"]: json.loads(row["value"]) for row in rows}
def clear_all() -> None:
"""Wipe env_state (does NOT touch session_backup or action_log)."""
conn = get_conn()
conn.execute("DELETE FROM env_state")
conn.commit()
def get_action_history(task_id: str, limit: int = 20) -> list:
conn = get_conn()
rows = conn.execute(
"""SELECT step, action, reward, success, message
FROM action_log WHERE task_id = ?
ORDER BY id DESC LIMIT ?""",
(task_id, limit)
).fetchall()
return [dict(r) for r in rows] |