backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)
This commit is contained in:
@@ -0,0 +1,714 @@
|
||||
# AI Development Tools - Technical Reference
|
||||
|
||||
This document provides technical details on the tools available to AI agents for development assistance and ROM debugging. It covers the tool architecture, API reference, and patterns for extending the system.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ z3ed Agent Service │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Conversation Handler │ │
|
||||
│ │ (Prompt Builder + AI Service) │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────┴───────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌────────────────────┐ ┌────────────────┐ │
|
||||
│ │ Tool Dispatcher │ │ Device Manager │ │
|
||||
│ └────────────────────┘ └────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────┼────┬──────┬──────┬─────┐ │
|
||||
│ ▼ ▼ ▼ ▼ ▼ ▼ │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Tool Implementations │ │
|
||||
│ │ │ │
|
||||
│ │ • FileSystemTool • BuildTool │ │
|
||||
│ │ • EmulatorTool • TestRunner │ │
|
||||
│ │ • MemoryInspector • DisassemblyTool │ │
|
||||
│ │ • ResourceTool • SymbolProvider │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## ToolDispatcher System
|
||||
|
||||
The `ToolDispatcher` class in `src/cli/service/agent/tool_dispatcher.h` is the central hub for tool management.
|
||||
|
||||
### Core Concept
|
||||
|
||||
Tools are extensible modules that perform specific operations. The dispatcher:
|
||||
1. Receives tool calls from the AI model
|
||||
2. Validates arguments
|
||||
3. Executes the tool
|
||||
4. Returns results to the AI model
|
||||
|
||||
### Tool Types
|
||||
|
||||
```cpp
|
||||
enum class ToolCallType {
|
||||
// FileSystem Tools
|
||||
kFilesystemList,
|
||||
kFilesystemRead,
|
||||
kFilesystemExists,
|
||||
kFilesystemInfo,
|
||||
|
||||
// Build Tools
|
||||
kBuildConfigure,
|
||||
kBuildCompile,
|
||||
kBuildTest,
|
||||
kBuildStatus,
|
||||
|
||||
// Test Tools
|
||||
kTestRun,
|
||||
kTestList,
|
||||
kTestCoverage,
|
||||
|
||||
// ROM Operations
|
||||
kRomInfo,
|
||||
kRomLoadGraphics,
|
||||
kRomExportData,
|
||||
|
||||
// Emulator Tools
|
||||
kEmulatorConnect,
|
||||
kEmulatorReadMemory,
|
||||
kEmulatorWriteMemory,
|
||||
kEmulatorSetBreakpoint,
|
||||
kEmulatorStep,
|
||||
kEmulatorRun,
|
||||
kEmulatorPause,
|
||||
|
||||
// Disassembly Tools
|
||||
kDisassemble,
|
||||
kDisassembleRange,
|
||||
kTraceExecution,
|
||||
|
||||
// Symbol/Debug Info
|
||||
kLookupSymbol,
|
||||
kGetStackTrace,
|
||||
};
|
||||
```
|
||||
|
||||
## Tool Implementations
|
||||
|
||||
### 1. FileSystemTool
|
||||
|
||||
Read-only filesystem access for agents. Fully documented in `filesystem-tool.md`.
|
||||
|
||||
**Tools**:
|
||||
- `filesystem-list`: List directory contents
|
||||
- `filesystem-read`: Read text files
|
||||
- `filesystem-exists`: Check path existence
|
||||
- `filesystem-info`: Get file metadata
|
||||
|
||||
**Example Usage**:
|
||||
```cpp
|
||||
ToolDispatcher dispatcher(rom, ai_service);
|
||||
auto result = dispatcher.DispatchTool({
|
||||
.tool_type = ToolCallType::kFilesystemRead,
|
||||
.args = {
|
||||
{"path", "src/app/gfx/arena.h"},
|
||||
{"lines", "50"}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 2. BuildTool (Phase 1)
|
||||
|
||||
CMake/Ninja integration for build management.
|
||||
|
||||
**Tools**:
|
||||
- `kBuildConfigure`: Run CMake configuration
|
||||
- `kBuildCompile`: Compile specific targets
|
||||
- `kBuildTest`: Build test targets
|
||||
- `kBuildStatus`: Check build status
|
||||
|
||||
**API**:
|
||||
```cpp
|
||||
struct BuildRequest {
|
||||
std::string preset; // cmake preset (mac-dbg, lin-ai, etc)
|
||||
std::string target; // target to build (yaze, z3ed, etc)
|
||||
std::vector<std::string> flags; // additional cmake/ninja flags
|
||||
bool verbose = false;
|
||||
};
|
||||
|
||||
struct BuildResult {
|
||||
bool success;
|
||||
std::string output;
|
||||
std::vector<CompileError> errors;
|
||||
std::vector<std::string> warnings;
|
||||
int exit_code;
|
||||
};
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```cpp
|
||||
BuildResult result = tool_dispatcher.Build({
|
||||
.preset = "mac-dbg",
|
||||
.target = "yaze",
|
||||
.verbose = true
|
||||
});
|
||||
|
||||
for (const auto& error : result.errors) {
|
||||
LOG_ERROR("Build", "{}:{}: {}",
|
||||
error.file, error.line, error.message);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Notes**:
|
||||
- Parses CMake/Ninja output for error extraction
|
||||
- Detects common error patterns (missing includes, undefined symbols, etc.)
|
||||
- Maps error positions to source files for FileSystemTool integration
|
||||
- Supports incremental builds (only rebuild changed targets)
|
||||
|
||||
### 3. TestRunner (Phase 1)
|
||||
|
||||
CTest integration for test automation.
|
||||
|
||||
**Tools**:
|
||||
- `kTestRun`: Execute specific tests
|
||||
- `kTestList`: List available tests
|
||||
- `kTestCoverage`: Analyze coverage
|
||||
|
||||
**API**:
|
||||
```cpp
|
||||
struct TestRequest {
|
||||
std::string preset; // cmake preset
|
||||
std::vector<std::string> filters; // test name patterns
|
||||
std::string label; // ctest label (stable, unit, etc)
|
||||
bool verbose = false;
|
||||
};
|
||||
|
||||
struct TestResult {
|
||||
bool all_passed;
|
||||
int passed_count;
|
||||
int failed_count;
|
||||
std::vector<TestFailure> failures;
|
||||
std::string summary;
|
||||
};
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```cpp
|
||||
TestResult result = tool_dispatcher.RunTests({
|
||||
.preset = "mac-dbg",
|
||||
.label = "stable",
|
||||
.filters = {"OverworldTest*"}
|
||||
});
|
||||
|
||||
for (const auto& failure : result.failures) {
|
||||
LOG_ERROR("Test", "{}: {}",
|
||||
failure.test_name, failure.error_message);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Notes**:
|
||||
- Integrates with ctest for test execution
|
||||
- Parses Google Test output format
|
||||
- Detects assertion types (EXPECT_EQ, EXPECT_TRUE, etc.)
|
||||
- Provides failure context (actual vs expected values)
|
||||
- Supports test filtering by name or label
|
||||
|
||||
### 4. MemoryInspector (Phase 2)
|
||||
|
||||
Emulator memory access and analysis.
|
||||
|
||||
**Tools**:
|
||||
- `kEmulatorReadMemory`: Read memory regions
|
||||
- `kEmulatorWriteMemory`: Write memory (for debugging)
|
||||
- `kEmulatorSetBreakpoint`: Set conditional breakpoints
|
||||
- `kEmulatorReadWatchpoint`: Monitor memory locations
|
||||
|
||||
**API**:
|
||||
```cpp
|
||||
struct MemoryReadRequest {
|
||||
uint32_t address; // SNES address (e.g., $7E:0000)
|
||||
uint32_t length; // bytes to read
|
||||
bool interpret = false; // try to decode as data structure
|
||||
};
|
||||
|
||||
struct MemoryReadResult {
|
||||
std::vector<uint8_t> data;
|
||||
std::string hex_dump;
|
||||
std::string interpretation; // e.g., "Sprite data: entity=3, x=120"
|
||||
};
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```cpp
|
||||
MemoryReadResult result = tool_dispatcher.ReadMemory({
|
||||
.address = 0x7E0000,
|
||||
.length = 256,
|
||||
.interpret = true
|
||||
});
|
||||
|
||||
// Result includes:
|
||||
// hex_dump: "00 01 02 03 04 05 06 07..."
|
||||
// interpretation: "WRAM header region"
|
||||
```
|
||||
|
||||
**Implementation Notes**:
|
||||
- Integrates with emulator's gRPC service
|
||||
- Detects common data structures (sprite tables, tile data, etc.)
|
||||
- Supports structured memory reads (tagged as "player RAM", "sprite data")
|
||||
- Provides memory corruption detection
|
||||
|
||||
### 5. DisassemblyTool (Phase 2)
|
||||
|
||||
65816 instruction decoding and execution analysis.
|
||||
|
||||
**Tools**:
|
||||
- `kDisassemble`: Disassemble single instruction
|
||||
- `kDisassembleRange`: Disassemble code region
|
||||
- `kTraceExecution`: Step through code with trace
|
||||
|
||||
**API**:
|
||||
```cpp
|
||||
struct DisassemblyRequest {
|
||||
uint32_t address; // ROM/RAM address
|
||||
uint32_t length; // bytes to disassemble
|
||||
bool with_trace = false; // include CPU state at each step
|
||||
};
|
||||
|
||||
struct DisassemblyResult {
|
||||
std::vector<Instruction> instructions;
|
||||
std::string assembly_text;
|
||||
std::vector<CpuState> trace_states; // if with_trace=true
|
||||
};
|
||||
|
||||
struct Instruction {
|
||||
uint32_t address;
|
||||
std::string opcode;
|
||||
std::string operand;
|
||||
std::string mnemonic;
|
||||
std::vector<std::string> explanation;
|
||||
};
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```cpp
|
||||
DisassemblyResult result = tool_dispatcher.Disassemble({
|
||||
.address = 0x0A8000,
|
||||
.length = 32,
|
||||
.with_trace = true
|
||||
});
|
||||
|
||||
for (const auto& insn : result.instructions) {
|
||||
LOG_INFO("Disasm", "{:06X} {} {}",
|
||||
insn.address, insn.mnemonic, insn.operand);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Notes**:
|
||||
- Uses `Disassembler65816` for instruction decoding
|
||||
- Explains each instruction's effect in plain English
|
||||
- Tracks register/flag changes in execution trace
|
||||
- Detects jump targets and resolves addresses
|
||||
- Identifies likely subroutine boundaries
|
||||
|
||||
### 6. ResourceTool (Phase 2)
|
||||
|
||||
ROM resource access and interpretation.
|
||||
|
||||
**Tools**:
|
||||
- Query ROM data structures (sprites, tiles, palettes)
|
||||
- Cross-reference memory addresses to ROM resources
|
||||
- Export resource data
|
||||
|
||||
**API**:
|
||||
```cpp
|
||||
struct ResourceQuery {
|
||||
std::string resource_type; // "sprite", "tile", "palette", etc
|
||||
uint32_t resource_id;
|
||||
bool with_metadata = true;
|
||||
};
|
||||
|
||||
struct ResourceResult {
|
||||
std::string type;
|
||||
std::string description;
|
||||
std::vector<uint8_t> data;
|
||||
std::map<std::string, std::string> metadata;
|
||||
};
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```cpp
|
||||
ResourceResult result = tool_dispatcher.QueryResource({
|
||||
.resource_type = "sprite",
|
||||
.resource_id = 0x13,
|
||||
.with_metadata = true
|
||||
});
|
||||
|
||||
// Returns sprite data, graphics, palette info
|
||||
```
|
||||
|
||||
## Tool Integration Patterns
|
||||
|
||||
### Pattern 1: Error-Driven Tool Chaining
|
||||
|
||||
When a tool produces an error, chain to informational tools:
|
||||
|
||||
```cpp
|
||||
// 1. Attempt to compile
|
||||
auto build_result = tool_dispatcher.Build({...});
|
||||
|
||||
// 2. If failed, analyze error
|
||||
if (!build_result.success) {
|
||||
for (const auto& error : build_result.errors) {
|
||||
// 3. Read the source file at error location
|
||||
auto file_result = tool_dispatcher.ReadFile({
|
||||
.path = error.file,
|
||||
.offset = error.line - 5,
|
||||
.lines = 15
|
||||
});
|
||||
|
||||
// 4. AI analyzes context and suggests fix
|
||||
// "You're missing #include 'app/gfx/arena.h'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 2: Memory Analysis Workflow
|
||||
|
||||
Debug memory corruption by reading and interpreting:
|
||||
|
||||
```cpp
|
||||
// 1. Read suspect memory region
|
||||
auto mem_result = tool_dispatcher.ReadMemory({
|
||||
.address = 0x7E7000,
|
||||
.length = 256,
|
||||
.interpret = true
|
||||
});
|
||||
|
||||
// 2. Set watchpoint if available
|
||||
if (needs_monitoring) {
|
||||
tool_dispatcher.SetWatchpoint({
|
||||
.address = 0x7E7000,
|
||||
.on_write = true
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Continue execution and capture who writes
|
||||
// AI analyzes the execution trace to find the culprit
|
||||
```
|
||||
|
||||
### Pattern 3: Instruction-by-Instruction Analysis
|
||||
|
||||
Understand complex routines:
|
||||
|
||||
```cpp
|
||||
// 1. Disassemble the routine
|
||||
auto disasm = tool_dispatcher.Disassemble({
|
||||
.address = 0x0A8000,
|
||||
.length = 128,
|
||||
.with_trace = true
|
||||
});
|
||||
|
||||
// 2. Analyze each instruction
|
||||
for (const auto& insn : disasm.instructions) {
|
||||
// - What registers are affected?
|
||||
// - What memory locations accessed?
|
||||
// - Is this a jump/call?
|
||||
}
|
||||
|
||||
// 3. Build understanding of routine's purpose
|
||||
// AI synthesizes into "This routine initializes sprite table"
|
||||
```
|
||||
|
||||
## Adding New Tools
|
||||
|
||||
### Step 1: Define Tool Type
|
||||
|
||||
Add to `enum class ToolCallType` in `tool_dispatcher.h`:
|
||||
|
||||
```cpp
|
||||
enum class ToolCallType {
|
||||
// ... existing ...
|
||||
kMyCustomTool,
|
||||
};
|
||||
```
|
||||
|
||||
### Step 2: Define Tool Interface
|
||||
|
||||
Create base class in `tool_dispatcher.h`:
|
||||
|
||||
```cpp
|
||||
class MyCustomTool : public ToolBase {
|
||||
public:
|
||||
std::string GetName() const override {
|
||||
return "my-custom-tool";
|
||||
}
|
||||
|
||||
std::string GetDescription() const override {
|
||||
return "Does something useful";
|
||||
}
|
||||
|
||||
absl::StatusOr<ToolResult> Execute(
|
||||
const ToolArgs& args) override;
|
||||
|
||||
bool RequiresLabels() const override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Step 3: Implement Tool
|
||||
|
||||
In `tool_dispatcher.cc`:
|
||||
|
||||
```cpp
|
||||
absl::StatusOr<ToolResult> MyCustomTool::Execute(
|
||||
const ToolArgs& args) {
|
||||
|
||||
// Validate arguments
|
||||
if (!args.count("required_arg")) {
|
||||
return absl::InvalidArgumentError(
|
||||
"Missing required_arg parameter");
|
||||
}
|
||||
|
||||
std::string required_arg = args.at("required_arg");
|
||||
|
||||
// Perform operation
|
||||
auto result = DoSomethingUseful(required_arg);
|
||||
|
||||
// Return structured result
|
||||
return ToolResult{
|
||||
.success = true,
|
||||
.output = result.ToString(),
|
||||
.data = result.AsJson()
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Register Tool
|
||||
|
||||
In `ToolDispatcher::DispatchTool()`:
|
||||
|
||||
```cpp
|
||||
case ToolCallType::kMyCustomTool: {
|
||||
MyCustomTool tool;
|
||||
return tool.Execute(args);
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Add to AI Prompt
|
||||
|
||||
Update the prompt builder to inform AI about the new tool:
|
||||
|
||||
```cpp
|
||||
// In prompt_builder.cc
|
||||
tools_description += R"(
|
||||
- my-custom-tool: Does something useful
|
||||
Args: required_arg (string)
|
||||
Example: {"tool_name": "my-custom-tool",
|
||||
"args": {"required_arg": "value"}}
|
||||
)";
|
||||
```
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### Pattern 1: Graceful Degradation
|
||||
|
||||
When a tool fails, provide fallback behavior:
|
||||
|
||||
```cpp
|
||||
// Try to use emulator tool
|
||||
auto mem_result = tool_dispatcher.ReadMemory({...});
|
||||
|
||||
if (!mem_result.ok()) {
|
||||
// Fallback: Use ROM data instead
|
||||
auto rom_result = tool_dispatcher.QueryResource({...});
|
||||
return rom_result;
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 2: Error Context
|
||||
|
||||
Always include context in errors:
|
||||
|
||||
```cpp
|
||||
if (!file_exists(path)) {
|
||||
return absl::NotFoundError(
|
||||
absl::StrFormat(
|
||||
"File not found: %s (checked in project dir: %s)",
|
||||
path, project_root));
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 3: Timeout Handling
|
||||
|
||||
Long operations should timeout gracefully:
|
||||
|
||||
```cpp
|
||||
// In BuildTool
|
||||
const auto timeout = std::chrono::minutes(5);
|
||||
auto result = RunBuildWithTimeout(preset, target, timeout);
|
||||
|
||||
if (result.timed_out) {
|
||||
return absl::DeadlineExceededError(
|
||||
"Build took too long (> 5 minutes). "
|
||||
"Try building specific target instead of all.");
|
||||
}
|
||||
```
|
||||
|
||||
## Tool State Management
|
||||
|
||||
### Session State
|
||||
|
||||
Tools operate within a session context:
|
||||
|
||||
```cpp
|
||||
struct ToolSession {
|
||||
std::string session_id;
|
||||
std::string rom_path;
|
||||
std::string build_preset;
|
||||
std::string workspace_dir;
|
||||
std::map<std::string, std::string> environment;
|
||||
};
|
||||
```
|
||||
|
||||
### Tool Preferences
|
||||
|
||||
Users can configure tool behavior:
|
||||
|
||||
```cpp
|
||||
struct ToolPreferences {
|
||||
bool filesystem = true; // Enable filesystem tools
|
||||
bool build = true; // Enable build tools
|
||||
bool test = true; // Enable test tools
|
||||
bool emulator = true; // Enable emulator tools
|
||||
bool experimental = false; // Enable experimental tools
|
||||
|
||||
int timeout_seconds = 300; // Default timeout
|
||||
bool verbose = false; // Verbose output
|
||||
};
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Caching
|
||||
|
||||
Cache expensive operations:
|
||||
|
||||
```cpp
|
||||
// Cache file reads
|
||||
std::unordered_map<std::string, FileContent> file_cache;
|
||||
|
||||
// Cache test results
|
||||
std::unordered_map<std::string, TestResult> test_cache;
|
||||
```
|
||||
|
||||
### Async Execution
|
||||
|
||||
Long operations should be async:
|
||||
|
||||
```cpp
|
||||
// In BuildTool
|
||||
auto future = std::async(std::launch::async,
|
||||
[this] { return RunBuild(); });
|
||||
|
||||
auto result = future.get(); // Wait for completion
|
||||
```
|
||||
|
||||
### Resource Limits
|
||||
|
||||
Enforce limits on resource usage:
|
||||
|
||||
```cpp
|
||||
// Limit memory reads
|
||||
constexpr size_t MAX_MEMORY_READ = 64 * 1024; // 64KB
|
||||
|
||||
// Limit disassembly length
|
||||
constexpr size_t MAX_DISASM_BYTES = 16 * 1024; // 16KB
|
||||
|
||||
// Limit files listed
|
||||
constexpr size_t MAX_FILES_LISTED = 1000;
|
||||
```
|
||||
|
||||
## Debugging Tools
|
||||
|
||||
### Tool Logging
|
||||
|
||||
Enable verbose logging for tool execution:
|
||||
|
||||
```cpp
|
||||
export Z3ED_TOOL_DEBUG=1
|
||||
z3ed agent chat --debug --log-file tools.log
|
||||
```
|
||||
|
||||
### Tool Testing
|
||||
|
||||
Unit tests for each tool in `test/unit/`:
|
||||
|
||||
```cpp
|
||||
TEST(FileSystemToolTest, ListsDirectoryRecursively) {
|
||||
FileSystemTool tool;
|
||||
auto result = tool.Execute({
|
||||
{"path", "src"},
|
||||
{"recursive", "true"}
|
||||
});
|
||||
EXPECT_TRUE(result.ok());
|
||||
}
|
||||
```
|
||||
|
||||
### Tool Profiling
|
||||
|
||||
Profile tool execution:
|
||||
|
||||
```bash
|
||||
z3ed agent chat --profile-tools
|
||||
# Output: Tool timings and performance metrics
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Input Validation
|
||||
|
||||
All tool inputs must be validated:
|
||||
|
||||
```cpp
|
||||
// FileSystemTool validates paths against project root
|
||||
if (!IsPathInProject(path)) {
|
||||
return absl::PermissionDeniedError(
|
||||
"Path outside project directory");
|
||||
}
|
||||
|
||||
// BuildTool validates preset names
|
||||
if (!IsValidPreset(preset)) {
|
||||
return absl::InvalidArgumentError(
|
||||
"Unknown preset: " + preset);
|
||||
}
|
||||
```
|
||||
|
||||
### Sandboxing
|
||||
|
||||
Operations should be sandboxed:
|
||||
|
||||
```cpp
|
||||
// BuildTool uses dedicated build directories
|
||||
const auto build_dir = workspace / "build_ai";
|
||||
|
||||
// FileSystemTool restricts to project directory
|
||||
// EmulatorTool only connects to local ports
|
||||
```
|
||||
|
||||
### Access Control
|
||||
|
||||
Sensitive operations may require approval:
|
||||
|
||||
```cpp
|
||||
// Emulator write operations log for audit
|
||||
LOG_WARNING("Emulator",
|
||||
"Writing to memory at {:06X} (value: {:02X})",
|
||||
address, value);
|
||||
|
||||
// ROM modifications require confirmation
|
||||
// Not implemented in agent, but planned for future
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **FileSystemTool**: `filesystem-tool.md`
|
||||
- **AI Infrastructure (archived)**: `archive/legacy-2025-11/ai-infrastructure-initiative-archived-2025-11-25.md`
|
||||
- **Agent Architecture**: `agent-architecture.md`
|
||||
- **Development Plan**: `../plans/ai-assisted-development-plan.md`
|
||||
100
docs/internal/agents/archive/utility-tools/ai-modularity.md
Normal file
100
docs/internal/agents/archive/utility-tools/ai-modularity.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# AI & gRPC Modularity Blueprint
|
||||
|
||||
*Date: November 16, 2025 – Author: GPT-5.1 Codex*
|
||||
|
||||
## 1. Scope & Goals
|
||||
|
||||
- Make AI/gRPC features optional without scattering `#ifdef` guards.
|
||||
- Ensure Windows builds succeed regardless of whether AI tooling is enabled.
|
||||
- Provide a migration path toward relocatable dependencies (`ext/`) and cleaner preset defaults for macOS + custom tiling window manager workflows (sketchybar/yabai/skhd, Emacs/Spacemacs).
|
||||
|
||||
## 2. Current Touchpoints
|
||||
|
||||
| Surface | Key Paths | Notes |
|
||||
| --- | --- | --- |
|
||||
| Editor UI | `src/app/editor/agent/**`, `app/gui/app/agent_chat_widget.cc`, `app/editor/agent/agent_chat_history_popup.cc` | Widgets always compile when `YAZE_ENABLE_GRPC=ON`, but they include protobuf types directly. |
|
||||
| Core Services | `src/app/service/grpc_support.cmake`, `app/service/*.cc`, `app/test/test_recorder.cc` | `yaze_grpc_support` bundles servers, generated protos, and even CLI code (`cli/service/planning/tile16_proposal_generator.cc`). |
|
||||
| CLI / z3ed | `src/cli/agent.cmake`, `src/cli/service/agent/*.cc`, `src/cli/service/ai/*.cc`, `src/cli/service/gui/*.cc` | gRPC, Gemeni/Ollama (JSON + httplib/OpenSSL) all live in one static lib. |
|
||||
| Build Flags | `cmake/options.cmake`, scattered `#ifdef Z3ED_AI` and `#ifdef Z3ED_AI_AVAILABLE` | Flags do not describe GUI vs CLI vs runtime needs, so every translation unit drags in gRPC headers once `YAZE_ENABLE_GRPC=ON`. |
|
||||
| Tests & Automation | `src/app/test/test_manager.cc`, `scripts/agent_test_suite.sh`, `.github/workflows/ci.yml` | Tests assume AI features exist; Windows agents hit linker issues when that assumption breaks. |
|
||||
|
||||
## 3. Coupling Pain Points
|
||||
|
||||
1. **Single Monolithic `yaze_agent`** – Links SDL, GUI, emulator, Abseil, yaml, nlohmann_json, httplib, OpenSSL, and gRPC simultaneously. No stubs exist when only CLI or GUI needs certain services (`src/cli/agent.cmake`).
|
||||
2. **Editor Hard Links** – `yaze_editor` unconditionally links `yaze_agent` when `YAZE_MINIMAL_BUILD` is `OFF`, so even ROM-editing-only builds drag in AI dependencies (`src/app/editor/editor_library.cmake`).
|
||||
3. **Shared Proto Targets** – `yaze_grpc_support` consumes CLI proto files, so editor-only builds still compile CLI automation code (`src/app/service/grpc_support.cmake`).
|
||||
4. **Preprocessor Guards** – UI code mixes `Z3ED_AI` and `Z3ED_AI_AVAILABLE`; CLI code checks `Z3ED_AI` while build system only defines `Z3ED_AI` when `YAZE_ENABLE_AI=ON`. These mismatches cause dead code paths and missing symbols.
|
||||
|
||||
## 4. Windows Build Blockers
|
||||
|
||||
- **Runtime library mismatch** – yaml-cpp and other dependencies are built `/MT` while `yaze_emu` uses `/MD`, causing cascades of `LNK2038` and `_Lockit`/`libcpmt` conflicts (`logs/windows_ci_linker_error.log`).
|
||||
- **OpenSSL duplication** – `yaze_agent` links cpp-httplib with OpenSSL while gRPC pulls BoringSSL, leading to duplicate symbol errors (`libssl.lib` vs `ssl.lib`) in the same log.
|
||||
- **Missing native dialogs** – `FileDialogWrapper` symbols fail to link when macOS-specific implementations are not excluded on Windows (also visible in the same log).
|
||||
- **Preset drift** – `win-ai` enables GRPC/AI without guaranteeing vcpkg/clang-cl or ROM assets; `win-dbg` disables gRPC entirely so editor agents fail to compile because of unconditional includes.
|
||||
|
||||
## 5. Proposed Modularization
|
||||
|
||||
| Proposed CMake Option | Purpose | Default | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `YAZE_BUILD_AGENT_UI` | Compile ImGui agent widgets (editor). | `ON` for GUI presets, `OFF` elsewhere. | Controls `app/editor/agent/**` sources. |
|
||||
| `YAZE_ENABLE_REMOTE_AUTOMATION` | Build/ship gRPC servers & automation bridges. | `ON` in `*-ai` presets. | Owns `yaze_grpc_support` + proto generation. |
|
||||
| `YAZE_ENABLE_AI_RUNTIME` | Include AI runtime (Gemini/Ollama, CLI planners). | `ON` in CLI/AI presets. | Governs `cli/service/ai/**`. |
|
||||
| `YAZE_ENABLE_AGENT_CLI` | Build `z3ed` with full agent features. | `ON` when CLI requested. | Allows `z3ed` to be disabled independently. |
|
||||
|
||||
Implementation guidelines:
|
||||
|
||||
1. **Split Targets**
|
||||
- `yaze_agent_core`: command routing, ROM helpers, no AI.
|
||||
- `yaze_agent_ai`: depends on JSON + OpenSSL + remote automation.
|
||||
- `yaze_agent_ui_bridge`: tiny facade that editor links only when `YAZE_BUILD_AGENT_UI=ON`.
|
||||
2. **Proto Ownership**
|
||||
- Keep proto generation under `yaze_grpc_support`, but do not add CLI sources to that target. Instead, expose headers/libs and let CLI link them conditionally.
|
||||
3. **Stub Providers**
|
||||
- Provide header-compatible no-op classes (e.g., `AgentChatWidgetBridge::Create()` returning `nullptr`) when UI is disabled, removing the need for `#ifdef` in ImGui panels.
|
||||
4. **Dependency Injection**
|
||||
- Replace `#ifdef Z3ED_AI_AVAILABLE` in `agent_chat_widget.cc` with an interface returned from `AgentFeatures::MaybeCreateChatPanel()`.
|
||||
|
||||
## 6. Preset & Feature Matrix
|
||||
|
||||
| Preset | GUI | CLI | GRPC | AI Runtime | Agent UI |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `mac-dbg` | ✅ | ✅ | ⚪ | ⚪ | ✅ |
|
||||
| `mac-ai` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| `lin-dbg` | ✅ | ✅ | ⚪ | ⚪ | ✅ |
|
||||
| `ci-windows` | ✅ | ✅ | ⚪ | ⚪ | ⚪ (core only) |
|
||||
| `ci-windows-ai` (new nightly) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| `win-dbg` | ✅ | ✅ | ⚪ | ⚪ | ✅ |
|
||||
| `win-ai` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
Legend: ✅ enabled, ⚪ disabled.
|
||||
|
||||
## 7. Migration Steps
|
||||
|
||||
1. **Define Options** in `cmake/options.cmake` and propagate via presets.
|
||||
2. **Restructure Libraries**:
|
||||
- Move CLI AI/runtime code into `yaze_agent_ai`.
|
||||
- Add `yaze_agent_stub` for builds without AI.
|
||||
- Make `yaze_editor` link against stub/real target via generator expressions.
|
||||
3. **CMake Cleanup**:
|
||||
- Limit `yaze_grpc_support` to gRPC-only code.
|
||||
- Guard JSON/OpenSSL includes behind `YAZE_ENABLE_AI_RUNTIME`.
|
||||
4. **Windows Hardening**:
|
||||
- Force `/MD` everywhere and ensure yaml-cpp inherits `CMAKE_MSVC_RUNTIME_LIBRARY`.
|
||||
- Allow only one SSL provider based on feature set.
|
||||
- Add preset validation in `scripts/verify-build-environment.ps1`.
|
||||
5. **CI/CD Split**:
|
||||
- Current `.github/workflows/ci.yml` runs GRPC on all platforms; adjust to run minimal Windows build plus nightly AI build to save time and reduce flakiness.
|
||||
6. **Docs + Scripts**:
|
||||
- Update build guides to describe new options.
|
||||
- Document how macOS users can integrate headless builds with sketchybar/yabai/skhd (focus on CLI usage + automation).
|
||||
7. **External Dependencies**:
|
||||
- Relocate submodules to `ext/` and update scripts so the new layout is enforced before toggling feature flags.
|
||||
|
||||
## 8. Deliverables
|
||||
|
||||
- This blueprint (`docs/internal/agents/ai-modularity.md`).
|
||||
- Updated CMake options, presets, and stubs.
|
||||
- Hardened Windows build scripts/logging.
|
||||
- CI/CD workflow split + release automation updates.
|
||||
- Documentation refresh & dependency relocation.
|
||||
|
||||
258
docs/internal/agents/archive/utility-tools/dev-assist-agent.md
Normal file
258
docs/internal/agents/archive/utility-tools/dev-assist-agent.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# DevAssistAgent - AI Development Assistant
|
||||
|
||||
## Overview
|
||||
|
||||
The DevAssistAgent is an AI-powered development assistant that helps developers while coding yaze itself. It provides intelligent analysis and suggestions for build errors, crashes, and test failures, making the development process more efficient.
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Build Monitoring & Error Resolution
|
||||
- **Real-time compilation error analysis**: Parses compiler output and provides targeted fixes
|
||||
- **Link failure diagnosis**: Identifies missing symbols and suggests library ordering fixes
|
||||
- **CMake configuration issues**: Helps resolve CMake errors and missing dependencies
|
||||
- **Cross-platform support**: Handles GCC, Clang, and MSVC error formats
|
||||
|
||||
### 2. Crash Analysis
|
||||
- **Stack trace analysis**: Parses segfaults, assertions, and stack overflows
|
||||
- **Root cause identification**: Suggests likely causes based on crash patterns
|
||||
- **Fix recommendations**: Provides actionable steps to resolve crashes
|
||||
- **Debug tool suggestions**: Recommends AddressSanitizer, Valgrind, etc.
|
||||
|
||||
### 3. Test Automation
|
||||
- **Affected test discovery**: Identifies tests related to changed files
|
||||
- **Test generation**: Creates unit tests for new or modified code
|
||||
- **Test failure analysis**: Parses test output and suggests fixes
|
||||
- **Coverage recommendations**: Suggests missing test cases
|
||||
|
||||
### 4. Code Quality Analysis
|
||||
- **Static analysis**: Checks for common C++ issues
|
||||
- **TODO/FIXME tracking**: Identifies technical debt markers
|
||||
- **Style violations**: Detects long lines and formatting issues
|
||||
- **Potential bugs**: Simple heuristics for null pointer risks
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
|
||||
```cpp
|
||||
class DevAssistAgent {
|
||||
// Main analysis interface
|
||||
std::vector<AnalysisResult> AnalyzeBuildOutput(const std::string& output);
|
||||
AnalysisResult AnalyzeCrash(const std::string& stack_trace);
|
||||
std::vector<TestSuggestion> GetAffectedTests(const std::vector<std::string>& changed_files);
|
||||
|
||||
// Build monitoring
|
||||
absl::Status MonitorBuild(const BuildConfig& config,
|
||||
std::function<void(const AnalysisResult&)> on_error);
|
||||
|
||||
// AI-enhanced features (optional)
|
||||
absl::StatusOr<std::string> GenerateTestCode(const std::string& source_file);
|
||||
};
|
||||
```
|
||||
|
||||
### Analysis Result Structure
|
||||
|
||||
```cpp
|
||||
struct AnalysisResult {
|
||||
ErrorType error_type; // Compilation, Link, Runtime, etc.
|
||||
std::string file_path; // Affected file
|
||||
int line_number; // Line where error occurred
|
||||
std::string description; // Human-readable description
|
||||
std::vector<std::string> suggested_fixes; // Ordered fix suggestions
|
||||
std::vector<std::string> related_files; // Files that may be involved
|
||||
double confidence; // 0.0-1.0 confidence in analysis
|
||||
bool ai_assisted; // Whether AI was used
|
||||
};
|
||||
```
|
||||
|
||||
### Error Pattern Recognition
|
||||
|
||||
The agent uses regex patterns to identify different error types:
|
||||
|
||||
1. **Compilation Errors**
|
||||
- Pattern: `([^:]+):(\d+):(\d+):\s*(error|warning):\s*(.+)`
|
||||
- Extracts: file, line, column, severity, message
|
||||
|
||||
2. **Link Errors**
|
||||
- Pattern: `undefined reference to\s*[']([^']+)[']`
|
||||
- Extracts: missing symbol name
|
||||
|
||||
3. **CMake Errors**
|
||||
- Pattern: `CMake Error at ([^:]+):(\d+)`
|
||||
- Extracts: CMakeLists.txt file and line
|
||||
|
||||
4. **Runtime Crashes**
|
||||
- Patterns for SIGSEGV, stack overflow, assertions
|
||||
- Stack frame extraction for debugging
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Build Error Analysis
|
||||
|
||||
```cpp
|
||||
// Initialize the agent
|
||||
auto tool_dispatcher = std::make_shared<ToolDispatcher>();
|
||||
auto ai_service = ai::ServiceFactory::Create("ollama"); // Optional
|
||||
|
||||
DevAssistAgent agent;
|
||||
agent.Initialize(tool_dispatcher, ai_service);
|
||||
|
||||
// Analyze build output
|
||||
std::string build_output = R"(
|
||||
src/app/editor/overworld.cc:45:10: error: 'Rom' was not declared in this scope
|
||||
src/app/editor/overworld.cc:50:20: error: undefined reference to 'LoadOverworld'
|
||||
)";
|
||||
|
||||
auto results = agent.AnalyzeBuildOutput(build_output);
|
||||
for (const auto& result : results) {
|
||||
std::cout << "Error: " << result.description << "\n";
|
||||
std::cout << "File: " << result.file_path << ":" << result.line_number << "\n";
|
||||
for (const auto& fix : result.suggested_fixes) {
|
||||
std::cout << " - " << fix << "\n";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Interactive Build Monitoring
|
||||
|
||||
```cpp
|
||||
DevAssistAgent::BuildConfig config;
|
||||
config.build_dir = "build";
|
||||
config.preset = "mac-dbg";
|
||||
config.verbose = true;
|
||||
config.stop_on_error = false;
|
||||
|
||||
agent.MonitorBuild(config, [](const DevAssistAgent::AnalysisResult& error) {
|
||||
// Handle each error as it's detected
|
||||
std::cout << "Build error detected: " << error.description << "\n";
|
||||
|
||||
if (error.ai_assisted && !error.suggested_fixes.empty()) {
|
||||
std::cout << "AI suggestion: " << error.suggested_fixes[0] << "\n";
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Crash Analysis
|
||||
|
||||
```cpp
|
||||
std::string stack_trace = R"(
|
||||
Thread 1 "yaze" received signal SIGSEGV, Segmentation fault.
|
||||
0x00005555555a1234 in OverworldEditor::Update() at src/app/editor/overworld.cc:123
|
||||
#0 0x00005555555a1234 in OverworldEditor::Update() at src/app/editor/overworld.cc:123
|
||||
#1 0x00005555555b5678 in EditorManager::UpdateEditors() at src/app/editor/manager.cc:456
|
||||
)";
|
||||
|
||||
auto crash_result = agent.AnalyzeCrash(stack_trace);
|
||||
std::cout << "Crash type: " << crash_result.description << "\n";
|
||||
std::cout << "Location: " << crash_result.file_path << ":" << crash_result.line_number << "\n";
|
||||
std::cout << "Root cause: " << crash_result.root_cause << "\n";
|
||||
```
|
||||
|
||||
### Test Discovery and Generation
|
||||
|
||||
```cpp
|
||||
// Find tests affected by changes
|
||||
std::vector<std::string> changed_files = {
|
||||
"src/app/gfx/bitmap.cc",
|
||||
"src/app/editor/overworld.h"
|
||||
};
|
||||
|
||||
auto test_suggestions = agent.GetAffectedTests(changed_files);
|
||||
for (const auto& suggestion : test_suggestions) {
|
||||
std::cout << "Test: " << suggestion.test_file << "\n";
|
||||
std::cout << "Reason: " << suggestion.reason << "\n";
|
||||
|
||||
if (!suggestion.is_existing) {
|
||||
// Generate new test if it doesn't exist
|
||||
auto test_code = agent.GenerateTestCode(changed_files[0], "ApplyPalette");
|
||||
if (test_code.ok()) {
|
||||
std::cout << "Generated test:\n" << *test_code << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with z3ed CLI
|
||||
|
||||
The DevAssistAgent can be used through the z3ed CLI tool:
|
||||
|
||||
```bash
|
||||
# Monitor build with error analysis
|
||||
z3ed agent dev-assist --monitor-build --preset mac-dbg
|
||||
|
||||
# Analyze a crash dump
|
||||
z3ed agent dev-assist --analyze-crash crash.log
|
||||
|
||||
# Generate tests for changed files
|
||||
z3ed agent dev-assist --generate-tests --files "src/app/gfx/*.cc"
|
||||
|
||||
# Get build status
|
||||
z3ed agent dev-assist --build-status
|
||||
```
|
||||
|
||||
## Common Error Patterns and Fixes
|
||||
|
||||
### Missing Headers
|
||||
**Pattern**: `fatal error: 'absl/status/status.h': No such file or directory`
|
||||
**Fixes**:
|
||||
1. Add `#include "absl/status/status.h"`
|
||||
2. Check CMakeLists.txt includes Abseil
|
||||
3. Verify include paths are correct
|
||||
|
||||
### Undefined References
|
||||
**Pattern**: `undefined reference to 'yaze::Rom::LoadFromFile'`
|
||||
**Fixes**:
|
||||
1. Ensure source file is compiled
|
||||
2. Check library link order
|
||||
3. Verify function is implemented (not just declared)
|
||||
|
||||
### Segmentation Faults
|
||||
**Pattern**: `Segmentation fault (core dumped)`
|
||||
**Fixes**:
|
||||
1. Check for null pointer dereferences
|
||||
2. Verify array bounds
|
||||
3. Look for use-after-free
|
||||
4. Run with AddressSanitizer
|
||||
|
||||
### CMake Configuration
|
||||
**Pattern**: `CMake Error: Could not find package Abseil`
|
||||
**Fixes**:
|
||||
1. Install missing dependency
|
||||
2. Set CMAKE_PREFIX_PATH
|
||||
3. Use vcpkg or system package manager
|
||||
|
||||
## AI Enhancement
|
||||
|
||||
When AI service is available (Ollama or Gemini), the agent provides:
|
||||
- Context-aware fix suggestions based on codebase patterns
|
||||
- Test generation with comprehensive edge cases
|
||||
- Natural language explanations of complex errors
|
||||
- Code quality recommendations
|
||||
|
||||
To enable AI features:
|
||||
```cpp
|
||||
auto ai_service = ai::ServiceFactory::Create("ollama");
|
||||
agent.Initialize(tool_dispatcher, ai_service);
|
||||
agent.SetAIEnabled(true);
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- Error pattern matching is fast (regex-based)
|
||||
- File system operations are cached for test discovery
|
||||
- AI suggestions are optional and async when possible
|
||||
- Build monitoring uses streaming output parsing
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Incremental Build Analysis**: Track which changes trigger which errors
|
||||
2. **Historical Error Database**: Learn from past fixes in the codebase
|
||||
3. **Automated Fix Application**: Apply simple fixes automatically
|
||||
4. **CI Integration**: Analyze CI build failures and suggest fixes
|
||||
5. **Performance Profiling**: Identify build bottlenecks and optimization opportunities
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Build Tool Documentation](filesystem-tool.md)
|
||||
- [AI Infrastructure Initiative (archived)](archive/legacy-2025-11/ai-infrastructure-initiative-archived-2025-11-25.md)
|
||||
- [Test Suite Configuration](../../test-suite-configuration.md)
|
||||
235
docs/internal/agents/archive/utility-tools/filesystem-tool.md
Normal file
235
docs/internal/agents/archive/utility-tools/filesystem-tool.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# FileSystemTool Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The FileSystemTool provides read-only filesystem operations for AI agents to explore the yaze codebase safely. It includes security features to prevent path traversal attacks and restricts access to the project directory.
|
||||
|
||||
## Available Tools
|
||||
|
||||
### 1. filesystem-list
|
||||
|
||||
List files and directories in a given path.
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
filesystem-list --path <directory> [--recursive] [--format <json|text>]
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `--path`: Directory to list (required)
|
||||
- `--recursive`: Include subdirectories (optional, default: false)
|
||||
- `--format`: Output format (optional, default: json)
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"tool_name": "filesystem-list",
|
||||
"args": {
|
||||
"path": "src/cli/service/agent",
|
||||
"recursive": "true",
|
||||
"format": "json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. filesystem-read
|
||||
|
||||
Read the contents of a text file.
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
filesystem-read --path <file> [--lines <count>] [--offset <start>] [--format <json|text>]
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `--path`: File to read (required)
|
||||
- `--lines`: Maximum number of lines to read (optional, default: all)
|
||||
- `--offset`: Starting line number (optional, default: 0)
|
||||
- `--format`: Output format (optional, default: json)
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"tool_name": "filesystem-read",
|
||||
"args": {
|
||||
"path": "src/cli/service/agent/tool_dispatcher.h",
|
||||
"lines": "50",
|
||||
"offset": "0",
|
||||
"format": "json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. filesystem-exists
|
||||
|
||||
Check if a file or directory exists.
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
filesystem-exists --path <file|directory> [--format <json|text>]
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `--path`: Path to check (required)
|
||||
- `--format`: Output format (optional, default: json)
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"tool_name": "filesystem-exists",
|
||||
"args": {
|
||||
"path": "docs/internal/agents",
|
||||
"format": "json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. filesystem-info
|
||||
|
||||
Get detailed information about a file or directory.
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
filesystem-info --path <file|directory> [--format <json|text>]
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `--path`: Path to get info for (required)
|
||||
- `--format`: Output format (optional, default: json)
|
||||
|
||||
**Returns:**
|
||||
- File/directory name
|
||||
- Type (file, directory, symlink)
|
||||
- Size (for files)
|
||||
- Modification time
|
||||
- Permissions
|
||||
- Absolute path
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"tool_name": "filesystem-info",
|
||||
"args": {
|
||||
"path": "CMakeLists.txt",
|
||||
"format": "json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Security Features
|
||||
|
||||
### Path Traversal Protection
|
||||
|
||||
The FileSystemTool prevents path traversal attacks by:
|
||||
1. Rejecting paths containing ".." sequences
|
||||
2. Normalizing all paths to absolute paths
|
||||
3. Verifying paths are within the project directory
|
||||
|
||||
### Project Directory Restriction
|
||||
|
||||
All filesystem operations are restricted to the yaze project directory. The tool automatically detects the project root by looking for:
|
||||
- CMakeLists.txt and src/yaze.cc (primary markers)
|
||||
- .git directory with src/cli and src/app subdirectories (fallback)
|
||||
|
||||
### Binary File Protection
|
||||
|
||||
The `filesystem-read` tool only reads text files. It determines if a file is text by:
|
||||
1. Checking file extension against a whitelist of known text formats
|
||||
2. Scanning the first 512 bytes for null bytes or non-printable characters
|
||||
|
||||
## Integration with ToolDispatcher
|
||||
|
||||
The FileSystemTool is integrated with the agent's ToolDispatcher system:
|
||||
|
||||
```cpp
|
||||
// In tool_dispatcher.h
|
||||
enum class ToolCallType {
|
||||
// ... other tools ...
|
||||
kFilesystemList,
|
||||
kFilesystemRead,
|
||||
kFilesystemExists,
|
||||
kFilesystemInfo,
|
||||
};
|
||||
|
||||
// Tool preference settings
|
||||
struct ToolPreferences {
|
||||
// ... other preferences ...
|
||||
bool filesystem = true; // Enable/disable filesystem tools
|
||||
};
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Base Class: FileSystemToolBase
|
||||
|
||||
Provides common functionality for all filesystem tools:
|
||||
- `ValidatePath()`: Validates and normalizes paths with security checks
|
||||
- `GetProjectRoot()`: Detects the yaze project root directory
|
||||
- `IsPathInProject()`: Verifies a path is within project bounds
|
||||
- `FormatFileSize()`: Human-readable file size formatting
|
||||
- `FormatTimestamp()`: Human-readable timestamp formatting
|
||||
|
||||
### Tool Classes
|
||||
|
||||
Each tool inherits from FileSystemToolBase and implements:
|
||||
- `GetName()`: Returns the tool name
|
||||
- `GetDescription()`: Returns a brief description
|
||||
- `GetUsage()`: Returns usage syntax
|
||||
- `ValidateArgs()`: Validates required arguments
|
||||
- `Execute()`: Performs the filesystem operation
|
||||
- `RequiresLabels()`: Returns false (no ROM labels needed)
|
||||
|
||||
## Usage in AI Agents
|
||||
|
||||
AI agents can use these tools to:
|
||||
1. **Explore project structure**: List directories to understand codebase organization
|
||||
2. **Read source files**: Examine implementation details and patterns
|
||||
3. **Check file existence**: Verify paths before operations
|
||||
4. **Get file metadata**: Understand file sizes, types, and timestamps
|
||||
|
||||
Example workflow:
|
||||
```python
|
||||
# Check if a directory exists
|
||||
response = tool_dispatcher.dispatch({
|
||||
"tool_name": "filesystem-exists",
|
||||
"args": {"path": "src/cli/service/agent/tools"}
|
||||
})
|
||||
|
||||
# List contents if it exists
|
||||
if response["exists"] == "true":
|
||||
response = tool_dispatcher.dispatch({
|
||||
"tool_name": "filesystem-list",
|
||||
"args": {"path": "src/cli/service/agent/tools"}
|
||||
})
|
||||
|
||||
# Read each source file
|
||||
for entry in response["entries"]:
|
||||
if entry["type"] == "file" and entry["name"].endswith(".cc"):
|
||||
content = tool_dispatcher.dispatch({
|
||||
"tool_name": "filesystem-read",
|
||||
"args": {"path": f"src/cli/service/agent/tools/{entry['name']}"}
|
||||
})
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Unit tests are provided in `test/unit/filesystem_tool_test.cc`:
|
||||
- Directory listing (normal and recursive)
|
||||
- File reading (with and without line limits)
|
||||
- File existence checks
|
||||
- File/directory info retrieval
|
||||
- Security validation (path traversal, binary files)
|
||||
|
||||
Run tests with:
|
||||
```bash
|
||||
./build/bin/yaze_test "*FileSystemTool*"
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements for future versions:
|
||||
1. **Pattern matching**: Support glob patterns in list operations
|
||||
2. **File search**: Find files by name or content patterns
|
||||
3. **Directory statistics**: Count files, calculate total size
|
||||
4. **Change monitoring**: Track file modifications since last check
|
||||
5. **Write operations**: Controlled write access for specific directories (with strict validation)
|
||||
@@ -0,0 +1,45 @@
|
||||
# GitHub Actions Remote Workflow Documentation
|
||||
|
||||
This document describes how to trigger GitHub Actions workflows remotely, specifically focusing on the `ci.yml` workflow and its custom inputs.
|
||||
|
||||
## Triggering `ci.yml` Remotely
|
||||
|
||||
The `ci.yml` workflow can be triggered manually via the GitHub UI or programmatically using the GitHub API (or `gh` CLI) thanks to the `workflow_dispatch` event.
|
||||
|
||||
### Inputs
|
||||
|
||||
The `workflow_dispatch` event for `ci.yml` supports the following custom inputs:
|
||||
|
||||
- **`build_type`**:
|
||||
- **Description**: Specifies the CMake build type.
|
||||
- **Type**: `choice`
|
||||
- **Options**: `Debug`, `Release`, `RelWithDebInfo`
|
||||
- **Default**: `RelWithDebInfo`
|
||||
|
||||
- **`run_sanitizers`**:
|
||||
- **Description**: A boolean flag to enable or disable memory sanitizer runs.
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
- **`upload_artifacts`**:
|
||||
- **Description**: A boolean flag to enable or disable uploading build artifacts.
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
- **`enable_http_api_tests`**:
|
||||
- **Description**: **(NEW)** A boolean flag to enable or disable an additional step that runs HTTP API tests after the build. When set to `true`, a script (`scripts/agents/test-http-api.sh`) will be executed to validate the HTTP server (checking if the port is up and the health endpoint responds).
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
|
||||
### Example Usage (GitHub CLI)
|
||||
|
||||
To trigger the `ci.yml` workflow with custom inputs using the `gh` CLI:
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml -f build_type=Release -f enable_http_api_tests=true
|
||||
```
|
||||
|
||||
This command will:
|
||||
- Trigger the `ci.yml` workflow.
|
||||
- Set the `build_type` to `Release`.
|
||||
- Enable the HTTP API tests.
|
||||
Reference in New Issue
Block a user