feat(agent-interface): centralize harness↔model snapping; fix nanoclaw capabilities#8
Merged
Merged
Conversation
…w capabilities - nanoclaw is router-backed (runs any model via the Tangle router), not Anthropic-locked - nanoclaw reasoning ceiling is 'none' (its runner sends no thinking flag), was 'ultracode' - add snapModelToHarness / snapHarnessToModel (+ ranking patterns) so sandbox-ui and agent-app import the catalog-aware snap logic instead of hand-rolling divergent copies - add a vitest suite; exclude test files from the published dist Part of the harness/model/effort selector unification (tangle-network/gtm-agent#395).
drewstone
approved these changes
Jun 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes
@tangle-network/agent-interfacethe single source of truth for harness↔modelsnapping, and corrects
nanoclaw's capabilities.Changes (
packages/agent-interface/src/harness-capabilities.ts)nanoclaw: ["anthropic"]fromharnessProviderLock. Its runner routes every provider through the Tangle router(
TANGLE_ROUTER_MODEL+ OpenAI/OpenRouter/Anthropic base URLs all → gateway), so it runs anymodel like
opencode.harnessSupportsModel("nanoclaw", <anything>)is nowtrue.ultracode → none. Its runner sends no thinking flag, soreasoningEffortsFor("nanoclaw")now returns["none"]instead of over-advertising the full ladder.sandbox-uiandagent-app):snapModelToHarness(harness, modelId, candidateIds)andsnapHarnessToModel(harness, modelId), plus a privateharnessPreferredModelPatternsrankingtable. Both reuse the existing
harnessSupportsModel/preferredHarnessForModeland arecatalog-agnostic (take
readonly string[]of canonical ids), so consumers can delete their forks.Supporting
src/harness-capabilities.test.ts(16 cases): compatibility + aliases, nanoclaw = any model,snap ranking (opus-before-sonnet, gpt-frontier-before-mini), the router-backed "don't snap" path,
reasoning ceilings (incl. nanoclaw = none), and model-capability narrowing.
package.json:test/test:watchscripts +vitestdevDep (catalog).tsconfig.json: exclude*.test.tsfrom the build so tests don't ship indist.0.14.0 → 0.15.0): new exports + the nanoclaw behavior change.Why
The harness↔model compatibility rule (and the snap helpers) were hand-copied into three places
that disagree — agent-interface,
sandbox-ui/src/chat/harness-model-compat.ts, andagent-app/src/harness/index.ts. Today the two consumers don't even call agent-interface'scopy, so its wrong
nanoclawlock is dead code; it would become a live regression the moment theymigrate. This PR fixes nanoclaw and lands the snap helpers here first, so the consumer PRs can
delete their forks and import from one source.
Verification
pnpm --filter @tangle-network/agent-interface build— clean; no test files indist.check-types— passes.pnpm --filter @tangle-network/agent-interface test— 16/16 pass, single run.Scope / follow-ups
First of a multi-repo unification tracked in tangle-network/gtm-agent#395:
sandbox-ui: rewriteharness-model-compat.tsto delegate to these exports (keep its 5 publicre-exports stable).
agent-app: add agent-interface as a peerDep; delegate the policy via a documentedas HarnessTypeboundary cast (its
Harnesstaxonomy —forge/cursor— diverges; full taxonomy unification is aseparate follow-up).
Draft until 0.15.0 is published and the consumer PRs are validated against it.