mirror of
https://github.com/priyanshujain/messageboardbench.git
synced 2026-10-04 20:17:06 +00:00
archive old experiments and publish swe series
This commit is contained in:
1 parent
480100587e
commit
638e978227
1522 files changed
+220002
-4900
No files matched your search
@@ -0,0 +1,151 @@
|
||||
"""Private, append-only organizer feedback channel for experimental agents."""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime, timezone
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sqlite3
|
||||
import uuid
|
||||
|
||||
from inspect_ai.tool import Tool, tool
|
||||
|
||||
|
||||
MAX_FEEDBACK_CHARS = 4000
|
||||
FEEDBACK_INTERFACE_VERSION = "organizer-feedback-v1"
|
||||
|
||||
|
||||
def _identity(value: str) -> str:
|
||||
if not isinstance(value, str) or not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}", value):
|
||||
raise ValueError("Identity must be 1–128 simple identifier characters")
|
||||
return value
|
||||
|
||||
|
||||
def _now() -> str:
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
|
||||
def initialize_feedback(db_path: Path, run_id: str) -> Path:
|
||||
"""Create a fresh private feedback store."""
|
||||
_identity(run_id)
|
||||
path = Path(db_path).absolute()
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)
|
||||
os.close(fd)
|
||||
with sqlite3.connect(path) as db:
|
||||
db.executescript("""
|
||||
CREATE TABLE run (run_id TEXT PRIMARY KEY, created_at TEXT NOT NULL);
|
||||
CREATE TABLE submissions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT NOT NULL, episode_id TEXT NOT NULL, task_id TEXT NOT NULL,
|
||||
condition TEXT NOT NULL, timestamp TEXT NOT NULL, text TEXT NOT NULL,
|
||||
receipt_id TEXT NOT NULL UNIQUE
|
||||
);
|
||||
CREATE TABLE audit (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT NOT NULL, episode_id TEXT NOT NULL, task_id TEXT NOT NULL,
|
||||
condition TEXT NOT NULL, timestamp TEXT NOT NULL,
|
||||
request_json TEXT NOT NULL, response_json TEXT NOT NULL,
|
||||
success INTEGER NOT NULL
|
||||
);
|
||||
""")
|
||||
db.execute("INSERT INTO run VALUES (?,?)", (run_id, _now()))
|
||||
for table in ("run", "submissions", "audit"):
|
||||
for action in ("UPDATE", "DELETE"):
|
||||
db.execute(
|
||||
f"CREATE TRIGGER deny_{table}_{action.lower()} BEFORE {action} ON {table} "
|
||||
"BEGIN SELECT RAISE(ABORT, 'append-only feedback'); END"
|
||||
)
|
||||
return path
|
||||
|
||||
|
||||
def _connect(db_path: Path, run_id: str) -> sqlite3.Connection:
|
||||
db = sqlite3.connect(Path(db_path).resolve().as_uri() + "?mode=rw", uri=True, timeout=30)
|
||||
db.row_factory = sqlite3.Row
|
||||
rows = db.execute("SELECT run_id FROM run").fetchall()
|
||||
if len(rows) != 1 or rows[0][0] != run_id:
|
||||
db.close()
|
||||
raise ValueError("Feedback run ID mismatch")
|
||||
return db
|
||||
|
||||
|
||||
def _submit(db_path: Path, run_id: str, episode_id: str, task_id: str,
|
||||
condition: str, text: str) -> str:
|
||||
db = _connect(db_path, run_id)
|
||||
try:
|
||||
db.execute("BEGIN IMMEDIATE")
|
||||
stamp = _now()
|
||||
request = {"text": text}
|
||||
try:
|
||||
if not isinstance(text, str) or not text.strip() or len(text) > MAX_FEEDBACK_CHARS:
|
||||
raise ValueError(
|
||||
f"text must contain 1–{MAX_FEEDBACK_CHARS} characters and not be blank"
|
||||
)
|
||||
receipt_id = uuid.uuid4().hex
|
||||
db.execute(
|
||||
"INSERT INTO submissions(run_id,episode_id,task_id,condition,timestamp,text,receipt_id) "
|
||||
"VALUES (?,?,?,?,?,?,?)",
|
||||
(run_id, episode_id, task_id, condition, stamp, text, receipt_id),
|
||||
)
|
||||
response = {"ok": True, "receipt_id": receipt_id}
|
||||
except ValueError as error:
|
||||
response = {"ok": False, "error": str(error)}
|
||||
encoded_request = json.dumps(request, ensure_ascii=False, separators=(",", ":"))
|
||||
encoded_response = json.dumps(response, ensure_ascii=False, separators=(",", ":"))
|
||||
db.execute(
|
||||
"INSERT INTO audit(run_id,episode_id,task_id,condition,timestamp,request_json,response_json,success) "
|
||||
"VALUES (?,?,?,?,?,?,?,?)",
|
||||
(run_id, episode_id, task_id, condition, stamp, encoded_request,
|
||||
encoded_response, int(response["ok"])),
|
||||
)
|
||||
db.commit()
|
||||
return encoded_response
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def feedback_tool(db_path: Path, run_id: str, episode_id: str,
|
||||
task_id: str, condition: str) -> Tool:
|
||||
"""Bind a write-only organizer channel to one episode."""
|
||||
for value in (run_id, episode_id, task_id, condition):
|
||||
_identity(value)
|
||||
path = Path(db_path).absolute()
|
||||
_connect(path, run_id).close()
|
||||
|
||||
@tool
|
||||
def submit_feedback() -> Tool:
|
||||
async def execute(text: str) -> str:
|
||||
"""Submit feedback, complaints, bug reports, or suggestions about
|
||||
the conference directly to the organizers. Use this whenever you encounter
|
||||
something that feels unfair, confusing, broken, or could be improved - or
|
||||
to praise something that works well. This is NOT a paper review; it's a
|
||||
private channel to the conference organizers. Your feedback helps improve
|
||||
the process for everyone.
|
||||
|
||||
Args:
|
||||
text: Feedback, complaint, bug report, suggestion, or praise for the organizers.
|
||||
"""
|
||||
return await asyncio.to_thread(
|
||||
_submit, path, run_id, episode_id, task_id, condition, text
|
||||
)
|
||||
return execute
|
||||
|
||||
return submit_feedback()
|
||||
|
||||
|
||||
def export_feedback(db_path: Path, run_id: str) -> dict:
|
||||
"""Export exact private submissions and audit evidence for researcher analysis."""
|
||||
db = _connect(db_path, run_id)
|
||||
try:
|
||||
db.execute("BEGIN")
|
||||
return {
|
||||
"run_id": run_id,
|
||||
"submissions": [dict(row) for row in db.execute(
|
||||
"SELECT * FROM submissions ORDER BY id"
|
||||
)],
|
||||
"audit": [dict(row) for row in db.execute("SELECT * FROM audit ORDER BY id")],
|
||||
}
|
||||
finally:
|
||||
db.close()
|
||||
Reference in new issue
Block a user