capture_plan()
Capture an execution plan from a prompt.
Design Philosophy: It captures the agent's intent as an LLM generates the plan dynamically from natural language. This is the foundation of ArmorIQ's intent-based security model.
Captures an execution plan from a prompt. The plan structure contains the steps the agent intends to execute.
client.capture_plan(
llm: str,
prompt: str,
plan: dict = None,
metadata: dict = None
) -> PlanCapturePrimary Use Case: LLM-Generated Plans
# ✓ Recommended: Let LLM generate the plan
captured = client.capture_plan(
llm="gpt-4",
prompt="Fetch user data, calculate risk score, and store result"
)
# LLM autonomously decides which MCPs and actions to useParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| llm | str | Yes | LLM identifier (e.g., "gpt-4", "claude-3", "gpt-3.5-turbo") |
| prompt | str | Yes | Natural language description of what to do |
| plan | dict | No | Optional pre-defined plan structure (if omitted, LLM generates it) |
| metadata | dict | No | Optional metadata to attach to plan |
Plan Structure (if providing explicit plan)
{
"steps": [
{
"action": str, # Action name (required)
"mcp": str, # MCP name (required)
"description": str, # Human-readable description (optional)
"metadata": dict # Additional metadata (optional)
}
],
"metadata": dict # Plan-level metadata (optional)
}Returns
PlanCapture object containing:
{
"plan": dict, # Original or LLM-generated plan
"llm": str, # LLM used
"prompt": str, # Original prompt
"metadata": dict # Attached metadata
}Raises
- InvalidPlanError: If plan structure is invalid
- ValueError: If required fields are missing
- CSRGException: If CSRG canonicalization fails
Examples
Method 1: Prompt-based (LLM generates plan)
# Let LLM generate the plan structure
captured = client.capture_plan(
llm="gpt-4",
prompt="Fetch user data from database and calculate risk score"
)
print(f"Generated {len(captured.plan['steps'])} steps")
print(f"Plan: {captured.plan}")Method 2: Explicit plan structure
# Provide exact plan structure
explicit_plan = {
"steps": [
{"action": "fetch_data", "mcp": "data-mcp"},
{"action": "analyze", "mcp": "analytics-mcp"}
]
}
captured = client.capture_plan(
llm="gpt-4",
prompt="Analyze data", # Still required for context
plan=explicit_plan # Use this exact structure
)
print(f"Steps: {len(captured.plan['steps'])}")Method 3: Plan with metadata
# Include metadata for tracking
captured = client.capture_plan(
llm="gpt-4",
prompt="Calculate credit risk for loan application",
plan={
"steps": [
{
"action": "calculate_risk",
"mcp": "analytics-mcp",
"description": "Calculate credit risk score",
"metadata": {"priority": "high"}
}
]
},
metadata={
"purpose": "credit_assessment",
"version": "1.2.0",
"tags": ["finance", "risk"]
}
)
print(f"Metadata: {captured.metadata}")What happens during capture_plan()?
- SDK receives prompt and optional plan structure
- If no plan provided, LLM generates it (or uses a template in current version)
- Plan structure is validated and stored
- Returns PlanCapture object with plan steps
What gets validated during capture_plan()?
Structural checks
- Required fields present (
action,mcpin each step) - Valid JSON format and data types
- No duplicate or malformed steps
Registry verification
- Each MCP exists in the MCP Registry
- Each action is supported by its MCP
- Action parameters match the expected schema
Canonicalization (CSRG)
- Plan converted to deterministic canonical form
- Cryptographic hash computed (
plan_hash) - Merkle proof structure generated for later verification
Storage
- Validated plan stored with unique
plan_id - Plan hash and proof artifacts saved
- Timestamp and metadata recorded
If validation fails: returns a specific error (e.g., InvalidPlanError, InvalidMCPError) with details about which step or field failed.