kin: auto-commit after pipeline

This commit is contained in:
Gros Frumos 2026-03-17 17:26:31 +02:00
parent 17d7806838
commit eab9e951ab
12 changed files with 1696 additions and 5 deletions

View file

@ -531,6 +531,86 @@ def get_running_pipelines_with_pid(conn: sqlite3.Connection) -> list[dict]:
return _rows_to_list(rows)
def get_pipeline_for_watch(conn: sqlite3.Connection, task_id: str) -> dict | None:
"""Return the most recent top-level pipeline for a task (for kin watch)."""
row = conn.execute(
"""SELECT id, task_id, project_id, status, pid, steps, created_at, completed_at
FROM pipelines
WHERE task_id = ? AND parent_pipeline_id IS NULL
ORDER BY created_at DESC, id DESC LIMIT 1""",
(task_id,),
).fetchone()
return _row_to_dict(row)
def get_current_agent_log(
conn: sqlite3.Connection, task_id: str, since_iso: str
) -> dict | None:
"""Return the most recent agent log for a task since a given datetime (for kin watch)."""
row = conn.execute(
"""SELECT agent_role, output_summary, duration_seconds, success, created_at
FROM agent_logs
WHERE task_id = ? AND created_at >= ?
ORDER BY id DESC LIMIT 1""",
(task_id, since_iso),
).fetchone()
return _row_to_dict(row)
def write_log(
conn: sqlite3.Connection,
pipeline_id: int,
message: str,
level: str = "INFO",
extra: dict | list | None = None,
) -> dict:
"""Insert a pipeline log entry. Returns inserted row as dict."""
extra_json = json.dumps(extra, ensure_ascii=False) if extra is not None else None
cur = conn.execute(
"""INSERT INTO pipeline_log (pipeline_id, message, level, extra_json)
VALUES (?, ?, ?, ?)""",
(pipeline_id, message, level, extra_json),
)
conn.commit()
row = conn.execute(
"SELECT * FROM pipeline_log WHERE id = ?", (cur.lastrowid,)
).fetchone()
return _row_to_dict(row)
def get_pipeline_logs(
conn: sqlite3.Connection,
pipeline_id: int,
since_id: int = 0,
) -> list[dict]:
"""Get pipeline log entries after since_id in chronological order."""
rows = conn.execute(
"""SELECT * FROM pipeline_log
WHERE pipeline_id = ? AND id > ?
ORDER BY id ASC""",
(pipeline_id, since_id),
).fetchall()
return _rows_to_list(rows)
def get_all_running_pipelines(conn: sqlite3.Connection) -> list[dict]:
"""Return all running pipelines with task/project info and current agent (for kin ps)."""
rows = conn.execute(
"""SELECT p.id, p.task_id, p.status, p.pid, p.created_at,
p.parent_pipeline_id,
t.title, proj.name AS project_name,
(SELECT agent_role FROM agent_logs
WHERE task_id = p.task_id AND created_at >= p.created_at
ORDER BY id DESC LIMIT 1) AS current_agent
FROM pipelines p
JOIN tasks t ON p.task_id = t.id
JOIN projects proj ON p.project_id = proj.id
WHERE p.status = 'running'
ORDER BY p.created_at DESC"""
).fetchall()
return _rows_to_list(rows)
# ---------------------------------------------------------------------------
# Support
# ---------------------------------------------------------------------------
@ -998,6 +1078,47 @@ def get_last_handoff(
return _row_to_dict(row)
# ---------------------------------------------------------------------------
# Project Links (KIN-079)
# ---------------------------------------------------------------------------
def create_project_link(
conn: sqlite3.Connection,
from_project: str,
to_project: str,
type: str,
description: str | None = None,
) -> dict:
"""Create a project dependency link. Returns the created link as dict."""
cur = conn.execute(
"""INSERT INTO project_links (from_project, to_project, type, description)
VALUES (?, ?, ?, ?)""",
(from_project, to_project, type, description),
)
conn.commit()
row = conn.execute(
"SELECT * FROM project_links WHERE id = ?", (cur.lastrowid,)
).fetchone()
return _row_to_dict(row)
def get_project_links(conn: sqlite3.Connection, project_id: str) -> list[dict]:
"""Get all project links where project_id is from_project or to_project."""
rows = conn.execute(
"SELECT * FROM project_links WHERE from_project = ? OR to_project = ?"
" ORDER BY created_at",
(project_id, project_id),
).fetchall()
return _rows_to_list(rows)
def delete_project_link(conn: sqlite3.Connection, link_id: int) -> bool:
"""Delete a project link by id. Returns True if deleted, False if not found."""
cur = conn.execute("DELETE FROM project_links WHERE id = ?", (link_id,))
conn.commit()
return cur.rowcount > 0
def get_chat_messages(
conn: sqlite3.Connection,
project_id: str,