feat(tools): expose voice, transcribe, captions, dispatch routing and payment rails (#72) - #63
feat(tools): expose voice, transcribe, captions, dispatch routing and payment rails (#72)#63yakimoto wants to merge 3 commits into
Conversation
… payment rails (#72)
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_0226eb3a-27a1-46b9-a918-c5ee7e45bbc3) |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 30 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
The registry went 18 -> 25 in the previous commit but the facts still said 18, so the generated README would have under-reported the surface and the drift gate would have measured against a stale count. Adds 7 capability entries and 7 claims (all resolver-verified against source), three tool tables, the two new env vars, and corrects the count in both .wave/repo.json and the capabilities.json 18-tools tag. Verified: 25 capabilities for 25 registered tools; all 29 claim resolvers resolve against the working tree.
…ckage The public-repo content-policy gate blocked this correctly: mcp-server ships to npm, and the source comment cited a file path inside a private WAVE repo. The substance of the comment (these routes are public, rate-limited per IP) is kept; only the internal path is removed.
Part of wave-av/wave-context#48. Addresses the mcp-server half of wave-av/wave-context#72.
The MCP server exposed 18 tools across Analytics / Billing / Streams / Studio — and none for the shipped fleet products. This adds 7, taking the registry to 25.
wave_speakPOST /v1/voicewave_transcribePOST /v1/transcribewave_captionPOST /v1/captionswave_routePOST /{ route, decision }wave_list_routing_profilesGET /profileswave_find_paid_servicesGET /v1/mpp/serviceswave_payment_schemesGET /v1/{x402,mpp}/facilitator/supportedEvery path is grounded in the spoke's own router, not the API spec
The spec at
wave-av/api-specdeclares/voice/generate,/voice/voices,/voice/clone,/captions/{jobId}/download,/transcribe/{id},/phone/*,/podcast/*— none of which exist.Each spoke owns its whole
/v1namespace with an exact-match router and 404s anything else, and thegateway forwards
/v1/<product>verbatim (spoke-routing.tsis a pure prefix map, no rewriting). Sobuilding against the spec would have shipped seven tools that 404. Filed as wave-av/api-spec#33; the
paths here come from
git show origin/main:src/api.tsin each spoke.Note this also means phone and podcast are not buildable:
wave-phone-edgeandwave-podcast-edgehave noapi.tsat all — theirsrc/isfavicon.ts,landing.ts,tokens.css.ts,worker.ts. They're landing shims, and/v1/phone//v1/podcastappear nowhere inthe gateway's routing table. No tool is claimed for either; that's the honest
plannedstate.Three design decisions worth flagging
1.
wave_speakreturns a receipt, not audio.POST /v1/voicereturnsaudio/mpegbytes. A toolresult is a text block, so the only ways to return audio are base64 (megabytes into the model's
context, for something it cannot listen to) or silently mangling the bytes through
res.text(). Itreports content type, size, and billed usage instead, and says plainly that the bytes aren't returned
and how to get them. If you'd rather it return base64 behind an opt-in flag with a size cap, say so
and I'll add it — this was the judgment call I was least certain about.
2. Audio input is by URL. Both spokes accept a
?url=they fetch server-side(
transcribe.ts,source.ts). That's the only sane path for tool arguments, and it's how an agentalready holds media.
3. A separate base URL, and a separate fetch helper.
getBaseUrl()iswave.online(the appsurface,
/api/v1/billing/...); the product spokes and payment rails live behind the gateway atapi.wave.online/v1/.... Reusing the existingwaveFetchwould have pointed every call at the wronghost and forced
Content-Type: application/jsononto content-type-sensitive spokes. HencegetApiBaseUrl()+gatewayFetch, with the caller owning the content type.wave-dispatchgets itsown helper again — it isn't behind the gateway at all.
Metered tools append a
[billed: <meter>, <n> min]line from the spoke'sx-wave-meter/x-wave-usage-minutesresponse headers, so an agent can see what the call it just made cost.Only the read half of the payment rails is exposed. The facilitator's
verifyandsettlearethe money-moving side and are deliberately not wrapped as agent tools.
Verification
Registry smoke check (the registry throws on a duplicate name at import, so a clean import is itself a check):
Live proof — the two public tools need no key, so they were run against production:
That 503 is a real production gap, not a bug in this PR — MPP service discovery is dark because its
Vectorize index isn't bound. Filed as wave-av/wave-gateway#730. The tool surfacing it verbatim rather
than swallowing it is the intended behavior.
The five authenticated tools could not be exercised end-to-end here: that needs a live
WAVE_API_KEY,and every product call is metered, so proving them bills real money. Worth doing deliberately against
a test org rather than incidentally in a PR.
Caveats
testscript, zero test files), so the gate is type-check +lint + build, matching existing convention. Test infrastructure is worth adding — I'll file it
separately rather than smuggle a framework into this PR.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Medium Risk
New external API integrations and billing-metered calls increase exposure to wrong-host misconfiguration and real usage charges; payment discovery is read-only and public routes omit API keys by design.
Overview
Adds seven MCP tools so agents can call WAVE fleet products and payment discovery that were missing from the registry (25 tools total). New modules wire voice / transcribe / captions through
gatewayFetchtoapi.wave.online(/v1/voice,/v1/transcribe,/v1/captions), dispatch viagetDispatchUrl()(wave_route,wave_list_routing_profiles), and public MPP/x402 discovery without sending an API key (wave_find_paid_services,wave_payment_schemes).Auth and HTTP layering split the app host (
getBaseUrl/ existingwaveFetch) from the gateway (getApiBaseUrl,getDispatchUrl).gatewayFetchdoes not forceContent-Type: application/jsonand surfacesx-wave-meter/x-wave-usage-minutesviausageNoteon metered calls.Behavior choices:
wave_speakreturns a receipt (type, size, billing) instead of audio bytes through text MCP results; transcribe/caption tools take public audio URLs in query params. Payment tools intentionally expose only discovery endpoints, not verify/settle.Reviewed by Cursor Bugbot for commit 43ddba1. Configure here.
Summary by cubic
Adds seven MCP tools for fleet products and payments (voice TTS, transcribe STT, captions, dispatch routing, and public payment discovery). Also adds gateway/dispatch fetch helpers, surfaces billed usage in tool outputs, updates SSOT facts to 25 tools, and removes a private-repo path from a payments comment (no runtime change).
New Features
wave_speak(POST /v1/voice) returns a receipt;wave_transcribe(POST /v1/transcribe) JSON transcript;wave_caption(POST /v1/captions) VTT/SRT/JSON cues.wave_route(POST /) classifies prompts;wave_list_routing_profiles(GET /profiles) is flag-gated.wave_find_paid_services(GET /v1/mpp/services);wave_payment_schemes(GET /v1/{x402,mpp}/facilitator/supported). No Authorization header is sent on these public routes.[billed: <meter>, <n> min]from response headers..wave/repo.jsonandcapabilities.jsonupdated to 25 tools with claims and tool tables.Migration
WAVE_API_BASE_URL(defaults to https://api.wave.online) andWAVE_DISPATCH_URL(defaults to https://dispatch.wave.online).WAVE_BASE_URLremains for the app host.wave_speakreturns no audio bytes; use the SDK or direct API if you need the audio.Written for commit 05bc83f. Summary will update on new commits.