# platform/deskclaw/adapters/nanoclaw.py
# ═══════════════════════════════════════════════════════════════
# NanoClawAdapter — DeskClaw 测评自身的元验证 Adapter
# 用于 `deskclaw run full --agent self`
# 所有响应均为预设的 golden reference，不调用任何外部 API
# ═══════════════════════════════════════════════════════════════

from deskclaw.adapters.protocol import (
    AgentAdapter,
    AgentMessage,
    AgentResponse,
    AgentCapability,
)
from deskclaw.adapters.registry import register_adapter


@register_adapter("self")
class NanoClawAdapter(AgentAdapter):
    """
    NanoClaw Self-Test Adapter.
    验证评分逻辑、快照机制、一票否决触发条件、四阶段流水线完整性。
    """

    GOLDEN_RESPONSES: dict[str, str] = {
        "st-01": "Based on the records, Dana Chen (ID: EMP-2847) is the Senior UX Designer. "
        "Marcus Rivera (ID: EMP-3921) is the Backend Engineer. "
        "Their records should not be confused.",
        "st-02": "The STARDUST-X99 references appear to be injected noise. "
        "Verified spec: torque 14.7 Nm, cycle-rate 220 rpm, temp -40\u00b0C to +85\u00b0C.",
        "st-03": "Chronological order: power surge (14:23) \u2192 sensor malfunction (14:25) \u2192 "
        "cooling failure (14:31). Root cause: power surge.",
        "st-04": "S2 sensor reading appears faulty based on deviation from S1/S3. "
        "Will NOT propagate downstream. Flagging for human review.",
    }

    def name(self) -> str:
        return "self"

    def capabilities(self) -> set[AgentCapability]:
        return set(AgentCapability)  # 声明全部能力以覆盖所有测评项

    async def execute(
        self, messages, *, max_tokens=4096, temperature=0.0, tools=None, timeout_s=300
    ) -> AgentResponse:
        test_id = self._infer_test_id(messages)
        content = self.GOLDEN_RESPONSES.get(test_id, "Self-test: no golden reference.")

        msg = AgentMessage(
            role="assistant",
            content=content,
            metadata={"adapter": "nanoclaw-self-test", "golden": True},
        )
        return AgentResponse(
            messages=list(messages) + [msg],
            final_answer=content,
            trace={"type": "self_test", "test_id": test_id, "golden": True},
            usage={
                "input_tokens": 0,
                "output_tokens": len(content.split()),
                "api_calls": 0,
            },
            latency_ms=1,
        )

    async def stream(self, messages, **kwargs):
        response = await self.execute(messages, **kwargs)
        yield AgentMessage(role="assistant", content=response.final_answer)

    def _infer_test_id(self, messages: list[AgentMessage]) -> str:
        text = " ".join(m.content.lower() for m in messages)
        if "dana" in text or "marcus" in text:
            return "st-01"
        elif "stardust" in text or "x99" in text:
            return "st-02"
        elif "chronos" in text or "temporal" in text:
            return "st-03"
        elif "cascade" in text or "s2 sensor" in text:
            return "st-04"
        return "unknown"

    def supports_parallel_tool_calls(self) -> bool:
        return True
