feat(executor): Add parallel tool executor and dev agent#7
Merged
Conversation
Implements V2 of the software lifecycle harness: a custom ADK agent that dispatches tool calls concurrently using sync.WaitGroup, bypassing llmagent's sequential execution loop. New packages: - executor/: Custom agent.Agent backed by a parallel tool dispatch loop. Injects function declarations via genai.GenerateContentConfig.Tools, calls model.GenerateContent directly, and fans out all tool calls in a single LLM response as goroutines. - devtools/: 9 dev-focused tools (bash with sandwich truncation + process- group kill, read_file, write_file, edit_file with uniqueness guard, list_dir, glob, search_files, git_status/diff/commit/push/branch, spawn_agent). All paths resolved against an explicit workDir. - agents/dev/: NewDev() wires executor + devtools into an agent.Agent. System prompt enforces TDD-first workflow and conventional commits. CLI: `agent run dev --task "..." --work-dir .` added as a subcommand. Pipeline: adds "dev" stage type to runStage() switch, allowing the implementation agent to be orchestrated as part of a multi-stage pipeline. StageConfig gains an optional `task` field for dev stage instructions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
executor/— Customagent.Agentthat bypasses ADK's sequentialllmagentloop. Injects*genai.FunctionDeclarations viagenai.GenerateContentConfig.Tools, callsmodel.GenerateContentdirectly, and fans out every tool call batch from a single LLM response as goroutines (sync.WaitGroup). Each dispatch logstool start/donewith per-call timing.devtools/— 9 dev-focused tools, all path-resolved against an explicitworkDir:bash(200 KB sandwich truncation, process-group kill viaSetpgid+WaitDelayfor reliable timeouts),read_file,write_file,edit_file(uniqueness guard +replace_all),list_dir,glob,search_files(with context lines),git_status/diff/commit/push/branch,spawn_agent(runsagent run devas subprocess).agents/dev/—NewDev()wires executor + devtools with a TDD-first system prompt (write failing tests first, verify build after every edit, conventional commits).cmd/dev.go—agent run dev --task "..." --work-dir .subcommand.pipeline/— Adds"dev"stage type torunStage()switch.StageConfiggains an optionaltaskfield for dev stage instructions.Key design decisions
Why bypass
llmagent? ADK'sbase_flow.goiterates function calls sequentially in a plainforloop. Parallel execution requires owning that loop.agent.New(agent.Config{Run: customFn})provides the hook without rip-and-replace of existing agents.Reliable bash timeouts:
/bin/sh -c cmdforks child processes that inherit the pipe. Killing only the shell leaves children holding the pipe open, blockingcmd.Wait()indefinitely. Fix:SysProcAttr{Setpgid: true}+cmd.Cancelkills the entire process group;cmd.WaitDelaycaps any remaining drain time.Test plan
go build ./...— clean compile, no import cyclesgo test -race ./...— all tests pass including new:executor/executor_test.go— parallel dispatch timing, no data race, unknown tool error, response constructiondevtools/bash_test.go— sandwich truncation, timeout (now ~2s not 60s), exit code capture, workDirdevtools/edit_test.go— basic replacement, not-found error, uniqueness guard, replace_allagents/dev/config_test.go— Validate() with/without WorkDiragent run dev --help— flags and description render correctly🤖 Generated with Claude Code