93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
# retoor <retoor@molodetz.nl>
|
|||
|
|
|
||
|
|
import asyncio
|
||
|
|
|
||
|
|
from devplacepy.database import get_setting, set_setting
|
||
|
|
from devplacepy.services.devii.agents.runner import SUBAGENT_BASE_PROMPT
|
||
|
|
from devplacepy.services.devii.config import FIELD_AGENTS_ENABLED
|
||
|
|
from devplacepy.services.devii.session import ORCHESTRATION_FRAGMENT
|
||
|
|
from devplacepy.services.manager import service_manager
|
||
|
|
from devplacepy.services.devii import DeviiService
|
||
|
|
from tests.conftest import run_async
|
||
|
|
|
||
|
|
|
||
|
|
def _hub():
|
||
|
|
if service_manager.get_service("devii") is None:
|
||
|
|
service_manager.register(DeviiService())
|
||
|
|
svc = service_manager.get_service("devii")
|
||
|
|
return svc.hub(), svc
|
||
|
|
|
||
|
|
|
||
|
|
def _session(channel, owner_id):
|
||
|
|
hub, svc = _hub()
|
||
|
|
return hub.get_or_create(
|
||
|
|
"guest", owner_id, "guest", "", svc.instance_base_url(), is_admin=False, channel=channel
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class _Conn:
|
||
|
|
def __init__(self):
|
||
|
|
self.frames = []
|
||
|
|
|
||
|
|
async def send_json(self, payload):
|
||
|
|
self.frames.append(payload)
|
||
|
|
|
||
|
|
|
||
|
|
def test_orchestration_block_follows_flag(local_db):
|
||
|
|
previous = get_setting(FIELD_AGENTS_ENABLED, "")
|
||
|
|
try:
|
||
|
|
set_setting(FIELD_AGENTS_ENABLED, "")
|
||
|
|
main = _session("main", "prompt-off")
|
||
|
|
assert "# ORCHESTRATION" not in main._compose_system_prompt()
|
||
|
|
set_setting(FIELD_AGENTS_ENABLED, "1")
|
||
|
|
assert "# ORCHESTRATION" in main._compose_system_prompt()
|
||
|
|
assert "agent_start" in main._compose_system_prompt()
|
||
|
|
assert "needs_user" in main._compose_system_prompt()
|
||
|
|
docs = _session("docs", "prompt-docs")
|
||
|
|
assert "# ORCHESTRATION" not in docs._compose_system_prompt()
|
||
|
|
finally:
|
||
|
|
set_setting(FIELD_AGENTS_ENABLED, previous or "")
|
||
|
|
|
||
|
|
|
||
|
|
def test_fragments_cover_contract_and_relay():
|
||
|
|
assert "four-part contract" in ORCHESTRATION_FRAGMENT
|
||
|
|
assert "budget_hint" in ORCHESTRATION_FRAGMENT
|
||
|
|
assert "agent_result" in ORCHESTRATION_FRAGMENT
|
||
|
|
assert "ui_prompt" in ORCHESTRATION_FRAGMENT
|
||
|
|
assert "ask_user" in SUBAGENT_BASE_PROMPT
|
||
|
|
assert "Confirmation-gated" in SUBAGENT_BASE_PROMPT
|
||
|
|
|
||
|
|
|
||
|
|
def test_trace_agent_emits_labelled_frame(local_db):
|
||
|
|
session = _session("main", "trace-agent")
|
||
|
|
conn = _Conn()
|
||
|
|
|
||
|
|
async def flow():
|
||
|
|
session.attach(conn)
|
||
|
|
try:
|
||
|
|
session.trace_agent("uid-1", "sg", "call", "fetch_url", "example.com")
|
||
|
|
await asyncio.sleep(0.2)
|
||
|
|
finally:
|
||
|
|
session.detach(conn)
|
||
|
|
|
||
|
|
run_async(flow())
|
||
|
|
assert conn.frames
|
||
|
|
frame = conn.frames[-1]
|
||
|
|
assert frame["type"] == "trace"
|
||
|
|
assert frame["agent"] == "sg"
|
||
|
|
assert frame["uid"] == "uid-1"
|
||
|
|
assert frame["name"] == "fetch_url"
|
||
|
|
|
||
|
|
|
||
|
|
def test_emit_agent_buffers_for_web_not_telegram(local_db):
|
||
|
|
main = _session("main", "emit-main")
|
||
|
|
telegram = _session("telegram", "emit-tg")
|
||
|
|
|
||
|
|
async def flow():
|
||
|
|
assert await main.emit_agent({"type": "agent", "kind": "done"}) is False
|
||
|
|
assert await telegram.emit_agent({"type": "agent", "kind": "done"}) is False
|
||
|
|
|
||
|
|
run_async(flow())
|
||
|
|
assert [f["type"] for f in main._buffer] == ["agent"]
|
||
|
|
assert telegram._buffer == []
|