feat(surf): SurfMarket / SurfChain / SurfSocial function-call tools#68
Merged
Conversation
The generic BlockRun primitive made the agent construct free-form Surf
paths and hand-handle x402. Weak routed models failed two ways: guessing
non-existent endpoints (market/token-ranking → 404 → circuit breaker), and
after discovery, trying to hand-roll SDK payment in Bash until the loop
guard tripped (~$0.58 wasted).
Add three VideoGen-style function-call tools, split by the existing skill
categories (surf-market / surf-chain / surf-social):
- `endpoint` is an enum of valid paths — the model picks, never guesses.
- Required params per endpoint are validated with a clear error.
- x402 is signed internally (same pattern as videogen.ts) — the model
never touches paths or payment, just fills params.
- Short-name tolerance: a model that drops the category prefix
("fear-greed" vs "market/fear-greed") is resolved when unambiguous;
ambiguous names ("ranking") return a "did you mean" list.
The generic BlockRun primitive stays for long-tail paths and future
partners; these three cover the high-traffic Surf surface with guardrails.
Verified:
- Direct execute(): market/fear-greed + market/ranking return data with
auto $0.001 payment; missing-param and unknown-endpoint give clean errors;
short names resolve.
- End-to-end: "market pulse" prompt drives SurfMarket across fear-greed +
ranking, returns real data (F&G 26, HYPE +9.6%), no fallback, no loop.
Known limitation: the endpoint tables are hand-maintained from the gateway's
SURF_ENDPOINTS registry. A follow-up should generate them so the gateway
stays the single source of truth (no drift).
SurfMarket worked when invoked but was activation-gated, so on a natural
prompt ("what's the crypto mood / which coins are pumping?") the agent
never reached for it — it fell back to TradingMarket prices and *guessed*
the Fear & Greed index, getting flagged twice for ungrounded claims.
PredictionMarket is already in CORE_TOOL_NAMES for exactly this reason
("what are the odds of X"). SurfMarket is the same shape of capability for
crypto market data, so it belongs in the hero surface too. SurfChain /
SurfSocial stay activation-gated (lower-frequency, long-tail).
Verified: same no-"surf"-mention prompt now drives SurfMarket on its own —
real Fear & Greed (26) + real token rankings, no hallucination flags, no
TradingMarket-only fallback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The generic
BlockRunprimitive exposes Surf as a free-formpathstring + manual x402. Weak routed models fail two ways (both reproduced):market/token-ranking/market/concept-ranking→ 404 → tool-failure circuit breaker disables BlockRun for the session (the original user bug).Prediction-market doesn't have this class of bug because it's a typed function-call tool. This PR gives Surf the same treatment.
What
Three VideoGen-style function-call tools, split by the existing skill categories:
SurfMarketSurfChainSurfSocialEach tool:
endpointis an enum of valid paths — the model picks, never guesses.videogen.ts) — the model never touches paths or payment.fear-greedvsmarket/fear-greed) resolves when unambiguous; ambiguous names (ranking) return a "did you mean" list.The generic
BlockRunprimitive stays for long-tail paths + future partners; these three cover the high-traffic Surf surface with guardrails.Verification
Direct
execute()(bypassing the LLM):End-to-end (haiku, multi-endpoint prompt):
(Same prompt on the generic primitive previously fell back to TradingMarket / looped.)
Known limitation / follow-up
The endpoint tables in
surf.tsare hand-maintained from the gateway'sSURF_ENDPOINTSregistry — they can drift. The durable fix is to generate them (codegen from the registry, or publish the list via the shared@blockrun/llmSDK) so the gateway stays the single source of truth. Tracked as follow-up; this PR is the validated prototype.Relationship to #67
Complementary. #67 (Surf endpoint discovery via 404
available+ inlined hints) hardens the generic primitive for long-tail/ad-hoc paths. This PR gives the high-traffic Surf surface first-class function tools. Both can land; the discovery fallback still covers paths not wrapped here.Scope
New file
src/tools/surf.ts(+343) + registration insrc/tools/index.ts. No change to existing tools.npm run buildclean.