feat: Add autonomous grok-swarm-agent for iterative file modifications#16
feat: Add autonomous grok-swarm-agent for iterative file modifications#16KHAEntertainment merged 7 commits intomasterfrom
Conversation
Implements a new agent mode that goes beyond single API calls: ## New Features ### grok_agent.py - Autonomous Agent Loop - Automatic file discovery in target directories - Iterative Grok 4.20 calls with context aggregation - Parses code blocks with multiple annotation formats: - lang:/path/to/file (e.g., python:/path/file.py) - // FILE: path/to/file (C-style markers) - # FILE: path/to/file (Python-style markers) - # filename.py (common Grok output format) - Applies changes with dry-run preview mode - Verification command support - Max iteration limits ### Parser Fixes - Fixed parse_and_write_files() to handle "python:cli.py" format - Added pattern 1b for lang:path without trailing newline - Added return statement that was missing - Fixed grok_bridge.py with same improvements ### Claude Code Integration - New SKILL.md for /grok-swarm-agent invocation - New command script for Claude Code - Triggers: "grok agent", "autonomous grok", "agent mode" ### OpenClaw Integration - New grok_agent_plugin.ts tool registration - Updated openclaw.plugin.json with agentScript config - Works with existing grok-swarm plugin structure ## Usage Preview mode: ``` grok-swarm-agent "refactor auth module" --target ./src ``` Apply changes: ``` grok-swarm-agent "refactor auth module" --target ./src --apply ``` With verification: ``` grok-swarm-agent "add tests" --apply --verify-cmd "pytest" ``` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughAdds a new autonomous Grok multi-agent: a Bash launcher and Claude skill, a Python agent package/CLI implementing iterative discovery/edits/verification, a TypeScript plugin tool to invoke it, enhanced Grok response parsing, and shared parsing patterns. Changes
Sequence Diagram(s)sequenceDiagram
participant Claude as Claude Platform
participant Shell as grok-swarm-agent.sh
participant Agent as grok_agent.py
participant FS as Target Filesystem
participant Grok as Grok Bridge
participant Verify as Verification Command
Claude->>Shell: invoke with task & options
Shell->>Agent: spawn python3 with args
Agent->>FS: discover source files
Agent->>Grok: call_grok(task, file context)
Grok-->>Agent: return annotated response
Agent->>Agent: parse_code_blocks / sanitize paths
Agent->>FS: preview or write changes
alt apply mode and verify_cmd provided
Agent->>Verify: run verify-cmd (cwd=target)
Verify-->>Agent: return verification output
end
Agent->>Agent: update state, check completion/iterations
alt continue
Agent->>Grok: next iteration
else finish
Agent-->>Shell: exit summary & status
Shell-->>Claude: return result
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (5)
src/agent/grok_agent.py (3)
354-362: Shell execution is intentional but worth documenting.Using
shell=Truehere allows compound commands likepytest tests/ -v && npm test, which is useful for verification. Since the user explicitly provides--verify-cmdwhen invoking the agent, the trust boundary is appropriate.However, if this agent is ever invoked by an untrusted source (web hook, chat input), this becomes an injection vector. Consider adding a docstring note:
📝 Documentation suggestion
def verify_changes(state: AgentState) -> tuple[bool, str]: """ Run verification command. + + WARNING: verify_cmd is executed via shell. Only invoke this agent + from trusted contexts where the user controls the command. Returns (success, output). """🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/grok_agent.py` around lines 354 - 362, Add a short docstring/comment near the subprocess.run call that explains why shell=True is used and the associated trust assumptions: document that state.verify_cmd is executed with shell=True to allow compound commands (e.g., "pytest ... && npm test"), that this is only safe when the verify command is provided by a trusted actor, and that invoking this agent from untrusted sources (webhooks, chat input) can create command-injection risks; reference the subprocess.run invocation and state.verify_cmd in the comment so future maintainers know why shell=True was chosen and when to avoid it.
473-476: Completion detection heuristic may trigger false positives.Checking for words like "done" or "complete" anywhere in the response is quite broad. Code or explanations might naturally contain these words (e.g.,
callback_done, "...once complete, call...") without meaning the agent's task is finished.For an MVP this is acceptable, but consider adding more context (e.g., checking the last few lines, requiring a specific marker like
[AGENT_DONE]).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/grok_agent.py` around lines 473 - 476, The current heuristic in grok_agent.py that lowercases response and checks any occurrence of tokens in done_markers (response_lower, done_markers) is too broad and causes false positives; change the check to only consider the last N lines or last M characters of the response and require a stricter token (e.g., an exact standalone word at end-of-line or a dedicated marker like "[AGENT_DONE]") instead of substring matches—update the logic where response_lower is used (the completion detection function) to first trim and split response into lines, inspect only the tail (e.g., last 3 lines) for either an exact match of one of the done_markers as a whole word or the explicit marker "[AGENT_DONE]", and only then return True.
32-34: Thesys.pathmanipulation works but is fragile.Directly inserting into
sys.pathis like hotwiring a car — it works, but it's not how things are supposed to work. If the directory structure changes, this breaks silently.For now, this is fine for an MVP script. If this grows, consider proper package installation or a
setup.py/pyproject.tomlthat installs both modules.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/grok_agent.py` around lines 32 - 34, The sys.path insertion that adds Path(__file__).parent.parent / "bridge" is fragile; remove that manipulation and instead import the bridge package properly by making bridge a real package and installing it (e.g., add __init__.py and publish/install via pyproject.toml or install in editable mode), then replace the dynamic import with a normal import like from bridge.grok_bridge import call_grok, read_files and delete the sys.path change; ensure the bridge package name matches when updating imports so calls to call_grok and read_files continue to work.src/plugin/grok_agent_plugin.ts (1)
49-55: Consider typingparamswith TypeBox'sStaticutility.You've defined a nice schema with TypeBox, but
params: anythrows away that type safety. It's like building a fence but leaving the gate open.✨ Type-safe params
+import { Type, Static } from "@sinclair/typebox"; + +type GrokAgentParams = Static<typeof GrokAgentSchema>; - async execute(_toolCallId: string, params: any) { + async execute(_toolCallId: string, params: GrokAgentParams) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/plugin/grok_agent_plugin.ts` around lines 49 - 55, The execute method currently accepts params: any which discards the TypeBox schema you defined; change the signature to accept a typed params using TypeBox's Static utility (import { Static } from '@sinclair/typebox') and use Static<typeof YourParamsSchema> (replace YourParamsSchema with the actual schema identifier you defined) so the method becomes async execute(_toolCallId: string, params: Static<typeof YourParamsSchema>); update any internal uses that assume any to match the stronger type and keep the existing json helper (function json) unchanged.platforms/claude/skills/grok-swarm-agent/SKILL.md (1)
14-18: Add language specifiers to fenced code blocks.The markdownlint tool flags these blocks for missing language hints. Adding
bashorshellhelps syntax highlighters and screen readers.📝 Quick fix
-``` +```bash use grok agent to refactor src/auth/-``` +```bash # Preview mode - shows what would changeAlso applies to: 38-50
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platforms/claude/skills/grok-swarm-agent/SKILL.md` around lines 14 - 18, Update the fenced code blocks in SKILL.md so they include a language specifier (e.g., add ```bash or ```shell after the opening backticks) for the blocks containing shell/CLI commands (the examples starting with "use grok agent to refactor src/auth/" and "# Preview mode - shows what would change"); apply the same change to the other fenced blocks flagged (around the later examples in the file) so all shell snippets have an explicit language hint for markdownlint and syntax highlighting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@platforms/claude/commands/grok-swarm-agent.sh`:
- Around line 38-41: The catch-all case currently swallows unknown flags (the *)
branch that just does "shift"); update that branch to notify the user and fail
fast: detect the unknown option ($1), print a clear error to stderr (e.g.,
"Unknown option: $1") and suggest correct usage or show the script's usage/help,
then exit with a non-zero status instead of silently shifting; modify the *)
case in the argument-parsing switch so unknown flags are reported and the script
stops (or at minimum warns) rather than discarding them.
- Around line 61-65: The script builds CMD and calls eval which allows command
injection via TASK or VERIFY_CMD; replace the eval-based execution with a direct
exec/spawn call that passes arguments as an array (no shell interpolation) using
AGENT_SCRIPT as the program and the flags/values as separate args (e.g.
"--platform", "claude", "--target", "$TARGET", etc.), and change how VERIFY_CMD
is captured so it contains only the command value (not a precombined
"--verify-cmd value" string) before adding it to the args array; remove use of
CMD and eval entirely and invoke the Python process with the safe argument
array.
In `@src/agent/grok_agent.py`:
- Around line 217-231: The filename-detection uses filename_pattern.match(part)
which only checks the start of part and misses cases where a language tag
precedes the filename (e.g., "python\n# cli.py..."); update the logic in the
same block that sets language and part to first strip the language line into a
new variable (e.g., rest or after_language) and run filename_pattern.match (or
search) against that rest instead of part, then adjust how you compute
filename_line_end and slice content from rest so blocks.append still gets
language, path_hint, content.strip(), and inferred_path filled correctly
(references: variables part, language, filename_pattern, filename_match,
filename_line_end, blocks).
- Line 439: The print statements use f-strings but contain no placeholders;
remove the unnecessary f prefix so they are plain strings. Locate the print(...)
calls that look like print(f"...", file=sys.stderr) (the four occurrences noted
in the review) and change them to print("...", file=sys.stderr) so the f prefix
is not used when there are no {placeholders}.
In `@src/bridge/grok_bridge.py`:
- Around line 204-208: The filename_pattern in src/bridge/grok_bridge.py
diverges from the equivalent regex in src/agent/grok_agent.py (it includes
sh|bash and jsx|tsx), causing inconsistent parsing; update filename_pattern to
match the agent's pattern exactly or extract the extension list into a shared
constant/function (e.g., a shared EXTENSIONS list or get_filename_regex()) used
by both grok_bridge.py and grok_agent.py so both modules use the identical regex
(ensure updates to the symbol filename_pattern in grok_bridge.py and the
corresponding pattern in grok_agent.py reference the same centralized source).
In `@src/plugin/grok_agent_plugin.ts`:
- Around line 18-19: Replace usage of new URL(import.meta.url).pathname with
Node's fileURLToPath to avoid Windows leading-slash paths: import {
fileURLToPath } from "url" and compute PLUGIN_ROOT as
join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..") so DEFAULT_AGENT
stays correct; update the declarations referencing PLUGIN_ROOT and DEFAULT_AGENT
accordingly. Also make the same change for the other module that uses
import.meta.url (the plugin index module) by switching its import.meta.url
handling to fileURLToPath/import.meta.url and using
dirname(fileURLToPath(import.meta.url)) before joining paths.
---
Nitpick comments:
In `@platforms/claude/skills/grok-swarm-agent/SKILL.md`:
- Around line 14-18: Update the fenced code blocks in SKILL.md so they include a
language specifier (e.g., add ```bash or ```shell after the opening backticks)
for the blocks containing shell/CLI commands (the examples starting with "use
grok agent to refactor src/auth/" and "# Preview mode - shows what would
change"); apply the same change to the other fenced blocks flagged (around the
later examples in the file) so all shell snippets have an explicit language hint
for markdownlint and syntax highlighting.
In `@src/agent/grok_agent.py`:
- Around line 354-362: Add a short docstring/comment near the subprocess.run
call that explains why shell=True is used and the associated trust assumptions:
document that state.verify_cmd is executed with shell=True to allow compound
commands (e.g., "pytest ... && npm test"), that this is only safe when the
verify command is provided by a trusted actor, and that invoking this agent from
untrusted sources (webhooks, chat input) can create command-injection risks;
reference the subprocess.run invocation and state.verify_cmd in the comment so
future maintainers know why shell=True was chosen and when to avoid it.
- Around line 473-476: The current heuristic in grok_agent.py that lowercases
response and checks any occurrence of tokens in done_markers (response_lower,
done_markers) is too broad and causes false positives; change the check to only
consider the last N lines or last M characters of the response and require a
stricter token (e.g., an exact standalone word at end-of-line or a dedicated
marker like "[AGENT_DONE]") instead of substring matches—update the logic where
response_lower is used (the completion detection function) to first trim and
split response into lines, inspect only the tail (e.g., last 3 lines) for either
an exact match of one of the done_markers as a whole word or the explicit marker
"[AGENT_DONE]", and only then return True.
- Around line 32-34: The sys.path insertion that adds
Path(__file__).parent.parent / "bridge" is fragile; remove that manipulation and
instead import the bridge package properly by making bridge a real package and
installing it (e.g., add __init__.py and publish/install via pyproject.toml or
install in editable mode), then replace the dynamic import with a normal import
like from bridge.grok_bridge import call_grok, read_files and delete the
sys.path change; ensure the bridge package name matches when updating imports so
calls to call_grok and read_files continue to work.
In `@src/plugin/grok_agent_plugin.ts`:
- Around line 49-55: The execute method currently accepts params: any which
discards the TypeBox schema you defined; change the signature to accept a typed
params using TypeBox's Static utility (import { Static } from
'@sinclair/typebox') and use Static<typeof YourParamsSchema> (replace
YourParamsSchema with the actual schema identifier you defined) so the method
becomes async execute(_toolCallId: string, params: Static<typeof
YourParamsSchema>); update any internal uses that assume any to match the
stronger type and keep the existing json helper (function json) unchanged.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4555c191-3851-4266-9126-4ddaf632174b
📒 Files selected for processing (7)
platforms/claude/commands/grok-swarm-agent.shplatforms/claude/skills/grok-swarm-agent/SKILL.mdskills/grok-refactor/openclaw.plugin.jsonsrc/agent/__init__.pysrc/agent/grok_agent.pysrc/bridge/grok_bridge.pysrc/plugin/grok_agent_plugin.ts
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 5 file(s) based on 6 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 5 file(s) based on 6 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/plugin/index.ts (1)
144-148: Consider clearing the SIGKILL fallback timeout.If the process exits gracefully after receiving SIGTERM (but before the 5-second SIGKILL fires), the inner timeout still lingers. While calling
kill("SIGKILL")on an already-dead process is harmless (it just returnsfalse), storing and clearing this timeout would be tidier—like turning off the stove even after you've already removed the pot.🧹 Optional: Track and clear the SIGKILL timeout
const timer = setTimeout(() => { timedOut = true; child.kill("SIGTERM"); - setTimeout(() => child.kill("SIGKILL"), 5000); + killTimer = setTimeout(() => child.kill("SIGKILL"), 5000); }, timeout * 1000); + + let killTimer: ReturnType<typeof setTimeout> | undefined;Then in the
closehandler:child.on("close", (code: number | null) => { clearTimeout(timer); + if (killTimer) clearTimeout(killTimer);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/plugin/index.ts` around lines 144 - 148, The SIGKILL fallback timeout created inside the setTimeout should be stored in a variable (e.g., sigkillTimer) so it can be cleared if the child process exits after SIGTERM; update the block where you call child.kill("SIGTERM") to assign the inner setTimeout to sigkillTimer, and in the child's 'close' (or exit) handler clear both timer and sigkillTimer (and also clear timer if the process exits before the initial timeout) to avoid dangling timers; reference symbols: timer, sigkillTimer (new), timedOut, child.kill("SIGTERM"), child.kill("SIGKILL"), and the child 'close'/'exit' handler when making changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/agent/grok_agent.py`:
- Around line 470-488: The loop currently lets response prose (done_markers)
override a failed verification recorded in state.errors; change the control flow
so the result of verify_changes is honored: when state.verify_cmd and
state.apply run verify_changes (the call in verify_changes), capture the boolean
success and if it is False (or state.errors non-empty) prevent returning True
based on response_lower/done_markers — i.e., only evaluate done_markers when
verification either wasn't requested or succeeded; use the existing symbols
(state.verify_cmd, state.apply, verify_changes, state.errors, response_lower,
done_markers, parse_code_blocks, state.iteration) to gate the early return so a
failed verification blocks the success path.
- Around line 16-19: The CLI examples use a named flag (--task) but the
ArgumentParser defines task as a positional argument; make them consistent by
changing the argparse add_argument for task to a named option (e.g.,
parser.add_argument('--task', '-t', required=True, dest='task', help=...)) or
alternately update all examples/wrappers to pass the task positionally; also
update any other argparse references in parse_args/main that assume a positional
task (and the help text) so the code and docs match.
- Around line 205-223: The file_marker_pattern and filename_pattern are
currently searched across the entire code block (variable part / rest), causing
interior comments to be mis-parsed as path annotations; restrict both checks to
only the first non-language line immediately after the fence. Concretely:
compute the first_non_lang_line from rest (e.g., split rest into lines and take
the first non-empty line), run file_marker_pattern.search and
filename_pattern.search against that single line instead of part/rest, and if a
marker is found remove only that first line from the content (update content =
rest after the first line) before appending to blocks; update references to
marker_match, filename_match, content, part, and rest accordingly.
- Around line 89-90: apply_changes_from_response() currently constructs
target_path by naive joining (Path(state.target) / path_hint) which allows
absolute paths, ../ traversal and file-as-directory corruption; fix by routing
every write through a single sanitized destination resolver (e.g., new function
sanitize_target_path(path_hint, state.target, output_dir)) and use it everywhere
(apply_changes_from_response, parse_and_write_files, verify_changes,
discover_files call sites). The sanitizer must: 1) treat path_hint as a relative
path only (reject or strip leading "/" and "~"), 2) resolve and reject any path
that escapes the canonicalized target/output_dir root (use Path.resolve() then
ensure .is_relative_to(root) or equivalent), 3) if state.target is a file, treat
its parent as the root or refuse writes into it, and 4) honor the --output-dir
flag as the final write root when provided; replace direct
Path(state.target)/path_hint joins with calls to this sanitizer and return a
safe Path or raise/skip invalid hints.
---
Nitpick comments:
In `@src/plugin/index.ts`:
- Around line 144-148: The SIGKILL fallback timeout created inside the
setTimeout should be stored in a variable (e.g., sigkillTimer) so it can be
cleared if the child process exits after SIGTERM; update the block where you
call child.kill("SIGTERM") to assign the inner setTimeout to sigkillTimer, and
in the child's 'close' (or exit) handler clear both timer and sigkillTimer (and
also clear timer if the process exits before the initial timeout) to avoid
dangling timers; reference symbols: timer, sigkillTimer (new), timedOut,
child.kill("SIGTERM"), child.kill("SIGKILL"), and the child 'close'/'exit'
handler when making changes.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 69a7ab61-9967-4ead-a4f3-a2c7ac82817f
📒 Files selected for processing (5)
platforms/claude/commands/grok-swarm-agent.shsrc/agent/grok_agent.pysrc/bridge/grok_bridge.pysrc/plugin/grok_agent_plugin.tssrc/plugin/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- platforms/claude/commands/grok-swarm-agent.sh
- src/plugin/grok_agent_plugin.ts
- src/bridge/grok_bridge.py
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 4 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 1 file(s) based on 4 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
src/agent/grok_agent.py (1)
387-389:⚠️ Potential issue | 🟠 MajorVerify the same tree you just wrote.
apply_changes_from_response()writes underoutput_dirwhen it is set and already treats a file target as “use the parent directory”.verify_changes()ignores both and always usescwd=state.target, so--target path/to/file.pycan fail withNotADirectoryError, and--output-dirverifies the stale tree instead of the generated one.Suggested fix
+def get_work_root(state: AgentState) -> Path: + root = Path(state.output_dir) if state.output_dir else Path(state.target) + return root.parent if root.is_file() else root + ... - base_root = state.output_dir if state.output_dir else state.target - target_path = sanitize_target_path(path_hint, base_root) + target_path = sanitize_target_path(path_hint, str(get_work_root(state))) ... - cwd=state.target, + cwd=get_work_root(state),Also applies to: 419-425
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/grok_agent.py` around lines 387 - 389, verify_changes() is using cwd=state.target unconditionally which causes NotADirectoryError and verifies the wrong tree when state.output_dir is set; change verify_changes() to compute base_root the same way apply_changes_from_response() does (base_root = state.output_dir if state.output_dir else state.target) and call sanitize_target_path(path_hint, base_root) to get target_path/parent dir, then use cwd=target_path (or its parent for file targets) so verification runs against the actual generated output; apply the same fix to the duplicate block around the 419-425 logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/agent/grok_agent.py`:
- Around line 474-481: The prompt returned by the function currently only
includes task, state.iteration/state.max_iterations and state.last_response;
update it to also include the verifier output (e.g., the variable capturing
verification failure such as verifier_output or verification_result) so the next
iteration sees why the previous attempt failed; modify the formatted string that
returns "Continue working on: {task}..." to append a labeled "Verifier output /
failure:" section containing the verifier text (or a truncated subset) and make
the same change wherever the previous-response-only prompt is produced (the
other occurrence around the verifier capture).
- Around line 387-389: The code currently applies state.output_dir to every
write by setting base_root = state.output_dir if state.output_dir else
state.target; change this so state.output_dir is used only for new files:
compute base_root = state.output_dir if (state.output_dir and the target is a
new file) else state.target. Determine "new file" by checking whether path_hint
refers to a non-existent file on disk (or an existing/new-file flag on state if
available) before calling sanitize_target_path(path_hint, base_root); also
update the CLI help text (lines referenced in the review) to match this
behavior. Ensure you touch the logic that builds target_path and any helper that
calls sanitize_target_path so existing-file edits continue to use state.target
while only newly created files are redirected to state.output_dir.
- Around line 505-514: call_grok() currently calls sys.exit() on failures which
raises SystemExit and bypasses the except Exception handler in this refactor
block; change the error handling so SystemExit is handled gracefully: either
(preferred) update call_grok to raise a regular exception (or a custom
exception) instead of calling sys.exit(), or (quicker) add an except SystemExit
as se: block around the call to call_grok (the call inside the try in
grok_agent.py) that converts the SystemExit into a handled error (append to
state.errors, print to stderr, and return False) so
state.last_response/state.errors are updated and the agent loop can continue;
reference call_grok, SystemExit, state.errors, and the try/except block
surrounding the Grok call when making the change.
---
Duplicate comments:
In `@src/agent/grok_agent.py`:
- Around line 387-389: verify_changes() is using cwd=state.target
unconditionally which causes NotADirectoryError and verifies the wrong tree when
state.output_dir is set; change verify_changes() to compute base_root the same
way apply_changes_from_response() does (base_root = state.output_dir if
state.output_dir else state.target) and call sanitize_target_path(path_hint,
base_root) to get target_path/parent dir, then use cwd=target_path (or its
parent for file targets) so verification runs against the actual generated
output; apply the same fix to the duplicate block around the 419-425 logic.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8b166b72-4d31-47a0-88aa-c5008ae66613
📒 Files selected for processing (1)
src/agent/grok_agent.py
Brings in the grok-swarm-agent feature from the open PR on feature/grok-swarm-agent, fixing three regressions before landing: Bug fixes vs. the open PR: - Created src/shared/patterns.py (get_filename_pattern_string()) which was imported but never committed, causing ImportError at startup - Fixed lang_path_pattern in grok_agent.py to match relative paths (python:cli.py) in addition to absolute paths — the PR's narrowed pattern ^(\w+):(/...) silently dropped relative-path annotations - src/bridge/grok_bridge.py now imports shared patterns gracefully (try/except) so the bridge still works without the shared module New files: - src/shared/__init__.py + patterns.py — shared regex utilities - src/agent/__init__.py + grok_agent.py — autonomous iterative agent loop (file discovery → Grok call → parse/apply → verify → iterate up to 5x) - src/plugin/grok_agent_plugin.ts — OpenClaw/Claude Code tool registration - platforms/claude/skills/grok-swarm-agent/SKILL.md — skill documentation - platforms/claude/commands/grok-swarm-agent.sh — slash command Updated: - src/plugin/index.ts — imports and registers the agent tool Closes #16 https://claude.ai/code/session_01No9S6TZbfTgocHwHYWwxRN
Applies all issue fixes (#14, #12, #11, #16) to the duplicate skills/grok-refactor/bridge/ files so both installation paths stay in parity: - grok_bridge.py: absolute path rebasing, fallback response save, grounding prompt, usage tracking, shared patterns Pattern 3 - usage_tracker.py: new (copied from src/bridge/) - shared/patterns.py: new (provides get_filename_pattern_string()) - SKILL.md: documents grounding prompt config and stats subcommand https://claude.ai/code/session_01No9S6TZbfTgocHwHYWwxRN
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 3 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
|
@KHAEntertainment I've opened a new pull request, #19, to work on those changes. Once the pull request is ready, I'll request review from you. |
Fixed 1 file(s) based on 3 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
…tern_string() Co-authored-by: KHAEntertainment <43256680+KHAEntertainment@users.noreply.github.com> Agent-Logs-Url: https://github.com/KHAEntertainment/grok-multiagent-plugin/sessions/c147bc88-9dac-4881-9e47-f0f87afc51d0
fix: Centralize filename regex into shared patterns module
Resolve conflicts by keeping master (PR #16) canonical versions for all overlapping files, preserving the PR branch's non-conflicting ESM fix in src/plugin/index.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Implements a new grok-swarm-agent mode that transforms grok-swarm from a one-shot API caller into an autonomous agent that can iteratively discover files, apply changes, and verify results.
Key Changes
New
src/agent/grok_agent.py- Autonomous agent loop with:--applyto actually write)Fixed
src/bridge/grok_bridge.py- Parser improvements:python:cli.pyformat (common Grok output)Claude Code Integration (
platforms/claude/):grok-swarm-agent/SKILL.mdgrok-swarm-agent.shOpenClaw Integration (
src/plugin/):grok_agent_plugin.tstool registrationopenclaw.plugin.jsonconfigHow It Works
Usage Examples
Test Results
Successfully tested on
.sandboxtask manager:--priorityand--allflags to list commandRelated Issue
Fixes issue #14 - grok-swarm Write/Edit File Flow problems
Test Plan
python:filenameformat--applyflag is set🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Documentation