feat: initialize resume agent with OfferPai sync

This commit is contained in:
Codex
2026-08-05 20:20:18 +08:00
commit 61ec750031
197 changed files with 33291 additions and 0 deletions
+641
View File
@@ -0,0 +1,641 @@
from __future__ import annotations
import json
import sqlite3
from contextlib import contextmanager
from datetime import UTC, datetime
from pathlib import Path
from typing import Any, Iterator
from uuid import uuid4
from .resume_document_core import attach_gap_report_staleness
from .models import (
BusinessResume,
ComponentBlock,
ConversationTurn,
SessionView,
)
def utc_now() -> str:
return datetime.now(UTC).isoformat()
class Database:
def __init__(self, path: str | Path) -> None:
self.path = str(path)
if self.path != ":memory:":
Path(self.path).parent.mkdir(parents=True, exist_ok=True)
def connect(self) -> sqlite3.Connection:
connection = sqlite3.connect(self.path, timeout=10, isolation_level=None)
connection.row_factory = sqlite3.Row
connection.execute("PRAGMA foreign_keys = ON")
connection.execute("PRAGMA busy_timeout = 10000")
if self.path != ":memory:":
connection.execute("PRAGMA journal_mode = WAL")
return connection
@contextmanager
def transaction(self, *, immediate: bool = False) -> Iterator[sqlite3.Connection]:
connection = self.connect()
try:
connection.execute("BEGIN IMMEDIATE" if immediate else "BEGIN")
yield connection
connection.commit()
except Exception:
connection.rollback()
raise
finally:
connection.close()
def initialize(self) -> None:
with self.transaction(immediate=True) as connection:
connection.executescript(
"""
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
stage TEXT NOT NULL,
revision INTEGER NOT NULL DEFAULT 0,
profile_json TEXT NOT NULL,
draft_id TEXT,
resume_id TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS turns (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
sequence INTEGER NOT NULL,
role TEXT NOT NULL,
content TEXT,
composer_mode TEXT NOT NULL,
created_at TEXT NOT NULL,
UNIQUE(session_id, sequence)
);
CREATE TABLE IF NOT EXISTS blocks (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
turn_id TEXT NOT NULL REFERENCES turns(id) ON DELETE CASCADE,
block_index INTEGER NOT NULL,
type TEXT NOT NULL,
lifecycle TEXT NOT NULL,
data_json TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE(turn_id, block_index)
);
CREATE TABLE IF NOT EXISTS resumes (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL UNIQUE REFERENCES sessions(id) ON DELETE CASCADE,
idempotency_key TEXT,
revision INTEGER NOT NULL,
content_json TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS resume_imports (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
file_name TEXT NOT NULL,
mime_type TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
sha256 TEXT NOT NULL,
object_key TEXT NOT NULL,
status TEXT NOT NULL,
document_json TEXT,
field_reviews_json TEXT NOT NULL DEFAULT '[]',
error_code TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE(session_id, sha256)
);
CREATE INDEX IF NOT EXISTS idx_resume_imports_session
ON resume_imports(session_id, created_at DESC);
CREATE TABLE IF NOT EXISTS optimization_runs (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
entry_id TEXT NOT NULL,
mode TEXT NOT NULL,
status TEXT NOT NULL,
source_revision INTEGER NOT NULL,
state_json TEXT NOT NULL,
proposal_json TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_optimization_runs_active
ON optimization_runs(session_id, entry_id, status);
CREATE INDEX IF NOT EXISTS idx_turns_session
ON turns(session_id, sequence);
CREATE INDEX IF NOT EXISTS idx_blocks_session
ON blocks(session_id, turn_id, block_index);
"""
)
def create_session(
self,
session_id: str,
stage: str,
profile: dict[str, Any],
initial_turn: dict[str, Any],
) -> None:
now = utc_now()
with self.transaction(immediate=True) as connection:
connection.execute(
"""INSERT INTO sessions
(id, stage, revision, profile_json, created_at, updated_at)
VALUES (?, ?, 0, ?, ?, ?)""",
(session_id, stage, json.dumps(profile, ensure_ascii=False), now, now),
)
self.insert_turn(connection, session_id=session_id, **initial_turn)
def fetch_session(
self, connection: sqlite3.Connection, session_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT * FROM sessions WHERE id = ?", (session_id,)
).fetchone()
if row is None:
return None
result = dict(row)
profile = json.loads(result.pop("profile_json"))
if profile.get("job_type") == "other":
# Sessions created before the workflow upgrade used "other". Treat
# them as internship sessions so existing users can still resume.
profile["job_type"] = "internship"
updated_at = utc_now()
connection.execute(
"UPDATE sessions SET profile_json = ?, updated_at = ? WHERE id = ?",
(json.dumps(profile, ensure_ascii=False), updated_at, session_id),
)
result["updated_at"] = updated_at
result["profile"] = profile
return result
def get_session(self, session_id: str) -> dict[str, Any] | None:
with self.transaction() as connection:
return self.fetch_session(connection, session_id)
def find_latest_session_by_external_user_id(
self, external_user_id: str
) -> dict[str, Any] | None:
normalized_user_id = str(external_user_id or "").strip()
if not normalized_user_id:
return None
with self.transaction() as connection:
row = connection.execute(
"""SELECT id
FROM sessions
WHERE json_extract(
profile_json, '$.external_account.provider'
) = 'offerpai'
AND CAST(
json_extract(
profile_json, '$.external_account.user_id'
) AS TEXT
) = ?
ORDER BY updated_at DESC, created_at DESC, id DESC
LIMIT 1""",
(normalized_user_id,),
).fetchone()
return (
self.fetch_session(connection, row["id"])
if row is not None
else None
)
def update_session(
self,
connection: sqlite3.Connection,
session_id: str,
*,
stage: str,
profile: dict[str, Any],
draft_id: str | None = None,
resume_id: str | None = None,
increment_revision: bool = True,
) -> dict[str, Any]:
current = self.fetch_session(connection, session_id)
if current is None:
raise KeyError(session_id)
revision = current["revision"] + (1 if increment_revision else 0)
draft_value = draft_id if draft_id is not None else current["draft_id"]
resume_value = resume_id if resume_id is not None else current["resume_id"]
connection.execute(
"""UPDATE sessions
SET stage = ?, revision = ?, profile_json = ?, draft_id = ?,
resume_id = ?, updated_at = ?
WHERE id = ?""",
(
stage,
revision,
json.dumps(profile, ensure_ascii=False),
draft_value,
resume_value,
utc_now(),
session_id,
),
)
updated = self.fetch_session(connection, session_id)
assert updated is not None
return updated
def insert_turn(
self,
connection: sqlite3.Connection,
*,
session_id: str,
role: str,
content: str | None,
composer_mode: str,
blocks: list[dict[str, Any]],
) -> str:
turn_id = f"turn_{uuid4().hex}"
sequence = connection.execute(
"SELECT COALESCE(MAX(sequence), 0) + 1 FROM turns WHERE session_id = ?",
(session_id,),
).fetchone()[0]
now = utc_now()
connection.execute(
"""INSERT INTO turns
(id, session_id, sequence, role, content, composer_mode, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(turn_id, session_id, sequence, role, content, composer_mode, now),
)
for index, block in enumerate(blocks):
connection.execute(
"""INSERT INTO blocks
(id, session_id, turn_id, block_index, type, lifecycle,
data_json, version, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?)""",
(
block.get("id", f"block_{uuid4().hex}"),
session_id,
turn_id,
index,
block["type"],
block.get("lifecycle", "active"),
json.dumps(block.get("data", {}), ensure_ascii=False),
now,
now,
),
)
return turn_id
def fetch_block(
self, connection: sqlite3.Connection, session_id: str, block_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT * FROM blocks WHERE id = ? AND session_id = ?",
(block_id, session_id),
).fetchone()
if row is None:
return None
result = dict(row)
result["data"] = json.loads(result.pop("data_json"))
return result
def update_block(
self,
connection: sqlite3.Connection,
block_id: str,
*,
lifecycle: str,
data: dict[str, Any] | None = None,
) -> None:
row = connection.execute(
"SELECT data_json FROM blocks WHERE id = ?", (block_id,)
).fetchone()
if row is None:
raise KeyError(block_id)
serialized = row["data_json"] if data is None else json.dumps(data, ensure_ascii=False)
connection.execute(
"""UPDATE blocks
SET lifecycle = ?, data_json = ?, version = version + 1, updated_at = ?
WHERE id = ?""",
(lifecycle, serialized, utc_now(), block_id),
)
def supersede_active_components(
self,
connection: sqlite3.Connection,
session_id: str,
) -> None:
"""Make component submissions single-use when chat or create advances the flow."""
connection.execute(
"""UPDATE blocks
SET lifecycle = 'superseded', version = version + 1, updated_at = ?
WHERE session_id = ? AND type = 'component' AND lifecycle = 'active'""",
(utc_now(), session_id),
)
def get_turn(self, turn_id: str) -> ConversationTurn:
with self.transaction() as connection:
return self.fetch_turn(connection, turn_id)
def fetch_turn(
self,
connection: sqlite3.Connection,
turn_id: str,
) -> ConversationTurn:
row = connection.execute("SELECT * FROM turns WHERE id = ?", (turn_id,)).fetchone()
if row is None:
raise KeyError(turn_id)
return self._turn_from_row(connection, row)
def list_turns(self, session_id: str) -> list[ConversationTurn]:
with self.transaction() as connection:
rows = connection.execute(
"SELECT * FROM turns WHERE session_id = ? ORDER BY sequence",
(session_id,),
).fetchall()
return [self._turn_from_row(connection, row) for row in rows]
def _turn_from_row(
self, connection: sqlite3.Connection, row: sqlite3.Row
) -> ConversationTurn:
block_rows = connection.execute(
"SELECT * FROM blocks WHERE turn_id = ? ORDER BY block_index", (row["id"],)
).fetchall()
blocks = [
ComponentBlock(
id=block["id"],
type=block["type"],
lifecycle=block["lifecycle"],
data=json.loads(block["data_json"]),
version=block["version"],
created_at=block["created_at"],
updated_at=block["updated_at"],
)
for block in block_rows
]
return ConversationTurn(
id=row["id"],
sequence=row["sequence"],
role=row["role"],
content=row["content"],
composer_mode=row["composer_mode"],
blocks=blocks,
created_at=row["created_at"],
)
def session_view(self, session: dict[str, Any]) -> SessionView:
profile = session["profile"]
phone = profile.get("phone")
masked_phone = f"{phone[:3]}****{phone[-4:]}" if phone else None
return SessionView(
id=session["id"],
stage=session["stage"],
revision=session["revision"],
job_type=profile.get("job_type"),
anchor_type=profile.get("anchor_type"),
masked_phone=masked_phone,
phone_source=profile.get("phone_source"),
name=profile.get("name"),
draft_id=session.get("draft_id"),
resume_id=session.get("resume_id"),
created_at=session["created_at"],
updated_at=session["updated_at"],
)
def fetch_resume(
self, connection: sqlite3.Connection, session_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT * FROM resumes WHERE session_id = ?", (session_id,)
).fetchone()
if row is None:
return None
result = dict(row)
result["content"] = json.loads(result.pop("content_json"))
return result
def insert_resume(
self,
connection: sqlite3.Connection,
*,
resume_id: str,
session_id: str,
idempotency_key: str | None,
content: dict[str, Any],
) -> dict[str, Any]:
now = utc_now()
connection.execute(
"""INSERT INTO resumes
(id, session_id, idempotency_key, revision, content_json, created_at, updated_at)
VALUES (?, ?, ?, 1, ?, ?, ?)""",
(
resume_id,
session_id,
idempotency_key,
json.dumps(content, ensure_ascii=False),
now,
now,
),
)
result = self.fetch_resume(connection, session_id)
assert result is not None
return result
def update_resume(
self,
connection: sqlite3.Connection,
session_id: str,
content: dict[str, Any],
) -> dict[str, Any]:
connection.execute(
"""UPDATE resumes
SET revision = revision + 1, content_json = ?, updated_at = ?
WHERE session_id = ?""",
(json.dumps(content, ensure_ascii=False), utc_now(), session_id),
)
result = self.fetch_resume(connection, session_id)
if result is None:
raise KeyError(session_id)
return result
def create_optimization_run(
self,
connection: sqlite3.Connection,
*,
run_id: str,
session_id: str,
entry_id: str,
mode: str,
status: str,
source_revision: int,
state: dict[str, Any],
proposal: dict[str, Any] | None = None,
) -> dict[str, Any]:
now = utc_now()
connection.execute(
"""INSERT INTO optimization_runs
(id, session_id, entry_id, mode, status, source_revision, state_json,
proposal_json, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(
run_id, session_id, entry_id, mode, status, source_revision,
json.dumps(state, ensure_ascii=False),
json.dumps(proposal, ensure_ascii=False) if proposal else None, now, now,
),
)
result = self.fetch_optimization_run(connection, session_id, run_id)
assert result is not None
return result
def fetch_optimization_run(
self, connection: sqlite3.Connection, session_id: str, run_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT * FROM optimization_runs WHERE id = ? AND session_id = ?", (run_id, session_id)
).fetchone()
if row is None:
return None
result = dict(row)
result["state"] = json.loads(result.pop("state_json"))
raw_proposal = result.pop("proposal_json")
result["proposal"] = json.loads(raw_proposal) if raw_proposal else None
return result
def find_active_optimization_run(
self, connection: sqlite3.Connection, session_id: str, entry_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"""SELECT id FROM optimization_runs
WHERE session_id = ? AND entry_id = ?
AND status IN ('question_pending', 'proposal_pending')
ORDER BY created_at DESC LIMIT 1""",
(session_id, entry_id),
).fetchone()
return self.fetch_optimization_run(connection, session_id, row["id"]) if row else None
def list_active_optimization_runs(
self, connection: sqlite3.Connection, session_id: str
) -> list[dict[str, Any]]:
rows = connection.execute(
"""SELECT id FROM optimization_runs
WHERE session_id = ?
AND status IN ('question_pending', 'proposal_pending')
ORDER BY updated_at ASC, created_at ASC""",
(session_id,),
).fetchall()
return [
run for row in rows
if (run := self.fetch_optimization_run(connection, session_id, row["id"])) is not None
]
def update_optimization_run(
self,
connection: sqlite3.Connection,
*,
session_id: str,
run_id: str,
status: str,
state: dict[str, Any],
proposal: dict[str, Any] | None,
) -> dict[str, Any]:
connection.execute(
"""UPDATE optimization_runs
SET status = ?, state_json = ?, proposal_json = ?, updated_at = ?
WHERE id = ? AND session_id = ?""",
(
status, json.dumps(state, ensure_ascii=False),
json.dumps(proposal, ensure_ascii=False) if proposal else None,
utc_now(), run_id, session_id,
),
)
result = self.fetch_optimization_run(connection, session_id, run_id)
if result is None:
raise KeyError(run_id)
return result
def create_resume_import(
self,
connection: sqlite3.Connection,
*,
import_id: str,
session_id: str,
file_name: str,
mime_type: str,
size_bytes: int,
sha256: str,
object_key: str,
document: dict[str, Any],
field_reviews: list[dict[str, Any]],
) -> dict[str, Any]:
now = utc_now()
connection.execute(
"""INSERT INTO resume_imports
(id, session_id, file_name, mime_type, size_bytes, sha256, object_key,
status, document_json, field_reviews_json, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 'awaiting_review', ?, ?, ?, ?)""",
(
import_id, session_id, file_name, mime_type, size_bytes, sha256, object_key,
json.dumps(document, ensure_ascii=False),
json.dumps(field_reviews, ensure_ascii=False), now, now,
),
)
result = self.fetch_resume_import(connection, session_id, import_id)
assert result is not None
return result
def fetch_resume_import(
self, connection: sqlite3.Connection, session_id: str, import_id: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT * FROM resume_imports WHERE id = ? AND session_id = ?", (import_id, session_id)
).fetchone()
if row is None:
return None
result = dict(row)
result["document"] = json.loads(result.pop("document_json")) if result.get("document_json") else None
result["field_reviews"] = json.loads(result.pop("field_reviews_json"))
return result
def find_resume_import_by_sha256(
self, connection: sqlite3.Connection, session_id: str, sha256: str
) -> dict[str, Any] | None:
row = connection.execute(
"SELECT id FROM resume_imports WHERE session_id = ? AND sha256 = ?",
(session_id, sha256),
).fetchone()
return self.fetch_resume_import(connection, session_id, row["id"]) if row else None
def update_resume_import_status(
self, connection: sqlite3.Connection, session_id: str, import_id: str, status: str
) -> dict[str, Any]:
connection.execute(
"UPDATE resume_imports SET status = ?, updated_at = ? WHERE id = ? AND session_id = ?",
(status, utc_now(), import_id, session_id),
)
result = self.fetch_resume_import(connection, session_id, import_id)
if result is None:
raise KeyError(import_id)
return result
@staticmethod
def resume_view(resume: dict[str, Any]) -> BusinessResume:
return BusinessResume(
id=resume["id"],
session_id=resume["session_id"],
revision=resume["revision"],
content=attach_gap_report_staleness(resume["content"]),
created_at=resume["created_at"],
updated_at=resume["updated_at"],
)
def delete_session(self, session_id: str) -> bool:
with self.transaction(immediate=True) as connection:
cursor = connection.execute("DELETE FROM sessions WHERE id = ?", (session_id,))
return cursor.rowcount > 0