Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
93c7d0c
Add utilities for plan execution, Git and Go agent tests, and path va…
alexlovelltroy Mar 2, 2026
c0497cc
Add multi-repo documentation generation example and enhance plan exec…
alexlovelltroy Mar 6, 2026
91912f6
Add Git and Go tooling modules with corresponding tests
alexlovelltroy Mar 10, 2026
2435ac0
Lazy load new agents in this branch.
mikegros Mar 10, 2026
cc3cf48
Retry commit of CSV utility functions after formatting.
alexlovelltroy Mar 11, 2026
7569449
Document dependencies for CSV processing in requirements.txt.
alexlovelltroy Mar 11, 2026
07857e1
Add documentation with usage examples for CSV utility functions.
alexlovelltroy Mar 11, 2026
dc4ae16
Integrated utility functions into CLI tool, allowing CSV filtering an…
alexlovelltroy Mar 11, 2026
feb6ace
Add example YAML configurations for plan execution and enhance lazy l…
alexlovelltroy Mar 11, 2026
d0eb149
Remove CSV utility functions and example usage scripts
alexlovelltroy Mar 11, 2026
76d57dd
Merge branch 'lanl:main' into alovelltroy/coding-agent
alexlovelltroy Mar 15, 2026
04e6c98
Apply suggestions from code review
alexlovelltroy Mar 17, 2026
783fa58
Enhance path validation to support unsafe writes via environment vari…
alexlovelltroy Mar 17, 2026
5ab40db
Addressed several bug code paths
alexlovelltroy Mar 17, 2026
0bc8bb5
Remove allow_unsafe_writes parameter from _validate_file_path and rel…
alexlovelltroy Mar 26, 2026
17c18b7
Merge branch 'lanl:main' into alovelltroy/coding-agent
alexlovelltroy Mar 26, 2026
76e7b3e
feat: add write_code_with_repo function to enforce repository boundaries
alexlovelltroy Mar 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions docs/git_go_agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# GitGoAgent Documentation

`GitGoAgent` is a specialized execution agent for git-managed Go repositories. It combines git control, Go development tools, code linting, and file operations to enable autonomous development workflows on Go projects.

## Basic Usage

```python
from pathlib import Path

from langchain.chat_models import init_chat_model
from ursa.agents import GitGoAgent

# Initialize the agent
agent = GitGoAgent(
llm=init_chat_model("openai:gpt-5-mini"),
workspace=Path("/path/to/your/repo"),
)

# Run a request
result = agent.invoke(
"Run tests, lint the code, and commit any fixes."
)
print(result["messages"][-1].text)
```

## Tools Available

### Git Operations
- `git_status`: Show repository status.
- `git_diff`: Show diffs (staged or unstaged).
- `git_log`: Show recent commits.
- `git_ls_files`: List tracked files.
- `git_add`: Stage files for commit.
- `git_commit`: Create a commit.
- `git_switch`: Switch branches (optionally creating new ones).
- `git_create_branch`: Create a branch without switching.

### Go Build and Test Tools
- `go_build`: Build the module using `go build ./...`
- `go_test`: Run tests with `go test ./...` (supports verbose mode)
- `go_vet`: Run Go vet for code pattern analysis
- `go_mod_tidy`: Validate and clean module dependencies

### Code Quality Tools
- `golangci_lint`: Run golangci-lint on the repository
- Automatically detects and uses `.golangci.yml` if present
- Falls back to default linter configuration if config file missing
- Provides helpful error messages if golangci-lint is not installed
- `gofmt_files`: Format .go files in-place using gofmt

### File Operations
- `read_file`: Read file contents
- `write_code`: Write new files (with optional path validation)
- `write_code_with_repo`: Write new files constrained to a repository path
- `edit_code`: Edit existing files (with optional path validation)

## Configuration and Behavior

### Timeouts
Operations use differentiated, operation-specific timeouts (not a unified timeout):

| Operation | Timeout | Rationale |
|-----------|---------|-----------|
| Git commands | 30 seconds | Should be near-instant; timeout indicates hanging (waiting for input or wrong directory) |
| Code formatting (`gofmt`) | 30 seconds | Usually fast operation |
| Code analysis (`go vet`, `go mod tidy`) | 60 seconds | Analysis is typically quick |
| Go build | 5 minutes (300s) | Builds on large codebases can be slow |
| Go test | 10 minutes (600s) | Test suites can legitimately take time |
| Linting (`golangci-lint`) | 3 minutes (180s) | Comprehensive linting takes moderate time |

**Design note:** If git commands timeout, it typically indicates:
- The agent is running commands in the wrong directory (should use `repo_path` parameter)
- Git is waiting for interactive input (e.g., passphrase, editor)
- Network issues when accessing remote repos

If other operations timeout, try running them in smaller chunks or profiling the specific operation.

### Path Safety
`write_code`, `write_code_with_repo`, and `edit_code` validate file paths to prevent:
- **Path traversal attacks** (e.g., `../../../etc/passwd` attempts are rejected)
- **Writes outside the workspace** (all files must be within the workspace directory)
- **Writes outside the repository** (`write_code_with_repo`, or `edit_code` when `repo_path` is used)

Path validation is enabled by default. For trusted sandbox/container usage, you can opt in to unsafe writes by setting:

```bash
export URSA_ALLOW_UNSAFE_WRITES=1
```

When enabled, workspace and repository boundary checks are bypassed for `write_code`, `write_code_with_repo`, and `edit_code`.

Example: Specifying a repo boundary ensures all file modifications stay within that repository.

### Golangci-lint Integration

The agent automatically integrates with `golangci-lint` for code quality checks:

```python
# Agent detects .golangci.yml and uses it automatically
agent.invoke("Run linting and report all issues")

# Linter configuration is respected while agent iterates on fixes
```

**Install golangci-lint** if not already present:
```bash
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
```

The linter supports:
- Custom linter configurations via `.golangci.yml`
- Extensibility to additional linters in future versions
- Clear error reporting when linter is misconfigured

## Common Workflows

### 1. Build and Test Validation
```python
agent.invoke(
"Build the module, run all tests, and report any failures."
)
```

### 2. Code Quality Check and Fix
```python
agent.invoke(
"Run golangci-lint, identify issues, and attempt to fix them automatically."
)
```

### 3. Feature Implementation with Git Integration
```python
agent.invoke(
"Create a new feature branch, implement the requested functionality, "
"run tests and linting, and commit the changes."
)
```

### 4. Dependency Management
```python
agent.invoke(
"Run go mod tidy to clean up dependencies, then commit the changes."
)
```

## Notes

- Operates only inside the configured workspace
- All file writes are validated against workspace and optionally repository boundaries
- Avoids destructive git operations by design (no force pushes, rebases, etc.)
- Supports subdirectory repositories via `repo_path` parameter on tools
- Explicit timeout handling prevents the agent from hanging on slow operations
- All tool output (stdout/stderr) is captured and returned to the agent for analysis
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pathlib import Path

from langchain.chat_models import init_chat_model

from ursa.agents import GitGoAgent


def main():
repo_root = Path.cwd()
agent = GitGoAgent(
llm=init_chat_model("openai:gpt-5-mini"),
workspace=repo_root,
)

prompt = "Show git status, list tracked .go files, and summarize any main.go you find."
result = agent.invoke(prompt)
print(result["messages"][-1].text)


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion examples/two_agent_examples/plan_execute/city_10_vowels.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def main():
return final_results

except Exception as e:
print(f"Error in example: {str(e)}")
print(f"Error in example: {e!s}")
import traceback

traceback.print_exc()
Expand Down
22 changes: 22 additions & 0 deletions examples/two_agent_examples/plan_execute/example_from_yaml.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Simple configuration for plan_execute_from_yaml.py
# Run with: python plan_execute_from_yaml.py --config example_from_yaml.yaml

problem: |
Write a simple Python script that reads a CSV file, filters rows where a "score"
column is above 90, and writes the results to a new CSV file.

project: csv_filter_project

planning_mode: single

models:
default: openai:gpt-4o-mini
choices:
- openai:gpt-4o-mini
- openai:gpt-3.5-turbo
- openai:gpt-5.2

logo:
enabled: false

symlink: {}
58 changes: 58 additions & 0 deletions examples/two_agent_examples/plan_execute/example_multi_repo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Simple configuration for plan_execute_multi_repo.py
# Run with: python plan_execute_multi_repo.py --config example_multi_repo.yaml

problem: |
Create a simple three-part system:
1. A shared library (utils_lib) with utility functions for CSV processing
2. A CLI tool (csv_cli) that uses the shared library
3. Documentation (docs) describing how to use the CLI

repos:
- name: utils_lib
path: /tmp/ursa_test_repos/utils_lib
url: https://github.com/example/utils_lib.git
branch: main
checkout: false
description: Shared utility functions for CSV processing
language: python

- name: csv_cli
path: /tmp/ursa_test_repos/csv_cli
url: https://github.com/example/csv_cli.git
branch: main
checkout: false
description: Command-line tool for CSV filtering
language: python

- name: docs
path: /tmp/ursa_test_repos/docs
url: https://github.com/example/docs.git
branch: main
checkout: false
description: Documentation for the CSV processing system
language: markdown

project: multi_repo_csv_system

models:
default: openai:gpt-4o-mini
choices:
- openai:gpt-4o-mini
- openai:gpt-3.5-turbo

planner:
reflection_steps: 1
research:
github:
enabled: false
queries: []

execution:
max_parallel: 2
recursion_limit: 2000
resume: false
status_interval_sec: 5
max_check_retries: 2
step_timeout_sec: 0
timeout_mode: pause
skip_failed_repos: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Multi-repo example: Generate boot-service documentation for openchami.org website
#
# This configuration orchestrates changes across two repos:
# 1. boot-service: Extract usage examples, API endpoints, and configuration details
# 2. openchami.org: Generate and publish documentation pages based on boot-service

project: openchami_boot_docs

# Problem statement: What are we trying to accomplish?
problem: |
Generate comprehensive documentation for the OpenCHAMI boot-service and publish it
on the openchami.org website. The documentation should include:

- Overview of what the boot-service does and its role in the OpenCHAMI ecosystem
- API endpoint reference with request/response examples
- Configuration guide (environment variables, config files, deployment options)
- Usage examples for common workflows (iPXE boot, cloud-init, etc.)
- Integration guide for administrators deploying the service
- One or more blog posts to describe the service to the OpenCHAMI community

The boot-service repo should be analyzed to extract accurate, up-to-date information.
The openchami.org repo should have new documentation pages created in the appropriate
location with proper navigation links.

# Repository definitions
repos:
- name: boot-service
url: https://github.com/openchami/boot-service
branch: main
checkout: true
language: go
description: OpenCHAMI boot orchestration service
checks:
# Verify the repo is in good state (don't break existing functionality)
- go mod verify
- go vet ./...

- name: openchami.org
url: https://github.com/openchami/openchami.org
branch: main
checkout: true
language: markdown # Documentation site (likely Hugo, Jekyll, or similar)
description: OpenCHAMI project website and documentation
checks:
# Verify documentation builds successfully
- npm run build || echo "No build command found, skipping"

# Model configuration
models:
# Available model providers
providers:
openai:
model_provider: openai
api_key_env: OPENAI_API_KEY

# Default model choice
choices:
- openai:gpt-5.2
- openai:gpt-5
- openai:o3
- openai:o3-mini
- my_endpoint:openai/gpt-oss-120b # <— example external endpoint + model
default: openai:gpt-5

# Override models for specific roles
planner: openai:gpt-5.2
executor: openai:gpt-5

# Named parameter profiles for different capabilities
profiles:
standard:
temperature: 0.2
max_completion_tokens: 8000

reasoning:
temperature: 0.1
max_completion_tokens: 16000
reasoning:
effort: medium

# Global defaults
defaults:
profile: standard
params:
temperature: 0.2
max_retries: 2

# Per-agent overrides
agents:
planner:
profile: reasoning
params:
max_completion_tokens: 16000

executor:
profile: standard
params:
max_completion_tokens: 10000

# Planning configuration
planner:
reflection_steps: 2 # Number of plan review iterations

research:
# GitHub research: automatically fetch issues/PRs from repo URLs
github:
enabled: true
max_issues: 20
max_prs: 10

# Execution configuration
execution:
max_parallel: 2 # Process both repos in parallel when possible
recursion_limit: 2000 # LangGraph recursion limit
resume: true # Support resuming from checkpoints
status_interval_sec: 10 # Progress table update frequency
max_check_retries: 2 # Retry failed verification checks
step_timeout_sec: 0 # timeout per step (0 = no limit)
timeout_mode: pause # On timeout: pause, skip, or fail
skip_failed_repos: false # Stop all repos if one fails
Loading
Loading