@promptbook/browser 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 +208 -56
  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 +212 -57
  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
@@ -1,15 +1,14 @@
1
1
  import { spaceTrim as spaceTrim$1 } from 'spacetrim';
2
2
  import { Registration } from 'destroyable';
3
3
  import { BehaviorSubject, Subject } from 'rxjs';
4
- import { randomBytes } from 'crypto';
5
- import { SHA256 } from 'crypto-js';
4
+ import CryptoJS from 'crypto-js';
6
5
  import hexEncoder from 'crypto-js/enc-hex';
7
6
  import { basename, join, dirname, isAbsolute } from 'path';
8
7
  import moment from 'moment';
9
8
  import { lookup, extension } from 'mime-types';
10
9
  import { forTime } from 'waitasecond';
11
10
  import sha256 from 'crypto-js/sha256';
12
- import { parse, unparse } from 'papaparse';
11
+ import papaparse from 'papaparse';
13
12
  import { fileSearchTool, tool, Agent as Agent$1, webSearchTool, run, setDefaultOpenAIClient, setDefaultOpenAIKey } from '@openai/agents';
14
13
  import colors from 'colors';
15
14
  import Bottleneck from 'bottleneck';
@@ -29,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
29
28
  * @generated
30
29
  * @see https://github.com/webgptorg/promptbook
31
30
  */
32
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-115';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-118';
33
32
  /**
34
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
35
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2332,7 +2331,7 @@ function valueToString(value) {
2332
2331
  * @public exported from `@promptbook/utils`
2333
2332
  */
2334
2333
  function computeHash(value) {
2335
- return SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
2334
+ return CryptoJS.SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
2336
2335
  }
2337
2336
  // TODO: [🥬][🥬] Use this ACRY
2338
2337
 
@@ -6161,21 +6160,22 @@ function getPointBounds(points) {
6161
6160
  * @private helper of `fractalAvatarVisual`
6162
6161
  */
6163
6162
  function drawDragonCurveLayer(context, points, options) {
6164
- const { size, primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
6163
+ const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
6165
6164
  const firstPoint = points[0];
6166
6165
  const lastPoint = points[points.length - 1];
6167
6166
  const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
6168
6167
  ribbonGradient.addColorStop(0, `${primaryColor}f2`);
6169
6168
  ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
6170
6169
  ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
6170
+ // Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
6171
+ // context.filter blur, which triggers a costly software rasterization pass every frame.
6171
6172
  context.save();
6172
6173
  context.beginPath();
6173
6174
  tracePolyline(context, points);
6174
- context.strokeStyle = `${shadowColor}82`;
6175
- context.lineWidth = strokeWidth * 1.8;
6175
+ context.strokeStyle = `${shadowColor}48`;
6176
+ context.lineWidth = strokeWidth * 4.5;
6176
6177
  context.lineJoin = 'round';
6177
6178
  context.lineCap = 'round';
6178
- context.filter = `blur(${size * 0.022}px)`;
6179
6179
  context.stroke();
6180
6180
  context.restore();
6181
6181
  context.beginPath();
@@ -6759,11 +6759,23 @@ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY,
6759
6759
  * @private helper of `minecraft2AvatarVisual`
6760
6760
  */
6761
6761
  function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
6762
+ const cx = size * 0.5 + interaction.gazeX * size * 0.03;
6763
+ const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
6764
+ const rx = size * (0.16 + interaction.intensity * 0.015);
6765
+ const ry = size * 0.055;
6766
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
6762
6767
  context.save();
6763
- context.fillStyle = `${palette.shadow}66`;
6764
- context.filter = `blur(${size * 0.02}px)`;
6768
+ context.translate(cx, cy);
6769
+ context.scale(1, ry / rx);
6770
+ const blurRadius = rx * 1.4;
6771
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
6772
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
6773
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
6774
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
6775
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
6776
+ context.fillStyle = shadowGradient;
6765
6777
  context.beginPath();
6766
- 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);
6778
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
6767
6779
  context.fill();
6768
6780
  context.restore();
6769
6781
  }
@@ -6987,13 +6999,27 @@ const minecraftAvatarVisual = {
6987
6999
  spotlight.addColorStop(1, `${palette.highlight}00`);
6988
7000
  context.fillStyle = spotlight;
6989
7001
  context.fillRect(0, 0, size, size);
6990
- context.save();
6991
- context.fillStyle = 'rgba(0, 0, 0, 0.22)';
6992
- context.filter = `blur(${size * 0.018}px)`;
6993
- context.beginPath();
6994
- context.ellipse(size * 0.5, size * 0.86, size * 0.2, size * 0.06, 0, 0, Math.PI * 2);
6995
- context.fill();
6996
- context.restore();
7002
+ {
7003
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
7004
+ const cx = size * 0.5;
7005
+ const cy = size * 0.86;
7006
+ const rx = size * 0.2;
7007
+ const ry = size * 0.06;
7008
+ const blurRadius = rx * 1.4;
7009
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
7010
+ shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
7011
+ shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
7012
+ shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
7013
+ shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
7014
+ context.save();
7015
+ context.translate(cx, cy);
7016
+ context.scale(1, ry / rx);
7017
+ context.fillStyle = shadowGradient;
7018
+ context.beginPath();
7019
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
7020
+ context.fill();
7021
+ context.restore();
7022
+ }
6997
7023
  drawVoxelCuboid(context, {
6998
7024
  x: bodyX,
6999
7025
  y: bodyY,
@@ -8045,6 +8071,35 @@ const LIGHT_DIRECTION$2 = normalizeVector3({
8045
8071
  y: -0.62,
8046
8072
  z: 0.94,
8047
8073
  });
8074
+ /**
8075
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
8076
+ *
8077
+ * @private helper of `octopus3dAvatarVisual`
8078
+ */
8079
+ const octopus3dStableStateCache = new WeakMap();
8080
+ /**
8081
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
8082
+ *
8083
+ * @private helper of `octopus3dAvatarVisual`
8084
+ */
8085
+ function getOctopus3dStableState(createRandom) {
8086
+ const cached = octopus3dStableStateCache.get(createRandom);
8087
+ if (cached !== undefined) {
8088
+ return cached;
8089
+ }
8090
+ const animationRandom = createRandom('octopus3d-animation-profile');
8091
+ const eyeRandom = createRandom('octopus3d-eye-profile');
8092
+ const leftEyePhaseOffset = eyeRandom() * 0.6;
8093
+ const rightEyePhaseOffset = eyeRandom() * 0.6;
8094
+ const state = {
8095
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
8096
+ animationPhase: animationRandom() * Math.PI * 2,
8097
+ leftEyePhaseOffset,
8098
+ rightEyePhaseOffset,
8099
+ };
8100
+ octopus3dStableStateCache.set(createRandom, state);
8101
+ return state;
8102
+ }
8048
8103
  /**
8049
8104
  * Proper 3D Octopus visual built from projected organic meshes and tentacles.
8050
8105
  *
@@ -8057,10 +8112,7 @@ const octopus3dAvatarVisual = {
8057
8112
  isAnimated: true,
8058
8113
  supportsPointerTracking: true,
8059
8114
  render({ context, size, palette, createRandom, timeMs, interaction }) {
8060
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
8061
- const animationRandom = createRandom('octopus3d-animation-profile');
8062
- const eyeRandom = createRandom('octopus3d-eye-profile');
8063
- const animationPhase = animationRandom() * Math.PI * 2;
8115
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
8064
8116
  const sceneCenterX = size * 0.5;
8065
8117
  const sceneCenterY = size * 0.56;
8066
8118
  const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
@@ -8157,12 +8209,12 @@ const octopus3dAvatarVisual = {
8157
8209
  x: -faceEyeSpacing,
8158
8210
  y: faceEyeYOffset,
8159
8211
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
8160
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
8212
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8161
8213
  drawProjectedOrganicEye(context, {
8162
8214
  x: faceEyeSpacing,
8163
8215
  y: faceEyeYOffset,
8164
8216
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
8165
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
8217
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8166
8218
  drawProjectedOrganicMouth(context, [
8167
8219
  {
8168
8220
  x: -mouthHalfWidth,
@@ -8206,14 +8258,28 @@ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCent
8206
8258
  /**
8207
8259
  * Draws the soft ground shadow below the octopus.
8208
8260
  *
8261
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
8262
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
8263
+ *
8209
8264
  * @private helper of `octopus3dAvatarVisual`
8210
8265
  */
8211
8266
  function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
8267
+ const cx = size * 0.5 + interaction.gazeX * size * 0.04;
8268
+ const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
8269
+ const rx = size * (0.18 + interaction.intensity * 0.02);
8270
+ const ry = size * 0.06;
8212
8271
  context.save();
8213
- context.fillStyle = `${palette.shadow}66`;
8214
- context.filter = `blur(${size * 0.022}px)`;
8272
+ context.translate(cx, cy);
8273
+ context.scale(1, ry / rx);
8274
+ const blurRadius = rx * 1.4;
8275
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
8276
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
8277
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
8278
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
8279
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
8280
+ context.fillStyle = shadowGradient;
8215
8281
  context.beginPath();
8216
- 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);
8282
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
8217
8283
  context.fill();
8218
8284
  context.restore();
8219
8285
  }
@@ -8444,6 +8510,35 @@ const LIGHT_DIRECTION$1 = normalizeVector3({
8444
8510
  y: -0.6,
8445
8511
  z: 0.98,
8446
8512
  });
8513
+ /**
8514
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
8515
+ *
8516
+ * @private helper of `octopus3d2AvatarVisual`
8517
+ */
8518
+ const octopus3d2StableStateCache = new WeakMap();
8519
+ /**
8520
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
8521
+ *
8522
+ * @private helper of `octopus3d2AvatarVisual`
8523
+ */
8524
+ function getOctopus3d2StableState(createRandom) {
8525
+ const cached = octopus3d2StableStateCache.get(createRandom);
8526
+ if (cached !== undefined) {
8527
+ return cached;
8528
+ }
8529
+ const animationRandom = createRandom('octopus3d2-animation-profile');
8530
+ const eyeRandom = createRandom('octopus3d2-eye-profile');
8531
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
8532
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
8533
+ const state = {
8534
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
8535
+ animationPhase: animationRandom() * Math.PI * 2,
8536
+ leftEyePhaseOffset,
8537
+ rightEyePhaseOffset,
8538
+ };
8539
+ octopus3d2StableStateCache.set(createRandom, state);
8540
+ return state;
8541
+ }
8447
8542
  /**
8448
8543
  * Octopus 3D 2 avatar visual.
8449
8544
  *
@@ -8456,10 +8551,7 @@ const octopus3d2AvatarVisual = {
8456
8551
  isAnimated: true,
8457
8552
  supportsPointerTracking: true,
8458
8553
  render({ context, size, palette, createRandom, timeMs, interaction }) {
8459
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
8460
- const animationRandom = createRandom('octopus3d2-animation-profile');
8461
- const eyeRandom = createRandom('octopus3d2-eye-profile');
8462
- const animationPhase = animationRandom() * Math.PI * 2;
8554
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
8463
8555
  const sceneCenterX = size * 0.5;
8464
8556
  const sceneCenterY = size * 0.575;
8465
8557
  const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
@@ -8512,8 +8604,8 @@ const octopus3d2AvatarVisual = {
8512
8604
  const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
8513
8605
  const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
8514
8606
  const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
8515
- drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
8516
- drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
8607
+ drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8608
+ drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8517
8609
  drawProjectedOrganicMouth(context, [
8518
8610
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
8519
8611
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -8542,14 +8634,28 @@ function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, scene
8542
8634
  /**
8543
8635
  * Draws the soft floor shadow that anchors the single mesh in the frame.
8544
8636
  *
8637
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
8638
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
8639
+ *
8545
8640
  * @private helper of `octopus3d2AvatarVisual`
8546
8641
  */
8547
8642
  function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
8643
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
8644
+ const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
8645
+ const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
8646
+ const ry = size * 0.062;
8548
8647
  context.save();
8549
- context.fillStyle = `${palette.shadow}66`;
8550
- context.filter = `blur(${size * 0.024}px)`;
8648
+ context.translate(cx, cy);
8649
+ context.scale(1, ry / rx);
8650
+ const blurRadius = rx * 1.4;
8651
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
8652
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
8653
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
8654
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
8655
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
8656
+ context.fillStyle = shadowGradient;
8551
8657
  context.beginPath();
8552
- 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);
8658
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
8553
8659
  context.fill();
8554
8660
  context.restore();
8555
8661
  }
@@ -8705,6 +8811,40 @@ const LIGHT_DIRECTION = normalizeVector3({
8705
8811
  * @private helper of `octopus3d3AvatarVisual`
8706
8812
  */
8707
8813
  const OCTOPUS_TENTACLE_COUNT = 8;
8814
+ /**
8815
+ * Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
8816
+ * mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
8817
+ * React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
8818
+ *
8819
+ * @private helper of `octopus3d3AvatarVisual`
8820
+ */
8821
+ const stableStateCache = new WeakMap();
8822
+ /**
8823
+ * Returns the stable per-avatar state, computing it on first access and returning the cached
8824
+ * result on every subsequent call within the same `<Avatar/>` mount.
8825
+ *
8826
+ * @private helper of `octopus3d3AvatarVisual`
8827
+ */
8828
+ function getOctopus3d3StableState(createRandom) {
8829
+ const cached = stableStateCache.get(createRandom);
8830
+ if (cached !== undefined) {
8831
+ return cached;
8832
+ }
8833
+ const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
8834
+ const animationRandom = createRandom('octopus3d3-animation-profile');
8835
+ const eyeRandom = createRandom('octopus3d3-eye-profile');
8836
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
8837
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
8838
+ const state = {
8839
+ morphologyProfile,
8840
+ animationPhase: animationRandom() * Math.PI * 2,
8841
+ leftEyePhaseOffset,
8842
+ rightEyePhaseOffset,
8843
+ tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
8844
+ };
8845
+ stableStateCache.set(createRandom, state);
8846
+ return state;
8847
+ }
8708
8848
  /**
8709
8849
  * Octopus 3D 3 avatar visual.
8710
8850
  *
@@ -8717,11 +8857,7 @@ const octopus3d3AvatarVisual = {
8717
8857
  isAnimated: true,
8718
8858
  supportsPointerTracking: true,
8719
8859
  render({ context, size, palette, createRandom, timeMs, interaction }) {
8720
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
8721
- const animationRandom = createRandom('octopus3d3-animation-profile');
8722
- const eyeRandom = createRandom('octopus3d3-eye-profile');
8723
- const animationPhase = animationRandom() * Math.PI * 2;
8724
- const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
8860
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
8725
8861
  const sceneCenterX = size * 0.5;
8726
8862
  const sceneCenterY = size * 0.535;
8727
8863
  const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
@@ -8798,8 +8934,8 @@ const octopus3d3AvatarVisual = {
8798
8934
  size,
8799
8935
  palette,
8800
8936
  });
8801
- drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
8802
- 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);
8937
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8938
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
8803
8939
  drawProjectedOrganicMouth(context, [
8804
8940
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
8805
8941
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -8850,14 +8986,30 @@ function drawContinuousOctopusAtmosphere(context, size, palette, sceneCenterX, s
8850
8986
  /**
8851
8987
  * Draws the soft lower shadow that anchors the octopus in the avatar frame.
8852
8988
  *
8989
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
8990
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
8991
+ *
8853
8992
  * @private helper of `octopus3d3AvatarVisual`
8854
8993
  */
8855
8994
  function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
8995
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
8996
+ const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
8997
+ const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
8998
+ const ry = size * 0.06;
8999
+ // Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
9000
+ // then fill with a radial gradient that approximates the blurry edge without context.filter.
8856
9001
  context.save();
8857
- context.fillStyle = `${palette.shadow}66`;
8858
- context.filter = `blur(${size * 0.025}px)`;
9002
+ context.translate(cx, cy);
9003
+ context.scale(1, ry / rx);
9004
+ const blurRadius = rx * 1.4;
9005
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
9006
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
9007
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
9008
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
9009
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
9010
+ context.fillStyle = shadowGradient;
8859
9011
  context.beginPath();
8860
- 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);
9012
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
8861
9013
  context.fill();
8862
9014
  context.restore();
8863
9015
  }
@@ -17462,7 +17614,7 @@ function getTimeoutToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
17462
17614
  * @private internal helper function
17463
17615
  */
17464
17616
  function $randomToken(randomness) {
17465
- return randomBytes(randomness).toString('hex');
17617
+ return CryptoJS.lib.WordArray.random(randomness).toString(CryptoJS.enc.Hex);
17466
17618
  }
17467
17619
  // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
17468
17620
  // TODO: Maybe use nanoid instead https://github.com/ai/nanoid
@@ -25356,7 +25508,7 @@ function $registeredScrapersMessage(availableScrapers) {
25356
25508
  * @public exported from `@promptbook/editable`
25357
25509
  */
25358
25510
  function knowledgeSourceContentToName(knowledgeSourceContent) {
25359
- const hash = SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
25511
+ const hash = CryptoJS.SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
25360
25512
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
25361
25513
  .toString( /* hex */)
25362
25514
  .substring(0, 20);
@@ -26204,7 +26356,7 @@ function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO:
26204
26356
  console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
26205
26357
  value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
26206
26358
  }
26207
- const csv = parse(value, settings);
26359
+ const csv = papaparse.parse(value, settings);
26208
26360
  return csv;
26209
26361
  }
26210
26362
 
@@ -26289,10 +26441,10 @@ const CsvFormatParser = {
26289
26441
  i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
26290
26442
  );
26291
26443
  */
26292
- await onProgress(unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
26444
+ await onProgress(papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
26293
26445
  }
26294
26446
  }
26295
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
26447
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
26296
26448
  },
26297
26449
  },
26298
26450
  {
@@ -26320,7 +26472,7 @@ const CsvFormatParser = {
26320
26472
  return /* not await */ mapCallback({ [key]: value }, index, array.length);
26321
26473
  }));
26322
26474
  }));
26323
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
26475
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
26324
26476
  },
26325
26477
  },
26326
26478
  ],
@@ -35025,7 +35177,7 @@ function emitAgentLlmExecutionToolsAssistantPreparationProgress(options) {
35025
35177
  * Computes one stable hash from a JSON-serializable value.
35026
35178
  */
35027
35179
  function computeJsonHash$1(value) {
35028
- return SHA256(JSON.stringify(value)).toString();
35180
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
35029
35181
  }
35030
35182
  /**
35031
35183
  * Handles OpenAI AgentKit-backed executions for `AgentLlmExecutionTools`.
@@ -35183,7 +35335,7 @@ AgentLlmExecutionToolsAgentKitRunner.vectorStoreCache = new Map();
35183
35335
  * Computes one stable hash from a JSON-serializable value.
35184
35336
  */
35185
35337
  function computeJsonHash(value) {
35186
- return SHA256(JSON.stringify(value)).toString();
35338
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
35187
35339
  }
35188
35340
  /**
35189
35341
  * Removes assistant-managed requirements before the prompt is executed via OpenAI Assistants.
@@ -36039,7 +36191,7 @@ class AgentLlmExecutionTools {
36039
36191
  * Returns a virtual model name representing the agent behavior.
36040
36192
  */
36041
36193
  get modelName() {
36042
- const hash = SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
36194
+ const hash = CryptoJS.SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
36043
36195
  const agentId = hash.substring(0, 10);
36044
36196
  return (normalizeToKebabCase(this.title) + '-' + agentId);
36045
36197
  }