Skip to content

Split engine provider selection from harness execution and route Claude/Codex via reflected CAPI endpoints#45490

Merged
pelikhan merged 5 commits into
mainfrom
copilot/split-agentic-engine
Jul 15, 2026
Merged

Split engine provider selection from harness execution and route Claude/Codex via reflected CAPI endpoints#45490
pelikhan merged 5 commits into
mainfrom
copilot/split-agentic-engine

Conversation

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This change separates inference-provider concerns from harness-runner concerns in the agentic engine flow, enabling Claude Code and Codex to run against GitHub Copilot CAPI-backed endpoints discovered at runtime. It also introduces explicit provider override semantics so workflows can select provider behavior without coupling to a specific harness implementation.

  • Provider override semantics (engine.provider)

    • Added engine.provider parsing as a first-class provider override for non-inline engines, while preserving existing engine.model-provider compatibility.
    • Kept inline engine.runtime + engine.provider object behavior intact (id/auth/request path).
  • Engine abstraction split (provider vs harness)

    • Introduced explicit inference-provider and harness-runner interfaces (with compatibility aliases) to decouple model-provider resolution from CLI harness execution mechanics.
    • Clarified intent in engine abstractions and call sites where harness capability is optional.
  • Known provider normalization

    • Consolidated provider alias normalization around known providers (github, anthropic, openai) and mapped GitHub aliases consistently (including github_models).
    • Ensures provider selection resolves predictably across parser/runtime paths.
  • Claude/Codex runtime endpoint routing from /reflect

    • Extended shared reflect utilities to resolve configured provider endpoints from AWF /reflect payloads.
    • Updated Claude harness to derive provider base URL from reflected endpoint data at runtime.
    • Updated Codex harness to derive and apply reflected endpoint routing by rewriting openai-proxy base_url and exporting corresponding env overrides.
  • Targeted test coverage updates

    • Added/updated parser and harness tests for:
      • engine.provider override behavior
      • provider-endpoint resolution from reflect data
      • Codex provider config rewrite/env wiring behavior
engine:
  id: claude
  provider: github   # runtime provider override (CAPI-backed endpoint selected from /reflect)
  model: claude-sonnet-4.6


✨ PR Review Safe Output Test - Run 29386867182

💥 [THE END] — Illustrated by Smoke Claude · 80.8 AIC · ⌖ 14.8 AIC · ⊞ 8.4K ·
Comment /smoke-claude to run again

Copilot AI and others added 2 commits July 14, 2026 13:13
…t routing

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…ne.provider override

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Split engine harness/provider concerns and route Claude/Codex via /reflect endpoints Split engine provider selection from harness execution and route Claude/Codex via reflected CAPI endpoints Jul 14, 2026
Copilot AI requested a review from pelikhan July 14, 2026 13:28
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot add smoke-github-Claude that uses github to run Claude code

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add smoke-github-Claude that uses github to run Claude code

Implemented in 57546cf: added smoke-github-claude and wired centralized slash-command routing so it runs Claude with GitHub provider (model-provider: github).

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category feature
Risk 🔴 High
Score 70/100 (impact:35, urgency:18, quality:17)
Action fast_track

Splits engine provider selection from harness execution and routes Claude/Codex via reflected CAPI endpoints. High-impact architectural change: new smoke workflow, new Go/JS files. Needs careful review.

Generated by 🔧 PR Triage Agent · 171 AIC · ⌖ 7.66 AIC · ⊞ 5.6K ·

@pelikhan pelikhan marked this pull request as ready for review July 14, 2026 22:14
Copilot AI review requested due to automatic review settings July 14, 2026 22:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Separates provider selection from harness execution and introduces reflected endpoint routing for Claude and Codex.

Changes:

  • Adds engine.provider parsing and provider aliases.
  • Adds runtime endpoint discovery and harness configuration.
  • Adds tests and a GitHub-provider Claude smoke workflow.
Show a summary per file
File Description
pkg/workflow/llm_provider.go Normalizes provider aliases.
pkg/workflow/engine.go Parses provider overrides.
pkg/workflow/engine_config_test.go Tests override precedence.
pkg/workflow/codex_engine.go Updates provider documentation.
pkg/workflow/claude_engine.go Updates provider documentation.
pkg/workflow/agentic_engine.go Renames provider and harness interfaces.
actions/setup/js/codex_harness.test.cjs Tests Codex endpoint configuration.
actions/setup/js/codex_harness.cjs Reconfigures Codex from reflect data.
actions/setup/js/claude_harness.cjs Configures Claude from reflect data.
actions/setup/js/awf_reflect.test.cjs Tests endpoint resolution.
actions/setup/js/awf_reflect.cjs Adds shared provider endpoint resolution.
.github/workflows/smoke-github-claude.md Adds Claude GitHub-provider smoke test.
.github/workflows/smoke-github-claude.lock.yml Compiles the smoke workflow.
.github/workflows/agentic_commands.yml Registers its slash command.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 13/14 changed files
  • Comments generated: 6
  • Review effort level: Medium

Comment thread pkg/workflow/engine.go
Comment on lines +335 to +337
if providerValue, hasProvider := engineObj["provider"]; hasProvider && !config.IsInlineDefinition {
if providerStr, ok := providerValue.(string); ok {
config.LLMProvider = strings.ToLower(strings.TrimSpace(providerStr))
Comment on lines +453 to +456
const providerConfig = configureCodexProviderFromReflect({
codexConfigPath: codexHome ? `${codexHome}/config.toml` : "",
reflectPath: AWF_REFLECT_OUTPUT_PATH,
provider: process.env.GH_AW_LLM_PROVIDER || "openai",
Comment on lines +458 to +460
if (providerConfig.configured) {
codexEnv = { ...codexEnv, ...providerConfig.env };
}
return normalized === provider;
};

const matched = endpoints.find(ep => endpointProviderMatches(ep?.provider)) || endpoints[0];
Comment on lines +15 to +18
engine:
id: claude
model-provider: github
model: claude-haiku-4.5
Comment on lines +329 to +333
async function buildClaudeChildEnv() {
const childEnv = { ...process.env };
const provider = normalizeReflectProviderName(process.env.GH_AW_LLM_PROVIDER, "anthropic");
try {
const raw = fs.readFileSync(AWF_REFLECT_OUTPUT_PATH, "utf8");
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 12.1 AIC · ⌖ 7.41 AIC · ⊞ 4.2K ·
Comment /souschef to run again

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

...

All review comments have been addressed in local commits 9ac976a and 0ad5861. Changes are blocked on push (token lacks write access — needs a maintainer re-trigger). Summary of fixes:

  • awf_reflect.cjs: removed endpoints[0] fallback; returns null with log when no endpoint matches the requested provider
  • codex_engine.go: added GH_AW_LLM_PROVIDER env var so the Codex harness receives the provider override (was missing, causing it to always fall back to openai)
  • codex_harness.cjs: skip OpenAI base URL validation when provider is not openai (prevents false fatal when github provider rewrites the endpoint)
  • JSON schema: added string provider field to the extended engine config (oneOf[1], additionalProperties: false) so engine.provider: github passes schema validation
  • smoke-github-claude.md: changed to use engine.provider: github shorthand to exercise the new code path (distinct from smoke-claude-on-copilot.md)
  • claude_harness.cjs: exported buildClaudeChildEnv with injectable env/reflectPath/logger/readFileSync deps; added 4 tests covering matched, missing, malformed, and default-provider cases
  • Tests: added TestParseWorkflowString_EngineProviderShorthandPassesSchema verifying the full parse+schema+YAML compilation path sets GH_AW_LLM_PROVIDER: github; updated awf_reflect.test.cjs to expect null on unknown provider

All make fmt, make agent-report-progress, Go tests, and targeted JS tests pass locally.

Copilot AI requested a review from gh-aw-bot July 14, 2026 23:54
@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage — Run §29379921158

Field Value
Category feature
Risk 🔴 high
Score 78 / 100
Action fast_track

Score breakdown: impact 40 + urgency 20 + quality 18

Rationale: Large feature (+2131 lines) splitting engine provider selection from harness execution and routing Claude/Codex via reflected CAPI endpoints. Critical-path architectural change enabling new model routing. Not draft, CI reviewer commented. Needs expedited human review.

Generated by 🔧 PR Triage Agent · 197.2 AIC · ⌖ 5.45 AIC · ⊞ 5.6K ·

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Codex - 29386867095\n- [#45578] [docs] Self-healing documentation fixes from issue analysis - 2026-07-15\n- [#45575] feat: add gh-aw-detection: true to 4 flagged audit/analysis workflows\n- Overall: FAIL

🔮 The oracle has spoken through Smoke Codex · 2.1 AIC · ⌖ 0.896 AIC · ⊞ 13.8K ·
Comment /smoke-codex to run again

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

Silent build winds blow
Git branches bend under new light
Checks settle in place

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Generated by 🧪 Smoke CI for #45490 ·

@github-actions

Copy link
Copy Markdown
Contributor

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Pull request created: #45608

Generated by Changeset Generator · 7.16 AIC · ⊞ 25.1K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two new blocking issues found in the changed lines.

🔍 Findings summary

TOML corruption bug (high)

configureCodexProviderFromReflect in codex_harness.cjs uses a non-lookahead regex terminal group (?:\n\[|$) that consumes the opening [ of the next TOML section. The trimEnd()-based append branch then places that stolen [ immediately before the injected base_url line, producing invalid TOML. Triggered whenever the openai-proxy section lacks a pre-existing base_url key. The test suite misses this path entirely.

normalizeLLMProvider silent behavior change (medium)

Previously any unrecognized provider string fell back to LLMProviderAnthropic. After refactoring to a lookup-table pass-through, unknown strings are returned verbatim. Any workflow with a typo or previously-tolerated unknown value will now resolve differently with no error. Needs an explicit test and documentation.

Existing review comments (from prior passes) cover: schema additionalProperties blocking engine.provider, GH_AW_LLM_PROVIDER not reaching Codex, OpenAI validation conflict after proxy rewrite, endpoints[0] silent wrong-provider fallback, duplicate smoke workflow, and missing Claude harness test coverage.

🔎 Code quality review by PR Code Quality Reviewer · 130.3 AIC · ⌖ 4.69 AIC · ⊞ 5.6K
Comment /review to run again

Comments that could not be inline-anchored

actions/setup/js/codex_harness.cjs:388

TOML corruption when base_url key is absent from the openai-proxy section: the regex consumes the \n[ boundary that starts the next TOML section header; rewriting the config then injects an orphan [ into the output, corrupting the file.

<details>
<summary>💡 Details and fix</summary>

The regex:

const providerSectionPattern = /\[model_providers\.openai-proxy\][\s\S]*?(?:\n\[|$)/;

is not a lookahead — it consumes \n[. When base_url is absent the else branch runs:…

pkg/workflow/llm_provider.go:438

normalizeLLMProvider no longer falls back to Anthropic for unknown providers: the previous implementation defaulted any unrecognized string to LLMProviderAnthropic; after this change unknown strings pass through as-is, silently changing behavior for any existing workflow with an unrecognized provider value.

<details>
<summary>💡 Details</summary>

Before:

switch strings.ToLower(strings.TrimSpace(provider)) {
case LLMProviderGitHub:
    return LLMProviderGitHub
case LLMProviderOpe</details>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💥 Automated smoke test review - all systems nominal!

💥 [THE END] — Illustrated by Smoke Claude · 80.8 AIC · ⌖ 14.8 AIC · ⊞ 8.4K
Comment /smoke-claude to run again

LLMProviderOpenAI = "openai"
)

var llmProviderAliases = map[string]string{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice extraction of the alias map — consider adding a brief comment documenting that keys must be lowercase since lookups normalize input.


type llmProviderProfile struct {
id string
gatewayPort int

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Returning the raw normalized value for unknown providers is a reasonable fallback — worth a test to confirm unexpected strings pass through unchanged.

@github-actions

Copy link
Copy Markdown
Contributor

Split engine provider selection from harness execution and route Claude/Codex via reflected CAPI endpoints
1❌ 2✅ 3✅ 4❌
5❌ 6✅ 7❌ 8✅
9✅ 10❌ 11✅ 12✅
13✅ 14❌ 15✅ 16✅
FAIL — author app/copilot-swe-agent; assignees pelikhan, Copilot

📰 BREAKING: Report filed by Smoke Copilot · 100.4 AIC · ⌖ 4.62 AIC · ⊞ 19K ·
Comment /smoke-copilot to run again
Add label smoke to run again

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

Automation hums at dawn
Bots trace bright paths through guarded code
Smoke turns green by noon

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

📰 BREAKING: Report filed by Smoke Copilot · 100.4 AIC · ⌖ 4.62 AIC · ⊞ 19K ·
Comment /smoke-copilot to run again
Add label smoke to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Smoke validation review recorded.

📰 BREAKING: Report filed by Smoke Copilot · 100.4 AIC · ⌖ 4.62 AIC · ⊞ 19K
Comment /smoke-copilot to run again
Add label smoke to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke tests: 1:✅,2:✅,3:❌,4:❌,5:❌,6:❌,7:❌,8:❌,9:❌,10:❌,11:❌,12:❌,13:❌,14:❌,15:❌. Overall: FAIL

📰 BREAKING: Report filed by Smoke Copilot - AOAI (Entra) · 30.8 AIC · ⌖ 3.17 AIC · ⊞ 17.6K ·
Comment /smoke-copilot-aoai-entra to run again
Add label smoke to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts on this branch.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Sighthound Security Scan — PR #45490 (run 29387934559)

102 actionable findings (outside test/testdata paths):

Severity Count
🔴 Critical 28
🟠 High 12
🟡 Medium 62

Top Findings by Severity

🔴 Critical — Command Injection (11 findings, Go)

Multiple exec.Command calls construct shell commands with potentially untrusted input:

File Line Snippet
dependabot.go 339 exec.Command(npmPath, "install", ...)
pip_validation.go 79 exec.Command(pipCmd, "index", "versions", pkgName, ...)
gitutil.go 176 exec.Command("git", ..., "HEAD:"+relPath)
experiments_command.go 609 exec.Command("git", "show", ref+":state.json")
runner_guard.go / poutine.go 68/100/201 exec.Command("docker", "run", ..., gitRoot+":/workdir", ...)
upgrade_command.go 460 exec.Command(exe, newArgs...)

Remediation: Validate and sanitize all inputs used in command arguments. Prefer allowlists or structured APIs over shell construction. Ensure gitRoot, ref, pkgName, and similar values are validated before use.

🔴 Critical — Code Injection (17 findings, JS)

Multiple eval sinks detected in add_comment.test.cjs (lines 356, 633, 673, 2204–3342). These appear to be generated test fixtures but should be reviewed.

Remediation: Audit eval usage in add_comment.test.cjs; replace with safer alternatives (e.g., JSON.parse or structured data access).

🟠 High — Path Traversal (7 findings)

File Lines
download_workflow.go 105
changeset.js 137
generate-agent-factory.js 217, 223, 232

Remediation: Resolve paths with filepath.Clean / path.resolve and verify they remain within the intended root before use.

🟡 Medium — Unsafe Deserialization (55 findings, Go)

yaml.Unmarshal into loosely typed targets across many files (e.g., safe_update_enforcement.go, pull_request_target_validation.go, permissions_parser.go, workflow_builder.go).

Remediation: Unmarshal into strict, well-defined structs. Avoid interface{} targets for untrusted YAML. Validate results after unmarshalling.


Scan root: /tmp/gh-aw/sighthound/repo · Exit code: 0 · Total scan findings: 128 · Actionable (non-test): 102

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by 🛡️ Sighthound Security Scan for #45490 · 19.5 AIC · ⌖ 5.49 AIC · ⊞ 4.1K ·

Copilot stopped work on behalf of obamohaid-hash due to an error July 15, 2026 04:19
…-engine

# Conflicts:
#	.github/workflows/agentic_commands.yml

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts on this branch.

Resolved in ab43990. The only conflict was in .github/workflows/agentic_commands.yml — our branch had added smoke-github-claude while main removed smoke-crush. Merged main in, then ran make recompile to regenerate all 256 lock files cleanly (no smoke-crush, smoke-github-claude present).

@pelikhan pelikhan merged commit 356d959 into main Jul 15, 2026
28 of 29 checks passed
@pelikhan pelikhan deleted the copilot/split-agentic-engine branch July 15, 2026 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants