feat(tools): fleet, dispatch and payment toolkits (#72) - #58
Conversation
Adds the shipped WAVE surface the ADK was missing: the voice/transcribe/captions product spokes (FleetToolkit), Dispatch model routing (DispatchToolkit), and the read half of the x402/MPP agent-payment rails (PaymentsToolkit). Registry goes 10 -> 17 tools. Every path comes from each spoke router at origin/main, not api-spec/openapi.yaml, which over-declares endpoints that 404 in production (wave-av/api-spec#33). AgentTool and the MCP-shape mapper move to src/tools/shared.ts so all four toolkits emit identical MCP definitions; AgentToolkit re-exports AgentTool from its original path, so the public API is unchanged.
|
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_8f5f1c1f-9cbb-40fd-a286-7717a40ff437) |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 44 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 |
|
Flagging a problem with this PR's base that I found after opening it. This repo is not the one that publishes Two consequences for this PR:
If Not re-basing it unilaterally — that decision belongs with wave-av/sdks#42. Holding here. |
Part of wave-av/wave-context#48. Delivers the adk half of wave-av/wave-context#72 (the mcp-server half is wave-av/mcp-server#63).
The ADK shipped 10 tools covering streams and live production — and nothing for the fleet products that are actually in production. This adds three toolkits, taking the registry to 17 tools.
FleetToolkitwave_speak,wave_transcribe,wave_captionPOST /v1/{voice,transcribe,captions}via the gatewayDispatchToolkitwave_route,wave_list_routing_profilesPOST /,GET /profiles— its own hostPaymentsToolkitwave_find_paid_services,wave_payment_schemesGET /v1/mpp/services,GET /v1/{x402,mpp}/facilitator/supported— publicEvery path is grounded in the spoke's own router, not the API spec
wave-av/api-specdeclares/voice/generate,/voice/voices,/voice/clone,/transcribe/{id},/captions/{jobId}/download,/phone/*,/podcast/*— none of which exist. Each spoke owns its whole/v1namespace with an exact-match router and 404s anything else; the gateway forwards/v1/<product>verbatim with no rewriting. Building from the spec would have shipped tools that 404. Filed as wave-av/api-spec#33; the paths here come fromgit show origin/main:src/api.tsin each spoke.Worth stating plainly: 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 are landing shims, and neither prefix appears in the gateway routing table. No tool is claimed for either.Three decisions worth your attention
1.
wave_speakgives code the bytes and a serialiser a receipt.POST /v1/voicereturnsaudio/mpeg. Returning the bytes is right for an SDK — discarding a response body is lossy and the caller can't recover it. But agent frameworks routinelyJSON.stringifya tool result straight into a model's context, where a megabyte of serialised byte array is useless to something that cannot listen. SoVoiceResultholds the realUint8Arrayon.audio, and itstoJSON()emits{ contentType, byteLength, usage }instead. No caller has to choose.This is the concrete answer to the open question I raised on mcp-server#63 — in MCP the tool result is text so a receipt is all that's possible, but in a TypeScript SDK we can have both.
2.
PaymentsToolkittakes no API key — not an optional one, none at all. Those gateway routes are public by design, because an agent has to discover what it can buy before it holds a WAVE key. The surest way to never send a credential to an endpoint that doesn't authenticate it is to have nothing to send. Only the read half is exposed; the facilitator'sverifyandsettleare the money-moving side and are deliberately not wrapped.3. A separate base URL and a separate fetch path, twice.
api.wave.onlinefronts the product spokes and the payment rails;dispatch.wave.onlinefronts Dispatch, which is not behind the gateway. ReusingAgentToolkit.call()would also have forcedContent-Type: application/jsononto content-type-sensitive spokes and — see below — swallowed every error.Two things this fixes on the way past
AgentTooland the MCP-shape mapper move tosrc/tools/shared.tsso all four toolkits emit identical MCP definitions.AgentToolkitre-exportsAgentToolfrom its original path, soimport { type AgentTool } from '@wave-av/adk'resolves exactly as before — the public API is unchanged, and the smoke check asserts it.The new toolkits throw a typed
WaveToolErrorcarrying the status and the response body verbatim.AgentToolkit.call()never checksresponse.ok, so it returns error bodies as though they were successful results — that's pre-existing and out of scope here, but it's whywave_find_paid_servicessurfacing a real 503 (below) is the intended behaviour rather than a swallowed empty list.WaveToolErroris also the export the README has been advertising from@wave-av/adk/toolswithout it existing.Verification
Smoke check against the built output (
dist/index.js, so it proves what a consumer gets) — 33/33:Live proof — the two public tools need no key, so they ran against production:
That 503 is a real production gap, not a defect in this PR — MPP service discovery is dark because its Vectorize index isn't bound (wave-av/wave-gateway#730). The toolkit raising it as a typed error rather than swallowing it is the point.
Caveats — read these
WAVE_API_KEY, and every product call is metered, so proving them bills real money. It should be done deliberately against a test org, not incidentally in a PR.src/__tests__/*.test.tsimportvitest, but vitest is absent frompackage-lock.json, there is notestscript, andtsconfig.jsonexcludes the test directory. So the gate here is type-check + lint + build + the out-of-repo smoke run above. I'm filing that separately rather than smuggling a test framework into this PR — and it is why I removed the words "and are covered by tests" from the Status prose in.wave/repo.json, which was not true.dist/is tracked but intentionally not updated here. It is committed at release time (prepublishOnlyrebuilds it), not per feature.AgentToolkit, so the new tools aren't reachable from Mastra/LangGraph/LiveKit yet. Filing that as a follow-up..wave/repo.jsonUpdated so the generated README covers the new surface: three new capabilities, six new resolver-verified claims, a corrected tool count (10 → 17), and a "Working with audio" section. The README prose changes ride in this PR deliberately — merging it is the review.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Medium Risk
Adds live production API clients (voice, payments discovery, Dispatch routing) with new error and auth semantics; framework adapters still only wrap AgentToolkit, so new tools aren’t reachable via Mastra/LangGraph/LiveKit yet.
Overview
Expands the ADK from 10 stream/production tools to 17 by adding
FleetToolkit,DispatchToolkit, andPaymentsToolkit, with shared plumbing insrc/tools/shared.tsand root exports fromsrc/index.ts.FleetToolkitaddswave_speak,wave_transcribe, andwave_captionagainst gateway paths grounded in spoke routers (POST /v1/voice,/v1/transcribe,/v1/captions).VoiceResultkeeps real audio on.audiowhiletoJSON()emits a usage receipt so serializers don’t dump megabytes into model context. STT tools pass a publicurlquery param; calls useassertOkandWaveToolErrorinstead ofAgentToolkit.call()’s unchecked JSON parsing.DispatchToolkittargetsdispatch.wave.online(notapi.wave.online) forwave_routeandwave_list_routing_profiles.PaymentsToolkitexposes read-only x402/MPP discovery with no API key and noAuthorizationheader; verify/settle are intentionally omitted.AgentToolkitnow delegatesAgentTool,validated, andtoMCPToolDefstosharedwithout changing the publicAgentToolimport path..wave/repo.jsondocuments the new capabilities, claims, tool count, and “Working with audio” guidance.Reviewed by Cursor Bugbot for commit f31bbad. Configure here.
Summary by cubic
Add
FleetToolkit,DispatchToolkit, andPaymentsToolkitto expose voice, transcription, captions, model routing, and payment discovery; the tool registry grows from 10 to 17 with paths grounded in live spokes and Dispatch (not the API spec).New Features
FleetToolkit(gateway):wave_speak(POST/v1/voice),wave_transcribe(POST/v1/transcribe),wave_caption(POST/v1/captions).VoiceResultreturns real audio bytes;toJSON()emits a small receipt. Usage/rate-limit headers surfaced viareadUsage.DispatchToolkit(own host):wave_route(POST/),wave_list_routing_profiles(GET/profiles). Defaults tohttps://dispatch.wave.online.PaymentsToolkit(public, no key):wave_find_paid_services(GET/v1/mpp/services),wave_payment_schemes(GET/v1/{x402,mpp}/facilitator/supported). Sends noAuthorizationheader by design.WaveToolErroron non-2xx (status/body preserved,isRateLimitedfor 429).Refactors
src/tools/shared.ts:AgentTool, MCP mapper (toMCPToolDefs),WaveToolError,readUsage,validated.AgentToolkitre-exports types; MCP tool defs are identical across toolkits.@wave-av/adk: new toolkits, types, and helpers..wave/repo.jsonto cover 17 tools and audio handling.Written for commit f31bbad. Summary will update on new commits.