Coding Agent
Norns includes a coding agent that can understand codebases and make changes. It supports reading files, searching code, editing files, running commands, and git operations.
Status
Enabled: As of RAV-136, the CodeDomainSupervisor is fully integrated with the NornsSupervisor and routes Domain.CODE operations.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ NornsSupervisor │
│ (Intent classification → Domain.CODE) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CodeDomainSupervisor │
│ LLM-based routing to appropriate workers │
│ Stores params in self._routing_params │
└─────────────────────────────────────────────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ CodeRead │ │ CodeWrite │ │ CodeExecute │ │ CodeContext │
│ Worker │ │ Worker │ │ Worker │ │ Worker │
│ file_read │ │ file_write │ │ run_command │ │ analyze_ │
│ code_search │ │ file_edit │ │ git_* │ │ project │
│ list_files │ │ file_create │ │ run_tests │ │ register_ │
│ get_symbols │ │ │ │ run_build │ │ project │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
└──────────────┴──────────────┴──────────────┘
│
▼
WorkerResult
(success, result, error)
Flow
- Intent Classification: NornsSupervisor classifies user message as
Domain.CODE - Supervisor Routing: CodeDomainSupervisor uses LLM to classify operation type and route to workers
- Worker Execution: Selected worker(s) execute with
WorkerResultreturn type - Result Synthesis: CodeDomainSupervisor combines results into coherent response
Key Files
| File | Purpose |
|---|---|
agents/domain_supervisors/code_supervisor.py | CodeDomainSupervisor implementation |
agents/workers/code_workers.py | All 4 worker implementations |
agents/supervisor.py | NornsSupervisor with Domain.CODE routing |
agents/base.py | BaseDomainSupervisor and BaseWorker interfaces |
Workers
CodeReadWorker
Handles read-only code operations.
Operations:
file_read- Read file contentscode_search- Search for patterns using greplist_files- List files in a directory with glob patternsget_file_symbols- Extract functions, classes, and imports
Parameter Aliases:
directory→path(for list_files)file_type→pattern(e.g., "python" → "*.py")
async def execute(
self, state: HierarchicalState, action: str,
operation: str = "file_read",
file_path: Optional[str] = None,
path: Optional[str] = None,
directory: Optional[str] = None, # alias for path
pattern: Optional[str] = None,
file_type: Optional[str] = None, # alias for pattern
query: Optional[str] = None,
**kwargs,
) -> WorkerResult
CodeWriteWorker
Handles file modification operations.
Operations:
file_write- Write complete file contentsfile_edit- Apply surgical editsfile_create- Create new files
CodeExecuteWorker
Runs allowed shell commands.
Operations:
run_command- Execute shell commandgit_status- Get git statusgit_diff- Get git diffgit_add- Stage filesgit_commit- Create commitrun_tests- Run project testsrun_build- Build project
Allowed Commands:
- Package managers: npm, yarn, pnpm, bun, pip, poetry
- Test runners: pytest, jest, vitest, mocha
- Build tools: make, cargo, go, tsc
- Git operations: status, diff, add, commit, log, branch
- Docker: docker, docker-compose
- Utilities: ls, cat, head, tail, grep, find, tree
Blocked Patterns:
rm -rf /- Commands with
; rm,&& rm,| rm - Redirects to
/dev/ - Piped curl/wget to shell
CodeContextWorker
Manages project understanding.
Operations:
analyze_project- Analyze project structure and tech stackget_project_context- Get summary of project contextlearn_pattern- Learn a code pattern for future referenceregister_project- Register a new project for operations
Database Tables
code_projects
Registered code projects.
| Column | Type | Description |
|---|---|---|
| project_id | UUID | Primary key |
| user_id | UUID | Owner |
| name | VARCHAR(255) | Project name |
| slug | VARCHAR(100) | URL-safe identifier |
| repo_type | VARCHAR(50) | local, gitlab, github |
| repo_url | TEXT | Remote URL |
| local_path | TEXT | Local filesystem path |
| primary_language | VARCHAR(50) | Main language |
| allowed_commands | TEXT[] | Permitted commands |
| blocked_paths | TEXT[] | Restricted paths |
| is_active | BOOLEAN | Whether project is accessible |
code_patterns
Learned code patterns for project context.
| Column | Type | Description |
|---|---|---|
| pattern_id | UUID | Primary key |
| project_id | UUID | Parent project |
| pattern_name | VARCHAR(255) | Pattern identifier |
| pattern_type | VARCHAR(50) | function, class, config, test, etc. |
| pattern_content | TEXT | Pattern template/example |
| usage_count | INTEGER | How often referenced |
code_operations
Audit log of all code operations.
| Column | Type | Description |
|---|---|---|
| operation_id | UUID | Primary key |
| user_id | UUID | Who performed |
| project_id | UUID | Target project |
| operation_type | VARCHAR(50) | read, write, execute |
| target_path | TEXT | File/directory affected |
| command | TEXT | Command executed (if applicable) |
| status | VARCHAR(50) | success, failed, blocked |
Security Model
Path Blocking
The following paths are blocked from read/write operations:
.envfilessecrets/directoriescredentialsfiles.git/config- SSH keys (
id_rsa,.ssh/)
Command Allowlist
Only explicitly allowed commands can be executed. The allowlist includes common development tools but excludes dangerous operations.
Audit Logging
All code operations are logged to the code_operations table with:
- User who performed the operation
- Target path
- Operation type
- Command executed (for execute operations)
- Success/failure status
Usage Examples
Read a file
@norns Read the main.py file
List files
@norns List all Python files in /app
Search code
@norns Search for "async def" in the codebase
Run tests
@norns Run the tests for the auth module
Check git status
@norns What's the git status?
Analyze project
@norns Analyze the structure of this project
Routing Examples
The CodeDomainSupervisor uses LLM to classify operations:
| User Request | Worker | Operation | Params |
|---|---|---|---|
| "read main.py" | code_read | file_read | file_path: "main.py" |
| "list python files in /app" | code_read | list_files | path: "/app", pattern: "*.py" |
| "search for UserService" | code_read | code_search | query: "UserService" |
| "edit main.py to add logging" | code_write | file_edit | - |
| "run pytest" | code_execute | run_tests | - |
| "git status" | code_execute | git_status | - |
| "analyze this project" | code_context | analyze_project | - |
Implementation Notes
WorkerResult Pattern
All workers return WorkerResult with:
@dataclass
class WorkerResult:
worker_name: str
domain: Domain
success: bool
result: Optional[Any] = None
error: Optional[str] = None
metadata: Optional[dict] = None
Parameter Forwarding
The CodeDomainSupervisor:
- Uses LLM to parse operation type and parameters
- Stores params in
self._routing_params - Passes params to workers via
**params
NornsSupervisor Integration
# In supervisor.py
self.domain_supervisors = {
Domain.CODE: CodeDomainSupervisor(),
# ... other domains
}
Testing
Smoke test commands:
# List files
curl -X POST http://docs/AI-ML-Platform/norns-agent:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"list all python files in /app"}]}'
# Read file
curl -X POST http://docs/AI-ML-Platform/norns-agent:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"read the file /app/main.py"}]}'
# Search code
curl -X POST http://docs/AI-ML-Platform/norns-agent:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"search for CodeReadWorker in the codebase"}]}'
Related
- Norns Agent - Main agent architecture
- Goals and Background Execution - Goal integration
- Bifrost MCP Gateway - Tool execution gateway