fix: harden OpenAI translation requests - #15229
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎭 Playwright: ✅ 1814 passed, 0 failed · 2 flaky📊 Browser Reports
📦 Bundle: 8.85 MB gzipDetailsSummary
Category Glance App Entry Points — 3.71 kBMain entry bundles and manifests
Status: 1 added Graph Workspace — 1.37 MBGraph editor runtime, canvas, workflow orchestration
Status: 3 added Views & Navigation — 124 kBTop-level views, pages, and routed surfaces
Status: 17 added Panels & Settings — 565 kBConfiguration panels, inspectors, and settings screens
Status: 26 added User & Accounts — 27.7 kBAuthentication, profile, and account management bundles
Status: 11 added Editors & Dialogs — 125 kBModals, dialogs, drawers, and in-app editors
Status: 8 added UI Components — 67.1 kBReusable component library chunks
Status: 14 added Data & Services — 3.52 MBStores, services, APIs, and repositories
Status: 17 added Utilities & Hooks — 550 kBHelpers, composables, and utility bundles
Status: 38 added Vendor & Third-Party — 16.8 MBExternal libraries and shared vendor chunks
Status: 18 added Other — 14.2 MBBundles that do not match a named category
Status: 286 added ⚡ Performance Report
Absolute values
Raw data{
"timestamp": "2026-08-15T00:54:25.148Z",
"gitSha": "089bc1e51814e267e4e58b211c27685d9a67a1da",
"branch": "bl/i18n-openai-client-contract",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2154.305000000022,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.991,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 652.686,
"heapDeltaBytes": 4975252,
"heapUsedBytes": 69410100,
"domNodes": 22,
"jsHeapTotalBytes": 25427968,
"scriptDurationMs": 12.39,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-idle",
"durationMs": 2017.2829999999635,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.958999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 496.82400000000007,
"heapDeltaBytes": 4993460,
"heapUsedBytes": 69527404,
"domNodes": 18,
"jsHeapTotalBytes": 24379392,
"scriptDurationMs": 8.788999999999998,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1884.6410000000446,
"styleRecalcs": 75,
"styleRecalcDurationMs": 37.856,
"layouts": 12,
"layoutDurationMs": 3.7849999999999993,
"taskDurationMs": 900.606,
"heapDeltaBytes": -16045620,
"heapUsedBytes": 48435128,
"domNodes": -281,
"jsHeapTotalBytes": 23040000,
"scriptDurationMs": 108.749,
"eventListeners": -153,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1904.7390000000632,
"styleRecalcs": 76,
"styleRecalcDurationMs": 40.99,
"layouts": 12,
"layoutDurationMs": 3.9439999999999995,
"taskDurationMs": 936.1500000000001,
"heapDeltaBytes": -15599668,
"heapUsedBytes": 48887696,
"domNodes": -282,
"jsHeapTotalBytes": 23302144,
"scriptDurationMs": 114.86000000000001,
"eventListeners": -153,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1721.576999999968,
"styleRecalcs": 32,
"styleRecalcDurationMs": 16.214,
"layouts": 6,
"layoutDurationMs": 0.6680000000000001,
"taskDurationMs": 366.475,
"heapDeltaBytes": 7916476,
"heapUsedBytes": 72352020,
"domNodes": 77,
"jsHeapTotalBytes": 24641536,
"scriptDurationMs": 10,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1751.7259999999624,
"styleRecalcs": 30,
"styleRecalcDurationMs": 17.693,
"layouts": 6,
"layoutDurationMs": 0.6719999999999998,
"taskDurationMs": 414.006,
"heapDeltaBytes": 8042228,
"heapUsedBytes": 72629860,
"domNodes": 75,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 12.584999999999999,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 624.2770000000064,
"styleRecalcs": 13,
"styleRecalcDurationMs": 8.941999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 392.93699999999995,
"heapDeltaBytes": -11099364,
"heapUsedBytes": 53511216,
"domNodes": 22,
"jsHeapTotalBytes": 25165824,
"scriptDurationMs": 55.615,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "dom-widget-clipping",
"durationMs": 607.7810000000454,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.899,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 402.14799999999997,
"heapDeltaBytes": -11324864,
"heapUsedBytes": 53220352,
"domNodes": 18,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 57.00600000000001,
"eventListeners": 0,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2037.842000000012,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.162000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 600.365,
"heapDeltaBytes": 12695600,
"heapUsedBytes": 72292060,
"domNodes": -281,
"jsHeapTotalBytes": 2719744,
"scriptDurationMs": 15.047999999999998,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2041.439999999966,
"styleRecalcs": 8,
"styleRecalcDurationMs": 7.195999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 681.7200000000001,
"heapDeltaBytes": 12916404,
"heapUsedBytes": 72895340,
"domNodes": -283,
"jsHeapTotalBytes": 3506176,
"scriptDurationMs": 19.324,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2170.659999999998,
"styleRecalcs": 68,
"styleRecalcDurationMs": 14.253999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1157.543,
"heapDeltaBytes": -7084360,
"heapUsedBytes": 54353836,
"domNodes": -282,
"jsHeapTotalBytes": 3768320,
"scriptDurationMs": 312.67499999999995,
"eventListeners": -177,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2188.5859999999866,
"styleRecalcs": 69,
"styleRecalcDurationMs": 15.935,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1207.0159999999998,
"heapDeltaBytes": 10791052,
"heapUsedBytes": 71594080,
"domNodes": -283,
"jsHeapTotalBytes": 3436544,
"scriptDurationMs": 314.73699999999997,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3147.498999999982,
"styleRecalcs": 65,
"styleRecalcDurationMs": 15.377000000000002,
"layouts": 60,
"layoutDurationMs": 8.357999999999999,
"taskDurationMs": 1375.334,
"heapDeltaBytes": -6264208,
"heapUsedBytes": 55451600,
"domNodes": -287,
"jsHeapTotalBytes": 2719744,
"scriptDurationMs": 377.85999999999996,
"eventListeners": -153,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3161.654999999996,
"styleRecalcs": 66,
"styleRecalcDurationMs": 17.005,
"layouts": 60,
"layoutDurationMs": 8.570999999999998,
"taskDurationMs": 1370.942,
"heapDeltaBytes": 17293056,
"heapUsedBytes": 79081720,
"domNodes": 14,
"jsHeapTotalBytes": 5505024,
"scriptDurationMs": 386.797,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "minimap-idle",
"durationMs": 2032.794000000024,
"styleRecalcs": 8,
"styleRecalcDurationMs": 7.677999999999997,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 623.4699999999999,
"heapDeltaBytes": 13229640,
"heapUsedBytes": 74550712,
"domNodes": -285,
"jsHeapTotalBytes": 2457600,
"scriptDurationMs": 14.176000000000002,
"eventListeners": -147,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2043.3309999999665,
"styleRecalcs": 7,
"styleRecalcDurationMs": 6.6160000000000005,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 685.222,
"heapDeltaBytes": 12613752,
"heapUsedBytes": 73684284,
"domNodes": -282,
"jsHeapTotalBytes": 1933312,
"scriptDurationMs": 17.531,
"eventListeners": -149,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 590.7230000000254,
"styleRecalcs": 47,
"styleRecalcDurationMs": 10.72,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 401.021,
"heapDeltaBytes": -10794020,
"heapUsedBytes": 53860628,
"domNodes": 20,
"jsHeapTotalBytes": 26214400,
"scriptDurationMs": 118.241,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 628.5030000000233,
"styleRecalcs": 48,
"styleRecalcDurationMs": 12.551000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 427.12800000000004,
"heapDeltaBytes": -10218328,
"heapUsedBytes": 54248020,
"domNodes": 22,
"jsHeapTotalBytes": 25690112,
"scriptDurationMs": 126.83800000000001,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 2003.4239999999954,
"styleRecalcs": 10,
"styleRecalcDurationMs": 7.582,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 466.70899999999995,
"heapDeltaBytes": 4984376,
"heapUsedBytes": 69730508,
"domNodes": 20,
"jsHeapTotalBytes": 24641536,
"scriptDurationMs": 7.308999999999999,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2005.0119999999652,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.154,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 488.77500000000003,
"heapDeltaBytes": 5240116,
"heapUsedBytes": 69970384,
"domNodes": 18,
"jsHeapTotalBytes": 25165824,
"scriptDurationMs": 7.838000000000001,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1693.6979999999835,
"styleRecalcs": 76,
"styleRecalcDurationMs": 35.642,
"layouts": 16,
"layoutDurationMs": 4.559,
"taskDurationMs": 741.2520000000001,
"heapDeltaBytes": -4096276,
"heapUsedBytes": 60740308,
"domNodes": 61,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 80.891,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1696.0520000000088,
"styleRecalcs": 77,
"styleRecalcDurationMs": 37.81699999999999,
"layouts": 16,
"layoutDurationMs": 4.864999999999999,
"taskDurationMs": 789.732,
"heapDeltaBytes": -3677016,
"heapUsedBytes": 61160184,
"domNodes": 63,
"jsHeapTotalBytes": 24903680,
"scriptDurationMs": 89.048,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-transition-enter",
"durationMs": 1400.699999999972,
"styleRecalcs": 18,
"styleRecalcDurationMs": 29.959,
"layouts": 13,
"layoutDurationMs": 11.439000000000002,
"taskDurationMs": 1018.7169999999999,
"heapDeltaBytes": -7804740,
"heapUsedBytes": 75421428,
"domNodes": 13673,
"jsHeapTotalBytes": 12582912,
"scriptDurationMs": 18.597999999999995,
"eventListeners": 2375,
"totalBlockingTimeMs": 128,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "viewport-pan-sweep",
"durationMs": 8275.041999999985,
"styleRecalcs": 249,
"styleRecalcDurationMs": 41.562000000000005,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 4133.612,
"heapDeltaBytes": 14182388,
"heapUsedBytes": 74455500,
"domNodes": -283,
"jsHeapTotalBytes": 3960832,
"scriptDurationMs": 959.083,
"eventListeners": -133,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8248.353999999948,
"styleRecalcs": 249,
"styleRecalcDurationMs": 42.111000000000004,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 4182.603999999999,
"heapDeltaBytes": 9286196,
"heapUsedBytes": 69255372,
"domNodes": -281,
"jsHeapTotalBytes": 3436544,
"scriptDurationMs": 966.5780000000001,
"eventListeners": -163,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.80000000000109
},
{
"name": "vue-large-graph-idle",
"durationMs": 18347.053000000018,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 17430.695,
"heapDeltaBytes": -42838144,
"heapUsedBytes": 167442732,
"domNodes": -8312,
"jsHeapTotalBytes": -10948608,
"scriptDurationMs": 157.67999999999998,
"eventListeners": -16387,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 18732.56900000001,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 17813.164,
"heapDeltaBytes": -30535796,
"heapUsedBytes": 167285884,
"domNodes": -8312,
"jsHeapTotalBytes": -13012992,
"scriptDurationMs": 146.436,
"eventListeners": -16387,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.780000000000047,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 21490.553999999975,
"styleRecalcs": 166,
"styleRecalcDurationMs": 20.828999999999986,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 20839.317000000003,
"heapDeltaBytes": -47316172,
"heapUsedBytes": 163379880,
"domNodes": -8312,
"jsHeapTotalBytes": -14622720,
"scriptDurationMs": 460.844,
"eventListeners": -16383,
"totalBlockingTimeMs": 103,
"frameDurationMs": 17.779999999999927,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 22157.036999999946,
"styleRecalcs": 179,
"styleRecalcDurationMs": 22.919000000000022,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 21555.512,
"heapDeltaBytes": -12169268,
"heapUsedBytes": 185253724,
"domNodes": -8312,
"jsHeapTotalBytes": -11804672,
"scriptDurationMs": 420.27899999999994,
"eventListeners": -16385,
"totalBlockingTimeMs": 83,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 107.516999999973,
"styleRecalcs": 8,
"styleRecalcDurationMs": 14.396,
"layouts": 2,
"layoutDurationMs": 0.49200000000000005,
"taskDurationMs": 78.779,
"heapDeltaBytes": 3161144,
"heapUsedBytes": 66787944,
"domNodes": 113,
"jsHeapTotalBytes": 3145728,
"scriptDurationMs": 5.606999999999999,
"eventListeners": 49,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "workflow-execution",
"durationMs": 455.01600000000053,
"styleRecalcs": 14,
"styleRecalcDurationMs": 20.549000000000003,
"layouts": 3,
"layoutDurationMs": 0.8049999999999999,
"taskDurationMs": 112.644,
"heapDeltaBytes": 4928348,
"heapUsedBytes": 68679572,
"domNodes": 123,
"jsHeapTotalBytes": 5242880,
"scriptDurationMs": 7.357000000000001,
"eventListeners": 97,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
}
]
} |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## bl/i18n-automation-reliability #15229 +/- ##
================================================================
Coverage 81.87% 81.87%
================================================================
Files 1884 1884
Lines 118158 118158
Branches 36173 35703 -470
================================================================
Hits 96742 96742
Misses 20962 20962
Partials 454 454
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
66d728d to
ea943db
Compare
ea943db to
532abef
Compare
aa4f9d5 to
ad6a441
Compare
Keep valid strings when a batch response contains a non-string value so the missing ids route through the existing retry-note rounds instead of failing the locale. Cut malformed-response retries to one, and report the locales that actually have pending work in the translation preflight.
ad6a441 to
ba3590f
Compare
Stacked on #15228.
Summary
Harden the OpenAI translation client contract and expose actual request/token usage.
Changes
Truncated batches (
finish_reason: "length") now split in half and retry each side instead of re-sending an identical request that will truncate again; a truncated single-item batch fails with the existing "lower maxItemsPerRequest" message.A batch response containing a non-string value keeps its valid strings — the affected ids fall through as missing and are re-sent with a
retryNoteby the existingtranslateLocaleItemsrounds, rather than failing the whole locale.response_format: { type: 'json_object' }guarantees parseable JSON, not schema adherence, sonulland numeric echoes remain possible.Malformed-response retries drop from 3 to 1. That inner loop re-sends a byte-identical prompt, so repeats past the first are unlikely to change the outcome; content failures still get
maxTranslationRounds: 3feedback-carrying attempts through the retry-note path. SDK network retries stay at 3, where retrying an identical request is correct.The translation preflight counts locales with pending items instead of every configured locale.
Review Focus
The truncation bisect has no split-depth or run-wide request cap. Worst case per chunk is bounded (~2n leaf calls, each with its own retry budget) but unbounded-feeling for a script that spends money; the usage line reports it only after the fact.
Validation:
mise exec -- pnpm test:unit scripts/i18n/update-locales.test.ts --run(26 passed)mise exec -- pnpm typecheck:scriptsmise exec -- pnpm typecheckmise exec -- pnpm lintmise exec -- pnpm knipmise exec -- pnpm format:check