Hello,
I have a contribution ready and validated, and I am opening an issue because
google/ax currently has pull_request_creation_policy: collaborators_only, so
external contributors cannot open a pull request from a fork: the web UI answers
"Pull request creation is restricted" and the API returns
<login> does not have the correct permissions to execute CreatePullRequest.
Issues work, so I am asking here for a way in.
I am happy to sign the Google CLA if I have not already, and to reshape any part of
this — I would just need either a collaborator invite (so I can open the PRs
myself), or a maintainer opening them from my fork's branches (pushed and public),
or I can hand the patches over.
All four branches are rebased on today's main (e09ed1b).
What it adds
DeepSeek Harness (dsh) as a task harness, on top of a pluggable model layer,
split into 4 stacked branches in psanchezg/ax, one per reviewable unit:
| # |
Branch |
Commits |
Diff |
What |
| 1 |
feat/dsh-adaptation-proposal |
1 |
1 file, +635 |
design note for the adaptation |
| 2 |
feat/model-providers |
9 |
25 files, +2460 -139 |
ModelSpec.base_url (field 8) and ModelSpec.api (field 9), provider registry + adapters, apply-time validation, docs and examples |
| 3 |
feat/agent-harness-seam |
4 |
16 files changed, 1199 insertions(+), 268 deletions(-) |
WorkspaceSpec.harness (field 4), the harness seam, credentials resolved from a Model |
| 4 |
feat/deepseek-harness |
17 |
21 files changed, 2361 insertions(+), 16 deletions(-) |
the DSH harness, its runner image, the guide and the manual validation runbook |
Getting the code
Compare links (each branch based on google/ax:main, stacked in this order):
Fetch them directly:
git remote add fork https://github.com/psanchezg/ax.git
git fetch fork feat/dsh-adaptation-proposal feat/model-providers feat/agent-harness-seam feat/deepseek-harness
Or take the whole series as a patch set — 31 commits, applies cleanly on
upstream/main with git am:
https://gist.github.com/psanchezg/8e982ae3d6bc45118b880a3448b6d771
Why it fits
- Providers. A
Model can say who serves it but not which endpoint or which
wire protocol. Both fields are additive and unset keeps today's per-provider
default, so existing manifests are unaffected. The adapters are plain
net/http (no new dependencies) and failures stay typed and loud: a missing key,
an HTTP error or an unreachable endpoint surfaces as an error carrying the
provider's status and body, never as a fabricated completion.
- Harness.
WorkspaceSpec.harness is opt-in: with no harness declared,
ResolveHarness("") still returns the Antigravity path and the task keeps its own
image, so nothing changes for existing manifests. When a workspace names a
Model, the controller injects the credential under the name the Model
declares, instead of the legacy Gemini variable.
- DSH. The harness writes the provider binding
dsh reads. That needs both the
llm-pi-ai provider entry and agent-default-model: registering the route is
not enough, because the shipped profile mounts its own adapter as the default and a
fresh agent would never ask for the Model's route.
Validation
make test green in all 8 packages, on the tip of each of the four branches.
- The series applies cleanly on a fresh
upstream/main (git format-patch + git am,
31 commits).
- Manual validation on macOS/arm64 and Linux/amd64 is recorded in
docs/deepseek-harness-validation.md (added by branch 4): the six sandbox checks
with their commands, expected output and what each one proves, the two
preconditions that block a new task, and two findings that changed the feature —
an agent can write outside /workspace (so the isolation criterion means "cannot
escape the sandbox"), and Running does not mean the agent is still working.
- One caveat worth knowing while reviewing: with the
Gateway removed, AX no longer
applies an egress policy, so in a cluster where the actor has no EgressGateway
dsh reports TRANSPORT: Connection error. The runbook documents it; it is not
something these branches change, but it does affect the end-to-end check.
Small doc note: CONTRIBUTING.md still describes the fork-and-open-a-PR flow, so the
restriction is easy to hit without warning — maybe worth a line there.
Happy to split, squash or drop any of it. Thank you!
Hello,
I have a contribution ready and validated, and I am opening an issue because
google/axcurrently haspull_request_creation_policy: collaborators_only, soexternal contributors cannot open a pull request from a fork: the web UI answers
"Pull request creation is restricted" and the API returns
<login> does not have the correct permissions to execute CreatePullRequest.Issues work, so I am asking here for a way in.
I am happy to sign the Google CLA if I have not already, and to reshape any part of
this — I would just need either a collaborator invite (so I can open the PRs
myself), or a maintainer opening them from my fork's branches (pushed and public),
or I can hand the patches over.
All four branches are rebased on today's
main(e09ed1b).What it adds
DeepSeek Harness (
dsh) as a task harness, on top of a pluggable model layer,split into 4 stacked branches in
psanchezg/ax, one per reviewable unit:feat/dsh-adaptation-proposalfeat/model-providersModelSpec.base_url(field 8) andModelSpec.api(field 9), provider registry + adapters, apply-time validation, docs and examplesfeat/agent-harness-seamWorkspaceSpec.harness(field 4), the harness seam, credentials resolved from aModelfeat/deepseek-harnessGetting the code
Compare links (each branch based on
google/ax:main, stacked in this order):Fetch them directly:
Or take the whole series as a patch set — 31 commits, applies cleanly on
upstream/mainwithgit am:https://gist.github.com/psanchezg/8e982ae3d6bc45118b880a3448b6d771
Why it fits
Modelcan say who serves it but not which endpoint or whichwire protocol. Both fields are additive and unset keeps today's per-provider
default, so existing manifests are unaffected. The adapters are plain
net/http(no new dependencies) and failures stay typed and loud: a missing key,an HTTP error or an unreachable endpoint surfaces as an error carrying the
provider's status and body, never as a fabricated completion.
WorkspaceSpec.harnessis opt-in: with noharnessdeclared,ResolveHarness("")still returns the Antigravity path and the task keeps its ownimage, so nothing changes for existing manifests. When a workspace names a
Model, the controller injects the credential under the name theModeldeclares, instead of the legacy Gemini variable.
dshreads. That needs both thellm-pi-aiprovider entry andagent-default-model: registering the route isnot enough, because the shipped profile mounts its own adapter as the default and a
fresh agent would never ask for the
Model's route.Validation
make testgreen in all 8 packages, on the tip of each of the four branches.upstream/main(git format-patch+git am,31 commits).
docs/deepseek-harness-validation.md(added by branch 4): the six sandbox checkswith their commands, expected output and what each one proves, the two
preconditions that block a new task, and two findings that changed the feature —
an agent can write outside
/workspace(so the isolation criterion means "cannotescape the sandbox"), and
Runningdoes not mean the agent is still working.Gatewayremoved, AX no longerapplies an egress policy, so in a cluster where the actor has no
EgressGatewaydshreportsTRANSPORT: Connection error.The runbook documents it; it is notsomething these branches change, but it does affect the end-to-end check.
Small doc note:
CONTRIBUTING.mdstill describes the fork-and-open-a-PR flow, so therestriction is easy to hit without warning — maybe worth a line there.
Happy to split, squash or drop any of it. Thank you!