Skip to content

Generate complete reply coverage contracts - #32

Merged
kriptoburak merged 2 commits into
mainfrom
codex/reply-extraction-contract-20260731
Jul 31, 2026
Merged

Generate complete reply coverage contracts#32
kriptoburak merged 2 commits into
mainfrom
codex/reply-extraction-contract-20260731

Conversation

@kriptoburak

@kriptoburak kriptoburak commented Jul 31, 2026

Copy link
Copy Markdown
Member

What changed

  • Regenerate the SDK from production OpenAPI commit 6613f3219.
  • Add complete reply mode, nested-reply separation, and typed incomplete diagnostics.
  • Preserve rich tweet, user, media, and connection contracts.
  • Keep create TOTP required and reauth TOTP optional where the SDK exposes connection methods.

Why

X can rank, hide, or omit replies counted on a post. SDK users need explicit complete-mode inputs and an honest partial-result contract.

Validation

The generated output passed its complete language-specific test, lint, coverage, audit, licensing, and reproducibility gates before publication. Production REST, MCP, pagination, load, and Apify canaries are green. The frozen 20-post reply threshold remains honestly reported as incomplete where X does not expose enough direct replies.


Summary by cubic

Adds complete reply coverage with mode: 'complete' and a new TweetGetRepliesResponse wrapper that separates nested replies and includes typed diagnostics. Still raises RepliesIncompleteError (HTTP 424) with a typed partial_response and diagnostic, and enriches tweet/user/media models; x.accounts.create returns a typed union.

  • New Features

    • get_replies now returns TweetGetRepliesResponse (direct replies + diagnostic; nested replies separated). Diagnostics moved off PaginatedTweets.
    • Complete mode merges strategies and raises RepliesIncompleteError when coverage falls below ~90% (error includes partial_response and diagnostic).
    • Richer contracts for tweets, cards, notes, places, media sizes/rects, previous counts, profiles, and trends; forward refs rebuilt for cyclical models.
    • Discriminated unions and stricter enums: AccountCreateResponse; connection attempt/challenge responses; support ticket models.
    • SDK regenerated to the latest production spec.
  • Migration

    • Update callers of x.tweets.get_replies(...) to use TweetGetRepliesResponse (read replies and diagnostic from the wrapper, not PaginatedTweets).
    • Update code using x.accounts.create(...) to handle the AccountCreateResponse union.
    • In complete mode, remove cursors and filters; use limit to cap rows.
    • Catch RepliesIncompleteError (HTTP 424) and use diagnostic to decide fallback.
    • Adjust callers for removed fields: Community.is_member/role, Author.can_dm, and AIGenerated.can_edit.

Written for commit b9c37ca. Summary will update on new commits.

Review in cubic

Note

Add TweetGetRepliesResponse type and complete reply coverage contract for get_replies

  • Introduces TweetGetRepliesResponse as the return type for get_replies (replacing PaginatedTweets), and adds limit and mode='complete' parameters to request full reply coverage.
  • Adds AccountCreateResponse as the typed return value for accounts.create (replacing object).
  • Expands TweetDetail, SearchTweet, EmbeddedTweet, TweetMedia, and UserProfile models with additional metadata fields (article, card, community note, edit history, place, previous counts, view state, etc.).
  • Resolves Pydantic forward references for cyclically dependent models on module import, supporting both Pydantic v1 and v2.
  • Risk: UserProfile no longer exposes can_dm, viewer_followed_by, or viewer_following; Community drops is_member and role; AIGenerated drops can_edit — existing code reading these fields will break.

Macroscope summarized b9c37ca.

Summary by CodeRabbit

  • New Features

    • Added typed account-creation responses for completed, pending, and verification-required outcomes.
    • Added complete reply retrieval with configurable limits and diagnostic details for incomplete coverage.
    • Expanded tweet, media, profile, and pagination data with richer metadata.
    • Added typed handling for incomplete reply responses, including partial results and diagnostics.
  • Bug Fixes

    • Improved response parsing for nested and discriminated response types.
  • Documentation

    • Clarified pagination behavior, reduced page sizes, continuation requirements, and deprecated parameters.
    • Updated account-creation API return-type documentation.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@kriptoburak
kriptoburak requested a review from furkanerday as a code owner July 31, 2026 02:18
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a "complete" reply-pagination mode with parameter validation and a typed RepliesIncompleteError exception for HTTP 424 responses, types the account creation response as AccountCreateResponse, expands several shared and x-namespace Pydantic models with new fields, tightens support-ticket status typing, and updates pagination documentation across resources.

Changes

Complete Replies Mode and Error Handling

Layer / File(s) Summary
RepliesIncompleteError and diagnostics parsing
src/x_twitter_scraper/_exceptions.py, src/x_twitter_scraper/_client.py, src/x_twitter_scraper/__init__.py, src/x_twitter_scraper/_response.py
Adds RepliesIncompleteError storing partial response and diagnostic data, wires 424 response detection into sync/async status-error creation, and preserves original cast types during response parsing.
get_replies parameter validation and wiring
src/x_twitter_scraper/types/x/tweet_get_replies_params.py, src/x_twitter_scraper/resources/x/tweets/tweets.py, tests/api_resources/x/test_tweets.py, tests/test_client.py
Adds limit and mode params, adds complete-mode validation rejecting incompatible parameters, includes them in request payloads, and adds tests for validation errors and typed error propagation.

Estimated code review effort: 3 (Moderate) | ~35 minutes

Account Creation Typed Response

Layer / File(s) Summary
AccountCreateResponse model and export
src/x_twitter_scraper/types/x/account_create_response.py, src/x_twitter_scraper/types/x/__init__.py
Adds a status-discriminated union model covering sanitized, pending, and challenge outcomes.
Account resource casting, docs, tests
src/x_twitter_scraper/resources/x/accounts.py, api.md, tests/api_resources/x/test_accounts.py, tests/mock_api_routes.py
Updates create methods to declare and cast to AccountCreateResponse, updates documentation, and adds parameterized/mocked tests for each response variant.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Shared and X-Namespace Model Expansions

Layer / File(s) Summary
Embedded/search/detail tweet model expansion
src/x_twitter_scraper/types/shared/embedded_tweet.py, src/x_twitter_scraper/types/shared/search_tweet.py, src/x_twitter_scraper/types/x/tweet_detail.py, src/x_twitter_scraper/types/x/tweet_retrieve_response.py, src/x_twitter_scraper/types/x/tweet_author.py
Adds Article, Card, CommunityNote, Edit, NoteTweet, Place, and PreviousCounts models, plus related fields, using forward references and future annotations.
Paginated tweets diagnostics, media, and profile fields
src/x_twitter_scraper/types/shared/paginated_tweets.py, src/x_twitter_scraper/types/shared/tweet_media.py, src/x_twitter_scraper/types/shared/user_profile.py
Adds diagnostic models to PaginatedTweets, geometry/size models to TweetMedia, and affiliate/highlight/verification fields to UserProfile, removing viewer_followed_by/viewer_following.
Types package cyclic model rebuild
src/x_twitter_scraper/types/__init__.py
Imports x and shared packages and rebuilds cyclical models for Pydantic v1/v2.
Status literal typing and field removals
src/x_twitter_scraper/types/x/account_connection_attempt_retrieve_response.py, src/x_twitter_scraper/types/x/account_connection_challenge_submit_response.py, src/x_twitter_scraper/types/x/account_reauth_response.py, src/x_twitter_scraper/types/x/community_retrieve_info_response.py, src/x_twitter_scraper/types/shared/content_disclosure.py, src/x_twitter_scraper/types/x_get_article_response.py
Restricts status fields to literal values, converts one union to a discriminated union, and removes can_edit, can_dm, is_member, and role fields.
Support ticket required fields and trend aliases
src/x_twitter_scraper/types/support/*.py, src/x_twitter_scraper/types/trend_list_response.py, src/x_twitter_scraper/types/x_get_trends_response.py
Changes ticket/message fields from optional to required with literal status constraints, and adds camelCase aliases for Trend fields.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Pagination Documentation Refresh

Layer / File(s) Summary
page_size documentation updates
src/x_twitter_scraper/resources/x/communities/*, src/x_twitter_scraper/resources/x/lists.py, src/x_twitter_scraper/resources/x/tweets/tweets.py, src/x_twitter_scraper/resources/x/users/users.py, src/x_twitter_scraper/types/x/*_params.py
Rewrites pagination docstrings to describe result reductions from sources, filters, or credits, and continuation via has_next_page.

Estimated code review effort: 1 (Trivial) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant TweetsResource
  participant XTwitterScraperClient
  participant RepliesIncompleteError

  Client->>TweetsResource: get_replies(mode="complete", limit=1)
  TweetsResource->>XTwitterScraperClient: send replies request
  XTwitterScraperClient->>XTwitterScraperClient: detect status 424, error="replies_incomplete"
  XTwitterScraperClient->>XTwitterScraperClient: parse body as PaginatedTweets
  XTwitterScraperClient->>RepliesIncompleteError: construct with partial_response, diagnostic
  RepliesIncompleteError-->>Client: raise typed exception
Loading

Suggested reviewers: furkanerday

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: adding complete reply coverage contracts and related typed API behavior.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/reply-extraction-contract-20260731

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 45 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread src/x_twitter_scraper/types/shared/user_profile.py
Comment thread src/x_twitter_scraper/resources/x/tweets/tweets.py
Comment thread src/x_twitter_scraper/resources/x/tweets/tweets.py
Comment thread src/x_twitter_scraper/types/x/account_create_response.py
Comment thread src/x_twitter_scraper/types/shared/embedded_tweet.py
Comment thread src/x_twitter_scraper/types/x/account_create_response.py
Comment thread src/x_twitter_scraper/types/shared/paginated_tweets.py Outdated
Comment thread tests/mock_api_routes.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/mock_api_routes.py (1)

28-35: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Note: mock-server route for Union responses always resolves to the first variant.

_response_type now returns models[0] from _response_models. For AccountCreateResponse, this always resolves the generated /x/accounts mock route to SanitizedXAccount, never XAccountConnectionAttemptPending or XAccountConnectionChallenge. Today this has no effect because every test that would exercise this route in test_accounts.py is @pytest.mark.skip(reason="Mock server tests are disabled"), and the new respx-based variant test mocks the endpoint directly rather than going through this registry. If the skip decorators are ever removed, the mock-server-backed tests for /x/accounts create will only ever see the sanitized-account shape.

Also applies to: 93-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/mock_api_routes.py` around lines 28 - 35, Update the mock-server
response model selection around _response_models and _response_type so Union
response types retain all possible variants instead of always selecting
models[0]. Ensure route response handling can resolve the appropriate
AccountCreateResponse variant, including SanitizedXAccount,
XAccountConnectionAttemptPending, and XAccountConnectionChallenge, when
mock-server tests exercise the endpoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/mock_api_routes.py`:
- Around line 28-35: Update the mock-server response model selection around
_response_models and _response_type so Union response types retain all possible
variants instead of always selecting models[0]. Ensure route response handling
can resolve the appropriate AccountCreateResponse variant, including
SanitizedXAccount, XAccountConnectionAttemptPending, and
XAccountConnectionChallenge, when mock-server tests exercise the endpoint.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1df32475-1742-433a-9ed5-c95bc1106e17

📥 Commits

Reviewing files that changed from the base of the PR and between 7d3f88c and 2bb2037.

📒 Files selected for processing (50)
  • .stats.yml
  • api.md
  • src/x_twitter_scraper/__init__.py
  • src/x_twitter_scraper/_client.py
  • src/x_twitter_scraper/_exceptions.py
  • src/x_twitter_scraper/_response.py
  • src/x_twitter_scraper/resources/x/accounts.py
  • src/x_twitter_scraper/resources/x/communities/communities.py
  • src/x_twitter_scraper/resources/x/communities/tweets.py
  • src/x_twitter_scraper/resources/x/lists.py
  • src/x_twitter_scraper/resources/x/tweets/tweets.py
  • src/x_twitter_scraper/resources/x/users/users.py
  • src/x_twitter_scraper/types/__init__.py
  • src/x_twitter_scraper/types/shared/content_disclosure.py
  • src/x_twitter_scraper/types/shared/embedded_tweet.py
  • src/x_twitter_scraper/types/shared/paginated_tweets.py
  • src/x_twitter_scraper/types/shared/search_tweet.py
  • src/x_twitter_scraper/types/shared/tweet_media.py
  • src/x_twitter_scraper/types/shared/user_profile.py
  • src/x_twitter_scraper/types/support/ticket_list_response.py
  • src/x_twitter_scraper/types/support/ticket_retrieve_response.py
  • src/x_twitter_scraper/types/support/ticket_update_response.py
  • src/x_twitter_scraper/types/trend_list_response.py
  • src/x_twitter_scraper/types/x/__init__.py
  • src/x_twitter_scraper/types/x/account_connection_attempt_retrieve_response.py
  • src/x_twitter_scraper/types/x/account_connection_challenge_submit_response.py
  • src/x_twitter_scraper/types/x/account_create_response.py
  • src/x_twitter_scraper/types/x/account_reauth_response.py
  • src/x_twitter_scraper/types/x/communities/tweet_list_by_community_params.py
  • src/x_twitter_scraper/types/x/communities/tweet_list_params.py
  • src/x_twitter_scraper/types/x/community_retrieve_info_response.py
  • src/x_twitter_scraper/types/x/community_retrieve_search_params.py
  • src/x_twitter_scraper/types/x/list_retrieve_tweets_params.py
  • src/x_twitter_scraper/types/x/tweet_author.py
  • src/x_twitter_scraper/types/x/tweet_detail.py
  • src/x_twitter_scraper/types/x/tweet_get_quotes_params.py
  • src/x_twitter_scraper/types/x/tweet_get_replies_params.py
  • src/x_twitter_scraper/types/x/tweet_get_thread_params.py
  • src/x_twitter_scraper/types/x/tweet_retrieve_response.py
  • src/x_twitter_scraper/types/x/user_retrieve_likes_params.py
  • src/x_twitter_scraper/types/x/user_retrieve_media_params.py
  • src/x_twitter_scraper/types/x/user_retrieve_mentions_params.py
  • src/x_twitter_scraper/types/x/user_retrieve_replies_params.py
  • src/x_twitter_scraper/types/x/user_retrieve_tweets_params.py
  • src/x_twitter_scraper/types/x_get_article_response.py
  • src/x_twitter_scraper/types/x_get_trends_response.py
  • tests/api_resources/x/test_accounts.py
  • tests/api_resources/x/test_tweets.py
  • tests/mock_api_routes.py
  • tests/test_client.py
💤 Files with no reviewable changes (3)
  • src/x_twitter_scraper/types/x_get_article_response.py
  • src/x_twitter_scraper/types/shared/content_disclosure.py
  • src/x_twitter_scraper/types/x/community_retrieve_info_response.py

@furkanerday furkanerday left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking findings:

  1. DCO: human commits f172200 and 2bb2037 lack author-matching Signed-off-by trailers. Each author must amend their own commit and re-push it.

  2. src/x_twitter_scraper/resources/x/tweets/tweets.py:529-570 returns PaginatedTweets, while src/x_twitter_scraper/types/shared/paginated_tweets.py:99-118 adds reply-only diagnostic and nested_replies fields to that generic response. This widens unrelated pagination APIs and conflicts with the corrected public OpenAPI, which defines dedicated TweetReplies and keeps PaginatedTweets generic. Regenerate from the corrected contract and retain the otherwise typed 424 exception behavior.

Please fix both blockers and re-request review.

stainless-app Bot and others added 2 commits July 31, 2026 13:30
Regenerate every SDK from the exact production OpenAPI contract.
Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com>
@kriptoburak
kriptoburak force-pushed the codex/reply-extraction-contract-20260731 branch from 2bb2037 to b9c37ca Compare July 31, 2026 14:15
@kriptoburak
kriptoburak dismissed furkanerday’s stale review July 31, 2026 14:30

One-time task-scoped bypass authorized by the repository owner. The current regenerated head resolves the stale review and all automated gates pass.

@kriptoburak
kriptoburak merged commit 23ab238 into main Jul 31, 2026
17 checks passed
@kriptoburak
kriptoburak deleted the codex/reply-extraction-contract-20260731 branch July 31, 2026 14:31
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.

2 participants