Skip to content

fix(build-agent): validate harness/provider pairing, ask connection mode upfront#11

Open
bekossy wants to merge 2 commits into
mainfrom
fix/harness-provider-validation
Open

fix(build-agent): validate harness/provider pairing, ask connection mode upfront#11
bekossy wants to merge 2 commits into
mainfrom
fix/harness-provider-validation

Conversation

@bekossy

@bekossy bekossy commented Jul 6, 2026

Copy link
Copy Markdown
Member

Context

When you build a simple, no-tool Agenta agent through this skill, the Agenta UI's Model & Harness sometimes never resolves (shows "Select a provider", nothing selected), even though creation reports success. Reproduced 4 times during QA testing against a self-hosted instance, across two coding agents.

Root cause: the coding agent occasionally wrote a config that paired harness.kind: "claude" (the Claude Code harness, which only runs Anthropic models) with llm.provider: "openai" and a raw model id. The create and commit endpoints accept this mismatch with no error, but the agent never resolves to a working Model & Harness and never runs correctly.

Changes

lib.sh gets two new checks: validate_agent_config (full check, used by create-agent.sh) and validate_agent_config_delta (lighter check, tolerant of a partial update-agent.sh delta). Both refuse a config where harness.kind is "claude" and llm.provider is anything other than "anthropic".

Before, this config was accepted silently:

{"harness": {"kind": "claude"}, "llm": {"provider": "openai", "model": "gpt-4o-mini"}}

After, create-agent.sh and update-agent.sh reject it before making any API call, with a message explaining the coupling and how to fix it.

Also, per review feedback on the credentials setup flow: the skill previously always wrote llm.connection.mode as "self_managed" without asking. It now explicitly asks the user which mode they want at setup, self_managed (bring your own provider key) or agenta (use the project's own managed key), and only asks for a provider key in the self_managed case. This is orthogonal to the harness/provider coupling above; both connection modes still require llm.provider: "anthropic" when harness.kind is "claude".

SKILL.md and config-schema.md now explain the coupling explicitly, since it is not one of the "fewest calls" simplifications a caller should improvise on.

Tests

No existing test harness for the shell scripts in this repo, so verified end to end against a live self-hosted instance:

  • A mismatched config (harness=claude, provider=openai) is rejected client-side by create-agent.sh. No API call is made, exit 1 with the new error message.
  • A config with harness=claude, provider=anthropic, connection.mode=agenta passes validation (confirms the new connection mode does not get flagged as a mismatch).
  • A known-good boilerplate config still creates and invokes fine, no regression.
  • update-agent.sh with a partial delta (only instructions) still succeeds, confirming the lighter delta check does not over-reject legitimate partial updates.
  • All edited scripts pass bash -n syntax checks.

One documented limitation, called out in lib.sh's comment: validate_agent_config_delta only catches a harness/provider mismatch when both fields are present together in the delta itself. A delta that changes only llm.provider (relying on merge to keep a previous harness.kind: "claude") will not be caught. update-agent.sh's own guidance is to always pass the complete config, which avoids this gap.

What to QA

  • Ask the coding agent to build a simple, no-tool agent. During credentials setup it should now ask which llm.connection.mode you want, not just silently assume self_managed.
  • Try to get it to write a mismatched harness/provider config (ask for a non-Claude model while keeping the default harness). create-agent.sh should refuse with the CONFIG ERROR message rather than creating a broken agent.
  • Regression: build a normal agent with the default boilerplate. It should still create and pass RESOLVED as before.

Independent of the trigger-revision-pinning PR (different scripts; only a shared SKILL.md/lib.sh edit in a different location of each file). Should merge cleanly in either order, or with a trivial rebase.

Closes #3.

…on.mode choice

Simple no-tool agents were coming out with no Model & Harness resolved in the
Agenta UI (reproduced 4x while QA-testing against a self-hosted instance).
Root cause: the stored config paired harness.kind="claude" (Claude Code
harness, Anthropic-only) with llm.provider="openai"/model="gpt-4o-mini". This
combination is accepted by the create/commit endpoints with no server-side
error, but never resolves to a working Model & Harness, so the agent looks
"created successfully" and then silently does nothing.

create-agent.sh and update-agent.sh now validate this pairing (and, for
creation, that the full boilerplate is present) before calling the API,
refusing with a specific fix message instead of creating a broken agent.
SKILL.md and config-schema.md now explain the coupling explicitly, since it
isn't a "fewest calls" simplification a caller should improvise on.

Also addresses review feedback on the credentials setup flow: the skill now
explicitly asks the user which llm.connection.mode they want (self_managed,
bring your own provider key, vs agenta, use the project's own managed key)
instead of silently assuming self_managed. harness.kind="claude" still
requires llm.provider="anthropic" either way; connection.mode is orthogonal
to that coupling.
this block you actually choose: `self_managed` (the user's own provider API key — the
default written above) or `agenta` (the project's own managed/subscription key, no separate
provider key needed). Ask the user which they want during credentials setup (`SKILL.md`);
don't assume `self_managed` for a cloud user without asking.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is wrong. @bekossy you need to explain the meaning of self-managed to the model. it always makes this mistake. self-managed means the runner is using subscription claude code / codex. which means no need to configure the api key. In cloud you can't use self-managed at all. only agenta managed (meaning the user provide their api keys in agenta and they are used)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You're right, I had it backwards. Fixed in config-schema.md and SKILL.md: self_managed means the runner itself is logged into its own Claude Code / Codex subscription, so Agenta needs no provider API key at all. agenta means the user's provider key lives in Agenta's vault and Agenta uses it on every call. Also added the point that self_managed isn't available on cloud at all since cloud runners have no subscription of their own, so cloud always means agenta. Added a setup transcript to the PR description showing the corrected flow, and resolved the merge conflicts from #12/#14.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @bekossy please like the first pr show examples of transcripts before and after (from setup with the agent asking to set up your connection up to this point)

Resolves conflicts from #12 (trigger revision pinning) and #14 (trigger
discovery descriptions), both already merged to main.

Also fixes a factual error caught in review: self_managed does NOT mean
"the user brings their own provider API key" and agenta does NOT mean "use
Agenta's own managed/subscription key" - that was backwards.

self_managed means the runner itself is logged into its own Claude Code /
Codex subscription (Claude Pro/Max, ChatGPT Plus); Agenta needs no provider
API key at all in that case. agenta means the user's provider API key lives
in Agenta's project vault and Agenta uses it on every call. Critically,
self_managed is not available on Agenta cloud at all (cloud runners have no
subscription of their own), so cloud always means agenta. SKILL.md and
config-schema.md corrected accordingly.
@bekossy

bekossy commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

Addressed both:

Ready for another look.

@bekossy
bekossy requested a review from mmabrouk July 7, 2026 08:07
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.

build-agent: Model & Harness config not persisted for simple (no-tool) agents — tool-wired agents unaffected

2 participants