veryfront 0.1.846 → 0.1.848
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/deno.js +1 -1
- package/esm/extensions/ext-llm-google/src/google-stream.d.ts.map +1 -1
- package/esm/extensions/ext-llm-google/src/google-stream.js +2 -0
- package/esm/extensions/ext-llm-openai/src/openai-chat-stream.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-chat-stream.js +3 -0
- package/esm/extensions/ext-llm-openai/src/openai-provider.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-provider.js +3 -0
- package/esm/extensions/ext-llm-openai/src/openai-responses-stream.d.ts +1 -0
- package/esm/extensions/ext-llm-openai/src/openai-responses-stream.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-responses-stream.js +3 -0
- package/esm/src/agent/ag-ui/browser-encoder.d.ts +5 -0
- package/esm/src/agent/ag-ui/browser-encoder.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/browser-encoder.js +42 -0
- package/esm/src/agent/ag-ui/browser-finalize-tracker.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/browser-finalize-tracker.js +15 -0
- package/esm/src/agent/ag-ui/chat-ui-chunk-browser-encoder.d.ts +1 -1
- package/esm/src/agent/ag-ui/chat-ui-chunk-browser-encoder.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/chat-ui-chunk-browser-encoder.js +20 -0
- package/esm/src/agent/hosted/agent-run-lifecycle.d.ts +3 -0
- package/esm/src/agent/hosted/agent-run-lifecycle.d.ts.map +1 -1
- package/esm/src/agent/hosted/lifecycle.d.ts +3 -0
- package/esm/src/agent/hosted/lifecycle.d.ts.map +1 -1
- package/esm/src/agent/hosted/trace-attributes.d.ts +3 -0
- package/esm/src/agent/hosted/trace-attributes.d.ts.map +1 -1
- package/esm/src/agent/hosted/trace-attributes.js +10 -2
- package/esm/src/agent/runtime/chat-stream-handler.d.ts +8 -0
- package/esm/src/agent/runtime/chat-stream-handler.d.ts.map +1 -1
- package/esm/src/agent/runtime/chat-stream-handler.js +11 -1
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +6 -1
- package/esm/src/agent/runtime/input-utils.d.ts +8 -0
- package/esm/src/agent/runtime/input-utils.d.ts.map +1 -1
- package/esm/src/agent/runtime/input-utils.js +13 -0
- package/esm/src/agent/runtime/runtime-tool-types.d.ts +9 -0
- package/esm/src/agent/runtime/runtime-tool-types.d.ts.map +1 -1
- package/esm/src/agent/schemas/agent.schema.d.ts +4 -0
- package/esm/src/agent/schemas/agent.schema.d.ts.map +1 -1
- package/esm/src/agent/schemas/agent.schema.js +4 -0
- package/esm/src/channels/invoke.d.ts +8 -0
- package/esm/src/channels/invoke.d.ts.map +1 -1
- package/esm/src/channels/invoke.js +16 -0
- package/esm/src/chat/ag-ui.d.ts +4 -0
- package/esm/src/chat/ag-ui.d.ts.map +1 -1
- package/esm/src/chat/ag-ui.js +2 -0
- package/esm/src/chat/chat-ui-message-helpers.d.ts.map +1 -1
- package/esm/src/chat/chat-ui-message-helpers.js +26 -6
- package/esm/src/chat/protocol.d.ts +2 -0
- package/esm/src/chat/protocol.d.ts.map +1 -1
- package/esm/src/chat/types.d.ts +6 -0
- package/esm/src/chat/types.d.ts.map +1 -1
- package/esm/src/chat/types.js +2 -0
- package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/templates/router.js +13 -7
- package/esm/src/provider/runtime-loader/provider-usage.d.ts +1 -0
- package/esm/src/provider/runtime-loader/provider-usage.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader/provider-usage.js +10 -0
- package/esm/src/rendering/renderer.d.ts +7 -0
- package/esm/src/rendering/renderer.d.ts.map +1 -1
- package/esm/src/rendering/renderer.js +169 -1
- package/esm/src/runtime/runtime-bridge.d.ts.map +1 -1
- package/esm/src/runtime/runtime-bridge.js +46 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
|
@@ -60,6 +60,59 @@ const logger = rendererLogger.component("renderer");
|
|
|
60
60
|
const DEFAULT_RENDER_PIPELINE_TIMEOUT_MS = 60_000;
|
|
61
61
|
const RENDER_PIPELINE_TIMEOUT_MS = getEnvNumber("RENDER_TIMEOUT_MS") ??
|
|
62
62
|
DEFAULT_RENDER_PIPELINE_TIMEOUT_MS;
|
|
63
|
+
/** Default number of sibling production routes to warm after the first cacheable request. */
|
|
64
|
+
const DEFAULT_RENDER_PREWARM_MAX_ROUTES = 12;
|
|
65
|
+
/** Default low-impact background concurrency for production route prewarm. */
|
|
66
|
+
const DEFAULT_RENDER_PREWARM_CONCURRENCY = 1;
|
|
67
|
+
/** Bound remembered release contexts so multi-tenant processes cannot grow without limit. */
|
|
68
|
+
const RENDER_PREWARM_CONTEXT_MAX_ENTRIES = 500;
|
|
69
|
+
const RENDER_PREWARM_MAX_ROUTES = getBoundedEnvNumber("VERYFRONT_RENDER_PREWARM_MAX_ROUTES", DEFAULT_RENDER_PREWARM_MAX_ROUTES, 0, 100);
|
|
70
|
+
const RENDER_PREWARM_CONCURRENCY = getBoundedEnvNumber("VERYFRONT_RENDER_PREWARM_CONCURRENCY", DEFAULT_RENDER_PREWARM_CONCURRENCY, 1, 8);
|
|
71
|
+
function getBoundedEnvNumber(name, fallback, min, max) {
|
|
72
|
+
const value = getEnvNumber(name);
|
|
73
|
+
if (value === undefined || Number.isNaN(value))
|
|
74
|
+
return fallback;
|
|
75
|
+
return Math.min(max, Math.max(min, value));
|
|
76
|
+
}
|
|
77
|
+
function normalizeComparableSlug(slug) {
|
|
78
|
+
const trimmed = slug.trim();
|
|
79
|
+
if (!trimmed || trimmed === "index" || trimmed === "/index")
|
|
80
|
+
return "/";
|
|
81
|
+
const withoutTrailingSlash = trimmed.replace(/\/+$/, "");
|
|
82
|
+
const normalized = withoutTrailingSlash.startsWith("/")
|
|
83
|
+
? withoutTrailingSlash
|
|
84
|
+
: `/${withoutTrailingSlash}`;
|
|
85
|
+
return normalized || "/";
|
|
86
|
+
}
|
|
87
|
+
function isConcretePrewarmSlug(slug) {
|
|
88
|
+
const comparable = normalizeComparableSlug(slug);
|
|
89
|
+
return !comparable.includes("[") && !comparable.includes("]") && !comparable.includes("*");
|
|
90
|
+
}
|
|
91
|
+
function prewarmSlugDepth(slug) {
|
|
92
|
+
const comparable = normalizeComparableSlug(slug);
|
|
93
|
+
if (comparable === "/")
|
|
94
|
+
return 0;
|
|
95
|
+
return comparable.split("/").filter(Boolean).length;
|
|
96
|
+
}
|
|
97
|
+
function selectPrewarmSlugs(currentSlug, pages, maxRoutes) {
|
|
98
|
+
if (maxRoutes <= 0)
|
|
99
|
+
return [];
|
|
100
|
+
const currentComparable = normalizeComparableSlug(currentSlug);
|
|
101
|
+
const seen = new Set();
|
|
102
|
+
const candidates = [];
|
|
103
|
+
for (const page of pages) {
|
|
104
|
+
if (!isConcretePrewarmSlug(page))
|
|
105
|
+
continue;
|
|
106
|
+
const comparable = normalizeComparableSlug(page);
|
|
107
|
+
if (comparable === currentComparable || seen.has(comparable))
|
|
108
|
+
continue;
|
|
109
|
+
seen.add(comparable);
|
|
110
|
+
candidates.push({ slug: page, comparable });
|
|
111
|
+
}
|
|
112
|
+
candidates.sort((a, b) => prewarmSlugDepth(a.comparable) - prewarmSlugDepth(b.comparable) ||
|
|
113
|
+
a.comparable.localeCompare(b.comparable));
|
|
114
|
+
return candidates.slice(0, maxRoutes).map(({ slug }) => slug);
|
|
115
|
+
}
|
|
63
116
|
/**
|
|
64
117
|
* Renderer - Shared renderer for all projects
|
|
65
118
|
*
|
|
@@ -89,6 +142,7 @@ export class Renderer {
|
|
|
89
142
|
* Key format: {cachePrefix}:{slug}:{colorScheme}
|
|
90
143
|
*/
|
|
91
144
|
renderFlight = new Singleflight();
|
|
145
|
+
productionPrewarmContexts = new Map();
|
|
92
146
|
constructor(options = {}) {
|
|
93
147
|
this.cache = new ContextAwareCacheCoordinator(options.cache);
|
|
94
148
|
}
|
|
@@ -139,6 +193,7 @@ export class Renderer {
|
|
|
139
193
|
colorScheme: effectiveOptions?.colorScheme,
|
|
140
194
|
duration: `${(performance.now() - startTime).toFixed(2)}ms`,
|
|
141
195
|
});
|
|
196
|
+
this.scheduleProductionRenderPrewarm(slug, effectiveCtx, effectiveOptions, cacheKey);
|
|
142
197
|
return cacheResult.cachedResult;
|
|
143
198
|
}
|
|
144
199
|
if (!(await acquireProjectSlot(effectiveCtx.projectId))) {
|
|
@@ -173,12 +228,18 @@ export class Renderer {
|
|
|
173
228
|
context: { slug, projectId: ctx.projectId, waiting: renderSemaphore.waiting },
|
|
174
229
|
});
|
|
175
230
|
}
|
|
231
|
+
let renderedSuccessfully = false;
|
|
176
232
|
try {
|
|
177
|
-
|
|
233
|
+
const result = await this.doRenderPage(slug, effectiveCtx, effectiveOptions, startTime, cacheKey);
|
|
234
|
+
renderedSuccessfully = true;
|
|
235
|
+
return result;
|
|
178
236
|
}
|
|
179
237
|
finally {
|
|
180
238
|
renderSemaphore.release();
|
|
181
239
|
await releaseProjectSlot(effectiveCtx.projectId);
|
|
240
|
+
if (renderedSuccessfully) {
|
|
241
|
+
this.scheduleProductionRenderPrewarm(slug, effectiveCtx, effectiveOptions, cacheKey);
|
|
242
|
+
}
|
|
182
243
|
}
|
|
183
244
|
}, {
|
|
184
245
|
"renderer.slug": slug,
|
|
@@ -232,6 +293,112 @@ export class Renderer {
|
|
|
232
293
|
const queryParamOptions = ctx.config?.cache?.queryParams;
|
|
233
294
|
return buildQueryAwareCacheKey(slug, options?.url, queryParamOptions);
|
|
234
295
|
}
|
|
296
|
+
scheduleProductionRenderPrewarm(currentSlug, ctx, options, cacheKey) {
|
|
297
|
+
if (!this.shouldScheduleProductionPrewarm(ctx, options, cacheKey))
|
|
298
|
+
return;
|
|
299
|
+
const prewarmKey = this.getProductionPrewarmKey(ctx);
|
|
300
|
+
if (this.productionPrewarmContexts.has(prewarmKey))
|
|
301
|
+
return;
|
|
302
|
+
const prewarmOptions = this.buildCanonicalPrewarmOptions(ctx, options);
|
|
303
|
+
let resolvePromise;
|
|
304
|
+
let rejectPromise;
|
|
305
|
+
const promise = new Promise((resolve, reject) => {
|
|
306
|
+
resolvePromise = resolve;
|
|
307
|
+
rejectPromise = reject;
|
|
308
|
+
});
|
|
309
|
+
this.rememberProductionPrewarm(prewarmKey, promise);
|
|
310
|
+
queueMicrotask(() => {
|
|
311
|
+
void this.runProductionRenderPrewarm(currentSlug, ctx, prewarmOptions)
|
|
312
|
+
.then(resolvePromise, rejectPromise);
|
|
313
|
+
});
|
|
314
|
+
promise.catch((error) => {
|
|
315
|
+
this.productionPrewarmContexts.delete(prewarmKey);
|
|
316
|
+
logger.warn("Production render prewarm failed", {
|
|
317
|
+
projectId: ctx.projectId,
|
|
318
|
+
releaseId: ctx.releaseId,
|
|
319
|
+
error: error instanceof Error ? error.message : String(error),
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
shouldScheduleProductionPrewarm(ctx, options, cacheKey) {
|
|
324
|
+
if (RENDER_PREWARM_MAX_ROUTES <= 0)
|
|
325
|
+
return false;
|
|
326
|
+
if (cacheKey === null)
|
|
327
|
+
return false;
|
|
328
|
+
if (ctx.environment !== "production" || ctx.mode !== "production")
|
|
329
|
+
return false;
|
|
330
|
+
if (!ctx.adapter?.fs)
|
|
331
|
+
return false;
|
|
332
|
+
if (options?.studioEmbed)
|
|
333
|
+
return false;
|
|
334
|
+
if (options?.params || options?.props)
|
|
335
|
+
return false;
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
getProductionPrewarmKey(ctx) {
|
|
339
|
+
return `${ctx.cachePrefix}:canonical`;
|
|
340
|
+
}
|
|
341
|
+
rememberProductionPrewarm(key, promise) {
|
|
342
|
+
while (this.productionPrewarmContexts.size >= RENDER_PREWARM_CONTEXT_MAX_ENTRIES) {
|
|
343
|
+
const oldest = this.productionPrewarmContexts.keys().next().value;
|
|
344
|
+
if (oldest === undefined)
|
|
345
|
+
break;
|
|
346
|
+
this.productionPrewarmContexts.delete(oldest);
|
|
347
|
+
}
|
|
348
|
+
this.productionPrewarmContexts.set(key, promise);
|
|
349
|
+
}
|
|
350
|
+
buildCanonicalPrewarmOptions(ctx, options) {
|
|
351
|
+
return {
|
|
352
|
+
environment: ctx.environment,
|
|
353
|
+
projectId: ctx.projectId,
|
|
354
|
+
projectSlug: ctx.projectSlug,
|
|
355
|
+
contentSourceId: ctx.contentSourceId,
|
|
356
|
+
releaseId: ctx.releaseId,
|
|
357
|
+
releaseAssetManifest: options?.releaseAssetManifest ?? null,
|
|
358
|
+
noHmr: options?.noHmr,
|
|
359
|
+
forceProductionScripts: options?.forceProductionScripts,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
async runProductionRenderPrewarm(currentSlug, ctx, options) {
|
|
363
|
+
const pages = await this.getAllPages(ctx);
|
|
364
|
+
const slugs = selectPrewarmSlugs(currentSlug, pages, RENDER_PREWARM_MAX_ROUTES);
|
|
365
|
+
if (slugs.length === 0)
|
|
366
|
+
return;
|
|
367
|
+
logger.debug("Production render prewarm started", {
|
|
368
|
+
projectId: ctx.projectId,
|
|
369
|
+
releaseId: ctx.releaseId,
|
|
370
|
+
currentSlug,
|
|
371
|
+
routeCount: slugs.length,
|
|
372
|
+
concurrency: RENDER_PREWARM_CONCURRENCY,
|
|
373
|
+
});
|
|
374
|
+
let nextIndex = 0;
|
|
375
|
+
const workerCount = Math.min(RENDER_PREWARM_CONCURRENCY, slugs.length);
|
|
376
|
+
const runWorker = async () => {
|
|
377
|
+
while (true) {
|
|
378
|
+
const index = nextIndex++;
|
|
379
|
+
if (index >= slugs.length)
|
|
380
|
+
return;
|
|
381
|
+
const slug = slugs[index];
|
|
382
|
+
try {
|
|
383
|
+
await this.renderPage(slug, ctx, options);
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
logger.warn("Production render prewarm route failed", {
|
|
387
|
+
slug,
|
|
388
|
+
projectId: ctx.projectId,
|
|
389
|
+
releaseId: ctx.releaseId,
|
|
390
|
+
error: error instanceof Error ? error.message : String(error),
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
await Promise.all(Array.from({ length: workerCount }, () => runWorker()));
|
|
396
|
+
logger.debug("Production render prewarm finished", {
|
|
397
|
+
projectId: ctx.projectId,
|
|
398
|
+
releaseId: ctx.releaseId,
|
|
399
|
+
routeCount: slugs.length,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
235
402
|
async doRenderPage(slug, ctx, options, startTime, cacheKey) {
|
|
236
403
|
const effectiveKey = cacheKey ?? dntShim.crypto.randomUUID();
|
|
237
404
|
const flightKey = this.getSingleflightKey(effectiveKey, ctx, options?.colorScheme);
|
|
@@ -344,6 +511,7 @@ export class Renderer {
|
|
|
344
511
|
}
|
|
345
512
|
async destroy() {
|
|
346
513
|
await this.cache.destroy();
|
|
514
|
+
this.productionPrewarmContexts.clear();
|
|
347
515
|
this.initialized = false;
|
|
348
516
|
this.initializationPromise = null;
|
|
349
517
|
logger.debug("Destroyed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-bridge.d.ts","sourceRoot":"","sources":["../../../src/src/runtime/runtime-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,cAAc,EACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EAEb,MAAM,sBAAsB,CAAC;AAE9B,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,4BAA4B,EAAE,CAAC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2BAA2B,CAAC,EAAE,6BAA6B,CAAC;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,4BAA4B,EAAE,CAAC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2BAA2B,CAAC,EAAE,6BAA6B,CAAC;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-bridge.d.ts","sourceRoot":"","sources":["../../../src/src/runtime/runtime-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,cAAc,EACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EAEb,MAAM,sBAAsB,CAAC;AAE9B,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,4BAA4B,EAAE,CAAC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2BAA2B,CAAC,EAAE,6BAA6B,CAAC;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,4BAA4B,EAAE,CAAC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2BAA2B,CAAC,EAAE,6BAA6B,CAAC;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAueF,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,WAAW,CAAC,yBAAyB,CAAC,CAuBjG;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CAsC1E;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY;;;;;;;;GAW1C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB;;;;;;;GAUlD;AACD,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAsBjE"}
|
|
@@ -68,14 +68,30 @@ function normalizeUsage(usage) {
|
|
|
68
68
|
const inputTokens = "total" in usage.inputTokens && typeof usage.inputTokens.total === "number"
|
|
69
69
|
? usage.inputTokens.total
|
|
70
70
|
: undefined;
|
|
71
|
+
const cacheReadInputTokens = "cached" in usage.inputTokens && typeof usage.inputTokens.cached === "number"
|
|
72
|
+
? usage.inputTokens.cached
|
|
73
|
+
: "cacheRead" in usage.inputTokens && typeof usage.inputTokens.cacheRead === "number"
|
|
74
|
+
? usage.inputTokens.cacheRead
|
|
75
|
+
: undefined;
|
|
76
|
+
const cacheCreationInputTokens = "cacheCreation" in usage.inputTokens && typeof usage.inputTokens.cacheCreation === "number"
|
|
77
|
+
? usage.inputTokens.cacheCreation
|
|
78
|
+
: undefined;
|
|
71
79
|
const outputTokens = "outputTokens" in usage && typeof usage.outputTokens === "object" && usage.outputTokens &&
|
|
72
80
|
"total" in usage.outputTokens && typeof usage.outputTokens.total === "number"
|
|
73
81
|
? usage.outputTokens.total
|
|
74
82
|
: undefined;
|
|
83
|
+
const reasoningTokens = "outputTokens" in usage && typeof usage.outputTokens === "object" && usage.outputTokens &&
|
|
84
|
+
"reasoning" in usage.outputTokens && typeof usage.outputTokens.reasoning === "number"
|
|
85
|
+
? usage.outputTokens.reasoning
|
|
86
|
+
: undefined;
|
|
75
87
|
return {
|
|
76
88
|
inputTokens,
|
|
77
89
|
outputTokens,
|
|
78
90
|
totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0),
|
|
91
|
+
...(cacheCreationInputTokens !== undefined ? { cacheCreationInputTokens } : {}),
|
|
92
|
+
...(cacheReadInputTokens !== undefined ? { cacheReadInputTokens } : {}),
|
|
93
|
+
...(cacheReadInputTokens !== undefined ? { cachedInputTokens: cacheReadInputTokens } : {}),
|
|
94
|
+
...(reasoningTokens !== undefined ? { reasoningTokens } : {}),
|
|
79
95
|
};
|
|
80
96
|
}
|
|
81
97
|
const flatUsage = usage;
|
|
@@ -83,6 +99,20 @@ function normalizeUsage(usage) {
|
|
|
83
99
|
inputTokens: flatUsage.inputTokens,
|
|
84
100
|
outputTokens: flatUsage.outputTokens,
|
|
85
101
|
totalTokens: flatUsage.totalTokens,
|
|
102
|
+
...(typeof flatUsage.cacheCreationInputTokens === "number"
|
|
103
|
+
? { cacheCreationInputTokens: flatUsage.cacheCreationInputTokens }
|
|
104
|
+
: {}),
|
|
105
|
+
...(typeof flatUsage.cacheReadInputTokens === "number"
|
|
106
|
+
? { cacheReadInputTokens: flatUsage.cacheReadInputTokens }
|
|
107
|
+
: {}),
|
|
108
|
+
...(typeof flatUsage.cachedInputTokens === "number"
|
|
109
|
+
? { cachedInputTokens: flatUsage.cachedInputTokens }
|
|
110
|
+
: typeof flatUsage.cacheReadInputTokens === "number"
|
|
111
|
+
? { cachedInputTokens: flatUsage.cacheReadInputTokens }
|
|
112
|
+
: {}),
|
|
113
|
+
...(typeof flatUsage.reasoningTokens === "number"
|
|
114
|
+
? { reasoningTokens: flatUsage.reasoningTokens }
|
|
115
|
+
: {}),
|
|
86
116
|
};
|
|
87
117
|
}
|
|
88
118
|
function normalizeFinishReason(finishReason) {
|
|
@@ -235,6 +265,7 @@ function normalizeStreamPart(part) {
|
|
|
235
265
|
}
|
|
236
266
|
const finishPart = part;
|
|
237
267
|
const usage = normalizeUsage(finishPart.usage);
|
|
268
|
+
const recomputedTotal = usage ? (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0) : undefined;
|
|
238
269
|
return {
|
|
239
270
|
type: "finish",
|
|
240
271
|
finishReason: normalizeFinishReason(finishPart.finishReason),
|
|
@@ -243,6 +274,21 @@ function normalizeStreamPart(part) {
|
|
|
243
274
|
totalUsage: {
|
|
244
275
|
inputTokens: usage.inputTokens,
|
|
245
276
|
outputTokens: usage.outputTokens,
|
|
277
|
+
...(usage.totalTokens !== undefined && usage.totalTokens !== recomputedTotal
|
|
278
|
+
? { totalTokens: usage.totalTokens }
|
|
279
|
+
: {}),
|
|
280
|
+
...(usage.cacheCreationInputTokens !== undefined
|
|
281
|
+
? { cacheCreationInputTokens: usage.cacheCreationInputTokens }
|
|
282
|
+
: {}),
|
|
283
|
+
...(usage.cacheReadInputTokens !== undefined
|
|
284
|
+
? { cacheReadInputTokens: usage.cacheReadInputTokens }
|
|
285
|
+
: {}),
|
|
286
|
+
...(usage.cachedInputTokens !== undefined
|
|
287
|
+
? { cachedInputTokens: usage.cachedInputTokens }
|
|
288
|
+
: {}),
|
|
289
|
+
...(usage.reasoningTokens !== undefined
|
|
290
|
+
? { reasoningTokens: usage.reasoningTokens }
|
|
291
|
+
: {}),
|
|
246
292
|
},
|
|
247
293
|
}
|
|
248
294
|
: {}),
|