Skip to content

fix: document watchOrderBook limit and params#406

Open
iccccccccccccc wants to merge 1 commit into
pmxt-dev:mainfrom
iccccccccccccc:fix-watch-order-book-limit-docs
Open

fix: document watchOrderBook limit and params#406
iccccccccccccc wants to merge 1 commit into
pmxt-dev:mainfrom
iccccccccccccc:fix-watch-order-book-limit-docs

Conversation

@iccccccccccccc
Copy link
Copy Markdown

Fixes #163

Summary

  • add params = {} support to the core watchOrderBook / watchOrderBooks signatures and method metadata
  • update venue overrides and TypeScript/Python SDK wrappers so callers can pass the CCXT-style third argument without it being dropped by the client surface
  • document limit and params in the public watch order book docs, SDK API refs, and llms-full.txt
  • add an API consistency regression test covering the core signature, method metadata, SDK wrappers, and docs export

Bug verification

  • Temporarily reverted the implementation/docs changes with the new test present; it failed on the missing params core signature and missing limit documentation.

Validation

  • npm --workspace=pmxt-core test -- --runTestsByPath test/pipeline/watch-order-book-api.test.ts
  • npx tsc -p core/tsconfig.json --noEmit
  • python -m py_compile sdks/python/pmxt/client.py

Notes

  • npm --workspace=pmxt-core run build does not run on this Windows checkout because the existing clean script calls rm -rf dist.
  • Full npm --workspace=pmxt-core test -- --runInBand has one unrelated existing failure in test/normalizers/exchange-normalizers-2.test.ts: expected year 2025, received 2026 for a Myriad resolutionDate assertion.

Copy link
Copy Markdown
Contributor

@realfishsam realfishsam left a comment

Choose a reason for hiding this comment

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

PR Review: PASS (NOT VERIFIED)

What This Does

Adds a CCXT-compatible third argument (params: Record<string, any>) to watchOrderBook and watchOrderBooks across the base class, all 9 exchange overrides, both SDK wrappers, server method metadata, and public docs. Before this PR, callers could not express exchange-specific WebSocket parameters through the public interface; the signatures only exposed (outcomeId, limit?). This makes the interface consistent with how CCXT signatures are shaped.

Blast Radius

  • core/src/BaseExchange.ts — base class signatures for watchOrderBook + watchOrderBooks; watchOrderBooks default implementation now forwards params to each individual watchOrderBook call
  • 9 exchange overrides — baozi, gemini-titan, kalshi, limitless, myriad, opinion, polymarket, polymarket_us, probable (all updated for signature consistency; all accept but do not use _params)
  • core/src/server/method-verbs.json — server GET-dispatch arg spec; params now registered so GET calls can include it
  • core/api-doc-config.generated.json — JSDoc-derived doc config
  • Both SDK wrapperssdks/typescript/pmxt/client.ts, sdks/python/pmxt/client.py
  • Docswatch-order-book.mdx, watch-order-books.mdx, websocket.mdx, llms-full.txt, sdks/python/API_REFERENCE.md, sdks/typescript/API_REFERENCE.md

Consumer Verification

Before (main branch):
BaseExchange.ts:1253 declared watchOrderBook(outcomeId: string, limit?: number) — no params. TypeScript SDK client.ts:1465 likewise had (outcomeId, limit?). Python SDK had watch_order_book(outcome_id, limit=None, **_compat_kwargs) — only reachable via **kwargs, not a typed parameter. Consumer calling watchOrderBook("id", 10, { foo: "bar" }) in TypeScript would get a compile error; in Python, params would silently route into _compat_kwargs and not reach the args array sent to the sidecar.

After (PR branch):
BaseExchange.ts:1251 declares watchOrderBook(outcomeId: string, limit?: number, params: Record<string, any> = {}). Both SDK wrappers expose the parameter explicitly. Consumer code compiles cleanly:

await exchange.watchOrderBook("OUTCOME_ID", 50, { someVenueParam: true });

TypeScript compile check: clean (npx tsc --noEmit). Python syntax check: clean (python3 -m py_compile).

Live WebSocket end-to-end verification was not possible in this environment — watchOrderBook requires an open WebSocket connection to the exchange, and outbound exchange network connections are not available here. Static analysis and unit tests were used instead.

Test Results

  • Build (npm run build --workspace=pmxt-core): PASS
  • New test (test/pipeline/watch-order-book-api.test.ts): PASS (2/2)
  • Full suite (npm test -- --runInBand): PASS (507/507) — the Myriad resolutionDate year failure noted in the PR description did not reproduce; it appears to be a date-sensitive flap that has since self-resolved
  • Server starts: PASS
  • E2E smoke (authenticated call to sidecar): confirmed auth middleware reached; exchange network calls timed out as expected in this environment

Findings

  1. docs/llms-full.txt is inconsistent for watchOrderBooks (docs/llms-full.txt:4234). The file was hand-edited to add the limit and params rows for the singular watchOrderBook section but not for the watchOrderBooks (plural) section, even though watch-order-books.mdx was correctly updated with both rows. Since llms-full.txt is generated by scripts/generate-llms.js from the .mdx sources, running npm run docs:llms would fix this. The publish workflow does run npm run docs:llms, so the inconsistency is self-healing at publish time — but the committed state of llms-full.txt is currently inconsistent. The new regression test only checks watch-order-book.mdx and llms-full.txt for the singular case; it does not catch this gap.

  2. Three generated files are hand-edited. core/api-doc-config.generated.json carries an explicit "Do not edit manually" header (generated by extract-jsdoc.js). core/src/server/method-verbs.json is produced by generate-openapi.js from the BaseExchange.ts AST (noted in app.ts:13). docs/llms-full.txt is produced by generate-llms.js. The PR author explains the build could not run on a Windows checkout due to rm -rf dist in the clean script. The hand-edits for api-doc-config.generated.json and method-verbs.json are correct — they match what the respective generators would produce from the updated BaseExchange.ts (the generator reads params: Record<string, any> = {}kind: 'object', optional: true). The publish workflow regenerates all three, so they self-heal. No blocking issue, but the process deviation is worth noting.

  3. params is accepted by every venue but forwarded to none. All 9 exchange overrides name the argument _params (intentionally unused). This is appropriate for a CCXT-compatibility stub, but it means any caller who passes venue-specific params will receive no error and no effect — silent no-op. This is not documented in the public-facing parameter description ("Optional exchange-specific parameters" does not indicate it is currently a no-op on all venues). Not a blocking issue, but a transparency gap worth a doc note on the page.

  4. null arrives as limit when params is passed without limit. Both SDKs insert undefined/None as a positional placeholder (e.g. args = [id, undefined, params] in TypeScript) to preserve the positional ordering before JSON-serializing to the sidecar. JSON.stringify([undefined])"[null]", so the server receives limit = null rather than limit = undefined. Since no currently active exchange implementation uses the limit value in its WebSocket subscription logic (Kalshi index.ts:354 calls this.ws.watchOrderBook(marketTicker) ignoring it; others are similar), there is no practical impact. Minor semantic inaccuracy only.

  5. Incidental pre-existing bug fixed in sdks/typescript/API_REFERENCE.md. The example previously showed watchOrderBook("12345", { limit: 10 }) — passing an object literal as the limit (number) parameter. Now corrected to watchOrderBook("12345", 10). Good catch.

PMXT Pipeline Check

  • Field propagation (3-layer): N/A — this is a WebSocket method; no OpenAPI field propagation path
  • OpenAPI sync: N/AwatchOrderBook is a WS method and does not appear in openapi.yaml; method-verbs.json (the relevant server config) is updated
  • Financial precision: N/A — no price/amount arithmetic
  • Type safety: OKRecord<string, any> is intentional here (CCXT convention); _params on all overrides prevents accidental use; no new ! assertions; TS compiles cleanly
  • Auth safety: OK — no credential handling touched

Semver Impact

minor — new optional parameters with defaults added to existing public methods; no existing call site breaks.

Risk

params is a stub with no current implementation on any venue. If a future PR implements actual venue-specific param routing, callers who already pass params objects will get previously-silent values forwarded to exchange WebSockets. That is the intended design, but it is worth flagging for whoever implements venue-side support: test existing callers that may inadvertently be passing params today.

The llms-full.txt inconsistency (Finding 1) is the only committed artifact that is factually wrong right now; it is resolved automatically at publish time but is observable between merge and tag.


Generated by Claude Code

Sign up for free to 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.

watchOrderBook docs omit limit parameter that the code accepts

3 participants