[PR #168] [MERGED] docs(models): re-align the dropped-params comments with the synced Router spec #169

Closed
opened 2026-10-31 22:05:16 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/comfy-typescript-sdk/pull/168
Author: @mattmillerai
Created: 9/21/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @mattmillerai

Base: main ← Head: matt/be-16281-router-dropped-params-docs


📝 Commits (5)

  • 90c6669 docs(models): re-align the dropped-params comments with the synced Router spec
  • d559e05 docs(models): scope the droppedParams null guarantee to what the spec promises
  • dd5e3d2 Merge remote-tracking branch 'origin/main' into matt/be-16281-router-dropped-params-docs
  • d3a2dc8 Merge remote-tracking branch 'origin/main' into matt/be-16281-router-dropped-params-docs
  • 025849b docs(models): ground the queued route's no-disclosure note in its declared contract

📊 Changes

4 files changed (+59 additions, -27 deletions)

View changed files

📝 CHANGELOG.md (+10 -0)
📝 src/sdk/modelRequests.ts (+5 -4)
📝 src/sdk/models.test.ts (+4 -5)
📝 src/sdk/models.ts (+40 -18)

📄 Description

ELI-5

A response header tells you which of your settings the Router had to drop when it translated your request for a different provider. Three comments in the code still described an older version of the contract: they said the spec's own declaration of that header was a bug that someone had filed against the server, and they said the header only ever shows up when you explicitly ask for another provider. The spec sync in #166 settled both points the other way — the header really is one JSON-encoded string on purpose, and an automatic retry can produce it too, even on a call that asked for nothing special. This rewrites those three comments to say what is now true. No code changes.

What changed

Comments only. git diff touches src/sdk/models.ts, src/sdk/models.test.ts and CHANGELOG.md; every changed line in the two source files is inside a comment (verified mechanically — filtering the diff's +/- lines for anything that is not //, *, /** or */ returns nothing).

  • parseDroppedParams TSDoc. Deleted the claim that the spec's prose and its declared schema disagree, that the declared schema is the wrong half, and that a spec defect is filed against the server's openapi.yml and would be reverted by the next sync. spec/router-openapi.yaml's RouterDroppedParamsHeader now declares type: string and its description says, in its own words, to "decode it with a JSON parser rather than splitting it on commas, because it is a single string on the wire… and each entry is a sentence carrying commas of its own". The comment now says that, keeps the example entry (moderation (fal applies its own, non-configurable safety filtering)) as the reason, and keeps the existing fallback rationale verbatim in spirit: keep a non-JSON value as ONE entry rather than guessing at delimiters, because a single entry a human can read beats two confident fragments.
  • RunJsonResult.droppedParams TSDoc. It named modelProvider as the only producer. The synced spec names two, both under the default strict_mode=false: an explicit model_provider translation and an automatic fallback_provider retry — which is on by default and independent of model_provider — so a call that never set modelProvider can still come back with a non-null value. The comment now says so, adds that a fallback retry's list describes THAT retry's translation rather than the primary attempt's, points at servingProvider for which provider it refers to, and spells out the null cases.
  • RunJsonResult.droppedParams TSDoc, review round 2 (d559e05). Three cursor-review findings on that same block, all settled by the vendored spec. (a) strictMode: true was listed unqualified as a null case; StrictMode at spec/router-openapi.yaml:888-895 says it is "only meaningful together with model_provider", and RouterDroppedParamsHeader names the automatic fallback_provider retry as an independent producer, so strictMode: true suppresses the modelProvider translation only and is not on its own a guarantee of null — the comment now says that and points at fallbackProvider for the case that is. (b) "each entry names the field and why" was unconditional, but parseDroppedParams keeps a header that is not a JSON array of strings as ONE entry holding the raw wire value, so that is now the normal case rather than a guarantee. (c) null for "translation ran and dropped nothing" holds only because the server omits the header there — a present-but-empty "[]" parses to an empty array, as models.test.ts:1746 and :1753 already assert — so callers are told to check !== null rather than truthiness. Still comments only.
  • First parseDroppedParams test comment. Rewritten to the same framing. The it(...) title and every expect are unchanged.
  • CHANGELOG. One ### Fixed bullet under [Unreleased]. The repo does log doc-comment changes (0.1.5 "TSDoc for the public API members that had none", 0.1.4 "…and doc comments updated to the new host") and src/ ships in the published package, so these comments are user-visible on hover.

RunBinaryResult.droppedParams already reads "As {@link RunJsonResult.droppedParams}" and is untouched, as is the DROPPED_PARAMS_HEADER constant's one-line comment, parseDroppedParams's body, every test assertion, and spec/.

Verification against what the spec actually says

The primary artifact here is the vendored spec as of #166 (commit 4491e4b; main has since moved past it without touching spec/router-openapi.yaml), and I read it directly rather than from the ticket's summary: spec/router-openapi.yaml:927-932 declares RouterDroppedParamsHeader with schema: {type: string}, example: '["moderation (fal applies its own, non-configurable safety filtering)"]', and a description that covers both producers ("whether the caller asked for that translation with model_provider (strict_mode=false, the default) or an automatic fallback_provider retry ran it") and the fallback-retry attribution ("On a fallback retry it names what that retry's own translation… dropped, never the primary attempt's"). Every substantive claim in the new comments is traceable to that block or to RouterFallbackProviderHeader at :938-943.

Negative-claim falsification (the capability-denial trigger) does not fire on this diff: it adds no "not supported"/"unavailable" string, no throw or deny path, and flips no test to assert a dead-end. The change is strictly the opposite direction — it documents a case (droppedParams non-null with no modelProvider) the old comment wrongly ruled out.

Provenance

  • Authored by: agent-work loop
  • Verified:
    • Head d3a2dc8 (merge of main at 8096086, no conflicts; the earlier CHANGELOG.md ### Fixed conflict was resolved by keeping both bullets).
    • pnpm test: 691 passed, 5 skipped, 0 failed (28 files passed, 1 skipped).
    • pnpm lint, pnpm format:check, pnpm typecheck and pnpm build: clean.
    • pnpm check:spec-drift: generated code is in sync, and the Router route matches the spec.
    • node scripts/sync-python-surface.mjs reports parity/python-surface.json is stale relative to Comfy-Org/comfy-python-sdk@refs/heads/main. main fails the same way (CI run 37967760042 at 8096086), so the problem is in the base, not this branch. The open fix is #201, and the check is not required.
  • Deviations: none against the original plan. d559e05 was added on top in response to review feedback. It gets no CHANGELOG bullet of its own, because the existing [Unreleased] bullet already covers the comment it refines.

Residual

Not fixed here, and worth its own look:

  • src/sdk/modelRequests.ts:893-899 carries a related claim that this sync may have weakened. The comment above the queued-collect result says the two alt-provider disclosure headers "are expected to be absent on this route — the queued /requests path takes no model_provider parameter, so a queued run cannot address an alternate provider and has nothing to disclose". Post-#166 the second producer of those headers is an automatic fallback_provider retry that is independent of model_provider, so "takes no model_provider" no longer establishes "has nothing to disclose" on its own. I did not change it: the four MODEL_REQUEST* operations are not declared in spec/router-openapi.yaml at all (held upstream, and the one-way sync strips a held operation — see AGENTS.md section 2), so there is nothing in the vendored contract that says whether fallback applies to the queued route, and guessing in a comment is how this ticket's defect got written in the first place. The code is unaffected either way — it reads the headers unconditionally and returns whatever is there. Resolving it needs a statement from the Router side about queued-route fallback.
  • Unexercised artifact: the producer. The ticket cites router_run.go's writeRouterResult in the cloud repo as the side that json.Marshals the list. That repo is not in this sandbox and is outside this PR's repo, so I could not read it. I substituted the vendored spec, which is the contract this SDK is actually checked against, and the parser's behavior is unchanged regardless — nothing in this diff depends on the Go source being what the ticket says it is.
  • Unexercised artifact: the originating investigation. The comment thread that motivated this arrived as a summary; I could not open the underlying investigation to check for anything it recorded and the summary omitted. No part of this diff rests on it — every claim is re-derived from the vendored spec in this repo.
  • Rebase note. #157 (X-Comfy-Credits-Used) has landed and is merged in here; src/sdk/models.ts auto-merged. #164 (replayed) and #152 (Idempotency-Key on errors) are still open, and each adds an adjacent RunJsonResult field rather than touching these comment blocks.
  • The red sdk-parity check is pre-existing and does not come from this branch. Earlier it failed with an ExtractionError on RouterRunResult. That was fixed by #167, which is merged in here. It now fails because the Python surface snapshot is stale, and main fails identically (run 37967760042 at 8096086). This is the case AGENTS.md section 6 describes as "usually not about your branch", and #201 is the open snapshot refresh.

Summary by CodeRabbit

  • Documentation
    • Clarified that dropped-parameter details are provided as a JSON-encoded array in a single response header, and how values are handled when the header does not match that format.
    • Explained that dropped parameters can result from explicit provider translation or automatic fallback retries. For fallback results, the field reflects the retry’s translation and may be null or an empty array depending on whether any parameters were dropped.
    • Updated descriptions of queued routes to clarify which provider options they omit. Parsing and header handling are unchanged.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Comfy-Org/comfy-typescript-sdk/pull/168 **Author:** [@mattmillerai](https://github.com/mattmillerai) **Created:** 9/21/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@mattmillerai](https://github.com/mattmillerai) **Base:** `main` ← **Head:** `matt/be-16281-router-dropped-params-docs` --- ### 📝 Commits (5) - [`90c6669`](https://github.com/Comfy-Org/comfy-typescript-sdk/commit/90c6669244e8484b1d3e9d75ae7c9677e67efb32) docs(models): re-align the dropped-params comments with the synced Router spec - [`d559e05`](https://github.com/Comfy-Org/comfy-typescript-sdk/commit/d559e05d528c23088f3e9442a9620e923a41ac9e) docs(models): scope the droppedParams null guarantee to what the spec promises - [`dd5e3d2`](https://github.com/Comfy-Org/comfy-typescript-sdk/commit/dd5e3d2493cb078d6d4130019c30496075c33cc6) Merge remote-tracking branch 'origin/main' into matt/be-16281-router-dropped-params-docs - [`d3a2dc8`](https://github.com/Comfy-Org/comfy-typescript-sdk/commit/d3a2dc881f7b6904aff292d08466cc1b38a0f58f) Merge remote-tracking branch 'origin/main' into matt/be-16281-router-dropped-params-docs - [`025849b`](https://github.com/Comfy-Org/comfy-typescript-sdk/commit/025849bce249d898342580c33a3d1840c2978947) docs(models): ground the queued route's no-disclosure note in its declared contract ### 📊 Changes **4 files changed** (+59 additions, -27 deletions) <details> <summary>View changed files</summary> 📝 `CHANGELOG.md` (+10 -0) 📝 `src/sdk/modelRequests.ts` (+5 -4) 📝 `src/sdk/models.test.ts` (+4 -5) 📝 `src/sdk/models.ts` (+40 -18) </details> ### 📄 Description ## ELI-5 A response header tells you which of your settings the Router had to drop when it translated your request for a different provider. Three comments in the code still described an older version of the contract: they said the spec's own declaration of that header was a bug that someone had filed against the server, and they said the header only ever shows up when you explicitly ask for another provider. The spec sync in #166 settled both points the other way — the header really is one JSON-encoded string on purpose, and an automatic retry can produce it too, even on a call that asked for nothing special. This rewrites those three comments to say what is now true. No code changes. ## What changed Comments only. `git diff` touches `src/sdk/models.ts`, `src/sdk/models.test.ts` and `CHANGELOG.md`; every changed line in the two source files is inside a comment (verified mechanically — filtering the diff's `+`/`-` lines for anything that is not `//`, `*`, `/**` or `*/` returns nothing). - **`parseDroppedParams` TSDoc.** Deleted the claim that the spec's prose and its declared schema disagree, that the declared schema is the wrong half, and that a spec defect is filed against the server's `openapi.yml` and would be reverted by the next sync. `spec/router-openapi.yaml`'s `RouterDroppedParamsHeader` now declares `type: string` and its description says, in its own words, to "decode it with a JSON parser rather than splitting it on commas, because it is a single string on the wire… and each entry is a sentence carrying commas of its own". The comment now says that, keeps the example entry (`moderation (fal applies its own, non-configurable safety filtering)`) as the reason, and keeps the existing fallback rationale verbatim in spirit: keep a non-JSON value as ONE entry rather than guessing at delimiters, because a single entry a human can read beats two confident fragments. - **`RunJsonResult.droppedParams` TSDoc.** It named `modelProvider` as the only producer. The synced spec names two, both under the default `strict_mode=false`: an explicit `model_provider` translation **and** an automatic `fallback_provider` retry — which is on by default and independent of `model_provider` — so a call that never set `modelProvider` can still come back with a non-null value. The comment now says so, adds that a fallback retry's list describes THAT retry's translation rather than the primary attempt's, points at `servingProvider` for which provider it refers to, and spells out the `null` cases. - **`RunJsonResult.droppedParams` TSDoc, review round 2 (`d559e05`).** Three cursor-review findings on that same block, all settled by the vendored spec. (a) `strictMode: true` was listed unqualified as a `null` case; `StrictMode` at `spec/router-openapi.yaml:888-895` says it is "only meaningful together with `model_provider`", and `RouterDroppedParamsHeader` names the automatic `fallback_provider` retry as an independent producer, so `strictMode: true` suppresses the `modelProvider` translation only and is not on its own a guarantee of `null` — the comment now says that and points at `fallbackProvider` for the case that is. (b) "each entry names the field and why" was unconditional, but `parseDroppedParams` keeps a header that is not a JSON array of strings as ONE entry holding the raw wire value, so that is now the normal case rather than a guarantee. (c) `null` for "translation ran and dropped nothing" holds only because the server omits the header there — a present-but-empty `"[]"` parses to an empty array, as `models.test.ts:1746` and `:1753` already assert — so callers are told to check `!== null` rather than truthiness. Still comments only. - **First `parseDroppedParams` test comment.** Rewritten to the same framing. The `it(...)` title and every `expect` are unchanged. - **CHANGELOG.** One `### Fixed` bullet under `[Unreleased]`. The repo does log doc-comment changes (`0.1.5` "TSDoc for the public API members that had none", `0.1.4` "…and doc comments updated to the new host") and `src/` ships in the published package, so these comments are user-visible on hover. `RunBinaryResult.droppedParams` already reads "As {@link RunJsonResult.droppedParams}" and is untouched, as is the `DROPPED_PARAMS_HEADER` constant's one-line comment, `parseDroppedParams`'s body, every test assertion, and `spec/`. ## Verification against what the spec actually says The primary artifact here is the vendored spec as of #166 (commit 4491e4b; `main` has since moved past it without touching `spec/router-openapi.yaml`), and I read it directly rather than from the ticket's summary: `spec/router-openapi.yaml:927-932` declares `RouterDroppedParamsHeader` with `schema: {type: string}`, `example: '["moderation (fal applies its own, non-configurable safety filtering)"]'`, and a description that covers both producers ("whether the caller asked for that translation with `model_provider` (`strict_mode=false`, the default) or an automatic `fallback_provider` retry ran it") and the fallback-retry attribution ("On a fallback retry it names what that retry's own translation… dropped, never the primary attempt's"). Every substantive claim in the new comments is traceable to that block or to `RouterFallbackProviderHeader` at `:938-943`. Negative-claim falsification (the capability-denial trigger) does not fire on this diff: it adds no "not supported"/"unavailable" string, no throw or deny path, and flips no test to assert a dead-end. The change is strictly the opposite direction — it documents a case (`droppedParams` non-null with no `modelProvider`) the old comment wrongly ruled out. ## Provenance - **Authored by:** agent-work loop - **Verified:** - Head `d3a2dc8` (merge of `main` at `8096086`, no conflicts; the earlier `CHANGELOG.md` `### Fixed` conflict was resolved by keeping both bullets). - `pnpm test`: 691 passed, 5 skipped, 0 failed (28 files passed, 1 skipped). - `pnpm lint`, `pnpm format:check`, `pnpm typecheck` and `pnpm build`: clean. - `pnpm check:spec-drift`: generated code is in sync, and the Router route matches the spec. - `node scripts/sync-python-surface.mjs` reports `parity/python-surface.json is stale relative to Comfy-Org/comfy-python-sdk@refs/heads/main`. `main` fails the same way (CI run 37967760042 at `8096086`), so the problem is in the base, not this branch. The open fix is #201, and the check is not required. - **Deviations:** none against the original plan. `d559e05` was added on top in response to review feedback. It gets no CHANGELOG bullet of its own, because the existing `[Unreleased]` bullet already covers the comment it refines. ## Residual Not fixed here, and worth its own look: - **`src/sdk/modelRequests.ts:893-899` carries a related claim that this sync may have weakened.** The comment above the queued-collect result says the two alt-provider disclosure headers "are expected to be absent on this route — the queued `/requests` path takes no `model_provider` parameter, so a queued run cannot address an alternate provider and has nothing to disclose". Post-#166 the second producer of those headers is an automatic `fallback_provider` retry that is independent of `model_provider`, so "takes no `model_provider`" no longer establishes "has nothing to disclose" on its own. I did not change it: the four `MODEL_REQUEST*` operations are not declared in `spec/router-openapi.yaml` at all (held upstream, and the one-way sync strips a held operation — see `AGENTS.md` section 2), so there is nothing in the vendored contract that says whether fallback applies to the queued route, and guessing in a comment is how this ticket's defect got written in the first place. The code is unaffected either way — it reads the headers unconditionally and returns whatever is there. Resolving it needs a statement from the Router side about queued-route fallback. - **Unexercised artifact: the producer.** The ticket cites `router_run.go`'s `writeRouterResult` in the `cloud` repo as the side that `json.Marshal`s the list. That repo is not in this sandbox and is outside this PR's repo, so I could not read it. I substituted the vendored spec, which is the contract this SDK is actually checked against, and the parser's behavior is unchanged regardless — nothing in this diff depends on the Go source being what the ticket says it is. - **Unexercised artifact: the originating investigation.** The comment thread that motivated this arrived as a summary; I could not open the underlying investigation to check for anything it recorded and the summary omitted. No part of this diff rests on it — every claim is re-derived from the vendored spec in this repo. - **Rebase note.** #157 (`X-Comfy-Credits-Used`) has landed and is merged in here; `src/sdk/models.ts` auto-merged. #164 (`replayed`) and #152 (`Idempotency-Key` on errors) are still open, and each adds an adjacent `RunJsonResult` field rather than touching these comment blocks. - **The red `sdk-parity` check is pre-existing and does not come from this branch.** Earlier it failed with an `ExtractionError` on `RouterRunResult`. That was fixed by #167, which is merged in here. It now fails because the Python surface snapshot is stale, and `main` fails identically (run 37967760042 at `8096086`). This is the case `AGENTS.md` section 6 describes as "usually not about your branch", and #201 is the open snapshot refresh. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified that dropped-parameter details are provided as a JSON-encoded array in a single response header, and how values are handled when the header does not match that format. * Explained that dropped parameters can result from explicit provider translation or automatic fallback retries. For fallback results, the field reflects the retry’s translation and may be `null` or an empty array depending on whether any parameters were dropped. * Updated descriptions of queued routes to clarify which provider options they omit. Parsing and header handling are unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 22:05:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/comfy-typescript-sdk#169
No description provided.