API: Resolver¶
from agentspec import resolve, ResolvedPlan, load_agent
from agentspec.resolver.merger import resolve_inheritance, TrustEscalationError
manifest = load_agent("my.agent")
plan = resolve(manifest, verbose=True)
resolve(manifest, verbose=False) -> ResolvedPlan¶
Auto-negotiates runtime, model, tools, auth, and system prompt.
Steps:
- Resolves inheritance chain (recursive)
- Detects available runtimes (
shutil.which) - Matches model preferences to runtime + auth
- Maps abstract skills to concrete tools
- Resolves MCP tools
- Builds system prompt
Raises RuntimeError if no model can be resolved.
ResolvedPlan¶
@dataclass
class ResolvedPlan:
runtime: str # e.g. "claude-code"
model: str # e.g. "claude/claude-sonnet-4-6"
tools: list[str]
missing_tools: list[str]
auth_source: str # e.g. "env.ANTHROPIC_API_KEY"
system_prompt: str
warnings: list[str]
decisions: list[str] # full trace
def to_dict(self) -> dict:
...
resolve_inheritance(manifest) -> AgentManifest¶
Walks the base: chain, merging according to merge: strategy. Enforces trust-restrict invariant.
Raises TrustEscalationError if child tries to escalate trust.
from agentspec.resolver.merger import resolve_inheritance, TrustEscalationError
try:
merged = resolve_inheritance(child_manifest)
except TrustEscalationError as e:
print(f"Refused: {e}")
RUNTIME_BINARIES¶
{
"claude-code": "claude",
"gemini-cli": "gemini",
"cursor": "cursor",
"codex-cli": "codex",
"opencode": "opencode",
"aider": "aider",
"ollama": "ollama",
}
Override by patching for testing:
from unittest.mock import patch
@patch("agentspec.resolver.resolver._detect_runtimes")
def test_my_thing(mock_runtimes):
mock_runtimes.return_value = {"claude-code": True, ...}
SKILL_MAP¶
{
"web-search": ["brave-mcp", "serper-mcp", "tavily-mcp"],
"code-execution": ["bash", "python-repl"],
"browser": ["playwright-mcp", "puppeteer-mcp"],
"git": ["git"],
"github": ["github-mcp"],
"noether-compose": ["noether"],
# ... extensible
}
Add custom mappings:
TRAIT_PROMPTS¶
Maps known traits to prompt fragments:
{
"cite-everything": "Always cite sources with URLs or references.",
"flag-uncertainty": "Mark uncertain information with [UNCERTAIN].",
"never-guess": "If you don't know something, say so. Never fabricate.",
"noether-first": "Prefer Noether compositions over writing code...",
# ...
}
Unknown traits pass through verbatim — they're added to the system prompt as-is.