Skip to content

feat(cli): add CLI agent providers (Claude Code, Copilot, Kiro) - #33

Open
buraksakalli wants to merge 2 commits into
huggingface:mainfrom
buraksakalli:feat/cli-providers
Open

feat(cli): add CLI agent providers (Claude Code, Copilot, Kiro)#33
buraksakalli wants to merge 2 commits into
huggingface:mainfrom
buraksakalli:feat/cli-providers

Conversation

@buraksakalli

Copy link
Copy Markdown

Adds first-class support for driving evaluations through user-installed CLI agents (claude, copilot, kiro-cli) so users can run upskill against existing subscriptions instead of raw ANTHROPIC_API_KEY / OPENAI_API_KEY.

Architecture:

  • New CliAgentExecutor peer to LocalFastAgentExecutor and RemoteFastAgentExecutor, dispatching to one of three CliAgentRunner implementations (ClaudeCodeRunner, CopilotCliRunner, KiroCliRunner) via a small registry.
  • Per-model executor routing (executors/router.py): cli.
    models route to CliAgentExecutor; everything else keeps its existing local/jobs path. This lets one upskill eval call mix CLI agents and fast-agent models in a single benchmark.
  • CliFastAgentAdapter satisfies the narrow SkillGenerator protocol upskill's generate.py uses, so skill generation, test generation, and refinement also work via a CLI provider — no API keys required.
  • _agent_session() dispatcher in cli.py: pure-cli runs skip _fast_agent_context entirely; hybrid runs strip cli.* slots from fast-agent's model_references and override per phase.
  • Subscription billing is preserved: ClaudeCodeRunner unsets ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN / CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX from the subprocess env by default and prints a one-shot stderr note when it does. Power users can override cli_providers..unset_env: [] to keep the vars (e.g. for Bedrock/Vertex routing).
  • Smart defaults: when every -m is cli., executor: jobs auto-downgrades to local (CLI providers always run locally) and test_gen_model defaults to the first cli. eval model so users with non-cli config defaults don't need extra flags.

Testing:

  • 48 new unit tests across runners, executor, router, env stripping, config, mixed-model orchestration, CLI help text.
  • 4 end-to-end tests that drive the full stack against fake CLI binary fixtures (no real CLIs needed in CI).
  • All 143 tests pass; ruff format/lint, ty, cpd all clean.

Docs:

  • README "CLI Providers" section with provider table, quick-start, full config example, and subscription-billing notes.
  • --model / --eval-model / --test-gen-model help text mentions the new cli. aliases.

Adds first-class support for driving evaluations through user-installed
CLI agents (claude, copilot, kiro-cli) so users can run upskill against
existing subscriptions instead of raw ANTHROPIC_API_KEY / OPENAI_API_KEY.

Architecture:

- New CliAgentExecutor peer to LocalFastAgentExecutor and
  RemoteFastAgentExecutor, dispatching to one of three CliAgentRunner
  implementations (ClaudeCodeRunner, CopilotCliRunner, KiroCliRunner)
  via a small registry.
- Per-model executor routing (executors/router.py): cli.<provider>
  models route to CliAgentExecutor; everything else keeps its existing
  local/jobs path. This lets one upskill eval call mix CLI agents and
  fast-agent models in a single benchmark.
- CliFastAgentAdapter satisfies the narrow SkillGenerator protocol
  upskill's generate.py uses, so skill generation, test generation,
  and refinement also work via a CLI provider — no API keys required.
- _agent_session() dispatcher in cli.py: pure-cli runs skip
  _fast_agent_context entirely; hybrid runs strip cli.* slots from
  fast-agent's model_references and override per phase.
- Subscription billing is preserved: ClaudeCodeRunner unsets
  ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN /
  CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX from the subprocess
  env by default and prints a one-shot stderr note when it does. Power
  users can override cli_providers.<name>.unset_env: [] to keep the
  vars (e.g. for Bedrock/Vertex routing).
- Smart defaults: when every -m is cli.*, executor: jobs auto-downgrades
  to local (CLI providers always run locally) and test_gen_model
  defaults to the first cli.* eval model so users with non-cli config
  defaults don't need extra flags.

Testing:

- 48 new unit tests across runners, executor, router, env stripping,
  config, mixed-model orchestration, CLI help text.
- 4 end-to-end tests that drive the full stack against fake CLI binary
  fixtures (no real CLIs needed in CI).
- All 143 tests pass; ruff format/lint, ty, cpd all clean.

Docs:

- README "CLI Providers" section with provider table, quick-start, full
  config example, and subscription-billing notes.
- --model / --eval-model / --test-gen-model help text mentions the new
  cli.<provider> aliases.
Copilot AI review requested due to automatic review settings May 20, 2026 17:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class support for running upskill evaluations (and generation flows) via user-installed CLI agent tools (claude, copilot, kiro-cli) using cli.<provider> model aliases, enabling subscription-backed runs without requiring Anthropic/OpenAI API keys. The PR introduces a per-model executor router so a single eval/benchmark can mix CLI-backed models and fast-agent models.

Changes:

  • Introduces CliAgentExecutor + per-provider runners (Claude Code, Copilot CLI, Kiro CLI) and integrates them via a per-model executor router.
  • Updates CLI orchestration to support pure-CLI and hybrid runs (CLI + fast-agent), including smart defaults/downgrades and test-gen routing.
  • Adds extensive unit + E2E tests and updates documentation for CLI providers and configuration.

Reviewed changes

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

Show a summary per file
File Description
src/upskill/cli_agents/__init__.py Exposes the CLI agents public API (CliProviderConfig, runners/protocols, defaults).
src/upskill/cli_agents/base.py Defines shared CLI runner contracts, subprocess execution helpers, env stripping + warning behavior, and default provider configs.
src/upskill/cli_agents/claude_code.py Implements Claude Code runner with JSON envelope parsing and token usage extraction.
src/upskill/cli_agents/copilot.py Implements Copilot CLI runner via plain-text execution helper.
src/upskill/cli_agents/fast_agent_adapter.py Adds an adapter so CLI executors can satisfy the generation/refinement protocol used by generate.py.
src/upskill/cli_agents/kiro.py Implements Kiro CLI runner via plain-text execution helper.
src/upskill/cli_agents/protocols.py Introduces a narrow SkillGenerator protocol for decoupling generation flows from fast-agent specifics.
src/upskill/config.py Adds cli_providers config with default providers and a merge strategy for user overrides.
src/upskill/executors/cli_agent.py Adds a new executor that materializes artifacts/workspace and dispatches one-shot requests to CLI runners.
src/upskill/executors/router.py Adds per-model executor routing between CLI executor and fast-agent local/jobs executors.
src/upskill/model_resolution.py Updates model resolution to default test-gen to a CLI model when all eval models are cli.*.
src/upskill/generate.py Switches generation flows to depend on the new narrow generator protocol.
src/upskill/cli.py Integrates CLI providers into eval, benchmark, and generate flows, adding session dispatching and per-model executor factories.
tests/test_cli_agent_executor.py Unit tests for CliAgentExecutor prompt composition, artifact persistence, cancellation, and error paths.
tests/test_executor_router.py Tests routing behavior for CLI vs fast-agent models and jobs/local selection.
tests/test_claude_code_runner.py Unit tests for Claude runner JSON parsing, error handling, and argv formation.
tests/test_copilot_cli_runner.py Unit tests for Copilot runner stdout parsing, error handling, and argv formation.
tests/test_kiro_cli_runner.py Unit tests for Kiro runner argv formation (including opt-in flags) and error handling.
tests/test_cli_env_stripping.py Tests env stripping and one-shot warnings, plus an end-to-end subprocess env capture for Claude.
tests/test_cli_agents_contract.py Contract tests for config schema, defaults, merge behavior, and runner protocol conformance.
tests/test_cli_agents_e2e.py End-to-end tests using fake CLI binaries to validate full router/executor/runner stack.
tests/test_mixed_model_eval.py Validates mixed-model eval routing and pure-CLI test-gen skipping fast-agent context.
tests/test_cli_help.py Ensures CLI help text mentions cli.<provider> model aliases.
tests/test_cli_generate_benchmark.py Updates generate/benchmark tests to validate the new executor-factory plumbing.
tests/fixtures/fake_cli_agents/fake_claude.py Fake Claude binary fixture for E2E tests (JSON envelope).
tests/fixtures/fake_cli_agents/fake_copilot.py Fake Copilot binary fixture for E2E tests (plain text).
tests/fixtures/fake_cli_agents/fake_kiro.py Fake Kiro binary fixture for E2E tests (plain text).
README.md Documents CLI providers, configuration, billing/env stripping behavior, and caveats.
.gitignore Ignores generated runs/ and skills/ output directories by default.

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

Comment thread src/upskill/executors/cli_agent.py Outdated
Comment thread src/upskill/model_resolution.py Outdated
- Use tuple form in isinstance() in _coerce_cli_metadata for the broadest
  compatibility with static analyzers and older runtimes (PEP 604 union
  form is fine on Python 3.10+ but tuple syntax avoids false positives).
- Rewrite _resolve_eval_test_gen_model docstring to match the implemented
  resolution order, and remove a dead-code branch that the previous order
  could never reach.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants