Repository navigation
docs(sdk): generated platform SDK reference and its sync - #1106
Tanmaycode1 wants to merge 11 commits into
Conversation
Add the Platform SDK Reference group to the SDK tab: 34 pages generated by future-agi/futureagi-sdk from its API contract (an overview, one page per resource with examples, signatures, parameters and returns, and a models table per area). The pages are never edited here. scripts/sync-sdk-reference.mjs copies the pages and the sidebar group from an SDK checkout and checks nav/page parity; .github/workflows/sdk-reference-sync.yml runs it weekly, on an SDK release dispatch or by hand, and opens a PR against main. audit-links.mjs now audits the generated group too. The ParamField styles move to a shared stylesheet so ResponseField renders styled on its own.
…kages are installable Close the chain backend contract -> SDK -> docs on the receiving side. The sync workflow now takes `sdk-release` dispatches from the SDK's release-please (stage: candidate, the version PR's head) and publish (stage: released, the published commit) workflows, a weekly schedule that syncs the newest published release, and a manual run for any ref as a labelled preview draft. scripts/sdk-reference-release.mjs decides the branch and the publish state: one branch per Python/TypeScript version pair, so a retry or the candidate->released transition rewrites the same PR instead of failing on an existing branch; a no-op diff opens nothing and closes a PR main already carries. A released claim is downgraded to a draft unless futureagi==X is on PyPI and @future-agi/sdk@Y is on npm, checked here, so the docs never describe an SDK users cannot install. The default is the newest published release, not the SDK's dev branch. node --test covers the decision; actionlint passes on the workflow.
nik13
left a comment
There was a problem hiding this comment.
Request changes — reference correctness and mobile readability
I checked the updated head 30cd2eb, including the release-aware resolver and same-version-pair PR updates. These are improvements: the original dev-default and unconditional branch-creation retry problems are no longer the behavior shown by this head, so I am not filing those stale findings. SDK #42 now also contains candidate/released event senders.
Two areas still need correction before publishing these pages:
- The copied SDK reference contains instructions that fail for an installed-package consumer. The area-model pages advertise an unsupported TypeScript
strictResponsesoption; the dashboard query example passes a string where the SDK requires an object; and the Errors overview points to the wrong import surface. Fix these in SDK #42's generator and resync—do not manually edit the generated copies here. The detailed root-cause findings are on SDK #42. - The new reference tables overflow phone-width pages. At a 390 px viewport, document widths were 402 px for prompts, 425 px for prompt models, and 536 px for annotation queues. Long method/model identifiers impose a table minimum width and the tables have visible overflow, rather than a bounded horizontal scroller. Keep all content reachable without horizontal page scroll.
What was actually tested
Cloud-only build and Chromium runs on docs ab903e0 paired with SDK d4631b0, followed by source comparison to the updated heads: the affected generator, examples/import behavior, reference pages, styles and components are unchanged, so these findings still apply. I have not represented the new resolver as end-to-end runtime-tested.
- SDK generation check and 37 generator tests passed.
- Docs link audit and 27 integration/scaffolding tests passed.
- Sync from the paired SDK checkout produced zero diff.
- Production build passed with Node 20.19.5. The initial Node 18.19.1 image was below Astro's minimum; that setup failure was corrected and is not attributed to the PR.
- All 34 generated routes returned 200; local method/model anchors and a cross-page model link resolved. Overview-to-resource navigation and Python/TypeScript code tabs worked. The long annotation-queues page rendered 23 method headings. No uncaught application JavaScript errors were observed.
- Phone-width layout failed as described; screenshots and DOM measurements were inspected.
- Clean-installed SDK consumer compilation reproduced five diagnostics across the documentation defects. A synthetic HTTP 429 demonstrated that the documented package-root RateLimitError fails an instanceof check, while the platform-subpath class matches.
Please regenerate/resync the corrected content and add reference-page consumer/mobile regressions. The existing build/browser CI mainly exercises the integrations directory, so it is green despite these new reference-page issues.
Release-chain status
The updated receiver now has registry checks, draft previews, exact dispatch SHAs, concurrency and existing-PR handling. The controlled backend → SDK generation example is useful. I separately verified backend run 41792555779 executed 93 Python SDK checks and 11 TypeScript SDK tests, with no warning-only skip. The SDK → docs event receiver still needs its real default-branch validation after merge; a resolver-only check is not that end-to-end result.
No live docs were changed and no package publication was performed in this review. The isolated preview VM and disk were deleted after collecting evidence.
| description: "The 6 response models returned by the prompts resources of the Future AGI Python and TypeScript SDKs, with every field and its type." | ||
| --- | ||
|
|
||
| The models returned by `client.prompts`, importable from `fi.platform.models` (Python) and `@future-agi/sdk/platform/models` (TypeScript). Types are language-neutral: `string[]` is a Python `list[str]` and a TypeScript `string[]`, and a type named after another model links to that model. Parsing is tolerant by default: a response that leaves a field out or adds one never breaks a call, and `strict_responses=True` (Python) or `strictResponses: true` (TypeScript) rejects a response that misses a field the contract requires (see the [overview](/docs/sdk/reference#strict-mode)). |
There was a problem hiding this comment.
[P2] Resync corrected SDK usage before publishing the generated reference
The generator currently emits strictResponses: true as a TypeScript validation option, but the installed SDK has no such ClientConfig property or runtime path. A clean-package consumer fails with TS2353. This same claim is repeated on all eight area-model pages.
Two other copied generator defects are verified: the dashboard query example uses a string for the object-valued time_range (TS2322), and the Errors overview points to @future-agi/sdk instead of @future-agi/sdk/platform. The root's legacy RateLimitError does not match the platform error thrown for a real HTTP 429.
These files should remain generated: fix sdkgen/generator/docs.py in SDK #42, regenerate, then rerun this sync. Please gate the docs examples against the installed SDK rather than treating a successful MDX build as usage validation.
|
|
||
| ## Methods | ||
|
|
||
| | Method | Description | |
There was a problem hiding this comment.
[P2] Contain the new reference tables at phone width
Cloud Chromium on the production build at 390 px viewport width reports a 536 px document width for this page. The method index table itself extends from x=16 to approximately x=536; its long identifiers keep the first column wide, leaving the description column off-screen. Prompts and prompt-models also overflow (402 px and 425 px document widths).
Wrap these generated reference tables in a bounded overflow-x:auto container, or provide safe wrapping/layout for identifiers and fields. Do not hide the overflow and cut off the descriptions. Add phone-width browser coverage for the reference pages; the current integration-directory browser tests don't exercise this surface. The source table/styles are unchanged between the tested ab903e0 and reviewed 30cd2eb heads.
…point paths at phone width Review findings on #1106 (nik13). The pages are resynced from futureagi-sdk 3269d58, where the generator was fixed: ref-aware example values (dashboards query shows an object for time_range), error imports from @future-agi/sdk/platform, no TypeScript strictResponses claim. Nothing was edited by hand here. Phone width: every generated table now sits in <div class="sdk-ref-table">, styled in global.css as a bounded horizontal scroller (max-width 100%, overflow-x auto), so a long identifier scrolls inside the table instead of widening the page; h3/h4 may break inside a single long identifier; and the ApiEndpoint badge lets a long path wrap (min-w-0, overflow-wrap: anywhere), which was the other source of document overflow. Nothing is clipped. scripts/sdk-reference-mobile.cjs (part of test:integrations:browser, so it runs in pr-checks after the preview starts) loads every page of the reference group at a 390 px viewport and fails if the document scrolls horizontally, if a table is outside .sdk-ref-table, or if any heading, cell or code block starts left of the viewport. Locally: 34 pages fit 390 px (annotation-queues was 536 px, prompts 402 px, prompt models 425 px before).
Review fixes (
|
c0040c9 to
c887cc9
Compare
nik13
left a comment
There was a problem hiding this comment.
The original generated-content and mobile-overflow findings are fixed. I verified the generator corrections on SDK 3269d58, the 164-example installed-package TypeScript gate and real HTTP 429 check in cloud CI, and independently rebuilt docs c887cc9 in a disposable cloud VM. All 34 routes/anchors, code-tab navigation, model links, and the former phone-width failures passed; screenshots were inspected. SDK #42 is now approved.
One remaining state-transition issue in the newer docs-sync workflow needs correction before I approve this automation: a candidate retry after the same-version docs PR has become ready does not put it back into draft (or reject the stale candidate event). The resolver says draft, but the existing-PR update changes only its title/body. The workflow can therefore report a draft candidate while the actual PR remains ready for merge.
I reproduced this with the exact workflow shell, real git branches, and a synthetic PR-state adapter in the cloud: input existing PR isDraft=false + STAGE=candidate/PUBLISH=draft; workflow exits 0 and prints '(candidate, draft)', but the resulting isDraft remains false. This is an offline lifecycle reproduction, not a claim of dispatching into the real docs repository.
Please make stage handling safe for reordered/retried events: either retain a newer released revision and ignore stale candidate updates, or explicitly convert an existing PR to draft before updating it with unverified candidate content. Add ready→candidate→released and repeated-event tests that assert the PR state, not only the resolver's decision string. Do not silently ignore a failed state change. Existing human review and docs CI remain required.
| else | ||
| gh pr edit "$number" --title "$title" --body-file "$RUNNER_TEMP/body.md" >/dev/null | ||
| fi | ||
| if [ "$PUBLISH" = ready ]; then |
There was a problem hiding this comment.
[P2] Keep the actual PR state consistent when a candidate event follows a released event
This branch promotes draft→ready, but there is no corresponding behavior for an existing ready PR when PUBLISH=draft. The else above only edits title/body, and the branch was already force-updated with the candidate content.
A retry or reordered candidate dispatch for the same version pair can therefore leave isDraft=false while this workflow prints future-agi/docs#… (candidate, draft). In a cloud fixture executing this exact shell with real git and a local PR-state adapter, an initially ready PR remained ready after the candidate update; no downgrade command was issued.
Either reject stale candidate events once a newer released revision is recorded, or convert the existing PR to draft before changing its branch content. Apply the matching state for every update and surface failures rather than swallowing them. Test ready→candidate→released transitions in addition to deciding the branch name/readiness string.
…s safely Review finding on #1106 (nik13): a candidate event arriving after the same version-pair PR was already marked ready rewrote the branch and the body and printed "(candidate, draft)" while the PR stayed ready for merge. The PR step moves into scripts/sdk-reference-pr.sh with explicit state rules: - An existing PR that is already ready belongs to a released revision the registries confirmed; a later candidate (or any draft decision) is a stale or reordered event and is ignored outright: no push, no title/body edit, no state change, a ::notice:: saying so, exit 0. - A ready decision promotes a draft with `gh pr ready`, and a failed promotion fails the run. The final state is read back from GitHub after every run and must match the decision, or the run fails; the printed state is the real one. - A no-op diff opens nothing and closes an open PR for the release; a preview is its own draft on its own branch. scripts/sdk-reference-pr.test.mjs runs the real script against a fake `gh` (a PR-state adapter on a JSON file) and a fake `git`, asserting PR state after candidate -> released -> stale candidate -> repeated released, the failed promotion, the no-diff close, the preview branch, and a missing variable. Part of npm run test:integrations (39 tests).
State-transition fix (
|
…erence # Conflicts: # package.json
…erence # Conflicts: # package.json
nik13
left a comment
There was a problem hiding this comment.
The original ready → candidate state mismatch is fixed on the normal path: stale candidates are ignored, failed promotion fails the run, and the final draft state is verified. Current-head CI is green. I also ran the existing 12 resolver/lifecycle tests in an isolated cloud sandbox; all passed.
Two remaining paths still violate the same protection for an already-ready release PR. Both were reproduced with this exact script, real git and an isolated bare remote, plus a synthetic GitHub PR-state adapter—not against live GitHub:
- If an older same-version candidate generates pages equal to main, the no-diff branch closes the existing ready PR and deletes its released branch before the stale-event guard can run. The ready branch in the reproduction still contained different released content that main did not have.
- If the initial PR lookup returns HTTP 502, the error is treated as no matching PR. The script force-pushes candidate content over the existing ready release branch, then fails when creating a duplicate PR. The workflow is red, but the ready PR's branch has already been replaced with unverified candidate content.
Please guard stale candidate events before any no-op cleanup and require a successful initial lookup before any mutation. Capture the lookup into a separate checked assignment; merely removing || true inside the read here-string does not preserve the substitution's failure status. Add regressions asserting both PR state and remote branch content for ready + candidate + no-diff and for an initial lookup error.
No live PR state or branches were changed by these tests; the temporary cloud sandbox was deleted and deletion verified. The earlier generated-content and mobile findings remain resolved. Separately, static cross-file review found that scheduled/default recovery only considers python-v tags even though the SDK releases Python and TypeScript independently. A newer TypeScript-only release can therefore be missed, or its docs replaced by a proposed update from the older Python-tag commit. This is a source-level finding, not a claimed live incident or part of the cloud reproduction. Please include both package release streams and select the latest eligible published SDK commit, with a Python release followed by a newer TypeScript-only release regression. These three issues are the remaining reasons for requesting changes.
| gh pr view "$1" --json isDraft --jq '.isDraft' | ||
| } | ||
|
|
||
| read -r number is_draft <<< "$(existing || true)" |
There was a problem hiding this comment.
[P2] Fail closed when the existing-PR lookup fails
existing || true makes a GitHub lookup error indistinguishable from an empty result. With a ready release PR already present, an incoming candidate and a transient HTTP 502, this leaves number empty, skips the stale-candidate guard, and reaches the force-push at line 70. Only afterward does gh pr create --draft fail because the PR already exists. The failure therefore leaves unverified candidate content on a PR that is still ready.
Reproduced with the unchanged script, real git/bare remote and a synthetic GitHub adapter: exit 1, remote content changes from released to candidate, and isDraft remains false. Capture and check the lookup in a separate assignment before read or any mutation; removing || true alone inside the here-string still lets read mask the lookup's exit status. Add a lookup-failure test that asserts no push, no branch-content change and no PR mutation.
| if git diff --quiet -- $pages; then | ||
| if [ -z "$number" ]; then | ||
| echo "main already carries the reference of futureagi-sdk@$short; nothing to open" | ||
| exit 0 | ||
| fi | ||
| gh pr close "$number" --delete-branch \ | ||
| --comment "main already carries the reference generated by futureagi-sdk@$short; nothing left to merge." |
There was a problem hiding this comment.
[P2] Ignore stale candidates before no-diff cleanup
This compares main with the incoming candidate's generated pages, not with the content already on the ready release PR. If an older same-version candidate happens to match main while the ready PR contains newer released pages, this branch closes the ready PR and deletes its branch before the stale-event guard at line 54 runs.
The cloud reproduction starts with main=baseline and an open ready PR whose real remote branch contains released content; the stale candidate also generates baseline. The script exits 0 after closing the PR and deleting that released branch, even though main does not contain its content. Move the ready-PR/stale-candidate check ahead of the no-diff branch so an ignored candidate cannot close or delete anything. Add the ready + candidate + no-diff regression and assert that the released branch and PR are unchanged.
| tags: io.tags ?? (() => github('git/matching-refs/tags/python-v')), | ||
| onPyPI: io.onPyPI ?? onPyPI, | ||
| onNpm: io.onNpm ?? onNpm, | ||
| }; | ||
| let ref = options.ref?.trim() || ''; | ||
| let stage = options.stage?.trim() || (ref ? 'preview' : 'released'); | ||
| if (!ref) { | ||
| ref = newestPythonTag(await get.tags()); |
There was a problem hiding this comment.
[P2] Include TypeScript releases in scheduled recovery
The no-ref path fetches only python-v* tags and selects the highest Python version, but the SDK versions and publishes its Python and TypeScript packages independently. After a TypeScript-only release with updated reference pages, the latest Python tag still points to the older SDK/docs revision. The weekly sync therefore cannot recover a missed TypeScript release dispatch. If the newer docs have already merged, it can instead open a ready PR restoring older pages: the older version pair is still installable, so the registry checks do not reject it.
Select the latest eligible published SDK commit across both package tag streams, keeping the existing registry checks. Add a regression with a Python release at commit A followed by a newer TypeScript-only release at commit B; scheduled/default resolution should choose B and must not revert B's reference. This finding comes from the resolver and independent package-release configuration; it is not a claimed live rollback.
…erence # Conflicts: # package.json
…efore cleanup, follow both release streams Review findings on #1106 (nik13), third round. - A failing `gh pr list` (a 502, say) used to read as "no PR", so a candidate could force-push over a ready release branch and only then fail on the duplicate create. The lookup is now captured in its own assignment and a failure stops the run before any git or PR mutation. - The ready-PR / stale-candidate rule now runs before the no-diff cleanup, so a stale candidate whose pages happen to match main can no longer close the ready PR and delete its released branch; it is ignored like any other stale event. - The scheduled default considered only python-v* tags. The SDK versions and publishes Python and TypeScript independently, so a TypeScript-only release was invisible and an older Python-tag commit could be proposed over newer pages. newestRelease() takes the newest tag of each stream, resolves both to commits and keeps the later commit; one stream alone is still a release, none fails closed. Registry checks are unchanged. Tests: lookup failure (no push, no create/edit/close, released PR still ready); ready + stale candidate + no diff (no close, no push, PR unchanged); a newer TypeScript-only release at commit B wins over the newest Python tag at A, and the reverse; single-stream and no-stream cases. 298 integration tests pass.
Third-round fixes (
|
Render the first released SDK contract with the pinned reviewed emitter; verify both released operation files before generating. Record immutable source provenance and require component tags plus unchanged source for independent package releases. Include untracked reference files in no-op detection and merge current docs main. Co-Authored-By: Claude Code <[email protected]>
Summary
Add the generated Platform SDK Reference to the SDK tab: 34 pages covering 162 published methods across 25 resources, plus the release-sync receiver and lifecycle tests.
The checked-in reference now matches the packages readers can install:
futureagi==0.7.0on PyPI@future-agi/[email protected]on npme61149de72c9907abd0921371126e4d40eb3e04a, backend contractv1.54.0error_clusters.list_traces,error_clusters.overview, the newer traces sort parameter, and newer model fields are no longer presented as available in those packages. This is a regeneration from released inputs, not manual deletion of selected page sections. The source commit, package versions and backend pin are recorded insrc/lib/sdk-reference-source.json.Rendering the first release
The published commit predates the docs emitter. A narrowly scoped bootstrap uses the reviewed emitter at
3269d584with only the published release's contract and catalog. It pins both checkout heads, refuses edited inputs, and requires those inputs to reproduce both released SDK operation files byte-for-byte before rendering.The weekly/manual workflow uses this same bridge only for that historical release. Future releases must carry their own generated reference; there is no silent fallback to SDK
dev. The generation and sync are documented inscripts/SDK_REFERENCE.md.Release and retry safeguards
Verification of the November 14 fix
All execution was in temporary labelled, expiring E2B sandboxes; cleanup was verified.
Initial verification attempts exposed two harness issues (a non-cone sparse checkout omitted the root manifest; a Node invocation incorrectly combined a filename with
--input-type) and the sandbox's default 2 GB Node heap limit. Corrected the harness and reran successfully with a 6 GB heap within the 8 GB sandbox. Final bootstrap verification used the same generator-only sparse layout as the workflow.The branch also merges docs
mainat970056be6443bff2051fbee1101f5b99de4cda12. Fresh PR CI is triggered by the push; consult the current checks rather than treating these cloud results as a completed GitHub run.Deployment boundary
SDK #42 is on SDK
dev; its sender still needs the separately reviewed promotion #50 before it runs on SDKmain. Merging this receiver does not promote or publish the SDK. Live repository-dispatch delivery can only be exercised after the receiver reaches docsmain; no live end-to-end dispatch is claimed here.The earlier mobile-table/component styling fixes remain in place. No credentials, branch-protection settings, or package versions are changed by this PR.
🤖 Generated with Claude Code