integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep - #749

Merged
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4
Jul 14, 2026
Merged

integration/v0.13.0-rc4: x402 settle-guard, /v1 discovery fix, hermes context config, flow de-flakes, dead-code sweep#749
OisinKyne merged 13 commits into
mainfrom
integration/v0.13.0-rc4

Conversation

@bussyjd

Copy link
Copy Markdown
Contributor

Summary

What changed: v0.13.0-rc4 integration train. Rolls up the four post-rc4 fix PRs (#743 x402 settle-guard for disconnected buyers + spec.maxConcurrentRuns, #744 flow-03 first-completion de-flake, #745 discovery /v1 api_base fix ending the poisoned-model-group 404s, #747 committee-verified dead-code sweep ~630 LOC + docs refresh) plus two integration-branch fixes found by the release smoke itself: explicit hermes model.context_length/max_tokens rendering (hermes ≥64K requirement invisible through LiteLLM) and flow-03 tool-call reasoning headroom.

Why it matters: closes the two chronic release-smoke failures (flow-11 poisoned model group, flow-03 flake), makes buyer-disconnect settlements impossible, and produces the first fully green 18-flow release smoke including the two OBOL flows (13/14) that had never passed.

Risk level: medium

Commit under test: 8f9b58e
Base branch: main

Scope

  • Code
  • Charts / manifests
  • Flows / QA scripts
  • Docs / skills

Validation

Unit tests:

go build ./... && go vet ./... && go test ./... -count=1 — all green at 8f9b58e58df56de5c886ac680415866858c40447
(go vet: pre-existing darwin-only unsafe.Pointer noise in internal/enclave excluded; present since #288)

Release smoke:

RELEASE_SMOKE_INCLUDE_OBOL=true RELEASE_SMOKE_INCLUDE_OBOL_FORK=true \
OBOL_LLM_ENDPOINT=http://127.0.0.1:8000/v1 OBOL_LLM_MODEL=qwen36-nvfp4 \
./flows/release-smoke.sh
RUN_ID: rc4-run7-20260714-171005 — result: PASS — 18/18 flows (suite numbering skips 12/15/18)

Flow tests:

FlowNetworkQA machine labelResult
01–11, 16–21 (local suite)k3d + anvilspark1 (GB10)PASS
flow-13 dual-stack OBOLk3d forkspark1PASS
flow-14 live OBOLbase-sepoliaspark1PASS

Live Chain Evidence

Network: base-sepolia (eip155:84532)
RPC/provider: Alchemy (key redacted)
Facilitator: https://x402.gcp.obol.tech

Contracts and tokens:

NameAddressVersion / notes
OBOL token0x0a09371a8b011d5110656ceBCc70603e53FD2c78ERC-20 + Permit2 flow
USDC (base-sepolia)0x036CbD53842c5426634e7929541eC2318f3dCF7eflow-11 settlement asset

Wallet roles:

RoleAddressSource
Alice / seller / register0xC0De030F6C37f490594F93fB99e2756703c4297Eflow-14 receipt summary
Bob / buyer / payer0x57b0eF875DeB5A37301F1640E469a2129Da9490Eflow-14 receipt summary

Transaction receipts:

PurposeTx hashStatus
ERC-8004 registration (agent 8092)0x7236a592437d102b0ffa2769f0904a58ee1e74011af472d213c0104c91315e3bsuccess
Settlement transfer (OBOL Permit2)0x13bfa013c7dcd6b7eb0021f0bf86b361d61f3adc6a091718ef1b0d2ee58c11800x1
USDC settlement (flow-11)0x1f554692bdabb9fafcaaa136400851d37672a9d3f99e317944ae8d7f48e074280x1

Known non-gating warning: flow-14 setMetadata reverts (custom error 0x7e273289) when metadata is already set on the live registry from a prior QA run; registration + settlement unaffected.

Runtime Evidence

ItemValue
OS / archUbuntu arm64 (NVIDIA GB10)
Backendk3d, anvil, cloudflared tunnels
QA LLMvLLM qwen36-nvfp4 (NVFP4), max_model_len 65536, qwen3_coder tool parser + qwen3 reasoning parser
hermes-agentnousresearch/hermes-agent:v2026.7.1

Superseded PRs

Content already on main (patch-equivalent, landed via the earlier rc4 train): #726, #728, #729, #730, #731, #732, #733.
Rolled into this integration branch: #743, #744, #745, #747.
All will be closed as superseded with a reference to this PR.

Related issues: #742 (zombie settlement, fixed), #746 (model-group newtypes follow-up), #748 (dormant-capability subtree decisions — TEE/OpenClaw kept).

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjdand others added 13 commits July 14, 2026 10:05
Renders gateway.api_server.max_concurrent_runs into the agent's
config.yaml. Nil omits the gateway block (Hermes internal default, 10);
0 disables the in-process cap so edge concurrency middleware governs
instead. Existing agents render byte-identical.
Part of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
If the buyer's request context is already canceled when the upstream
handler succeeds, do not settle — the buyer would be debited for a
response nobody receives (proven on-chain against hyperliquid-analyst,
see #742). Reports failure reason client_disconnected; the interceptor
hijacks the write path so nothing reaches the dead socket.
Fixes the propagated-cancel leg of #742.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
The first chat completion after stack-up intermittently fails with
empty output (curl -f hides the response; observed across three
release-smoke runs while steps 3-7 through the same port-forward and
key always pass). Retry up to 3x and surface the HTTP status so a real
failure is diagnosable instead of an empty string.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Local-server auto-discovery registered OpenAI-compatible endpoints
(vLLM on :8000) with a bare api_base. LiteLLM's OpenAI provider does
not append /v1 (CLAUDE.md pitfall 6), so every request through the
discovered entry hit POST /chat/completions and 404'd. When an explicit
'obol model setup custom --endpoint .../v1' entry shared the same model
group, requests coin-flipped between the good and bad deployment —
root cause of the intermittent release-smoke flow-11 step[43] 404 and
the flow-03 step[2] flake (latent since v0.10.0, 69f25bf).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
Zero callers anywhere (including tests) — flagged by the /v1 pipeline
audit's dead-code sweep alongside WarnAndStripV1Suffix (removed in
#745). Other deadcode-tool hits in internal/{buy,inference} are
test-covered exported API and were left alone.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…urrent-runs', 'origin/fix/flow03-first-request-retry' and 'origin/fix/discovery-api-base-v1' into integration/v0.13.0-rc4
Two-vendor (GPT + Grok) audited deletions, intersection-only:
- inference: dead ProbeEndpoint/ScanLocalEndpoints/DetectServerType/
ParseModelsResponse wrappers (live path is the *Context variants
used by model discovery); tests retargeted to live functions
- erc8004: superseded NewClient/Register/RegisterDetailed/SetAgentURI
(+ETH/RegisterWithOpts/SubmitRegister); tests retargeted to the
WithOpts variants
- x402: ResolveAssetInfo/BuildV1Requirement/TokenSupportedOnChain
(production uses ResolveAssetInfoForPayment/BuildV2Requirement/
ResolveToken); test coverage migrated, not dropped
- hermes: hermesExecArgs legacy test adapter + dead List/Skills/
ResolveInstance; agentruntime/dns/stack/schemas/serviceoffercontroller
zero-reference symbols; dead flow-lib shell functions
- flow-11: fix stale diag capture (deploy/litellm -c x402-buyer ->
deploy/x402-buyer, stale since the b68fc34 split)
Held back by committee split or product decision: RouteRulesForOffer
(golden-test seam), erc8004 SetMetadata, all TEE/CoCo + enclave +
OpenClaw capabilities (kept intentionally, see #748).
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
- pitfall 6 generalized: EVERY LiteLLM openai/ api_base must include
/v1 (LiteLLM posts <api_base>/chat/completions verbatim); buyer-side
tooling uses the opposite convention; discovery fixed in #745
- new pitfall 22: poisoned model group (two deployments, one bare
api_base -> intermittent 404, no retry; GET /model/info vs CM is
the decisive check)
- new pitfall 23: buyer disconnect != no charge (hermes non-streaming
path completes + settles after abort; keep runs short via
spec.maxTurns; maxConcurrentRuns semantics; 4xx never settled)
- skill: lessons table updated (poisoned model group, parserless QA
endpoint -> relaunch with publisher-exact launcher), version 3.2.0
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…d agents
Hermes agents cannot discover the real context window through LiteLLM
(its /models response strips max_model_len) and fall back to assuming
65536 tokens — then request max_tokens=65536, which any backend with a
smaller window rejects. Hermes misclassifies that as context exhaustion,
compresses a near-empty conversation, and dies with "Context length
exceeded (21 tokens). Cannot compress further." — the exact failure of
flow-13/14 step 45 (agent readiness preflight), reproduced and fixed
standalone against hermes-agent v2026.7.1 + vLLM.
Hermes also hard-requires >=64K context, so the QA endpoint itself must
serve >=65536 (spark1 vLLM relaunched with --max-model-len 65536).
- generateConfig: honor OBOL_LLM_CONTEXT_LENGTH / OBOL_LLM_MAX_TOKENS
env knobs -> model.context_length / model.max_tokens (hermes config
resolution step 0, overrides its probing)
- release-smoke: default OBOL_LLM_CONTEXT_LENGTH=65536,
OBOL_LLM_MAX_TOKENS=8192 whenever the OBOL flows are enabled
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…s 100->2048)
Reasoning models (qwen3 family behind the vLLM reasoning parser) emit
reasoning_content before the tool call; at max_tokens=100 the budget is
sometimes exhausted mid-reasoning and the response comes back
finish_reason=length with no tool_calls — an intermittent FAIL on an
otherwise healthy endpoint (passed run5, failed run6, temperature=0
notwithstanding). 2048 verified live: finish_reason=stop, tool call
returned.
Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

@OisinKyneOisinKyne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems like a surprising amount of deletions but i'll trust you on it

@OisinKyne
OisinKyne merged commit 2b17616 into mainJul 14, 2026
11 checks passed
@OisinKyne
OisinKyne deleted the integration/v0.13.0-rc4 branch July 14, 2026 11:11
Sign up for freeto 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

@bussyjd@OisinKyne