Skip to content

[codex] Expose agent harness selection decisions#70760

Merged
steipete merged 6 commits intoopenclaw:mainfrom
100yenadmin:feat/harness-selection-observability-v2
Apr 23, 2026
Merged

[codex] Expose agent harness selection decisions#70760
steipete merged 6 commits intoopenclaw:mainfrom
100yenadmin:feat/harness-selection-observability-v2

Conversation

@100yenadmin
Copy link
Copy Markdown
Contributor

Summary

  • Expose a pure resolveAgentHarnessSelection(...) decision object for the existing embedded harness selector.
  • Keep the existing AgentHarness SPI and runtime behavior unchanged; selectAgentHarness(...) now delegates to the decision helper.
  • Add structured debug logging from runAgentHarnessAttemptWithFallback(...) so operators can see selected harness id, policy runtime/fallback values, selection reason, and candidate support results.
  • Document the observability path for diagnosing codex/* vs openai-codex/* routing without redesigning Pi/Codex harness selection.

Scope Guard

Validation

  • node scripts/run-vitest.mjs run --config test/vitest/vitest.agents.config.ts src/agents/harness/selection.test.ts
  • pnpm tsgo:core:test
  • pnpm exec oxlint src/agents/harness/selection.ts src/agents/harness/selection.test.ts
  • pnpm exec oxfmt --check src/agents/harness/selection.ts src/agents/harness/selection.test.ts docs/plugins/sdk-agent-harness.md docs/plugins/codex-harness.md
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.full-core-support-boundary.config.ts test/scripts/lint-suppressions.test.ts
  • git diff --check

Notes

  • Current head: eb82cc910f.
  • The debug record is emitted only when the agents/harness logger is debug-enabled.
  • Auto-mode tests assert each plugin supports(...) method is still called exactly once per candidate.

Copilot AI review requested due to automatic review settings April 23, 2026 19:59
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation agents Agent runtime and tooling size: M labels Apr 23, 2026
@100yenadmin
Copy link
Copy Markdown
Contributor Author

@steipete GPT 5.4 fixes

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR refactors selectAgentHarness to delegate to a new pure resolveAgentHarnessSelection helper that returns a structured AgentHarnessSelectionDecision object, then adds a gated log.debug call in runAgentHarnessAttemptWithFallback so operators can inspect the selected harness, policy values, and per-candidate support results without any behavior change. The existing SPI and public wire format are untouched, and the new tests confirm no duplicate supports(...) probes occur.

Confidence Score: 5/5

Safe to merge — no behavioral changes, all remaining findings are P2 style/cleanup suggestions.

The change is purely additive observability: a new exported decision type, a pure selection helper, and a debug-gated log call. Runtime paths are equivalent to before, existing tests still pass, and two new tests cover the auto-selection and pinned-PI paths. The only issues are a redundant intermediate .map() and a slightly misleading enum value name — both P2.

No files require special attention.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/harness/selection.ts
Line: 138-142

Comment:
**Redundant intermediate `.map()` on `candidates`**

`candidates` already has the shape `{ harness: AgentHarness, support: AgentHarnessSupport }`. The `.map()` on lines 139–142 re-builds an identical object, adding an allocation with no transformation. The `.filter()` can operate on `candidates` directly.

```suggestion
  const supported = candidates
    .filter(
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/harness/selection.ts
Line: 125

Comment:
**Misleading `selectedReason` value name**

`"forced_plugin_missing_pi_fallback"` reads as "the PI fallback is missing", but what actually happened is the opposite: the requested plugin harness is missing, so we are *using* the PI fallback. A name like `"forced_plugin_missing_fallback_pi"` or `"forced_plugin_fallback_to_pi"` would match the runtime semantics visible in the log record.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat: expose agent harness selection dec..." | Re-trigger Greptile

Comment thread src/agents/harness/selection.ts Outdated
Comment thread src/agents/harness/selection.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves observability of embedded agent harness selection by factoring the selection logic into an exported decision helper and emitting structured debug logs that explain why a harness was chosen (and what candidates were considered), without changing the existing AgentHarness SPI or runtime selection behavior.

Changes:

  • Add resolveAgentHarnessSelection(...) to return a selection decision object (selected harness + policy + reason + candidate metadata), and update selectAgentHarness(...) to delegate to it.
  • Add debug-gated structured logging in runAgentHarnessAttemptWithFallback(...) to record selection details.
  • Update plugin docs to describe the new observability path for diagnosing PI vs Codex harness routing.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/agents/harness/selection.ts Exposes selection decision helper and emits structured debug logs during embedded runs.
src/agents/harness/selection.test.ts Adds tests for decision observability and ensures no duplicate supports(...) probes.
docs/plugins/sdk-agent-harness.md Documents the structured selection log record for debugging routing decisions.
docs/plugins/codex-harness.md Adds guidance on using the selection log record to spot model-prefix mismatches.

Comment thread docs/plugins/sdk-agent-harness.md Outdated
Comment thread docs/plugins/codex-harness.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread src/agents/harness/selection.ts Outdated
Comment on lines +40 to +52
export type AgentHarnessSelectionDecision = {
harness: AgentHarness;
policy: AgentHarnessPolicy;
selectedHarnessId: string;
selectedHarnessLabel: string;
selectedReason:
| "pinned"
| "forced_pi"
| "forced_plugin"
| "forced_plugin_fallback_to_pi"
| "auto_plugin"
| "auto_pi_fallback";
candidates: AgentHarnessSelectionCandidate[];
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveAgentHarnessSelection(...) is described in the PR as exposing a “pure” decision object, but AgentHarnessSelectionDecision includes a live harness: AgentHarness reference (functions, potentially non-serializable). This makes it awkward to safely persist/emit/JSON-serialize the decision (and increases the risk of accidental logging of function bodies or large closures). Consider returning the selected harness separately (e.g., { harness, decision }) or making the exported decision type omit harness and instead expose only selectedHarnessId/label plus candidates/policy.

Copilot uses AI. Check for mistakes.
@steipete steipete force-pushed the feat/harness-selection-observability-v2 branch from 02d6f74 to fe39f12 Compare April 23, 2026 20:53
@steipete steipete merged commit 137dbc7 into openclaw:main Apr 23, 2026
68 checks passed
@steipete
Copy link
Copy Markdown
Contributor

Landed via squash onto main.

Thanks @100yenadmin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants