Skip to content

Update client identities and WorkBuddy failover - #115

Merged
maiphucgiang merged 4 commits into
mainfrom
update/client-identities
Nov 4, 2026
Merged

maiphucgiang merged 4 commits into
mainfrom
update/client-identities

Conversation

@maiphucgiang

@maiphucgiang maiphucgiang commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • update CodeBuddy CLI identities to 2.179.3 and align current SDK/runtime headers
  • align international WorkBuddy 5.9.4 and retain the official embedded CLI 2.165.0
  • add same-account domestic WorkBuddy backup-origin failover before the response starts

Validation

  • 99 backend test files, 2354 tests passed
  • real domestic CLI and WorkBuddy backup-origin smoke requests returned HTTP 200

Summary by Sourcery

Align client identities with current upstream profiles and add safe domestic WorkBuddy backup-origin failover before responses start.

New Features:

  • Add same-account domestic WorkBuddy failover to the official backup origin for eligible gateway and connection failures before a response begins.

Bug Fixes:

  • Prevent origin retries for content-filter, channel, model-specific, ambiguous transport, and mid-stream failures.

Enhancements:

  • Align domestic and international CodeBuddy and WorkBuddy client identities, versions, SDK headers, and runtime headers with the updated official profiles.
  • Preserve request domain and account identity across WorkBuddy failover while recording possible duplicate-billing warnings for replayable failures.

Documentation:

  • Update English and Chinese advanced documentation with the revised client identities, runtime headers, and domestic WorkBuddy failover behavior.

Tests:

  • Expand identity, runtime-header, failover safety, protected-error, transport-failure, streaming, and billing-warning coverage.

@sourcery-ai

sourcery-ai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

This PR refreshes client identity and runtime headers across CLI and WorkBuddy profiles, then adds narrowly scoped domestic WorkBuddy origin failover that retries eligible pre-response gateway or connection failures against the official backup origin using the same account and request domain.

Sequence diagram for domestic WorkBuddy origin failover

sequenceDiagram
    participant Client
    participant API
    participant Primary as WorkBuddyPrimary
    participant Backup as WorkBuddyBackup

    Client->>API: chat request
    API->>Primary: _backend_stream(/v2/chat/completions)
    alt HTTP 200 before response
        Primary-->>API: response stream
        API-->>Client: response
    else 408/502/503/504
        Primary-->>API: gateway error
        API->>Backup: _backend_stream(wb.tencentbuddy.com)
        Backup-->>API: response stream
        API-->>Client: response
    else connection failure before response
        Primary--xAPI: httpx.HTTPError
        API->>Backup: _backend_stream(wb.tencentbuddy.com)
        Backup-->>API: response stream
        API-->>Client: response
    end
Loading

Flow diagram for failover eligibility

flowchart TD
    A[Domestic WorkBuddy request] --> B{Primary attempt fails before response?}
    B -->|No| C[Return primary response or error]
    B -->|Yes| D{408, 502, 503, 504, or safe connection failure?}
    D -->|No| E[Propagate failure]
    D -->|Yes| F[Retry once at wb.tencentbuddy.com]
    F --> G[Preserve same account and X-Domain]
Loading

File-Level Changes

Change Details Files
Updated per-profile client identity versions and runtime metadata to match the intended CodeBuddy and WorkBuddy packages.
  • Bumped domestic and international CLI identities to 2.179.3 while retaining WorkBuddy embedded CLI 2.165.0.
  • Aligned international WorkBuddy to 5.9.4 and updated SDK/runtime headers for CLI and international WorkBuddy profiles.
  • Extended identity and request-context tests, including legacy-mode header coverage.
app/client_profiles.py
app/request_context.py
docs/advanced.md
docs/advanced.zh-CN.md
tests/test_identity_sync.py
tests/test_request_context.py
Added constrained same-account failover for domestic WorkBuddy before a response begins.
  • Recognized only domestic WorkBuddy chat URLs and mapped them to the official wb.tencentbuddy.com backup origin.
  • Retried gateway statuses 408/502/503/504 and safe connection failures without replaying after response start.
  • Preserved the original account and X-Domain while keeping channel fallback behavior separate.
  • Added URL, transport, streaming, protocol, and response-start safety tests.
app/site_routing.py
app/upstream_compat.py
converter.py
tests/test_api_flow.py
tests/test_upstream_compat.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-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.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="converter.py" line_range="5046" />
<code_context>
+                    yield response
+                    return
+                raw = await read_bounded_error(response)
+                if should_origin_fallback(origin_url, response.status_code):
+                    switch_origin(status_code=response.status_code)
+                    continue
</code_context>
<issue_to_address>
**Gateway retries duplicate completions**

When the primary returns 408, 502, 503, or 504 after its backend has accepted or completed the request, the primary may already have accepted and processed the POST before returning an eligible gateway status, so `_checked_chat_stream` sends the same completion again to the backup without an upstream idempotency key; the caller receives one response while the primary and backup can both incur generation or billing.

Only replay statuses known to mean the request was not processed, or use an upstream-supported idempotency mechanism before retrying ambiguous responses.
</issue_to_address>

### Comment 2
<location path="converter.py" line_range="5046" />
<code_context>
+                    yield response
+                    return
+                raw = await read_bounded_error(response)
+                if should_origin_fallback(origin_url, response.status_code):
+                    switch_origin(status_code=response.status_code)
+                    continue
</code_context>
<issue_to_address>
**Refusals are replayed to backup**

When a selected transient HTTP status carries a recognized content-filter or no-failover business error, `_checked_chat_stream` checks the status and switches origins before `_check_upstream_status` can apply its protections, so the request is replayed instead of preserving the original refusal.

Apply the error-body protections before switching origins, and do not fail over for recognized content-filter or no-failover errors.
</issue_to_address>

### Comment 3
<location path="app/client_profiles.py" line_range="124-125" />
<code_context>
+    profile = profile_for_auth(auth)
+    headers = {**SDK_HEADERS, **_auth_headers(auth, account), **_identity_claim_headers(auth, account)}
+    if profile in ("cn-cli", "intl-cli"):
+        headers["x-stainless-package-version"] = "7.39.0"
+        headers["X-Agent-Runtime"] = "other"
+    elif profile == "intl-work":
+        headers["X-Agent-Runtime"] = "local-agent"
</code_context>
<issue_to_address>
**Profile identity differs across requests**

When a CLI or international WorkBuddy profile makes a refresh or account-lookup request, or a CLI profile makes a catalog request, `refresh_headers` omits the profile overrides, so CLI refresh and account requests use SDK version 6.25 and omit the runtime header; `catalog_headers` also omits the runtime header for CLI requests. The upstream therefore receives inconsistent client identities across the account flow.

Apply the profile-specific SDK-version and runtime overrides in the refresh and catalog header builders as well as the chat header builder.

Also at `docs/advanced.md:140`, `docs/advanced.zh-CN.md:140`.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 3 findings to address first, and on eligible domestic WorkBuddy failures, the gateway sends the same request and account headers to wb.tencentbuddy.com, so a prompt or identity data already sent there cannot be taken back by reverting. Retrying transient gateway responses may also cause the upstream to process a request more than once.

Blocking findings: converter.py:5046, converter.py:5046, app/client_profiles.py:125


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread converter.py Outdated
yield response
return
raw = await read_bounded_error(response)
if should_origin_fallback(origin_url, response.status_code):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium · Gateway retries duplicate completions

When the primary returns 408, 502, 503, or 504 after its backend has accepted or completed the request, the primary may already have accepted and processed the POST before returning an eligible gateway status, so _checked_chat_stream sends the same completion again to the backup without an upstream idempotency key; the caller receives one response while the primary and backup can both incur generation or billing.

Only replay statuses known to mean the request was not processed, or use an upstream-supported idempotency mechanism before retrying ambiguous responses.

Prompt for AI agents
In `converter.py` at line 5046:

**Gateway retries duplicate completions**

When the primary returns 408, 502, 503, or 504 after its backend has accepted or completed the request, the primary may already have accepted and processed the POST before returning an eligible gateway status, so `_checked_chat_stream` sends the same completion again to the backup without an upstream idempotency key; the caller receives one response while the primary and backup can both incur generation or billing.

Only replay statuses known to mean the request was not processed, or use an upstream-supported idempotency mechanism before retrying ambiguous responses.

Comment thread converter.py Resolved
Comment thread app/client_profiles.py
Comment on lines +124 to +125
headers["x-stainless-package-version"] = "7.39.0"
headers["X-Agent-Runtime"] = "other"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium · Profile identity differs across requests

When a CLI or international WorkBuddy profile makes a refresh or account-lookup request, or a CLI profile makes a catalog request, refresh_headers omits the profile overrides, so CLI refresh and account requests use SDK version 6.25 and omit the runtime header; catalog_headers also omits the runtime header for CLI requests. The upstream therefore receives inconsistent client identities across the account flow.

Apply the profile-specific SDK-version and runtime overrides in the refresh and catalog header builders as well as the chat header builder.

Also at docs/advanced.md:140, docs/advanced.zh-CN.md:140.

Prompt for AI agents
In `app/client_profiles.py` at lines 124-125:

**Profile identity differs across requests**

When a CLI or international WorkBuddy profile makes a refresh or account-lookup request, or a CLI profile makes a catalog request, `refresh_headers` omits the profile overrides, so CLI refresh and account requests use SDK version 6.25 and omit the runtime header; `catalog_headers` also omits the runtime header for CLI requests. The upstream therefore receives inconsistent client identities across the account flow.

Apply the profile-specific SDK-version and runtime overrides in the refresh and catalog header builders as well as the chat header builder.

Also at `docs/advanced.md:140`, `docs/advanced.zh-CN.md:140`.

@maiphucgiang
maiphucgiang merged commit fef7876 into main Nov 4, 2026
9 checks passed
@maiphucgiang
maiphucgiang deleted the update/client-identities branch November 4, 2026 17:36
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.

1 participant