@promptbook/wizard 0.112.0-115 → 0.112.0-118

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.
Files changed (31) hide show
  1. package/esm/index.es.js +211 -59
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/_packages/components.index.d.ts +2 -0
  4. package/esm/src/_packages/node.index.d.ts +20 -0
  5. package/esm/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
  6. package/esm/src/book-3.0/CliAgent.d.ts +15 -17
  7. package/esm/src/book-3.0/agentFolderPaths.d.ts +30 -0
  8. package/esm/src/book-3.0/cliAgentEnv.d.ts +33 -0
  9. package/esm/src/book-components/BookEditor/BookEditorBrowserConfig.d.ts +2 -0
  10. package/esm/src/book-components/BookEditor/BookEditorForClient.d.ts +7 -0
  11. package/esm/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +9 -0
  12. package/esm/src/cli/cli-commands/agent-folder/agentProjectPaths.d.ts +2 -30
  13. package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
  14. package/esm/src/scrapers/website/utils/createShowdownConverter.d.ts +2 -2
  15. package/esm/src/version.d.ts +1 -1
  16. package/package.json +2 -3
  17. package/umd/index.umd.js +215 -59
  18. package/umd/index.umd.js.map +1 -1
  19. package/umd/src/_packages/components.index.d.ts +2 -0
  20. package/umd/src/_packages/node.index.d.ts +20 -0
  21. package/umd/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
  22. package/umd/src/book-3.0/CliAgent.d.ts +15 -17
  23. package/umd/src/book-3.0/agentFolderPaths.d.ts +30 -0
  24. package/umd/src/book-3.0/cliAgentEnv.d.ts +33 -0
  25. package/umd/src/book-components/BookEditor/BookEditorBrowserConfig.d.ts +2 -0
  26. package/umd/src/book-components/BookEditor/BookEditorForClient.d.ts +7 -0
  27. package/umd/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +9 -0
  28. package/umd/src/cli/cli-commands/agent-folder/agentProjectPaths.d.ts +2 -30
  29. package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
  30. package/umd/src/scrapers/website/utils/createShowdownConverter.d.ts +2 -2
  31. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -7,20 +7,19 @@ import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
7
7
  import { mkdir, rm, readFile, readdir, rename, rmdir, stat, access, constants, writeFile, watch, unlink } from 'fs/promises';
8
8
  import { spawn } from 'child_process';
9
9
  import { forTime } from 'waitasecond';
10
- import { SHA256 } from 'crypto-js';
10
+ import CryptoJS from 'crypto-js';
11
11
  import hexEncoder from 'crypto-js/enc-hex';
12
12
  import { basename, join, dirname, isAbsolute, relative } from 'path';
13
13
  import { Readability } from '@mozilla/readability';
14
14
  import { JSDOM } from 'jsdom';
15
- import { Converter } from 'showdown';
15
+ import showdown from 'showdown';
16
16
  import * as dotenv from 'dotenv';
17
17
  import sha256 from 'crypto-js/sha256';
18
18
  import JSZip from 'jszip';
19
19
  import { Subject, BehaviorSubject } from 'rxjs';
20
- import { randomBytes } from 'crypto';
21
20
  import moment from 'moment';
22
21
  import { lookup, extension } from 'mime-types';
23
- import { parse, unparse } from 'papaparse';
22
+ import papaparse from 'papaparse';
24
23
  import { fileSearchTool, tool, Agent as Agent$1, webSearchTool, run, setDefaultOpenAIClient, setDefaultOpenAIKey } from '@openai/agents';
25
24
  import OpenAI from 'openai';
26
25
 
@@ -38,7 +37,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
38
37
  * @generated
39
38
  * @see https://github.com/webgptorg/promptbook
40
39
  */
41
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-115';
40
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-118';
42
41
  /**
43
42
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
44
43
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2346,7 +2345,7 @@ class ParseError extends Error {
2346
2345
  * @private internal helper function
2347
2346
  */
2348
2347
  function $randomToken(randomness) {
2349
- return randomBytes(randomness).toString('hex');
2348
+ return CryptoJS.lib.WordArray.random(randomness).toString(CryptoJS.enc.Hex);
2350
2349
  }
2351
2350
  // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
2352
2351
  // TODO: Maybe use nanoid instead https://github.com/ai/nanoid
@@ -13301,7 +13300,7 @@ function $registeredScrapersMessage(availableScrapers) {
13301
13300
  * @public exported from `@promptbook/editable`
13302
13301
  */
13303
13302
  function knowledgeSourceContentToName(knowledgeSourceContent) {
13304
- const hash = SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
13303
+ const hash = CryptoJS.SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
13305
13304
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
13306
13305
  .toString( /* hex */)
13307
13306
  .substring(0, 20);
@@ -14181,7 +14180,7 @@ function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO:
14181
14180
  console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
14182
14181
  value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
14183
14182
  }
14184
- const csv = parse(value, settings);
14183
+ const csv = papaparse.parse(value, settings);
14185
14184
  return csv;
14186
14185
  }
14187
14186
 
@@ -14266,10 +14265,10 @@ const CsvFormatParser = {
14266
14265
  i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
14267
14266
  );
14268
14267
  */
14269
- await onProgress(unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
14268
+ await onProgress(papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
14270
14269
  }
14271
14270
  }
14272
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
14271
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
14273
14272
  },
14274
14273
  },
14275
14274
  {
@@ -14297,7 +14296,7 @@ const CsvFormatParser = {
14297
14296
  return /* not await */ mapCallback({ [key]: value }, index, array.length);
14298
14297
  }));
14299
14298
  }));
14300
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
14299
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
14301
14300
  },
14302
14301
  },
14303
14302
  ],
@@ -16313,7 +16312,7 @@ async function getScraperIntermediateSource(source, options) {
16313
16312
  const { filename: sourceFilename, url } = source;
16314
16313
  const { rootDirname, cacheDirname, intermediateFilesStrategy, extension, isVerbose } = options;
16315
16314
  // TODO: [👬] DRY
16316
- const hash = SHA256(
16315
+ const hash = CryptoJS.SHA256(
16317
16316
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
16318
16317
  hexEncoder.parse(sourceFilename || url || 'untitled'))
16319
16318
  .toString( /* hex */)
@@ -17216,7 +17215,7 @@ const _WebsiteScraperMetadataRegistration = $scrapersMetadataRegister.register(w
17216
17215
  * @private utility of `WebsiteScraper`
17217
17216
  */
17218
17217
  function createShowdownConverter() {
17219
- return new Converter({
17218
+ return new showdown.Converter({
17220
17219
  flavor: 'github',
17221
17220
  /*
17222
17221
  > import showdownHighlight from 'showdown-highlight';
@@ -17400,7 +17399,7 @@ function normalizeWhitespaces(sentence) {
17400
17399
  * @public exported from `@promptbook/utils`
17401
17400
  */
17402
17401
  function computeHash(value) {
17403
- return SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
17402
+ return CryptoJS.SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
17404
17403
  }
17405
17404
  // TODO: [🥬][🥬] Use this ACRY
17406
17405
 
@@ -22094,21 +22093,22 @@ function getPointBounds(points) {
22094
22093
  * @private helper of `fractalAvatarVisual`
22095
22094
  */
22096
22095
  function drawDragonCurveLayer(context, points, options) {
22097
- const { size, primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
22096
+ const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
22098
22097
  const firstPoint = points[0];
22099
22098
  const lastPoint = points[points.length - 1];
22100
22099
  const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
22101
22100
  ribbonGradient.addColorStop(0, `${primaryColor}f2`);
22102
22101
  ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
22103
22102
  ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
22103
+ // Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
22104
+ // context.filter blur, which triggers a costly software rasterization pass every frame.
22104
22105
  context.save();
22105
22106
  context.beginPath();
22106
22107
  tracePolyline(context, points);
22107
- context.strokeStyle = `${shadowColor}82`;
22108
- context.lineWidth = strokeWidth * 1.8;
22108
+ context.strokeStyle = `${shadowColor}48`;
22109
+ context.lineWidth = strokeWidth * 4.5;
22109
22110
  context.lineJoin = 'round';
22110
22111
  context.lineCap = 'round';
22111
- context.filter = `blur(${size * 0.022}px)`;
22112
22112
  context.stroke();
22113
22113
  context.restore();
22114
22114
  context.beginPath();
@@ -22692,11 +22692,23 @@ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY,
22692
22692
  * @private helper of `minecraft2AvatarVisual`
22693
22693
  */
22694
22694
  function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
22695
+ const cx = size * 0.5 + interaction.gazeX * size * 0.03;
22696
+ const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
22697
+ const rx = size * (0.16 + interaction.intensity * 0.015);
22698
+ const ry = size * 0.055;
22699
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
22695
22700
  context.save();
22696
- context.fillStyle = `${palette.shadow}66`;
22697
- context.filter = `blur(${size * 0.02}px)`;
22701
+ context.translate(cx, cy);
22702
+ context.scale(1, ry / rx);
22703
+ const blurRadius = rx * 1.4;
22704
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
22705
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
22706
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
22707
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
22708
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
22709
+ context.fillStyle = shadowGradient;
22698
22710
  context.beginPath();
22699
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.03, size * 0.85 + Math.sin(timeMs / 880) * size * 0.01, size * (0.16 + interaction.intensity * 0.015), size * 0.055, 0, 0, Math.PI * 2);
22711
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
22700
22712
  context.fill();
22701
22713
  context.restore();
22702
22714
  }
@@ -22920,13 +22932,27 @@ const minecraftAvatarVisual = {
22920
22932
  spotlight.addColorStop(1, `${palette.highlight}00`);
22921
22933
  context.fillStyle = spotlight;
22922
22934
  context.fillRect(0, 0, size, size);
22923
- context.save();
22924
- context.fillStyle = 'rgba(0, 0, 0, 0.22)';
22925
- context.filter = `blur(${size * 0.018}px)`;
22926
- context.beginPath();
22927
- context.ellipse(size * 0.5, size * 0.86, size * 0.2, size * 0.06, 0, 0, Math.PI * 2);
22928
- context.fill();
22929
- context.restore();
22935
+ {
22936
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
22937
+ const cx = size * 0.5;
22938
+ const cy = size * 0.86;
22939
+ const rx = size * 0.2;
22940
+ const ry = size * 0.06;
22941
+ const blurRadius = rx * 1.4;
22942
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
22943
+ shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
22944
+ shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
22945
+ shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
22946
+ shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
22947
+ context.save();
22948
+ context.translate(cx, cy);
22949
+ context.scale(1, ry / rx);
22950
+ context.fillStyle = shadowGradient;
22951
+ context.beginPath();
22952
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
22953
+ context.fill();
22954
+ context.restore();
22955
+ }
22930
22956
  drawVoxelCuboid(context, {
22931
22957
  x: bodyX,
22932
22958
  y: bodyY,
@@ -23978,6 +24004,35 @@ const LIGHT_DIRECTION$2 = normalizeVector3({
23978
24004
  y: -0.62,
23979
24005
  z: 0.94,
23980
24006
  });
24007
+ /**
24008
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
24009
+ *
24010
+ * @private helper of `octopus3dAvatarVisual`
24011
+ */
24012
+ const octopus3dStableStateCache = new WeakMap();
24013
+ /**
24014
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
24015
+ *
24016
+ * @private helper of `octopus3dAvatarVisual`
24017
+ */
24018
+ function getOctopus3dStableState(createRandom) {
24019
+ const cached = octopus3dStableStateCache.get(createRandom);
24020
+ if (cached !== undefined) {
24021
+ return cached;
24022
+ }
24023
+ const animationRandom = createRandom('octopus3d-animation-profile');
24024
+ const eyeRandom = createRandom('octopus3d-eye-profile');
24025
+ const leftEyePhaseOffset = eyeRandom() * 0.6;
24026
+ const rightEyePhaseOffset = eyeRandom() * 0.6;
24027
+ const state = {
24028
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
24029
+ animationPhase: animationRandom() * Math.PI * 2,
24030
+ leftEyePhaseOffset,
24031
+ rightEyePhaseOffset,
24032
+ };
24033
+ octopus3dStableStateCache.set(createRandom, state);
24034
+ return state;
24035
+ }
23981
24036
  /**
23982
24037
  * Proper 3D Octopus visual built from projected organic meshes and tentacles.
23983
24038
  *
@@ -23990,10 +24045,7 @@ const octopus3dAvatarVisual = {
23990
24045
  isAnimated: true,
23991
24046
  supportsPointerTracking: true,
23992
24047
  render({ context, size, palette, createRandom, timeMs, interaction }) {
23993
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
23994
- const animationRandom = createRandom('octopus3d-animation-profile');
23995
- const eyeRandom = createRandom('octopus3d-eye-profile');
23996
- const animationPhase = animationRandom() * Math.PI * 2;
24048
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
23997
24049
  const sceneCenterX = size * 0.5;
23998
24050
  const sceneCenterY = size * 0.56;
23999
24051
  const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
@@ -24090,12 +24142,12 @@ const octopus3dAvatarVisual = {
24090
24142
  x: -faceEyeSpacing,
24091
24143
  y: faceEyeYOffset,
24092
24144
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
24093
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
24145
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24094
24146
  drawProjectedOrganicEye(context, {
24095
24147
  x: faceEyeSpacing,
24096
24148
  y: faceEyeYOffset,
24097
24149
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
24098
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
24150
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24099
24151
  drawProjectedOrganicMouth(context, [
24100
24152
  {
24101
24153
  x: -mouthHalfWidth,
@@ -24139,14 +24191,28 @@ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCent
24139
24191
  /**
24140
24192
  * Draws the soft ground shadow below the octopus.
24141
24193
  *
24194
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
24195
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
24196
+ *
24142
24197
  * @private helper of `octopus3dAvatarVisual`
24143
24198
  */
24144
24199
  function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
24200
+ const cx = size * 0.5 + interaction.gazeX * size * 0.04;
24201
+ const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
24202
+ const rx = size * (0.18 + interaction.intensity * 0.02);
24203
+ const ry = size * 0.06;
24145
24204
  context.save();
24146
- context.fillStyle = `${palette.shadow}66`;
24147
- context.filter = `blur(${size * 0.022}px)`;
24205
+ context.translate(cx, cy);
24206
+ context.scale(1, ry / rx);
24207
+ const blurRadius = rx * 1.4;
24208
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
24209
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
24210
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
24211
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
24212
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
24213
+ context.fillStyle = shadowGradient;
24148
24214
  context.beginPath();
24149
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.04, size * 0.87 + Math.sin(timeMs / 920) * size * 0.008, size * (0.18 + interaction.intensity * 0.02), size * 0.06, 0, 0, Math.PI * 2);
24215
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
24150
24216
  context.fill();
24151
24217
  context.restore();
24152
24218
  }
@@ -24377,6 +24443,35 @@ const LIGHT_DIRECTION$1 = normalizeVector3({
24377
24443
  y: -0.6,
24378
24444
  z: 0.98,
24379
24445
  });
24446
+ /**
24447
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
24448
+ *
24449
+ * @private helper of `octopus3d2AvatarVisual`
24450
+ */
24451
+ const octopus3d2StableStateCache = new WeakMap();
24452
+ /**
24453
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
24454
+ *
24455
+ * @private helper of `octopus3d2AvatarVisual`
24456
+ */
24457
+ function getOctopus3d2StableState(createRandom) {
24458
+ const cached = octopus3d2StableStateCache.get(createRandom);
24459
+ if (cached !== undefined) {
24460
+ return cached;
24461
+ }
24462
+ const animationRandom = createRandom('octopus3d2-animation-profile');
24463
+ const eyeRandom = createRandom('octopus3d2-eye-profile');
24464
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
24465
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
24466
+ const state = {
24467
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
24468
+ animationPhase: animationRandom() * Math.PI * 2,
24469
+ leftEyePhaseOffset,
24470
+ rightEyePhaseOffset,
24471
+ };
24472
+ octopus3d2StableStateCache.set(createRandom, state);
24473
+ return state;
24474
+ }
24380
24475
  /**
24381
24476
  * Octopus 3D 2 avatar visual.
24382
24477
  *
@@ -24389,10 +24484,7 @@ const octopus3d2AvatarVisual = {
24389
24484
  isAnimated: true,
24390
24485
  supportsPointerTracking: true,
24391
24486
  render({ context, size, palette, createRandom, timeMs, interaction }) {
24392
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
24393
- const animationRandom = createRandom('octopus3d2-animation-profile');
24394
- const eyeRandom = createRandom('octopus3d2-eye-profile');
24395
- const animationPhase = animationRandom() * Math.PI * 2;
24487
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
24396
24488
  const sceneCenterX = size * 0.5;
24397
24489
  const sceneCenterY = size * 0.575;
24398
24490
  const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
@@ -24445,8 +24537,8 @@ const octopus3d2AvatarVisual = {
24445
24537
  const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
24446
24538
  const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
24447
24539
  const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
24448
- drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
24449
- drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
24540
+ drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24541
+ drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24450
24542
  drawProjectedOrganicMouth(context, [
24451
24543
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
24452
24544
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -24475,14 +24567,28 @@ function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, scene
24475
24567
  /**
24476
24568
  * Draws the soft floor shadow that anchors the single mesh in the frame.
24477
24569
  *
24570
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
24571
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
24572
+ *
24478
24573
  * @private helper of `octopus3d2AvatarVisual`
24479
24574
  */
24480
24575
  function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
24576
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
24577
+ const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
24578
+ const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
24579
+ const ry = size * 0.062;
24481
24580
  context.save();
24482
- context.fillStyle = `${palette.shadow}66`;
24483
- context.filter = `blur(${size * 0.024}px)`;
24581
+ context.translate(cx, cy);
24582
+ context.scale(1, ry / rx);
24583
+ const blurRadius = rx * 1.4;
24584
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
24585
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
24586
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
24587
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
24588
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
24589
+ context.fillStyle = shadowGradient;
24484
24590
  context.beginPath();
24485
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.045, size * 0.88 + Math.sin(timeMs / 940) * size * 0.008, size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018), size * 0.062, 0, 0, Math.PI * 2);
24591
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
24486
24592
  context.fill();
24487
24593
  context.restore();
24488
24594
  }
@@ -24638,6 +24744,40 @@ const LIGHT_DIRECTION = normalizeVector3({
24638
24744
  * @private helper of `octopus3d3AvatarVisual`
24639
24745
  */
24640
24746
  const OCTOPUS_TENTACLE_COUNT = 8;
24747
+ /**
24748
+ * Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
24749
+ * mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
24750
+ * React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
24751
+ *
24752
+ * @private helper of `octopus3d3AvatarVisual`
24753
+ */
24754
+ const stableStateCache = new WeakMap();
24755
+ /**
24756
+ * Returns the stable per-avatar state, computing it on first access and returning the cached
24757
+ * result on every subsequent call within the same `<Avatar/>` mount.
24758
+ *
24759
+ * @private helper of `octopus3d3AvatarVisual`
24760
+ */
24761
+ function getOctopus3d3StableState(createRandom) {
24762
+ const cached = stableStateCache.get(createRandom);
24763
+ if (cached !== undefined) {
24764
+ return cached;
24765
+ }
24766
+ const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
24767
+ const animationRandom = createRandom('octopus3d3-animation-profile');
24768
+ const eyeRandom = createRandom('octopus3d3-eye-profile');
24769
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
24770
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
24771
+ const state = {
24772
+ morphologyProfile,
24773
+ animationPhase: animationRandom() * Math.PI * 2,
24774
+ leftEyePhaseOffset,
24775
+ rightEyePhaseOffset,
24776
+ tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
24777
+ };
24778
+ stableStateCache.set(createRandom, state);
24779
+ return state;
24780
+ }
24641
24781
  /**
24642
24782
  * Octopus 3D 3 avatar visual.
24643
24783
  *
@@ -24650,11 +24790,7 @@ const octopus3d3AvatarVisual = {
24650
24790
  isAnimated: true,
24651
24791
  supportsPointerTracking: true,
24652
24792
  render({ context, size, palette, createRandom, timeMs, interaction }) {
24653
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
24654
- const animationRandom = createRandom('octopus3d3-animation-profile');
24655
- const eyeRandom = createRandom('octopus3d3-eye-profile');
24656
- const animationPhase = animationRandom() * Math.PI * 2;
24657
- const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
24793
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
24658
24794
  const sceneCenterX = size * 0.5;
24659
24795
  const sceneCenterY = size * 0.535;
24660
24796
  const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
@@ -24731,8 +24867,8 @@ const octopus3d3AvatarVisual = {
24731
24867
  size,
24732
24868
  palette,
24733
24869
  });
24734
- drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
24735
- drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
24870
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24871
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24736
24872
  drawProjectedOrganicMouth(context, [
24737
24873
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
24738
24874
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -24783,14 +24919,30 @@ function drawContinuousOctopusAtmosphere(context, size, palette, sceneCenterX, s
24783
24919
  /**
24784
24920
  * Draws the soft lower shadow that anchors the octopus in the avatar frame.
24785
24921
  *
24922
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
24923
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
24924
+ *
24786
24925
  * @private helper of `octopus3d3AvatarVisual`
24787
24926
  */
24788
24927
  function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
24928
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
24929
+ const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
24930
+ const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
24931
+ const ry = size * 0.06;
24932
+ // Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
24933
+ // then fill with a radial gradient that approximates the blurry edge without context.filter.
24789
24934
  context.save();
24790
- context.fillStyle = `${palette.shadow}66`;
24791
- context.filter = `blur(${size * 0.025}px)`;
24935
+ context.translate(cx, cy);
24936
+ context.scale(1, ry / rx);
24937
+ const blurRadius = rx * 1.4;
24938
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
24939
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
24940
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
24941
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
24942
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
24943
+ context.fillStyle = shadowGradient;
24792
24944
  context.beginPath();
24793
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.045, size * 0.9 + Math.sin(timeMs / 980) * size * 0.007, size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02), size * 0.06, 0, 0, Math.PI * 2);
24945
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
24794
24946
  context.fill();
24795
24947
  context.restore();
24796
24948
  }
@@ -49799,7 +49951,7 @@ function emitAgentLlmExecutionToolsAssistantPreparationProgress(options) {
49799
49951
  * Computes one stable hash from a JSON-serializable value.
49800
49952
  */
49801
49953
  function computeJsonHash$1(value) {
49802
- return SHA256(JSON.stringify(value)).toString();
49954
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
49803
49955
  }
49804
49956
  /**
49805
49957
  * Handles OpenAI AgentKit-backed executions for `AgentLlmExecutionTools`.
@@ -49957,7 +50109,7 @@ AgentLlmExecutionToolsAgentKitRunner.vectorStoreCache = new Map();
49957
50109
  * Computes one stable hash from a JSON-serializable value.
49958
50110
  */
49959
50111
  function computeJsonHash(value) {
49960
- return SHA256(JSON.stringify(value)).toString();
50112
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
49961
50113
  }
49962
50114
  /**
49963
50115
  * Removes assistant-managed requirements before the prompt is executed via OpenAI Assistants.
@@ -50759,7 +50911,7 @@ class AgentLlmExecutionTools {
50759
50911
  * Returns a virtual model name representing the agent behavior.
50760
50912
  */
50761
50913
  get modelName() {
50762
- const hash = SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
50914
+ const hash = CryptoJS.SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
50763
50915
  const agentId = hash.substring(0, 10);
50764
50916
  return (normalizeToKebabCase(this.title) + '-' + agentId);
50765
50917
  }