Skip to content

QVAC-21691 feat[api]: SDK-side support for the Python full-fidelity client#3351

Closed
lauripiisang wants to merge 1 commit into
mainfrom
QVAC-21691-python-parity-sdk-side
Closed

QVAC-21691 feat[api]: SDK-side support for the Python full-fidelity client#3351
lauripiisang wants to merge 1 commit into
mainfrom
QVAC-21691-python-parity-sdk-side

Conversation

@lauripiisang

Copy link
Copy Markdown
Contributor

🎯 What problem does this PR solve?

The Python SDK client (separate PR, stacked on this one) needs behaviour that
only the @qvac/sdk worker can provide once, so every language binding shares
it instead of re-implementing (and drifting). This PR is the @qvac/sdk side
of that work, split out so it reviews on its own.

🛠️ How does it solve it?

  • Worker-orchestrated completion — a new completionOrchestrate duplex
    method runs the multi-turn tool loop + MCP in the worker and emits
    toolCallback frames; the client only routes each callback to a
    user-supplied handler. The existing completion() API is unchanged.
  • Translate detection → workerserver/bare/ops/translate.ts
    auto-detects the source language when from is omitted (LLM), so the JS and
    Python clients share one detector instead of each shipping its own (they
    disagreed on the same input). The LLM server-param refine now requires only
    to; the wire from was already optional.
  • Plugin contract exportscripts/export-plugin-contract.ts emits a
    per-plugin contract so custom plugins get typed clients.
  • Data exporters for the generated Python client
    contract/model-type-maps.json (alias/engine → canonical model type) and
    contract/error-codes.json (error-code registries), so the Python client
    generates those tables instead of hand-copying them; contract:check fails
    if they drift.
  • Cross-client conformance corpuse2e/conformance/cases.json with a
    direct-SDK JS runner (run.mjs); the Python client runs the same cases, so
    the two can't diverge on covered behaviour.

🔌 API changes ([api])

New public duplex method completionOrchestrate (additive; nothing removed):

const run = completion({ modelId, history, tools, orchestrate: true })
for await (const event of run.events) { /* ... */ }
const final = await run.final

✅ Testing

  • bun run build (lint + typecheck + compile), contract:check, and
    bun run test:unit all pass.
  • completionOrchestrate handler + plugin-contract unit tests added.
  • run:local:desktop --filter translation-llm — 9/9 against the rebuilt worker
    (covers the from-omitted autodetect path).

📝 Notes

The Python client PR (packages/sdk-python) is stacked on this branch — merge
this first, then that one retargets to main.

…lient

The @qvac/sdk changes the Python client depends on (split out from the
python-sdk PR so each package reviews on its own):

- worker-orchestrated completion: a new `completionOrchestrate` duplex method
  runs the tool-calling loop + MCP in the worker and emits `toolCallback`
  frames, so every language binding gets it without reimplementing the loop
  (contract: completion-stream schemas, method-shapes, handler-registry,
  handlers/completion-orchestrate)
- translate source-language detection moves into the worker
  (server/bare/ops/translate.ts): `from` is auto-detected when omitted, so
  Python and JS share one detector instead of each shipping its own (they
  disagreed); the LLM `from`/`to` server refine now requires only `to`
- plugin contract export (scripts/export-plugin-contract.ts +
  scripts/contract/plugin-contract.ts) so custom plugins get typed clients
- contract exporters for the maps/codes the Python client generates from:
  model-type-maps.json (alias/engine resolution) and error-codes.json
- cross-client conformance corpus (e2e/conformance/cases.json + run.mjs): the
  JS runner and the Python runner execute the same cases so the clients can't
  drift on covered behaviour

Verified: SDK build (lint + typecheck + compile), contract:check, unit tests,
and the translation-llm e2e (9/9) against the rebuilt worker.
@lauripiisang
lauripiisang requested review from a team as code owners July 20, 2026 16:17
@github-actions

Copy link
Copy Markdown
Contributor

Review Status

Current Status: ❌ PENDING
Approvals so far: none

Pending reviews: Needs 1 Management or Team Lead, and 1 more from Management, Team Lead, or Member.

@github-actions

Copy link
Copy Markdown
Contributor

License compliance — clean

No new dependency license findings in this PR.

Warn-only (shadow) mode — this check does not block merges yet.

Updated automatically by the canonical license compliance workflow.

NOTICE presence (advisory)

Missing NOTICE (advisory, does not block):

  • ./packages/embed-llamacpp/benchmarks/server
  • ./packages/embed-llamacpp/benchmarks/performance
  • ./packages/ggml-coload-smoke
  • ./packages/llm-llamacpp/benchmarks/server
  • ./packages/llm-llamacpp/benchmarks/performance
  • ./packages/fabric/test/integration
  • ./packages/transcription-whispercpp/benchmarks/server
  • ./packages/transcription-parakeet/benchmarks/server
  • ./packages/sdk/e2e
  • ./packages/vla-ggml/sim/server
  • ./.github/actions/release-merge-guard
  • ./docs/website

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

QVAC E2E — android — ✅ all tests passed (91/103, 1773s)

Config: suite=smoke · filter=(none) · exclude=(none)
Device pool: Google Pixel 10 Pro - Android 16 — ☀️ highly available
View run · Artifacts: reports · Device Farm logs

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

QVAC E2E — ios — ✅ all tests passed (91/103, 796s)

Config: suite=smoke · filter=(none) · exclude=(none)
Device pool: iPhone 16 Pro - iOS 18 — ☀️ highly available
View run · Artifacts: reports · Device Farm logs

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

QVAC E2E — windows — ✅ all tests passed (103/103, 415s)

Config: suite=smoke · filter=(none) · exclude=(none)
View run · Artifacts: reports

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

QVAC E2E — linux — ✅ all tests passed (103/103, 277s)

Config: suite=smoke · filter=(none) · exclude=(none)
View run · Artifacts: reports

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

QVAC E2E — macos — ✅ all tests passed (103/103, 220s)

Config: suite=smoke · filter=(none) · exclude=(none)
View run · Artifacts: reports

@lauripiisang

Copy link
Copy Markdown
Contributor Author

Superseded by #3354 — the SDK contract, generated Python client, and worker behaviour are CI-coupled and can't be split into a clean SDK-only PR, so the full-fidelity Python work ships as one PR (#3354).

@lauripiisang
lauripiisang deleted the QVAC-21691-python-parity-sdk-side branch July 20, 2026 16:56
@github-actions github-actions Bot added the e2e-tested Test suite has run on this PR. Does not indicate tests pass/fail - see results in comments. label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e2e-tested Test suite has run on this PR. Does not indicate tests pass/fail - see results in comments. test-e2e-smoke Triggers smoke e2e test suite [Currently SDK-only] verified Authorize secrets / label-gate in PR workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant