diff --git a/hermes_cli/kanban_db.py b/hermes_cli/kanban_db.py index c6722410da7..f622aa20e8e 100644 --- a/hermes_cli/kanban_db.py +++ b/hermes_cli/kanban_db.py @@ -599,6 +599,7 @@ class Task: # JSON array of skill names. None = use only the defaults; empty # list = explicitly no extra skills. skills: Optional[list] = None + model_override: Optional[str] = None # Per-task override for the consecutive-failure circuit breaker. # The value is the failure count at which the breaker trips — e.g. # ``max_retries=1`` blocks on the first failure (zero retries), @@ -668,6 +669,7 @@ class Task: row["current_step_key"] if "current_step_key" in keys else None ), skills=skills_value, + model_override=row["model_override"] if "model_override" in keys and row["model_override"] else None, max_retries=( row["max_retries"] if "max_retries" in keys else None ), @@ -792,6 +794,10 @@ CREATE TABLE IF NOT EXISTS tasks ( -- Appended to the dispatcher's built-in `--skills kanban-worker`. -- NULL or empty array = no extras. skills TEXT, + -- Per-task model override. When set, the dispatcher passes -m + -- to the worker, overriding the profile's default model. NULL = use + -- the profile default. + model_override TEXT, -- Per-task override for the consecutive-failure circuit breaker. -- The value is the failure count at which the breaker trips — e.g. -- ``max_retries=1`` blocks on the first failure. NULL (the common @@ -1077,6 +1083,9 @@ def _migrate_add_optional_columns(conn: sqlite3.Connection) -> None: # they were getting before the column existed). _add_column_if_missing(conn, "tasks", "max_retries", "max_retries INTEGER") + if "model_override" not in cols: + conn.execute("ALTER TABLE tasks ADD COLUMN model_override TEXT") + # task_events gained a run_id column; back-fill it as NULL for # historical events (they predate runs and can't be attributed). ev_cols = {row["name"] for row in conn.execute("PRAGMA table_info(task_events)")} @@ -4348,6 +4357,8 @@ def _default_spawn( for sk in task.skills: if sk and sk != "kanban-worker": cmd.extend(["--skills", sk]) + if task.model_override: + cmd.extend(["-m", task.model_override]) cmd.extend([ "chat", "-q", prompt,