kin: KIN-135-backend_dev
This commit is contained in:
parent
4c01e0e4ee
commit
24be66d16c
9 changed files with 436 additions and 6 deletions
104
core/models.py
104
core/models.py
|
|
@ -23,6 +23,16 @@ TASK_CATEGORIES = [
|
|||
"ARCH", "TEST", "PERF", "DOCS", "FIX", "OBS",
|
||||
]
|
||||
|
||||
# Valid categories for task returns (KIN-135)
|
||||
RETURN_CATEGORIES = [
|
||||
"requirements_unclear",
|
||||
"scope_too_large",
|
||||
"technical_blocker",
|
||||
"missing_context",
|
||||
"recurring_quality_fail",
|
||||
"conflicting_requirements",
|
||||
]
|
||||
|
||||
|
||||
def validate_completion_mode(value: str) -> str:
|
||||
"""Validate completion mode from LLM output. Falls back to 'review' if invalid."""
|
||||
|
|
@ -1301,3 +1311,97 @@ def get_chat_messages(
|
|||
query += " ORDER BY created_at ASC, id ASC LIMIT ?"
|
||||
params.append(limit)
|
||||
return _rows_to_list(conn.execute(query, params).fetchall())
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Task returns — escalation tracking (KIN-135)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def record_task_return(
|
||||
conn: sqlite3.Connection,
|
||||
task_id: str,
|
||||
reason_category: str,
|
||||
reason_text: str | None = None,
|
||||
returned_by: str = "system",
|
||||
pipeline_id: int | None = None,
|
||||
) -> dict:
|
||||
"""Record a task return to PM and increment return_count.
|
||||
|
||||
reason_category must be one of RETURN_CATEGORIES; defaults to 'missing_context'
|
||||
if an invalid value is supplied (fail-open).
|
||||
Returns the inserted task_returns row as dict.
|
||||
"""
|
||||
if reason_category not in RETURN_CATEGORIES:
|
||||
reason_category = "missing_context"
|
||||
|
||||
# Determine the next return_number for this task
|
||||
row = conn.execute(
|
||||
"SELECT COALESCE(MAX(return_number), 0) FROM task_returns WHERE task_id = ?",
|
||||
(task_id,),
|
||||
).fetchone()
|
||||
next_number = (row[0] if row else 0) + 1
|
||||
|
||||
conn.execute(
|
||||
"""INSERT INTO task_returns
|
||||
(task_id, return_number, reason_category, reason_text, returned_by, pipeline_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)""",
|
||||
(task_id, next_number, reason_category, reason_text, returned_by, pipeline_id),
|
||||
)
|
||||
conn.execute(
|
||||
"UPDATE tasks SET return_count = return_count + 1 WHERE id = ?",
|
||||
(task_id,),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
inserted = conn.execute(
|
||||
"SELECT * FROM task_returns WHERE task_id = ? ORDER BY id DESC LIMIT 1",
|
||||
(task_id,),
|
||||
).fetchone()
|
||||
return dict(inserted) if inserted else {}
|
||||
|
||||
|
||||
def get_task_returns(
|
||||
conn: sqlite3.Connection,
|
||||
task_id: str,
|
||||
limit: int = 20,
|
||||
) -> list[dict]:
|
||||
"""Return task return history ordered by return_number ASC."""
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM task_returns WHERE task_id = ? ORDER BY return_number ASC LIMIT ?",
|
||||
(task_id, limit),
|
||||
).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def check_return_pattern(
|
||||
conn: sqlite3.Connection,
|
||||
task_id: str,
|
||||
) -> dict:
|
||||
"""Analyse return history for a recurring pattern.
|
||||
|
||||
Returns:
|
||||
{
|
||||
"pattern_detected": bool, # True if dominant_category appears >= 2 times
|
||||
"dominant_category": str | None,
|
||||
"occurrences": int,
|
||||
}
|
||||
"""
|
||||
from collections import Counter
|
||||
|
||||
rows = conn.execute(
|
||||
"SELECT reason_category FROM task_returns WHERE task_id = ?",
|
||||
(task_id,),
|
||||
).fetchall()
|
||||
|
||||
if not rows:
|
||||
return {"pattern_detected": False, "dominant_category": None, "occurrences": 0}
|
||||
|
||||
counts = Counter(r[0] for r in rows)
|
||||
dominant_category, occurrences = counts.most_common(1)[0]
|
||||
pattern_detected = occurrences >= 2
|
||||
|
||||
return {
|
||||
"pattern_detected": pattern_detected,
|
||||
"dominant_category": dominant_category,
|
||||
"occurrences": occurrences,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue