Skip to content

fix(openai): repair recalled TypeScript SDK contracts - #535

Merged
nik13 merged 5 commits into
devfrom
fix/opus-followup-traceAI-488
Nov 2, 2026
Merged

nik13 merged 5 commits into
devfrom
fix/opus-followup-traceAI-488

Conversation

@nik13

@nik13 nik13 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow up on all nine findings from the independent recall of merged #488. Keep the maintained shared TypeScript OpenAI instrumentor and preserve SDK objects, promise helpers, transport payloads and cancellation behavior.

  • Serialize function/custom tool-call variants without dereferencing a missing function; accept Responses stored-prompt requests without input.
  • Apply shared-core input hiding to embedding text. Granular text/image/message hiding now also redacts opaque raw/value copies; vector hiding covers copied output payloads. Remove the old embedding privacy exemption from the OTLP wire regression.
  • Treat Responses instructions as input, not invocation metadata. Export output-owned response fields rather than echoed request parameters, and route provider errors through the privacy-aware span wrapper.
  • Observe controller/request aborts independently of iterator startup. Finish once, distinguish deadline failures from intentional early exits, detach listeners, and preserve parser/transport errors when the SDK aborts during error unwinding.
  • Mark failed/incomplete Responses payloads and terminal events as ERROR. Preserve reported streaming usage, response model/id and finish reasons, including final usage-only chunks.

Independent review round 1 fixes

  • Treat stored-prompt substitution values as input content, not invocation metadata; retain prompt identity/version while masking text/image values and every raw/value duplicate.
  • Strip MCP authorization and all headers from telemetry-only tool copies independently of capture flags. Preserve original request objects, wire payloads and returned SDK objects.
  • Integrate the shared structured-message redactor and 88 native/legacy privacy tests from fix(fi-core): redact native GenAI message payloads #416 at 8630636b3d80e6b8cefdf85e41b1d9da8e88e344, retaining this PR's raw/value and embedding rules. Text hiding now covers custom-tool payloads too; combined flags fail closed.
  • Preserve requested model aliases while recording streamed response models separately. Aggregate function/custom tool deltas by SDK index, including interleaved/sparse indices and custom name/input fragments.
  • Invoke installed core Jest directly under network isolation, avoiding a Corepack download with an empty isolated cache. Keep all runtime tests network-isolated.

The independent review's seven findings were reproduced before fixes: 4 failing endpoint probes on SDK 4.0.0 and 18 failures/1 passing control on SDK 7.47.0 after expanding transport/privacy controls; the companion native-message suite had 73 failures/15 passes. All now pass. Empty-cache Corepack also reproduced the CI bootstrap failure; direct Jest passes in the same isolated environment.

Independent review round 2 fixes

  • Keep Chat prediction content and text-completion suffixes out of unmasked invocation metadata; retain them only in maskable input payloads, without changing requests or SDK results.
  • Serialize computer screenshots as structured image parts so image-only hiding removes image URLs and file IDs, while leaving ordinary text and tool identity intact.
  • Preserve the requested model for non-streaming Chat/text/Responses and streamed Responses; record the server model only in the response-model field. Correct the gateway expectation that previously codified the overwrite.
  • Select streamed Chat/text choice zero by its SDK index, not each chunk's array position. Cover interleaved and reordered n=2 choices plus usage-only chunks.
  • Declare the existing direct @opentelemetry/core import as a runtime dependency (aligned with core at ^2.0.1). Add clean non-hoisted pnpm consumers and isolated CJS/ESM import tests to every SDK matrix job.

All five findings reproduced before fixes: floor endpoint probes had 6 failures, latest had 11 failures and 1 passing control; both strict CJS/ESM imports failed with the missing direct dependency. Expanded final probes now pass, including capture-enabled controls, string/array predictions, URL/file screenshots and unchanged caller/transport/SDK payloads. Existing mock streams now declare the required choice index; their output-content expectations were not weakened.

Reproduction and tests

On unmodified dev 7cb1d3e42d9e3f80f3f80dc51a87417acdeb0c67, the original real-SDK recall suites reproduced 12 failures / 5 passes on 4.0.0 and 17 failures / 5 passes on 7.47.0 before fixes. These failures cover all nine recall findings. The committed expanded tests also cover listener cleanup, repeated/pre-iteration abort, hidden deadline/provider errors, failed/incomplete streamed Responses, returned SDK payload equality, custom-tool attributes and stream metadata.

Final local results (all runtime tests/builds inside the assigned macOS sandbox denying outbound networking; synthetic fetch or loopback HTTP/OTLP only):

Check OpenAI 4.0.0 OpenAI 7.47.0
Packed OpenAI + core recall/review/privacy/context regressions 34 passed 72 passed
Shared native/legacy GenAI privacy contracts 88 passed 88 passed
Vercel gateway contracts, each capture enabled/disabled 20 passed 23 passed
Non-hoisted packed CJS/ESM import contracts 2 passed 2 passed
Native API-promise contracts 42 passed 56 passed
Provider/patch-ownership/OTLP regressions 68 passed 74 passed
Clean-consumer automatic/manual OTLP contracts, each JSON/protobuf and plain/gzip 17 passed, 5 Responses-absent skips per combination 22 passed per combination
  • OpenAI locked-SDK unit suite: 185 passed, 2 existing skips, 15 snapshots passed. Streaming snapshots retain the requested model and record the server model separately; tool-call snapshots include the discriminator. Gateway assertions were not weakened.
  • Shared-core unit suite: 164 passed, including creation/setter/link duplicate-payload privacy and disabled-flag controls.
  • CommonJS, ESM and ESNext builds pass. The ESM README recipe runs against the packed packages and loopback OTLP; recipe and latest-SDK custom-tool/stored-prompt/stream request fixtures typecheck.
  • Frozen workspace dependency install, git diff --check, and release-plan consistency check pass (129 packages).
  • Existing CI matrix now packs the modified core instead of installing old core 1.1.0 and executes the new regressions across SDK 4.0.0, 5.23.2, 6.0.0, 7.0.0 and 7.47.0. Local endpoint runs cover floor/latest; intermediate versions remain CI coverage, not a local-run claim.

Release and overlap

The shared privacy fixes require both the core and OpenAI patch releases. Release core first, then OpenAI; upgrade both packages together. README commands no longer pin the old core. This PR does not publish packages, bump versions, edit changelogs, merge anything, or claim a live vendor/Cloud test.

Checked existing open PRs before implementation. #410 concerns already-integrated API-promise mechanics, not these recall findings. #520 fixes Python Responses, not TypeScript. #416 fixes native GenAI/structured-message masking. Round 1 now integrates its existing implementation/tests rather than relying on an unmerged companion, preserving this PR's separate raw/value and embedding rules. #416 itself was not merged or modified; reconcile this overlap when landing it. MCP credential fields are removed here, while arbitrary customer tool descriptions/custom attributes remain outside general content-hiding guarantees.

Standards self-review

Traced the changed request, response, privacy, abort and streaming aggregation paths against the contracts/types, correctness, performance, failure modes, testing, security and PR-shape checklist. The newly declared runtime dependency repairs a verified direct-import resolution failure; no provider replacement, copied customer tracing glue, or duplicate spans. No Python, migration, frontend, application authz or OSS/EE boundary change; those mechanical gates do not apply. Independent review is still required.

E2E coverage

not applicable (no application e2e/ harness) · flows hit: n/a · marker: n/a · verdict: not applicable. Re-runnable package contracts and real SDK/OTLP regressions are committed in this PR.

Independent recall, round 3

  • Sanitize MCP server URLs in telemetry down to their origin (including URL userinfo, path, query and fragment), and omit nested tool_search_output authorization/headers without modifying caller objects, SDK transport requests or returned data. Invalid URLs fail closed.
  • Serialize Responses custom-tool calls/results in semantic input and output messages, including streamed terminal responses, while retaining the existing text-hiding rules.
  • Reproduced the findings on the prior packed SDK; added failing-first tests, current-SDK type witnesses, and the new suite to the 4.0.0–7.47.0 CI matrix. After the fix, packed floor/latest combined regressions pass (91/91, 140/140); locked OpenAI and core Jest suites pass (185/185 and 164/164). All runtime testing used synthetic requests under outbound-network-denying sandbox.
  • Merged the latest dev into this existing branch with a normal merge commit; no new PR or force push. Independent review and merge gate remain outstanding.

🤖 Generated with Claude Code

nik13 and others added 5 commits November 2, 2026 02:45
Handle custom tools and optional Responses inputs, protect duplicate private payloads, and preserve stream abort, failure and usage semantics. Add floor/latest SDK and shared-core regressions.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Protect stored-prompt inputs and MCP credentials in all telemetry copies. Integrate the shared structured-message redactor and tests from #416 at 8630636 while preserving duplicate-payload masking. Aggregate function/custom deltas by SDK index without overwriting request model metadata. Run core Jest directly inside network-isolated CI.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Mask prediction/suffix content, preserve screenshot structure and request models, select streamed choice zero by SDK index, and declare the directly imported OTel core dependency. Cover real SDK bounds and strict non-hoisted CJS/ESM imports.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
…m tools

Co-Authored-By: Claude Code <noreply@anthropic.com>
@nik13
nik13 merged commit 6621397 into dev Nov 2, 2026
93 of 98 checks passed
@nik13
nik13 deleted the fix/opus-followup-traceAI-488 branch November 2, 2026 21:40
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