kin: KIN-016 Агенты должны уметь говорить 'не могу'. Если агент не может выполнить задачу (нет доступа, не понимает, выходит за компетенцию) — он должен вернуть status: blocked с причиной, а не пытаться угадывать. PM при получении blocked от агента — эскалирует к человеку через GUI (уведомление) и Telegram (когда будет).
This commit is contained in:
parent
a605e9d110
commit
d9172fc17c
35 changed files with 2375 additions and 23 deletions
|
|
@ -265,3 +265,83 @@ class TestReviseContext:
|
|||
prompt = format_prompt(ctx, "backend_dev", "You are a developer.")
|
||||
assert "## Director's revision request:" not in prompt
|
||||
assert "## Your previous output (before revision):" not in prompt
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# KIN-071: project_type and SSH context
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestOperationsProject:
|
||||
"""KIN-071: operations project_type propagates to context and prompt."""
|
||||
|
||||
@pytest.fixture
|
||||
def ops_conn(self):
|
||||
c = init_db(":memory:")
|
||||
models.create_project(
|
||||
c, "srv", "My Server", "",
|
||||
project_type="operations",
|
||||
ssh_host="10.0.0.1",
|
||||
ssh_user="root",
|
||||
ssh_key_path="~/.ssh/id_rsa",
|
||||
ssh_proxy_jump="jumpt",
|
||||
)
|
||||
models.create_task(c, "SRV-001", "srv", "Scan server")
|
||||
yield c
|
||||
c.close()
|
||||
|
||||
def test_slim_project_includes_project_type(self, ops_conn):
|
||||
"""KIN-071: _slim_project включает project_type."""
|
||||
ctx = build_context(ops_conn, "SRV-001", "sysadmin", "srv")
|
||||
assert ctx["project"]["project_type"] == "operations"
|
||||
|
||||
def test_slim_project_includes_ssh_fields_for_operations(self, ops_conn):
|
||||
"""KIN-071: _slim_project включает ssh_* поля для operations-проектов."""
|
||||
ctx = build_context(ops_conn, "SRV-001", "sysadmin", "srv")
|
||||
proj = ctx["project"]
|
||||
assert proj["ssh_host"] == "10.0.0.1"
|
||||
assert proj["ssh_user"] == "root"
|
||||
assert proj["ssh_key_path"] == "~/.ssh/id_rsa"
|
||||
assert proj["ssh_proxy_jump"] == "jumpt"
|
||||
|
||||
def test_slim_project_no_ssh_fields_for_development(self):
|
||||
"""KIN-071: development-проект не получает ssh_* в slim."""
|
||||
c = init_db(":memory:")
|
||||
models.create_project(c, "dev", "Dev", "/path")
|
||||
models.create_task(c, "DEV-001", "dev", "A task")
|
||||
ctx = build_context(c, "DEV-001", "backend_dev", "dev")
|
||||
assert "ssh_host" not in ctx["project"]
|
||||
c.close()
|
||||
|
||||
def test_sysadmin_context_gets_decisions_and_modules(self, ops_conn):
|
||||
"""KIN-071: sysadmin роль получает все decisions и modules."""
|
||||
models.add_module(ops_conn, "srv", "nginx", "service", "/etc/nginx")
|
||||
models.add_decision(ops_conn, "srv", "gotcha", "Port 80 in use", "conflict")
|
||||
ctx = build_context(ops_conn, "SRV-001", "sysadmin", "srv")
|
||||
assert "decisions" in ctx
|
||||
assert "modules" in ctx
|
||||
assert len(ctx["modules"]) == 1
|
||||
|
||||
def test_format_prompt_includes_ssh_connection_section(self, ops_conn):
|
||||
"""KIN-071: format_prompt добавляет '## SSH Connection' для operations."""
|
||||
ctx = build_context(ops_conn, "SRV-001", "sysadmin", "srv")
|
||||
prompt = format_prompt(ctx, "sysadmin", "You are sysadmin.")
|
||||
assert "## SSH Connection" in prompt
|
||||
assert "10.0.0.1" in prompt
|
||||
assert "root" in prompt
|
||||
assert "jumpt" in prompt
|
||||
|
||||
def test_format_prompt_no_ssh_section_for_development(self):
|
||||
"""KIN-071: development-проект не получает SSH-секцию в prompt."""
|
||||
c = init_db(":memory:")
|
||||
models.create_project(c, "dev", "Dev", "/path")
|
||||
models.create_task(c, "DEV-001", "dev", "A task")
|
||||
ctx = build_context(c, "DEV-001", "backend_dev", "dev")
|
||||
prompt = format_prompt(ctx, "backend_dev", "You are a dev.")
|
||||
assert "## SSH Connection" not in prompt
|
||||
c.close()
|
||||
|
||||
def test_format_prompt_includes_project_type(self, ops_conn):
|
||||
"""KIN-071: format_prompt включает Project type в секцию проекта."""
|
||||
ctx = build_context(ops_conn, "SRV-001", "sysadmin", "srv")
|
||||
prompt = format_prompt(ctx, "sysadmin", "You are sysadmin.")
|
||||
assert "Project type: operations" in prompt
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue