Skip to content

Dynamic Agents

Dynamic agents allow you to extend Gravity with custom behaviors without writing C# code. They are defined as JSON files and loaded at startup, using the LLM as their reasoning engine while routing tool calls through the shared ReasoningRouter.

JSON Definition Format

{
  "name": "my_custom_agent",
  "description": "Specialized agent for code review tasks",
  "system": "You are an expert code reviewer. Focus on security, performance, and maintainability. Use the code_editor tool to examine files.",
  "verbs": ["review", "audit", "analyze"],
  "maxSteps": 10,
  "canWrite": false,
  "parameters": {
    "focusAreas": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Areas to focus on: security, performance, style, architecture"
    }
  }
}
FieldTypeRequiredDescription
namestringYesUnique identifier (snake_case, used in tool routing)
descriptionstringYesHuman-readable description shown in help
systemstringYesSystem prompt defining agent behavior
verbsstring[]YesTrigger verbs for intent routing
maxStepsintegerNoMax reasoning iterations (default: 10)
canWritebooleanNoWhether agent can perform write operations (default: false)
parametersobjectNoJSON schema for agent-specific parameters

Loading at Startup

  1. Place .json files in the agents/ directory next to the executable
  2. On startup, AgentLoader scans the directory
  3. Each file is validated against the schema
  4. Valid agents are registered in the DI container as IAgent implementations
  5. Agent descriptors are included in the tool manifest sent to the LLM

Invalid agents are logged but don't block startup.

Tool Call Routing

Dynamic agents use the LLM as their reasoning engine. When the LLM outputs a tool call:

  1. ReasoningRouter intercepts the call
  2. Validates parameters against the action's JSON schema
  3. Checks approval policy (IsDestructive flag)
  4. Routes to the target IAgent (built-in or MCP)
  5. Returns AgentResult to the dynamic agent's conversation

This gives dynamic agents access to all built-in tools (file operations, shell, search, etc.) without reimplementing them.

Complete Example: Security Auditor Agent

File: agents/security_auditor.json

{
  "name": "security_auditor",
  "description": "Performs security-focused code reviews",
  "system": "You are a security auditor. Scan for: SQL injection, XSS, path traversal, hardcoded secrets, insecure crypto, missing auth checks. Use code_editor to read files. Report findings with file:line references.",
  "verbs": ["audit", "security-review", "scan"],
  "maxSteps": 15,
  "canWrite": false,
  "parameters": {
    "severityThreshold": {
      "type": "string",
      "enum": ["low", "medium", "high", "critical"],
      "default": "medium"
    },
    "includeTests": { "type": "boolean", "default": false }
  }
}

Usage in chat: "Audit the Controllers folder for security issues"