@promptbook/wizard 0.112.0-117 → 0.112.0-119
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/index.es.js +197 -44
- package/esm/index.es.js.map +1 -1
- package/esm/src/_packages/node.index.d.ts +10 -0
- package/esm/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/esm/src/book-3.0/CliAgent.d.ts +7 -2
- package/esm/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/esm/src/book-components/BookEditor/BookEditor.d.ts +1 -1
- package/esm/src/book-components/BookEditor/BookEditorForClient.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/CitationIframePreview.d.ts +20 -0
- package/esm/src/book-components/_common/Dropdown/Dropdown.d.ts +1 -1
- package/esm/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +1 -1
- package/esm/src/book-components/_common/Modal/Modal.d.ts +1 -1
- package/esm/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/esm/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/esm/src/book-components/icons/ExitFullscreenIcon.d.ts +1 -1
- package/esm/src/book-components/icons/FullscreenIcon.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +197 -44
- package/umd/index.umd.js.map +1 -1
- package/umd/src/_packages/node.index.d.ts +10 -0
- package/umd/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/umd/src/book-3.0/CliAgent.d.ts +7 -2
- package/umd/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/umd/src/book-components/BookEditor/BookEditor.d.ts +1 -1
- package/umd/src/book-components/BookEditor/BookEditorForClient.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/CitationIframePreview.d.ts +20 -0
- package/umd/src/book-components/_common/Dropdown/Dropdown.d.ts +1 -1
- package/umd/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +1 -1
- package/umd/src/book-components/_common/Modal/Modal.d.ts +1 -1
- package/umd/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/umd/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/umd/src/book-components/icons/ExitFullscreenIcon.d.ts +1 -1
- package/umd/src/book-components/icons/FullscreenIcon.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/umd/src/version.d.ts +1 -1
|
@@ -11,6 +11,11 @@ import type { CliAgentThinkingLevel } from '../book-3.0/CliAgent';
|
|
|
11
11
|
import type { CliAgentRunOptions } from '../book-3.0/CliAgent';
|
|
12
12
|
import type { CliAgentOptions } from '../book-3.0/CliAgent';
|
|
13
13
|
import { CliAgent } from '../book-3.0/CliAgent';
|
|
14
|
+
import { CLI_AGENT_HARNESS_NAMES } from '../book-3.0/cliAgentEnv';
|
|
15
|
+
import { CLI_AGENT_THINKING_LEVEL_VALUES } from '../book-3.0/cliAgentEnv';
|
|
16
|
+
import { PTBK_HARNESS_ENV } from '../book-3.0/cliAgentEnv';
|
|
17
|
+
import { PTBK_MODEL_ENV } from '../book-3.0/cliAgentEnv';
|
|
18
|
+
import { PTBK_THINKING_LEVEL_ENV } from '../book-3.0/cliAgentEnv';
|
|
14
19
|
import type { LiteAgentOptions } from '../book-3.0/LiteAgent';
|
|
15
20
|
import type { LiteAgentRunOptions } from '../book-3.0/LiteAgent';
|
|
16
21
|
import { LiteAgent } from '../book-3.0/LiteAgent';
|
|
@@ -39,6 +44,11 @@ export type { CliAgentThinkingLevel };
|
|
|
39
44
|
export type { CliAgentRunOptions };
|
|
40
45
|
export type { CliAgentOptions };
|
|
41
46
|
export { CliAgent };
|
|
47
|
+
export { CLI_AGENT_HARNESS_NAMES };
|
|
48
|
+
export { CLI_AGENT_THINKING_LEVEL_VALUES };
|
|
49
|
+
export { PTBK_HARNESS_ENV };
|
|
50
|
+
export { PTBK_MODEL_ENV };
|
|
51
|
+
export { PTBK_THINKING_LEVEL_ENV };
|
|
42
52
|
export type { LiteAgentOptions };
|
|
43
53
|
export type { LiteAgentRunOptions };
|
|
44
54
|
export { LiteAgent };
|
|
@@ -15,7 +15,7 @@ export type BookNodeAgentSource = Book | string_book;
|
|
|
15
15
|
*/
|
|
16
16
|
export type BookNodeAgentSourceOptions = {
|
|
17
17
|
readonly agentPath?: string;
|
|
18
|
-
readonly book?: BookNodeAgentSource;
|
|
18
|
+
readonly book?: string | BookNodeAgentSource;
|
|
19
19
|
readonly currentWorkingDirectory?: string;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { BookNodeAgentSourceOptions } from './BookNodeAgentSource';
|
|
2
|
+
import { CLI_AGENT_HARNESS_NAMES, CLI_AGENT_THINKING_LEVEL_VALUES } from './cliAgentEnv';
|
|
2
3
|
/**
|
|
3
4
|
* CLI harness names supported by `ptbk agent exec`.
|
|
4
5
|
*
|
|
5
6
|
* @public exported from `@promptbook/node`
|
|
6
7
|
*/
|
|
7
|
-
export type CliAgentHarness =
|
|
8
|
+
export type CliAgentHarness = (typeof CLI_AGENT_HARNESS_NAMES)[number];
|
|
8
9
|
/**
|
|
9
10
|
* Thinking levels supported by CLI coding harnesses.
|
|
10
11
|
*
|
|
11
12
|
* @public exported from `@promptbook/node`
|
|
12
13
|
*/
|
|
13
|
-
export type CliAgentThinkingLevel =
|
|
14
|
+
export type CliAgentThinkingLevel = (typeof CLI_AGENT_THINKING_LEVEL_VALUES)[number];
|
|
14
15
|
/**
|
|
15
16
|
* Per-run CLI options exposed by `CliAgent`.
|
|
16
17
|
*
|
|
@@ -22,6 +23,7 @@ export type CliAgentRunOptions = {
|
|
|
22
23
|
readonly allowCredits?: boolean;
|
|
23
24
|
readonly context?: string;
|
|
24
25
|
readonly harness?: CliAgentHarness;
|
|
26
|
+
readonly isVerbose?: boolean;
|
|
25
27
|
readonly model?: string;
|
|
26
28
|
readonly noUi?: boolean;
|
|
27
29
|
readonly thinkingLevel?: CliAgentThinkingLevel;
|
|
@@ -38,6 +40,9 @@ export type CliAgentOptions = BookNodeAgentSourceOptions & CliAgentRunOptions;
|
|
|
38
40
|
* It uses the same harnesses and execution path as `ptbk agent exec`, running the runner
|
|
39
41
|
* in-process instead of spawning a separate CLI process.
|
|
40
42
|
*
|
|
43
|
+
* When no `harness` is provided in the constructor or per-run options, `CliAgent` falls back
|
|
44
|
+
* to the `PTBK_HARNESS` environment variable, mirroring `ptbk agent exec` behavior.
|
|
45
|
+
*
|
|
41
46
|
* @public exported from `@promptbook/node`
|
|
42
47
|
*/
|
|
43
48
|
export declare class CliAgent {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All CLI harness names supported by `CliAgent` and `ptbk agent exec`.
|
|
3
|
+
*
|
|
4
|
+
* @public exported from `@promptbook/node`
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLI_AGENT_HARNESS_NAMES: readonly ["openai-codex", "github-copilot", "cline", "claude-code", "opencode", "gemini"];
|
|
7
|
+
/**
|
|
8
|
+
* All supported thinking-level values for CLI coding-agent runners.
|
|
9
|
+
*
|
|
10
|
+
* @public exported from `@promptbook/node`
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLI_AGENT_THINKING_LEVEL_VALUES: readonly ["low", "medium", "high", "xhigh"];
|
|
13
|
+
/**
|
|
14
|
+
* Environment variable used as the default runner identifier when `--harness` is omitted or not set in `CliAgent`.
|
|
15
|
+
*
|
|
16
|
+
* Set this to one of the harness names (`openai-codex`, `github-copilot`, `cline`, `claude-code`, `opencode`, `gemini`)
|
|
17
|
+
* so that `CliAgent` and `ptbk agent exec` can run without an explicit `harness` option.
|
|
18
|
+
*
|
|
19
|
+
* @public exported from `@promptbook/node`
|
|
20
|
+
*/
|
|
21
|
+
export declare const PTBK_HARNESS_ENV = "PTBK_HARNESS";
|
|
22
|
+
/**
|
|
23
|
+
* Environment variable used as the default runner model when `--model` is omitted or not set in `CliAgent`.
|
|
24
|
+
*
|
|
25
|
+
* @public exported from `@promptbook/node`
|
|
26
|
+
*/
|
|
27
|
+
export declare const PTBK_MODEL_ENV = "PTBK_MODEL";
|
|
28
|
+
/**
|
|
29
|
+
* Environment variable used as the default thinking level when `--thinking-level` is omitted or not set in `CliAgent`.
|
|
30
|
+
*
|
|
31
|
+
* @public exported from `@promptbook/node`
|
|
32
|
+
*/
|
|
33
|
+
export declare const PTBK_THINKING_LEVEL_ENV = "PTBK_THINKING_LEVEL";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
2
|
import type { Promisable } from 'type-fest';
|
|
3
3
|
import type { string_book } from '../../book-2.0/agent-source/string_book';
|
|
4
4
|
import type { number_percent } from '../../types/number_percent';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the citation iframe preview component.
|
|
3
|
+
*
|
|
4
|
+
* @private component of `<ChatCitationModal/>`
|
|
5
|
+
*/
|
|
6
|
+
export type CitationIframePreviewProps = {
|
|
7
|
+
src: string;
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Renders a citation URL preview as an iframe when the target page allows embedding,
|
|
12
|
+
* or falls back to a server-side screenshot with an "Open in new tab" link when it
|
|
13
|
+
* does not (e.g. X-Frame-Options: DENY / SAMEORIGIN).
|
|
14
|
+
*
|
|
15
|
+
* Embedding capability is determined by `GET /api/page-preview/check?url=<url>`.
|
|
16
|
+
* If that endpoint is unavailable the component falls back to the iframe directly.
|
|
17
|
+
*
|
|
18
|
+
* @private component of `<ChatCitationModal/>`
|
|
19
|
+
*/
|
|
20
|
+
export declare function CitationIframePreview({ src, title }: CitationIframePreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,29 +1,13 @@
|
|
|
1
1
|
import { Command as Program } from 'commander';
|
|
2
2
|
import type { ThinkingLevel } from '../coder/ThinkingLevel';
|
|
3
|
+
import { PTBK_HARNESS_ENV, PTBK_MODEL_ENV, PTBK_THINKING_LEVEL_ENV } from '../../../book-3.0/cliAgentEnv';
|
|
4
|
+
export { PTBK_HARNESS_ENV, PTBK_MODEL_ENV, PTBK_THINKING_LEVEL_ENV };
|
|
3
5
|
/**
|
|
4
6
|
* Runner identifiers supported by Promptbook CLI agent orchestration commands.
|
|
5
7
|
*
|
|
6
8
|
* @private internal utility of `promptbookCli`
|
|
7
9
|
*/
|
|
8
10
|
export declare const PROMPT_RUNNER_HARNESS_NAMES: readonly ["openai-codex", "github-copilot", "cline", "claude-code", "opencode", "gemini"];
|
|
9
|
-
/**
|
|
10
|
-
* Environment variable used as the default runner identifier when `--harness` is omitted.
|
|
11
|
-
*
|
|
12
|
-
* @private internal utility of `promptbookCli`
|
|
13
|
-
*/
|
|
14
|
-
export declare const PTBK_HARNESS_ENV = "PTBK_HARNESS";
|
|
15
|
-
/**
|
|
16
|
-
* Environment variable used as the default runner model when `--model` is omitted.
|
|
17
|
-
*
|
|
18
|
-
* @private internal utility of `promptbookCli`
|
|
19
|
-
*/
|
|
20
|
-
export declare const PTBK_MODEL_ENV = "PTBK_MODEL";
|
|
21
|
-
/**
|
|
22
|
-
* Environment variable used as the default runner thinking level when `--thinking-level` is omitted.
|
|
23
|
-
*
|
|
24
|
-
* @private internal utility of `promptbookCli`
|
|
25
|
-
*/
|
|
26
|
-
export declare const PTBK_THINKING_LEVEL_ENV = "PTBK_THINKING_LEVEL";
|
|
27
11
|
/**
|
|
28
12
|
* Runner identifier supported by Promptbook CLI agent orchestration commands.
|
|
29
13
|
*
|
package/esm/src/version.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
|
|
|
15
15
|
export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
|
|
16
16
|
/**
|
|
17
17
|
* Represents the version string of the Promptbook engine.
|
|
18
|
-
* It follows semantic versioning (e.g., `0.112.0-
|
|
18
|
+
* It follows semantic versioning (e.g., `0.112.0-118`).
|
|
19
19
|
*
|
|
20
20
|
* @generated
|
|
21
21
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptbook/wizard",
|
|
3
|
-
"version": "0.112.0-
|
|
3
|
+
"version": "0.112.0-119",
|
|
4
4
|
"description": "Promptbook: Create persistent AI agents that turn your company's scattered knowledge into action",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"types": "./esm/src/_packages/wizard.index.d.ts",
|
|
100
100
|
"typings": "./esm/src/_packages/wizard.index.d.ts",
|
|
101
101
|
"peerDependencies": {
|
|
102
|
-
"@promptbook/core": "0.112.0-
|
|
102
|
+
"@promptbook/core": "0.112.0-119"
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
105
|
"@ai-sdk/deepseek": "0.1.17",
|
package/umd/index.umd.js
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
* @generated
|
|
53
53
|
* @see https://github.com/webgptorg/promptbook
|
|
54
54
|
*/
|
|
55
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
55
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-119';
|
|
56
56
|
/**
|
|
57
57
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
58
58
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -10034,7 +10034,7 @@
|
|
|
10034
10034
|
return { skippedReason: 'invalid_data_url' };
|
|
10035
10035
|
}
|
|
10036
10036
|
return {
|
|
10037
|
-
file: new File([parsed.buffer], parsed.filename, {
|
|
10037
|
+
file: new File([new Uint8Array(parsed.buffer)], parsed.filename, {
|
|
10038
10038
|
type: parsed.mimeType,
|
|
10039
10039
|
}),
|
|
10040
10040
|
sizeBytes: parsed.buffer.length,
|
|
@@ -22108,21 +22108,22 @@
|
|
|
22108
22108
|
* @private helper of `fractalAvatarVisual`
|
|
22109
22109
|
*/
|
|
22110
22110
|
function drawDragonCurveLayer(context, points, options) {
|
|
22111
|
-
const {
|
|
22111
|
+
const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
|
|
22112
22112
|
const firstPoint = points[0];
|
|
22113
22113
|
const lastPoint = points[points.length - 1];
|
|
22114
22114
|
const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
|
|
22115
22115
|
ribbonGradient.addColorStop(0, `${primaryColor}f2`);
|
|
22116
22116
|
ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
|
|
22117
22117
|
ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
|
|
22118
|
+
// Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
|
|
22119
|
+
// context.filter blur, which triggers a costly software rasterization pass every frame.
|
|
22118
22120
|
context.save();
|
|
22119
22121
|
context.beginPath();
|
|
22120
22122
|
tracePolyline(context, points);
|
|
22121
|
-
context.strokeStyle = `${shadowColor}
|
|
22122
|
-
context.lineWidth = strokeWidth *
|
|
22123
|
+
context.strokeStyle = `${shadowColor}48`;
|
|
22124
|
+
context.lineWidth = strokeWidth * 4.5;
|
|
22123
22125
|
context.lineJoin = 'round';
|
|
22124
22126
|
context.lineCap = 'round';
|
|
22125
|
-
context.filter = `blur(${size * 0.022}px)`;
|
|
22126
22127
|
context.stroke();
|
|
22127
22128
|
context.restore();
|
|
22128
22129
|
context.beginPath();
|
|
@@ -22706,11 +22707,23 @@
|
|
|
22706
22707
|
* @private helper of `minecraft2AvatarVisual`
|
|
22707
22708
|
*/
|
|
22708
22709
|
function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
|
|
22710
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.03;
|
|
22711
|
+
const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
|
|
22712
|
+
const rx = size * (0.16 + interaction.intensity * 0.015);
|
|
22713
|
+
const ry = size * 0.055;
|
|
22714
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
22709
22715
|
context.save();
|
|
22710
|
-
context.
|
|
22711
|
-
context.
|
|
22716
|
+
context.translate(cx, cy);
|
|
22717
|
+
context.scale(1, ry / rx);
|
|
22718
|
+
const blurRadius = rx * 1.4;
|
|
22719
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
22720
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
22721
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
22722
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
22723
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
22724
|
+
context.fillStyle = shadowGradient;
|
|
22712
22725
|
context.beginPath();
|
|
22713
|
-
context.
|
|
22726
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
22714
22727
|
context.fill();
|
|
22715
22728
|
context.restore();
|
|
22716
22729
|
}
|
|
@@ -22934,13 +22947,27 @@
|
|
|
22934
22947
|
spotlight.addColorStop(1, `${palette.highlight}00`);
|
|
22935
22948
|
context.fillStyle = spotlight;
|
|
22936
22949
|
context.fillRect(0, 0, size, size);
|
|
22937
|
-
|
|
22938
|
-
|
|
22939
|
-
|
|
22940
|
-
|
|
22941
|
-
|
|
22942
|
-
|
|
22943
|
-
|
|
22950
|
+
{
|
|
22951
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
22952
|
+
const cx = size * 0.5;
|
|
22953
|
+
const cy = size * 0.86;
|
|
22954
|
+
const rx = size * 0.2;
|
|
22955
|
+
const ry = size * 0.06;
|
|
22956
|
+
const blurRadius = rx * 1.4;
|
|
22957
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
22958
|
+
shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
|
|
22959
|
+
shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
|
|
22960
|
+
shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
|
|
22961
|
+
shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
|
|
22962
|
+
context.save();
|
|
22963
|
+
context.translate(cx, cy);
|
|
22964
|
+
context.scale(1, ry / rx);
|
|
22965
|
+
context.fillStyle = shadowGradient;
|
|
22966
|
+
context.beginPath();
|
|
22967
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
22968
|
+
context.fill();
|
|
22969
|
+
context.restore();
|
|
22970
|
+
}
|
|
22944
22971
|
drawVoxelCuboid(context, {
|
|
22945
22972
|
x: bodyX,
|
|
22946
22973
|
y: bodyY,
|
|
@@ -23992,6 +24019,35 @@
|
|
|
23992
24019
|
y: -0.62,
|
|
23993
24020
|
z: 0.94,
|
|
23994
24021
|
});
|
|
24022
|
+
/**
|
|
24023
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
24024
|
+
*
|
|
24025
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
24026
|
+
*/
|
|
24027
|
+
const octopus3dStableStateCache = new WeakMap();
|
|
24028
|
+
/**
|
|
24029
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
24030
|
+
*
|
|
24031
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
24032
|
+
*/
|
|
24033
|
+
function getOctopus3dStableState(createRandom) {
|
|
24034
|
+
const cached = octopus3dStableStateCache.get(createRandom);
|
|
24035
|
+
if (cached !== undefined) {
|
|
24036
|
+
return cached;
|
|
24037
|
+
}
|
|
24038
|
+
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
24039
|
+
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
24040
|
+
const leftEyePhaseOffset = eyeRandom() * 0.6;
|
|
24041
|
+
const rightEyePhaseOffset = eyeRandom() * 0.6;
|
|
24042
|
+
const state = {
|
|
24043
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
24044
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24045
|
+
leftEyePhaseOffset,
|
|
24046
|
+
rightEyePhaseOffset,
|
|
24047
|
+
};
|
|
24048
|
+
octopus3dStableStateCache.set(createRandom, state);
|
|
24049
|
+
return state;
|
|
24050
|
+
}
|
|
23995
24051
|
/**
|
|
23996
24052
|
* Proper 3D Octopus visual built from projected organic meshes and tentacles.
|
|
23997
24053
|
*
|
|
@@ -24004,10 +24060,7 @@
|
|
|
24004
24060
|
isAnimated: true,
|
|
24005
24061
|
supportsPointerTracking: true,
|
|
24006
24062
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24007
|
-
const morphologyProfile =
|
|
24008
|
-
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
24009
|
-
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
24010
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24063
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
|
|
24011
24064
|
const sceneCenterX = size * 0.5;
|
|
24012
24065
|
const sceneCenterY = size * 0.56;
|
|
24013
24066
|
const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
|
|
@@ -24104,12 +24157,12 @@
|
|
|
24104
24157
|
x: -faceEyeSpacing,
|
|
24105
24158
|
y: faceEyeYOffset,
|
|
24106
24159
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
24107
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24160
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24108
24161
|
drawProjectedOrganicEye(context, {
|
|
24109
24162
|
x: faceEyeSpacing,
|
|
24110
24163
|
y: faceEyeYOffset,
|
|
24111
24164
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
24112
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 +
|
|
24165
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24113
24166
|
drawProjectedOrganicMouth(context, [
|
|
24114
24167
|
{
|
|
24115
24168
|
x: -mouthHalfWidth,
|
|
@@ -24153,14 +24206,28 @@
|
|
|
24153
24206
|
/**
|
|
24154
24207
|
* Draws the soft ground shadow below the octopus.
|
|
24155
24208
|
*
|
|
24209
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24210
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24211
|
+
*
|
|
24156
24212
|
* @private helper of `octopus3dAvatarVisual`
|
|
24157
24213
|
*/
|
|
24158
24214
|
function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
|
|
24215
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.04;
|
|
24216
|
+
const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
|
|
24217
|
+
const rx = size * (0.18 + interaction.intensity * 0.02);
|
|
24218
|
+
const ry = size * 0.06;
|
|
24159
24219
|
context.save();
|
|
24160
|
-
context.
|
|
24161
|
-
context.
|
|
24220
|
+
context.translate(cx, cy);
|
|
24221
|
+
context.scale(1, ry / rx);
|
|
24222
|
+
const blurRadius = rx * 1.4;
|
|
24223
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24224
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24225
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24226
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24227
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24228
|
+
context.fillStyle = shadowGradient;
|
|
24162
24229
|
context.beginPath();
|
|
24163
|
-
context.
|
|
24230
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24164
24231
|
context.fill();
|
|
24165
24232
|
context.restore();
|
|
24166
24233
|
}
|
|
@@ -24391,6 +24458,35 @@
|
|
|
24391
24458
|
y: -0.6,
|
|
24392
24459
|
z: 0.98,
|
|
24393
24460
|
});
|
|
24461
|
+
/**
|
|
24462
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
24463
|
+
*
|
|
24464
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24465
|
+
*/
|
|
24466
|
+
const octopus3d2StableStateCache = new WeakMap();
|
|
24467
|
+
/**
|
|
24468
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
24469
|
+
*
|
|
24470
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24471
|
+
*/
|
|
24472
|
+
function getOctopus3d2StableState(createRandom) {
|
|
24473
|
+
const cached = octopus3d2StableStateCache.get(createRandom);
|
|
24474
|
+
if (cached !== undefined) {
|
|
24475
|
+
return cached;
|
|
24476
|
+
}
|
|
24477
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
24478
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
24479
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
24480
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
24481
|
+
const state = {
|
|
24482
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
24483
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24484
|
+
leftEyePhaseOffset,
|
|
24485
|
+
rightEyePhaseOffset,
|
|
24486
|
+
};
|
|
24487
|
+
octopus3d2StableStateCache.set(createRandom, state);
|
|
24488
|
+
return state;
|
|
24489
|
+
}
|
|
24394
24490
|
/**
|
|
24395
24491
|
* Octopus 3D 2 avatar visual.
|
|
24396
24492
|
*
|
|
@@ -24403,10 +24499,7 @@
|
|
|
24403
24499
|
isAnimated: true,
|
|
24404
24500
|
supportsPointerTracking: true,
|
|
24405
24501
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24406
|
-
const morphologyProfile =
|
|
24407
|
-
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
24408
|
-
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
24409
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24502
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
|
|
24410
24503
|
const sceneCenterX = size * 0.5;
|
|
24411
24504
|
const sceneCenterY = size * 0.575;
|
|
24412
24505
|
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
@@ -24459,8 +24552,8 @@
|
|
|
24459
24552
|
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
24460
24553
|
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
24461
24554
|
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
24462
|
-
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24463
|
-
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 +
|
|
24555
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24556
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24464
24557
|
drawProjectedOrganicMouth(context, [
|
|
24465
24558
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
24466
24559
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -24489,14 +24582,28 @@
|
|
|
24489
24582
|
/**
|
|
24490
24583
|
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
24491
24584
|
*
|
|
24585
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24586
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24587
|
+
*
|
|
24492
24588
|
* @private helper of `octopus3d2AvatarVisual`
|
|
24493
24589
|
*/
|
|
24494
24590
|
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
24591
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
24592
|
+
const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
|
|
24593
|
+
const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
|
|
24594
|
+
const ry = size * 0.062;
|
|
24495
24595
|
context.save();
|
|
24496
|
-
context.
|
|
24497
|
-
context.
|
|
24596
|
+
context.translate(cx, cy);
|
|
24597
|
+
context.scale(1, ry / rx);
|
|
24598
|
+
const blurRadius = rx * 1.4;
|
|
24599
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24600
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24601
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24602
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24603
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24604
|
+
context.fillStyle = shadowGradient;
|
|
24498
24605
|
context.beginPath();
|
|
24499
|
-
context.
|
|
24606
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24500
24607
|
context.fill();
|
|
24501
24608
|
context.restore();
|
|
24502
24609
|
}
|
|
@@ -24652,6 +24759,40 @@
|
|
|
24652
24759
|
* @private helper of `octopus3d3AvatarVisual`
|
|
24653
24760
|
*/
|
|
24654
24761
|
const OCTOPUS_TENTACLE_COUNT = 8;
|
|
24762
|
+
/**
|
|
24763
|
+
* Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
|
|
24764
|
+
* mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
|
|
24765
|
+
* React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
|
|
24766
|
+
*
|
|
24767
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
24768
|
+
*/
|
|
24769
|
+
const stableStateCache = new WeakMap();
|
|
24770
|
+
/**
|
|
24771
|
+
* Returns the stable per-avatar state, computing it on first access and returning the cached
|
|
24772
|
+
* result on every subsequent call within the same `<Avatar/>` mount.
|
|
24773
|
+
*
|
|
24774
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
24775
|
+
*/
|
|
24776
|
+
function getOctopus3d3StableState(createRandom) {
|
|
24777
|
+
const cached = stableStateCache.get(createRandom);
|
|
24778
|
+
if (cached !== undefined) {
|
|
24779
|
+
return cached;
|
|
24780
|
+
}
|
|
24781
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
24782
|
+
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
24783
|
+
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
24784
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
24785
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
24786
|
+
const state = {
|
|
24787
|
+
morphologyProfile,
|
|
24788
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24789
|
+
leftEyePhaseOffset,
|
|
24790
|
+
rightEyePhaseOffset,
|
|
24791
|
+
tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
|
|
24792
|
+
};
|
|
24793
|
+
stableStateCache.set(createRandom, state);
|
|
24794
|
+
return state;
|
|
24795
|
+
}
|
|
24655
24796
|
/**
|
|
24656
24797
|
* Octopus 3D 3 avatar visual.
|
|
24657
24798
|
*
|
|
@@ -24664,11 +24805,7 @@
|
|
|
24664
24805
|
isAnimated: true,
|
|
24665
24806
|
supportsPointerTracking: true,
|
|
24666
24807
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24667
|
-
const morphologyProfile =
|
|
24668
|
-
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
24669
|
-
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
24670
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24671
|
-
const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
|
|
24808
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
|
|
24672
24809
|
const sceneCenterX = size * 0.5;
|
|
24673
24810
|
const sceneCenterY = size * 0.535;
|
|
24674
24811
|
const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
|
|
@@ -24745,8 +24882,8 @@
|
|
|
24745
24882
|
size,
|
|
24746
24883
|
palette,
|
|
24747
24884
|
});
|
|
24748
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24749
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 +
|
|
24885
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24886
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24750
24887
|
drawProjectedOrganicMouth(context, [
|
|
24751
24888
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
24752
24889
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -24797,14 +24934,30 @@
|
|
|
24797
24934
|
/**
|
|
24798
24935
|
* Draws the soft lower shadow that anchors the octopus in the avatar frame.
|
|
24799
24936
|
*
|
|
24937
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24938
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24939
|
+
*
|
|
24800
24940
|
* @private helper of `octopus3d3AvatarVisual`
|
|
24801
24941
|
*/
|
|
24802
24942
|
function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
24943
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
24944
|
+
const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
|
|
24945
|
+
const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
|
|
24946
|
+
const ry = size * 0.06;
|
|
24947
|
+
// Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
|
|
24948
|
+
// then fill with a radial gradient that approximates the blurry edge without context.filter.
|
|
24803
24949
|
context.save();
|
|
24804
|
-
context.
|
|
24805
|
-
context.
|
|
24950
|
+
context.translate(cx, cy);
|
|
24951
|
+
context.scale(1, ry / rx);
|
|
24952
|
+
const blurRadius = rx * 1.4;
|
|
24953
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24954
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24955
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24956
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24957
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24958
|
+
context.fillStyle = shadowGradient;
|
|
24806
24959
|
context.beginPath();
|
|
24807
|
-
context.
|
|
24960
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24808
24961
|
context.fill();
|
|
24809
24962
|
context.restore();
|
|
24810
24963
|
}
|