refactor: no comments left - one-line module docstrings, contracts on public fields only; jobs/job.py; example config and README

This commit is contained in:
hh committed 2026-09-02 00:33:04 +02:00
1 parent 3915ab48f9
commit 0e07e8409d
65 files changed
+795 -1891

No files matched your search

+8 -46
View File
@@ -1,16 +1,7 @@
"""Cross-frontend turn record.
Frontends that finish a turn (the Anthropic Messages frontend, the
markdown frontend) emit a :class:`TurnRecord` to every handler in
``GatewayRuntime.turn_log_handlers``. The markdown frontend uses this
to persist chats from other frontends into the Obsidian vault — see
``frontends/markdown/crossfront.py``.
Kept tiny on purpose: it carries the structured-enough payload a logger
needs (which agent ran, input history, the assembled assistant reply)
and nothing else. The full event stream is gone by the time handlers
run — if a future consumer needs deltas it would subscribe at a lower
level, not here.
Frontends emit a :class:`TurnRecord` to every handler in
``GatewayRuntime.turn_log_handlers`` after a turn finishes.
"""
from __future__ import annotations
@@ -26,10 +17,6 @@ if TYPE_CHECKING:
__all__ = ["TurnRecord", "slugify"]
# Filesystem-safe slug: collapse anything that isn't a word char or
# space/hyphen to a hyphen, then squash runs of separators. Aimed at
# letting users build filenames from ``record.first_user_text`` without
# hand-rolling sanitization in every config.
_SLUG_BAD_RE = re.compile(r"[^\w\s\-]+", flags=re.UNICODE)
_SLUG_SEP_RE = re.compile(r"[\s\-]+", flags=re.UNICODE)
@@ -37,10 +24,7 @@ _SLUG_SEP_RE = re.compile(r"[\s\-]+", flags=re.UNICODE)
def slugify(text: str, *, maxlen: int = 40) -> str:
"""Sanitize ``text`` for use as a filename fragment.
Strips punctuation, collapses whitespace/hyphens into single ``-``,
and truncates to ``maxlen``. Returns ``"untitled"`` for empty input.
Unicode letters are preserved (Obsidian handles them fine; macOS
and modern Linux fs's too).
Truncates to ``maxlen`` and returns ``"untitled"`` for empty input.
"""
cleaned = _SLUG_BAD_RE.sub(" ", text).strip()
cleaned = _SLUG_SEP_RE.sub("-", cleaned).strip("-")
@@ -55,17 +39,8 @@ def slugify(text: str, *, maxlen: int = 40) -> str:
class TurnRecord:
"""One completed turn, as seen by a frontend.
``input_messages`` is the conversation history sent to the backend
(everything *before* the assistant reply). ``output_message`` is the
finalized assistant ``Message`` (post-accumulation, with all content
blocks attached). ``system`` is the per-request system prompt if any
— agents own their own ``system_prompt``, this is the override the
caller passed; most handlers can ignore it.
``source`` names the frontend that produced the record so the
cross-frontend logger can avoid logging its own turns (markdown
frontend writing the file would otherwise also receive its own
broadcast and double-write).
``input_messages`` excludes the assistant reply; ``source`` names the
producing frontend so a cross-frontend logger can skip its own turns.
"""
agent_name: str
@@ -76,12 +51,7 @@ class TurnRecord:
@property
def first_user_text(self) -> str:
"""Plain text of the *earliest* user turn in this conversation.
Useful for naming new files by topic. Empty string if the input
history somehow has no user turn (shouldn't happen — turns are
broadcast only after a user → assistant cycle).
"""
"""Empty string if the input history has no user turn."""
for msg in self.input_messages:
if msg.get("role") == "user":
return _text_of(msg.get("content", ""))
@@ -89,7 +59,6 @@ class TurnRecord:
@property
def last_user_text(self) -> str:
"""Plain text of the most recent user turn (the trigger)."""
for msg in reversed(self.input_messages):
if msg.get("role") == "user":
return _text_of(msg.get("content", ""))
@@ -109,10 +78,8 @@ class TurnRecord:
def _text_of(content: object) -> str:
"""Flatten an Anthropic ``MessageParam.content`` field to a plain string.
Handles both shapes the SDK accepts: raw string, or a list of block
dicts (we pull ``text`` blocks only). Anything we don't recognize is
silently skipped — these helpers exist for naming files, not for
faithful content reconstruction.
Handles both raw-string and block-list shapes; unrecognized content is
silently skipped since this exists for naming, not faithful reconstruction.
"""
if isinstance(content, str):
return content
@@ -121,11 +88,6 @@ def _text_of(content: object) -> str:
for blk in content:
if not isinstance(blk, dict):
continue
# ``MessageParam.content`` is typed as a union of typed-dicts
# per Anthropic SDK; we only care about plain ``text`` blocks
# and look them up via ``Any`` to dodge the keyed-typed-dict
# variance gymnastics (``ty`` won't let an open dict alias a
# closed-keyed one).
d: Any = blk
if d.get("type") == "text":
parts.append(str(d.get("text", "")))