feat(execution): Add response parser for LLM artifact extraction

Implements regex-based response parser to extract file creation actions
and artifacts from LLM text responses. Agents can now produce actual
work products (files, PRs) instead of just returning instructions.

Changes:
- pkg/ai/response_parser.go: New parser with 4 extraction patterns
  * Markdown code blocks with filename comments
  * Inline backtick filenames followed by "content:" and code blocks
  * File header notation (--- filename: ---)
  * Shell heredoc syntax (cat > file << EOF)

- pkg/execution/engine.go: Skip sandbox when SandboxType empty/none
  * Prevents Docker container errors during testing
  * Preserves artifacts from AI response without sandbox execution

- pkg/ai/{ollama,resetdata}.go: Integrate response parser
  * Both providers now parse LLM output for extractable artifacts
  * Fallback to task_analysis action if no artifacts found

- internal/runtime/agent_support.go: Fix AI provider initialization
  * Set DefaultProvider in RoleModelMapping (prevents "provider not found")

- prompts/defaults.md: Add Rule O for output format guidance
  * Instructs LLMs to format responses for artifact extraction
  * Provides examples and patterns for file creation/modification
  * Explains pipeline: extraction → workspace → tests → PR → review

Test results:
- Before: 0 artifacts, 0 files generated
- After: 2 artifacts extracted successfully from LLM response
- hello.sh (60 bytes) with correct shell script content

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-10-11 22:08:08 +11:00
parent fe6765afea
commit df5ec34b4f
6 changed files with 1185 additions and 162 deletions

View File

@@ -477,10 +477,16 @@ func (p *ResetDataProvider) handleHTTPError(statusCode int, body []byte) *Provid
// parseResponseForActions extracts actions from the response text
func (p *ResetDataProvider) parseResponseForActions(response string, request *TaskRequest) ([]TaskAction, []Artifact) {
var actions []TaskAction
var artifacts []Artifact
// Use the response parser to extract structured actions and artifacts
parser := NewResponseParser()
actions, artifacts := parser.ParseResponse(response)
// Create a basic task analysis action
// If parser found concrete actions, return them
if len(actions) > 0 {
return actions, artifacts
}
// Otherwise, create a basic task analysis action as fallback
action := TaskAction{
Type: "task_analysis",
Target: request.TaskTitle,