feat: support local-script targets in opfor hunt#192
Conversation
Extends `opfor hunt` to accept `type: "local-script"` targets (previously HTTP-only), matching the local-script support already in `opfor run`. Adds a TargetClient that shells out to a user script per turn instead of making an HTTP request, threading hunt's per-thread threadId through as the script's sessionId so thread forks get proper session isolation for free. Also fixes two related bugs: - local-script error responses weren't prefixed with "ERROR:", so isTargetError() never flagged them as target errors - --ui fell back to the setup wizard whenever --endpoint was absent, even when --target-config supplied a valid local-script target
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe PR adds local-script target configuration and execution, routes these targets through a dedicated client, updates hunt CLI validation and UI behavior, extends local-script timeout and error handling, and documents target configuration and session propagation. ChangesLocal-script target support
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant HuntCLI
participant createTargetClient
participant LocalScriptTargetClient
participant invokeLocalTargetScript
HuntCLI->>createTargetClient: create client from local-script TargetConfig
createTargetClient->>LocalScriptTargetClient: construct local-script client
LocalScriptTargetClient->>invokeLocalTargetScript: send prompt and thread session
invokeLocalTargetScript-->>LocalScriptTargetClient: return response or error
LocalScriptTargetClient-->>HuntCLI: return mapped target result
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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.
🧹 Nitpick comments (1)
core/src/autonomous/target/localScript.ts (1)
12-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake the error message actionable.
Per coding guidelines, error messages should tell the user how to fix the problem, not just that something failed. The current message says what's missing but not how to set it.
As per coding guidelines: "Write actionable error messages that tell the user how to fix the problem, not just that something failed."
♻️ Proposed fix
- throw new Error("local-script target is missing `scriptPath`."); + throw new Error( + "local-script target is missing `scriptPath`. Set `scriptPath` on the target in --target-config (e.g., { \"type\": \"local-script\", \"scriptPath\": \"./adapter.js\" })." + );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/src/autonomous/target/localScript.ts` around lines 12 - 15, Update the missing-scriptPath error in createLocalScriptTargetClient to include actionable guidance explaining that the caller must set config.scriptPath to the local script path, while preserving the existing validation behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@core/src/autonomous/target/localScript.ts`:
- Around line 12-15: Update the missing-scriptPath error in
createLocalScriptTargetClient to include actionable guidance explaining that the
caller must set config.scriptPath to the local script path, while preserving the
existing validation behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5fd84311-d2a9-4246-ac9d-1fef8639d89c
📒 Files selected for processing (5)
core/src/autonomous/lib/types.tscore/src/autonomous/target/http.tscore/src/autonomous/target/localScript.tscore/src/lib/localScriptTarget.tsrunners/cli/src/commands/hunt.ts
Add hunt.md coverage for the local-script target support added in this PR — --target-config usage, session/threadId wiring, and the 240s per-turn timeout.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/hunt.md`:
- Around line 29-40: Update the `--endpoint` option description in the options
table to state that the flag is required only when no endpoint is provided by
`--target-config`, while preserving the exception for local-script targets
configured there.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ad791ef to
403746e
Compare
Problem
opfor hunt(the autonomous commander/operator/scout red-teaming mode) only supported HTTP targets. If a target's chat API couldn't be modeled as a simple request/response HTTP call — e.g. async/polling APIs, session ids embedded in a URL path segment rather than a body/header field (whichsession.sendhas no way to express), or auth flows needing custom logic — there was no way to pointopfor huntat it.opfor runalready supportedtype: "local-script"targets for exactly this case;opfor huntexplicitly threw"local-script targets are not supported by opfor hunt (HTTP only).".Separately,
--uihad a bug: it fell back to launching the setup wizard whenever--endpointwas omitted, even when a valid target was already supplied via--target-config(which is how local-script targets are configured, since they have noendpoint).Solution
TargetKind("http" | "local-script") to the autonomous runner'sTargetConfig, plus ascriptPathfield.createLocalScriptTargetClient(), aTargetClientimplementation that shells out to a user script per turn (via the sameinvokeLocalTargetScriptstdin/stdout contractopfor runalready uses) instead of making an HTTP request. Hunt's per-threadthreadIdis passed through as the script'ssessionId, so thread forks each get isolated sessions automatically — no extra wiring needed.createTargetClient()now branches onconfig.typeto pick the HTTP or local-script client.throwinmapAgentTargetToAutonomous()and added proper mapping, validation (checksscriptPathinstead ofendpoint), and name-fallback (script basename instead of URL host) for local-script targets.--ui's fallback condition to also check!opts.targetConfig, so it only launches the setup wizard when no target was specified at all."ERROR:", which meantisTargetError()never actually flagged them as errors (it checksresponse.startsWith("ERROR:")) — errors from a script were silently treated as normal target replies.Changes
core/src/autonomous/lib/types.ts—TargetKindtype,type/scriptPathfields onTargetConfigcore/src/autonomous/target/http.ts— branch tocreateLocalScriptTargetClient()increateTargetClient()core/src/autonomous/target/localScript.ts(new) — local-scriptTargetClientimplementationcore/src/lib/localScriptTarget.ts— timeout 30s → 240s; error responses now prefixedERROR:runners/cli/src/commands/hunt.ts— local-script mapping/validation/naming inmapAgentTargetToAutonomous();--uifallback condition fixIssue
N/A
Summary by CodeRabbit
New Features
opfor hunt.--ui.Bug Fixes
Documentation