fix: drop the underlying model from agent discovery surfaces (402 + /skill.md)#673
Open
bussyjd wants to merge 6 commits into
Open
fix: drop the underlying model from agent discovery surfaces (402 + /skill.md)#673bussyjd wants to merge 6 commits into
bussyjd wants to merge 6 commits into
Conversation
An Obol Agent (type=agent) runs its own model, skills, and memory — the buyer
never selects one, and Hermes ignores the chat-completions `model` field
(resolved from its own config). Surfacing the underlying model in the 402 page
is noise and exposes an implementation detail, and pay-agent's required
`--model` flag had no effect on agent calls.
- paymentrequired.go agentCopy: remove '(running <model>)', the '"model":' line
in the example body, and '--model <id>' from the pay-agent example. The agent
copy is now model-free.
- buy-x402 buy.py: pay-agent no longer accepts/sends --model (synthesised body
is just {messages, stream}); usage strings updated.
- buy-x402 SKILL.md: pay-agent documented without --model.
go build + x402/buyer/embed tests green.
Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
mergeAgentExtras no longer adds extra.agentModel — an Obol Agent runs its own model and the buyer never selects one, so the model id is an internal detail, not buyer-facing info (it also rendered in the HTML 402 page's raw-JSON card). agentSkills/agentRuntime still surface so clients can tell it's an agent. Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
…t offers For agent offers the buyer never selects a model — the agent runs its own and ignores the chat-completions `model` field — so the bazaar discovery example now seeds the neutral 'your-model-id' placeholder instead of the real upstream id (which also rendered in the HTML 402 page's embedded raw-JSON card). Inference offers are unchanged: there the model IS buyer-selectable, so the real id stays. Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
…for agent offers The /skill.md catalog (and its Service Details section) showed the agent's underlying model in the Model column / **Model** bullet. An agent runs its own model and ignores the request `model` field, so the id is an internal detail — agent rows now render '—' and omit the **Model** bullet. Inference offers keep their model (there the buyer selects it). Mirrors the 402 page/extra/bazaar model-strip in internal/x402. The /api/services.json feed still resolves the agent model on purpose (drives the storefront UI) — left untouched. Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
…mojibake The skill-catalog busybox httpd served .md/.html with a bare text/* Content-Type (no charset), so clients fell back to Latin-1/CP1252 and rendered UTF-8 em dashes (the catalog's '—' placeholders, accented operator descriptions) as '—'. Add charset=utf-8 to the text MIME mappings. JSON stays clean (always UTF-8 per RFC 8259). Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
Two fixes for type=agent offers whose skills shell out to scripts (buy-x402, the hyperliquid data skill), found while debugging the hyperliquid-analyst: - Disable the code_execution toolset. execute_code runs arbitrary in-process Python that bypasses the terminal DANGEROUS_PATTERNS gate, so Hermes fails it closed without a per-script approval no human can grant in an unattended paid turn. Small models then loop on it until the turn dies (observed: gemma4 returning a templated placeholder answer instead of fetching data). Disabling it routes skills through the terminal tool, where benign python3 auto-approves and dangerous commands stay gated. - Raise terminal.timeout/lifetime_seconds 80s/90s -> 170s/180s. Sold agents run behind a named tunnel (no ~100s quick-tunnel cut), and a paid data call (x402 round-trip + a first-party query) can exceed 80s, timing out heavier queries. Claude-Session: https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD
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
For
type=agentoffers, stop surfacing the underlying model everywhere it leaked into discovery — the 402 page copy, the JSON 402extra, the bazaar discovery example, and the/skill.mdcatalog — and drop the useless--modelflag frompay-agent.Why
An Obol Agent runs its own model, skills, and memory — the buyer never selects one. Hermes resolves the model from its own config (
model.default) and ignores the chat-completionsmodelfield, so:(running <model>)text and"model": "<model>"body example on the 402 page are noise that also leak an implementation detail (e.g. a specific small/uncensored model on a public-facing agent),extra.agentModel, the bazaar discovery example'smodel, and the/skill.mdcatalog'sModelcolumn /**Model**bullet exposed that same internal id to buyers, indexers, and facilitators, andpay-agent's required--modelhad no effect on agent calls — it was required-by-CLI but a no-op.Inference offers are deliberately unchanged: there the buyer does select the model (
paid/<remote-model>), so the real id stays buyer-facing.Changes
internal/x402/paymentrequired.go(agentCopy): remove(running <model>), the"model":line in the example body, and--model <id>from thepay-agentexample. The example is nowpay-agent <url> --message "…".internal/x402/verifier.go(mergeAgentExtras): stop addingextra.agentModel; keepagentSkills/agentRuntimeso clients still know it's an agent.internal/x402/bazaar.go(BuildBazaarExtension): foragentoffers, seed the bazaar chat-completions example with the neutralyour-model-idplaceholder instead of the real upstream id (which also rendered in the HTML 402 page's embedded raw-JSON card).inferenceoffers keep the real id.internal/serviceoffercontroller/render.go(buildSkillCatalogMarkdown): agent rows render—in the Model column and omit the**Model**detail bullet (newcatalogModelNamehelper). Inference/HTTP offers unchanged.internal/embed/skills/buy-x402/scripts/buy.py(pay-agent): no longer accepts or sends--model— the synthesised body is just{messages, stream}. Usage strings updated.buy-x402/SKILL.md:pay-agentdocumented without--model.agent_extras_test.go,bazaar_test.go,paymentrequired_test.go,render_test.goupdated/added to assert the real model is absent from agent discovery surfaces (addedmustNotContain+TestBuildSkillCatalogMarkdown_AgentModelStripped).Verify
go build ./...✅go test ./internal/x402/... ./internal/serviceoffercontroller/... ./internal/embed/...✅python3 -m py_compile buy.py✅intel.v1337.org/services/hyperliquid-analyst:gemma4-aeon-uncensorednow appears 0× in both the JSON 402 and the HTML page;extra.agentModelis gone;agentSkills/agentRuntimeretained; USDC verification intact (name=USDC, base-sepolia,amount=10000= $0.01). (The/skill.mdchange ships with the serviceoffer-controller — redeploy the controller to pick it up live.)Notes
/api/services.jsonstill resolves the agent model on purpose — that feed drives the storefront UI display, a separate design choice. Left untouched here; can revisit if we want the storefront to hide it too.https://claude.ai/code/session_01XgUndZjSoxr2jNNGG5sVYD