@promptbook/components 0.112.0-47 → 0.112.0-48
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 +885 -143
- package/esm/index.es.js.map +1 -1
- package/esm/src/avatars/AvatarOrImage.d.ts +5 -1
- package/esm/src/avatars/avatarInteractionUtils.d.ts +81 -0
- package/esm/src/avatars/avatarInteractionUtils.test.d.ts +1 -0
- package/esm/src/avatars/avatarPointerTracking.d.ts +17 -0
- package/esm/src/avatars/avatarRenderingUtils.d.ts +3 -2
- package/esm/src/avatars/avatarRenderingUtils.test.d.ts +1 -0
- package/esm/src/avatars/index.d.ts +1 -1
- package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +35 -0
- package/esm/src/avatars/visuals/octopusAvatarVisualShared.d.ts +34 -0
- package/esm/src/avatars/visuals/octopusAvatarVisualShared.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/TeamToolCallModalContent.test.d.ts +2 -0
- package/esm/src/commitments/USE/USE.d.ts +1 -0
- package/esm/src/commitments/USE/aggregateUseCommitmentSystemMessages.d.ts +1 -1
- package/esm/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.d.ts +47 -0
- package/esm/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.test.d.ts +1 -0
- package/esm/src/commitments/_common/createSerpSearchToolFunction.d.ts +12 -0
- package/esm/src/commitments/index.d.ts +2 -1
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.test.d.ts +1 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +884 -142
- package/umd/index.umd.js.map +1 -1
- package/umd/src/avatars/AvatarOrImage.d.ts +5 -1
- package/umd/src/avatars/avatarInteractionUtils.d.ts +81 -0
- package/umd/src/avatars/avatarInteractionUtils.test.d.ts +1 -0
- package/umd/src/avatars/avatarPointerTracking.d.ts +17 -0
- package/umd/src/avatars/avatarRenderingUtils.d.ts +3 -2
- package/umd/src/avatars/avatarRenderingUtils.test.d.ts +1 -0
- package/umd/src/avatars/index.d.ts +1 -1
- package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +35 -0
- package/umd/src/avatars/visuals/octopusAvatarVisualShared.d.ts +34 -0
- package/umd/src/avatars/visuals/octopusAvatarVisualShared.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/TeamToolCallModalContent.test.d.ts +2 -0
- package/umd/src/commitments/USE/USE.d.ts +1 -0
- package/umd/src/commitments/USE/aggregateUseCommitmentSystemMessages.d.ts +1 -1
- package/umd/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.d.ts +47 -0
- package/umd/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.test.d.ts +1 -0
- package/umd/src/commitments/_common/createSerpSearchToolFunction.d.ts +12 -0
- package/umd/src/commitments/index.d.ts +2 -1
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.test.d.ts +1 -0
- package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* @generated
|
|
31
31
|
* @see https://github.com/webgptorg/promptbook
|
|
32
32
|
*/
|
|
33
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
33
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-48';
|
|
34
34
|
/**
|
|
35
35
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
36
36
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1392,11 +1392,12 @@
|
|
|
1392
1392
|
* Creates the shared derived palette used by every avatar visual.
|
|
1393
1393
|
*
|
|
1394
1394
|
* @param avatarDefinition Stable avatar definition.
|
|
1395
|
+
* @param surface Surface style used by the parent UI.
|
|
1395
1396
|
* @returns Derived palette.
|
|
1396
1397
|
*
|
|
1397
1398
|
* @private utility of the avatar rendering system
|
|
1398
1399
|
*/
|
|
1399
|
-
function createAvatarPalette(avatarDefinition) {
|
|
1400
|
+
function createAvatarPalette(avatarDefinition, surface = 'framed') {
|
|
1400
1401
|
const normalizedAvatarDefinition = normalizeAvatarDefinition(avatarDefinition);
|
|
1401
1402
|
const primaryColor = Color.fromSafe(normalizedAvatarDefinition.colors[0] || PROMPTBOOK_COLOR);
|
|
1402
1403
|
const secondaryColor = Color.fromSafe(normalizedAvatarDefinition.colors[1] || primaryColor.then(lighten(0.12)).then(saturate(0.16)));
|
|
@@ -1406,8 +1407,8 @@
|
|
|
1406
1407
|
const highlightColor = Color.fromSafe(accentColor.then(lighten(0.22)).then(saturate(0.08)));
|
|
1407
1408
|
const shadowColor = Color.fromSafe(primaryColor.then(darken(0.46)).then(saturate(0.14)));
|
|
1408
1409
|
return {
|
|
1409
|
-
background: backgroundColor.toHex(),
|
|
1410
|
-
backgroundSecondary: backgroundSecondaryColor.toHex(),
|
|
1410
|
+
background: surface === 'transparent' ? 'transparent' : backgroundColor.toHex(),
|
|
1411
|
+
backgroundSecondary: surface === 'transparent' ? 'transparent' : backgroundSecondaryColor.toHex(),
|
|
1411
1412
|
primary: primaryColor.toHex(),
|
|
1412
1413
|
secondary: secondaryColor.toHex(),
|
|
1413
1414
|
accent: accentColor.toHex(),
|
|
@@ -1426,6 +1427,9 @@
|
|
|
1426
1427
|
* @private utility of the avatar rendering system
|
|
1427
1428
|
*/
|
|
1428
1429
|
function drawAvatarFrame(context, size, palette) {
|
|
1430
|
+
if (palette.background === 'transparent' && palette.backgroundSecondary === 'transparent') {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1429
1433
|
const gradient = context.createLinearGradient(0, 0, size, size);
|
|
1430
1434
|
gradient.addColorStop(0, palette.background);
|
|
1431
1435
|
gradient.addColorStop(1, palette.backgroundSecondary);
|
|
@@ -1577,7 +1581,7 @@
|
|
|
1577
1581
|
*
|
|
1578
1582
|
* @private shared avatar contract
|
|
1579
1583
|
*/
|
|
1580
|
-
const DEFAULT_AGENT_AVATAR_VISUAL_ID = '
|
|
1584
|
+
const DEFAULT_AGENT_AVATAR_VISUAL_ID = 'octopus3';
|
|
1581
1585
|
/**
|
|
1582
1586
|
* Resolve a base URL for relative images, preferring the provided base or browser location.
|
|
1583
1587
|
*
|
|
@@ -11722,6 +11726,7 @@
|
|
|
11722
11726
|
* Supported USE types:
|
|
11723
11727
|
* - USE BROWSER: Enables the agent to use a web browser tool
|
|
11724
11728
|
* - USE SEARCH ENGINE (future): Enables search engine access
|
|
11729
|
+
* - USE DEEPSEARCH: Enables deeper research-oriented search access
|
|
11725
11730
|
* - USE FILE SYSTEM (future): Enables file system operations
|
|
11726
11731
|
* - USE MCP (future): Enables MCP server connections
|
|
11727
11732
|
*
|
|
@@ -11744,7 +11749,7 @@
|
|
|
11744
11749
|
* Short one-line description of USE commitments.
|
|
11745
11750
|
*/
|
|
11746
11751
|
get description() {
|
|
11747
|
-
return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
|
|
11752
|
+
return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, DEEPSEARCH, etc.).';
|
|
11748
11753
|
}
|
|
11749
11754
|
/**
|
|
11750
11755
|
* Icon for this commitment.
|
|
@@ -11765,6 +11770,7 @@
|
|
|
11765
11770
|
|
|
11766
11771
|
- **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
|
|
11767
11772
|
- **USE SEARCH ENGINE** (future) - Enables search engine access
|
|
11773
|
+
- **USE DEEPSEARCH** - Enables deeper research-oriented search access
|
|
11768
11774
|
- **USE FILE SYSTEM** (future) - Enables file system operations
|
|
11769
11775
|
- **USE MCP** (future) - Enables MCP server connections
|
|
11770
11776
|
|
|
@@ -11819,7 +11825,7 @@
|
|
|
11819
11825
|
* Checks if this is a known USE type
|
|
11820
11826
|
*/
|
|
11821
11827
|
isKnownUseType(useType) {
|
|
11822
|
-
const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
|
|
11828
|
+
const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'DEEPSEARCH', 'FILE SYSTEM', 'MCP'];
|
|
11823
11829
|
return knownTypes.includes(useType.toUpperCase());
|
|
11824
11830
|
}
|
|
11825
11831
|
}
|
|
@@ -11832,6 +11838,7 @@
|
|
|
11832
11838
|
*/
|
|
11833
11839
|
const AGGREGATED_USE_COMMITMENT_TYPES = [
|
|
11834
11840
|
'USE BROWSER',
|
|
11841
|
+
'USE DEEPSEARCH',
|
|
11835
11842
|
'USE SEARCH ENGINE',
|
|
11836
11843
|
'USE TIME',
|
|
11837
11844
|
];
|
|
@@ -11911,6 +11918,15 @@
|
|
|
11911
11918
|
- Do not tell the user you cannot search for information, YOU CAN.
|
|
11912
11919
|
${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
|
|
11913
11920
|
`);
|
|
11921
|
+
case 'USE DEEPSEARCH':
|
|
11922
|
+
return spacetrim.spaceTrim((block) => `
|
|
11923
|
+
Tool:
|
|
11924
|
+
- You have access to DeepSearch via the tool "deep_search".
|
|
11925
|
+
- Use it for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
|
|
11926
|
+
- Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
|
|
11927
|
+
- Do not pretend you cannot research current information when this tool is available.
|
|
11928
|
+
${block(formatOptionalInstructionBlock('DeepSearch instructions', combinedAdditionalInstructions))}
|
|
11929
|
+
`);
|
|
11914
11930
|
}
|
|
11915
11931
|
}
|
|
11916
11932
|
/**
|
|
@@ -13460,6 +13476,207 @@
|
|
|
13460
13476
|
}
|
|
13461
13477
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
13462
13478
|
|
|
13479
|
+
/**
|
|
13480
|
+
* A search engine implementation that uses the SerpApi to fetch Google search results.
|
|
13481
|
+
*
|
|
13482
|
+
* @private <- TODO: !!!! Export via some package
|
|
13483
|
+
*/
|
|
13484
|
+
class SerpSearchEngine {
|
|
13485
|
+
get title() {
|
|
13486
|
+
return 'SerpApi Search Engine';
|
|
13487
|
+
}
|
|
13488
|
+
get description() {
|
|
13489
|
+
return 'Search engine that uses SerpApi to fetch Google search results';
|
|
13490
|
+
}
|
|
13491
|
+
checkConfiguration() {
|
|
13492
|
+
if (!process.env.SERP_API_KEY) {
|
|
13493
|
+
throw new Error('SERP_API_KEY is not configured');
|
|
13494
|
+
}
|
|
13495
|
+
}
|
|
13496
|
+
async search(query, options = {}) {
|
|
13497
|
+
const apiKey = process.env.SERP_API_KEY;
|
|
13498
|
+
if (!apiKey) {
|
|
13499
|
+
throw new Error('SERP_API_KEY is not configured');
|
|
13500
|
+
}
|
|
13501
|
+
const url = new URL('https://serpapi.com/search');
|
|
13502
|
+
url.searchParams.set('api_key', apiKey);
|
|
13503
|
+
url.searchParams.set('engine', 'google');
|
|
13504
|
+
url.searchParams.set('q', query);
|
|
13505
|
+
for (const [key, value] of Object.entries(options)) {
|
|
13506
|
+
url.searchParams.set(key, String(value));
|
|
13507
|
+
}
|
|
13508
|
+
const response = await fetch(url.toString());
|
|
13509
|
+
if (!response.ok) {
|
|
13510
|
+
const body = await response.text();
|
|
13511
|
+
throw new Error(`SerpApi failed with status ${response.status}: ${response.statusText}\n${body}`);
|
|
13512
|
+
}
|
|
13513
|
+
const data = (await response.json());
|
|
13514
|
+
return (data.organic_results || []).map((item) => ({
|
|
13515
|
+
title: item.title,
|
|
13516
|
+
url: item.link,
|
|
13517
|
+
snippet: item.snippet || '',
|
|
13518
|
+
}));
|
|
13519
|
+
}
|
|
13520
|
+
}
|
|
13521
|
+
|
|
13522
|
+
/**
|
|
13523
|
+
* Creates one SERP-backed tool function used as a local fallback for search-like commitments.
|
|
13524
|
+
*
|
|
13525
|
+
* @param toolName - Technical tool name used for validation messages.
|
|
13526
|
+
* @param resultLabel - Human-readable label used in formatted results.
|
|
13527
|
+
* @returns Async tool function compatible with commitment tool registration.
|
|
13528
|
+
*
|
|
13529
|
+
* @private internal helper for search-like commitments
|
|
13530
|
+
*/
|
|
13531
|
+
function createSerpSearchToolFunction(toolName, resultLabel) {
|
|
13532
|
+
return async (rawArgs) => {
|
|
13533
|
+
const { query, ...searchOptions } = rawArgs;
|
|
13534
|
+
if (typeof query !== 'string' || !query.trim()) {
|
|
13535
|
+
throw new Error(`${toolName} query is required`);
|
|
13536
|
+
}
|
|
13537
|
+
const searchEngine = new SerpSearchEngine();
|
|
13538
|
+
const results = await searchEngine.search(query, searchOptions);
|
|
13539
|
+
return spacetrim.spaceTrim((block) => `
|
|
13540
|
+
${resultLabel} results for "${query}"${Object.keys(searchOptions).length === 0
|
|
13541
|
+
? ''
|
|
13542
|
+
: ` with options ${JSON.stringify(searchOptions)}`}:
|
|
13543
|
+
|
|
13544
|
+
${block(results
|
|
13545
|
+
.map((result) => spacetrim.spaceTrim(`
|
|
13546
|
+
- **${result.title}**
|
|
13547
|
+
${result.url}
|
|
13548
|
+
${result.snippet}
|
|
13549
|
+
`))
|
|
13550
|
+
.join('\n\n'))}
|
|
13551
|
+
`);
|
|
13552
|
+
};
|
|
13553
|
+
}
|
|
13554
|
+
|
|
13555
|
+
/**
|
|
13556
|
+
* USE DEEPSEARCH commitment definition
|
|
13557
|
+
*
|
|
13558
|
+
* The `USE DEEPSEARCH` commitment indicates that the agent should use a deeper research-oriented
|
|
13559
|
+
* search workflow instead of lightweight web search when it needs fresh information from the internet.
|
|
13560
|
+
*
|
|
13561
|
+
* The content following `USE DEEPSEARCH` is an arbitrary text that the agent should know
|
|
13562
|
+
* (e.g. search scope or research instructions).
|
|
13563
|
+
*
|
|
13564
|
+
* Example usage in agent source:
|
|
13565
|
+
*
|
|
13566
|
+
* ```book
|
|
13567
|
+
* USE DEEPSEARCH
|
|
13568
|
+
* USE DEEPSEARCH Compare official vendor documentation with independent benchmarks.
|
|
13569
|
+
* ```
|
|
13570
|
+
*
|
|
13571
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
13572
|
+
*/
|
|
13573
|
+
class UseDeepSearchCommitmentDefinition extends BaseCommitmentDefinition {
|
|
13574
|
+
constructor() {
|
|
13575
|
+
super('USE DEEPSEARCH');
|
|
13576
|
+
}
|
|
13577
|
+
get requiresContent() {
|
|
13578
|
+
return false;
|
|
13579
|
+
}
|
|
13580
|
+
/**
|
|
13581
|
+
* Short one-line description of USE DEEPSEARCH.
|
|
13582
|
+
*/
|
|
13583
|
+
get description() {
|
|
13584
|
+
return 'Enable the agent to use DeepSearch for more thorough internet research.';
|
|
13585
|
+
}
|
|
13586
|
+
/**
|
|
13587
|
+
* Icon for this commitment.
|
|
13588
|
+
*/
|
|
13589
|
+
get icon() {
|
|
13590
|
+
return '🔬';
|
|
13591
|
+
}
|
|
13592
|
+
/**
|
|
13593
|
+
* Markdown documentation for USE DEEPSEARCH commitment.
|
|
13594
|
+
*/
|
|
13595
|
+
get documentation() {
|
|
13596
|
+
return spacetrim.spaceTrim(`
|
|
13597
|
+
# USE DEEPSEARCH
|
|
13598
|
+
|
|
13599
|
+
Enables the agent to use DeepSearch for broader, more thorough internet research than lightweight web search.
|
|
13600
|
+
|
|
13601
|
+
## Key aspects
|
|
13602
|
+
|
|
13603
|
+
- The content following \`USE DEEPSEARCH\` is arbitrary guidance for the research workflow.
|
|
13604
|
+
- In Agents Server, the OpenAI Agents SDK runtime uses a nested deep-research agent for this tool.
|
|
13605
|
+
- Use this for investigations, comparisons, market scans, or other tasks that benefit from deeper synthesis.
|
|
13606
|
+
- Prefer regular \`USE SEARCH ENGINE\` when a quick factual lookup is enough.
|
|
13607
|
+
|
|
13608
|
+
## Examples
|
|
13609
|
+
|
|
13610
|
+
\`\`\`book
|
|
13611
|
+
Due Diligence Researcher
|
|
13612
|
+
|
|
13613
|
+
GOAL Investigate vendors thoroughly before making recommendations.
|
|
13614
|
+
USE DEEPSEARCH Compare official sources with credible third-party analysis.
|
|
13615
|
+
RULE Cite the strongest supporting sources in the final answer.
|
|
13616
|
+
\`\`\`
|
|
13617
|
+
|
|
13618
|
+
\`\`\`book
|
|
13619
|
+
Market Analyst
|
|
13620
|
+
|
|
13621
|
+
GOAL Build concise but well-grounded research briefs.
|
|
13622
|
+
USE DEEPSEARCH Focus on recent public information and competing viewpoints.
|
|
13623
|
+
CLOSED
|
|
13624
|
+
\`\`\`
|
|
13625
|
+
`);
|
|
13626
|
+
}
|
|
13627
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
13628
|
+
const existingTools = requirements.tools || [];
|
|
13629
|
+
const updatedTools = existingTools.some((tool) => tool.name === 'deep_search')
|
|
13630
|
+
? existingTools
|
|
13631
|
+
: [
|
|
13632
|
+
...existingTools,
|
|
13633
|
+
{
|
|
13634
|
+
name: 'deep_search',
|
|
13635
|
+
description: spacetrim.spaceTrim(`
|
|
13636
|
+
Research the internet deeply and synthesize a grounded answer.
|
|
13637
|
+
Use this tool for broader investigations, comparisons, and requests that need more than a quick search.
|
|
13638
|
+
`),
|
|
13639
|
+
parameters: {
|
|
13640
|
+
type: 'object',
|
|
13641
|
+
properties: {
|
|
13642
|
+
query: {
|
|
13643
|
+
type: 'string',
|
|
13644
|
+
description: 'The research question or investigation request.',
|
|
13645
|
+
},
|
|
13646
|
+
},
|
|
13647
|
+
required: ['query'],
|
|
13648
|
+
additionalProperties: false,
|
|
13649
|
+
},
|
|
13650
|
+
},
|
|
13651
|
+
];
|
|
13652
|
+
return appendAggregatedUseCommitmentPlaceholder({
|
|
13653
|
+
...requirements,
|
|
13654
|
+
tools: updatedTools,
|
|
13655
|
+
_metadata: {
|
|
13656
|
+
...requirements._metadata,
|
|
13657
|
+
useDeepSearch: content || true,
|
|
13658
|
+
},
|
|
13659
|
+
}, this.type);
|
|
13660
|
+
}
|
|
13661
|
+
/**
|
|
13662
|
+
* Gets human-readable titles for tool functions provided by this commitment.
|
|
13663
|
+
*/
|
|
13664
|
+
getToolTitles() {
|
|
13665
|
+
return {
|
|
13666
|
+
deep_search: 'DeepSearch',
|
|
13667
|
+
};
|
|
13668
|
+
}
|
|
13669
|
+
/**
|
|
13670
|
+
* Gets the local fallback implementation for the `deep_search` tool.
|
|
13671
|
+
*/
|
|
13672
|
+
getToolFunctions() {
|
|
13673
|
+
return {
|
|
13674
|
+
deep_search: createSerpSearchToolFunction('deep_search', 'DeepSearch'),
|
|
13675
|
+
};
|
|
13676
|
+
}
|
|
13677
|
+
}
|
|
13678
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
13679
|
+
|
|
13463
13680
|
/**
|
|
13464
13681
|
* Lightweight email token matcher used for `USE EMAIL` first-line parsing.
|
|
13465
13682
|
*
|
|
@@ -15691,49 +15908,6 @@
|
|
|
15691
15908
|
}
|
|
15692
15909
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
15693
15910
|
|
|
15694
|
-
/**
|
|
15695
|
-
* A search engine implementation that uses the SerpApi to fetch Google search results.
|
|
15696
|
-
*
|
|
15697
|
-
* @private <- TODO: !!!! Export via some package
|
|
15698
|
-
*/
|
|
15699
|
-
class SerpSearchEngine {
|
|
15700
|
-
get title() {
|
|
15701
|
-
return 'SerpApi Search Engine';
|
|
15702
|
-
}
|
|
15703
|
-
get description() {
|
|
15704
|
-
return 'Search engine that uses SerpApi to fetch Google search results';
|
|
15705
|
-
}
|
|
15706
|
-
checkConfiguration() {
|
|
15707
|
-
if (!process.env.SERP_API_KEY) {
|
|
15708
|
-
throw new Error('SERP_API_KEY is not configured');
|
|
15709
|
-
}
|
|
15710
|
-
}
|
|
15711
|
-
async search(query, options = {}) {
|
|
15712
|
-
const apiKey = process.env.SERP_API_KEY;
|
|
15713
|
-
if (!apiKey) {
|
|
15714
|
-
throw new Error('SERP_API_KEY is not configured');
|
|
15715
|
-
}
|
|
15716
|
-
const url = new URL('https://serpapi.com/search');
|
|
15717
|
-
url.searchParams.set('api_key', apiKey);
|
|
15718
|
-
url.searchParams.set('engine', 'google');
|
|
15719
|
-
url.searchParams.set('q', query);
|
|
15720
|
-
for (const [key, value] of Object.entries(options)) {
|
|
15721
|
-
url.searchParams.set(key, String(value));
|
|
15722
|
-
}
|
|
15723
|
-
const response = await fetch(url.toString());
|
|
15724
|
-
if (!response.ok) {
|
|
15725
|
-
const body = await response.text();
|
|
15726
|
-
throw new Error(`SerpApi failed with status ${response.status}: ${response.statusText}\n${body}`);
|
|
15727
|
-
}
|
|
15728
|
-
const data = (await response.json());
|
|
15729
|
-
return (data.organic_results || []).map((item) => ({
|
|
15730
|
-
title: item.title,
|
|
15731
|
-
url: item.link,
|
|
15732
|
-
snippet: item.snippet || '',
|
|
15733
|
-
}));
|
|
15734
|
-
}
|
|
15735
|
-
}
|
|
15736
|
-
|
|
15737
15911
|
/**
|
|
15738
15912
|
* USE SEARCH ENGINE commitment definition
|
|
15739
15913
|
*
|
|
@@ -15877,26 +16051,7 @@
|
|
|
15877
16051
|
*/
|
|
15878
16052
|
getToolFunctions() {
|
|
15879
16053
|
return {
|
|
15880
|
-
|
|
15881
|
-
console.log('!!!! [Tool] web_search called', { args });
|
|
15882
|
-
const { query, ...options } = args;
|
|
15883
|
-
if (!query) {
|
|
15884
|
-
throw new Error('Search query is required');
|
|
15885
|
-
}
|
|
15886
|
-
const searchEngine = new SerpSearchEngine();
|
|
15887
|
-
const results = await searchEngine.search(query, options);
|
|
15888
|
-
return spacetrim.spaceTrim((block) => `
|
|
15889
|
-
Search results for "${query}"${Object.keys(options).length === 0 ? '' : ` with options ${JSON.stringify(options)}`}:
|
|
15890
|
-
|
|
15891
|
-
${block(results
|
|
15892
|
-
.map((result) => spacetrim.spaceTrim(`
|
|
15893
|
-
- **${result.title}**
|
|
15894
|
-
${result.url}
|
|
15895
|
-
${result.snippet}
|
|
15896
|
-
`))
|
|
15897
|
-
.join('\n\n'))}
|
|
15898
|
-
`);
|
|
15899
|
-
},
|
|
16054
|
+
web_search: createSerpSearchToolFunction('web_search', 'Search'),
|
|
15900
16055
|
};
|
|
15901
16056
|
}
|
|
15902
16057
|
}
|
|
@@ -17542,6 +17697,7 @@
|
|
|
17542
17697
|
new ClosedCommitmentDefinition(),
|
|
17543
17698
|
new TeamCommitmentDefinition(),
|
|
17544
17699
|
new UseBrowserCommitmentDefinition(),
|
|
17700
|
+
new UseDeepSearchCommitmentDefinition(),
|
|
17545
17701
|
new UseSearchEngineCommitmentDefinition(),
|
|
17546
17702
|
new UseSpawnCommitmentDefinition(),
|
|
17547
17703
|
new UseTimeoutCommitmentDefinition(),
|
|
@@ -17853,6 +18009,11 @@
|
|
|
17853
18009
|
label: 'Internet',
|
|
17854
18010
|
iconName: 'Search',
|
|
17855
18011
|
},
|
|
18012
|
+
'USE DEEPSEARCH': {
|
|
18013
|
+
type: 'search-engine',
|
|
18014
|
+
label: 'DeepSearch',
|
|
18015
|
+
iconName: 'Search',
|
|
18016
|
+
},
|
|
17856
18017
|
'USE TIME': {
|
|
17857
18018
|
type: 'time',
|
|
17858
18019
|
label: 'Time',
|
|
@@ -25728,6 +25889,320 @@
|
|
|
25728
25889
|
}), children: jsxRuntime.jsx(SendIcon, { size: 25 }) })] }), speechRecognition && (jsxRuntime.jsx(ChatInputAreaDictationPanel, { bubbleText: speechRecognitionUiDescriptor.bubbleText, bubbleTone: speechRecognitionUiDescriptor.bubbleTone, shouldShowPanel: shouldShowDictationPanel, isExpanded: isDictationPanelExpanded, interimText: dictationInterimText, error: dictationError, lastFinalChunk: dictationLastFinalChunk, editableChunk: dictationEditableChunk, canBacktrack: canBacktrack, dictationSettings: dictationSettings, isBrowserSpeechFallbackSupported: isBrowserSpeechFallbackSupported, canOpenBrowserSettings: canOpenBrowserSettings, onToggleExpanded: toggleDictationPanel, onExpand: expandDictationPanel, onEditableChunkChange: setDictationEditableChunk, onRetryPermissionRequest: handleRetryPermissionRequest, onOpenBrowserSettings: handleOpenBrowserSettings, onApplyCorrection: handleApplyCorrection, onBacktrackLastChunk: handleBacktrackLastChunk, onDictationSettingChange: handleDictationSettingChange })), isUploading && (jsxRuntime.jsxs("div", { className: styles$5.uploadProgress, children: [jsxRuntime.jsx("div", { className: styles$5.uploadProgressBar, children: jsxRuntime.jsx("div", { className: styles$5.uploadProgressFill }) }), jsxRuntime.jsx("span", { children: "Uploading files..." })] })), isDragOver && onFileUpload && (jsxRuntime.jsx("div", { className: styles$5.dragOverlay, children: jsxRuntime.jsxs("div", { className: styles$5.dragOverlayContent, children: [jsxRuntime.jsx(AttachmentIcon, { size: 48 }), jsxRuntime.jsx("span", { children: "Drop files here to upload" })] }) }))] }));
|
|
25729
25890
|
}
|
|
25730
25891
|
|
|
25892
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
25893
|
+
/**
|
|
25894
|
+
* Maximum normalized eye travel used when the viewer moves across the viewport.
|
|
25895
|
+
*
|
|
25896
|
+
* @private utility of the avatar rendering system
|
|
25897
|
+
*/
|
|
25898
|
+
const MAX_GAZE_OFFSET = 0.78;
|
|
25899
|
+
/**
|
|
25900
|
+
* Maximum normalized body lean used for subtle mantle response.
|
|
25901
|
+
*
|
|
25902
|
+
* @private utility of the avatar rendering system
|
|
25903
|
+
*/
|
|
25904
|
+
const MAX_BODY_OFFSET = 0.28;
|
|
25905
|
+
/**
|
|
25906
|
+
* Smoothing window used while a live pointer or touch target is active.
|
|
25907
|
+
*
|
|
25908
|
+
* @private utility of the avatar rendering system
|
|
25909
|
+
*/
|
|
25910
|
+
const ACTIVE_INTERACTION_SMOOTHING_MS = 90;
|
|
25911
|
+
/**
|
|
25912
|
+
* Slower smoothing window used when easing the avatar back to its idle state.
|
|
25913
|
+
*
|
|
25914
|
+
* @private utility of the avatar rendering system
|
|
25915
|
+
*/
|
|
25916
|
+
const IDLE_INTERACTION_SMOOTHING_MS = 230;
|
|
25917
|
+
/**
|
|
25918
|
+
* Maximum frame delta allowed when smoothing interaction after tab stalls.
|
|
25919
|
+
*
|
|
25920
|
+
* @private utility of the avatar rendering system
|
|
25921
|
+
*/
|
|
25922
|
+
const MAX_INTERACTION_FRAME_DELTA_MS = 64;
|
|
25923
|
+
/**
|
|
25924
|
+
* Extra damping used for the slower body lean compared with the quicker eye motion.
|
|
25925
|
+
*
|
|
25926
|
+
* @private utility of the avatar rendering system
|
|
25927
|
+
*/
|
|
25928
|
+
const BODY_INTERACTION_SMOOTHING_MULTIPLIER = 1.2;
|
|
25929
|
+
/**
|
|
25930
|
+
* Stable zeroed interaction state used by non-interactive render paths.
|
|
25931
|
+
*
|
|
25932
|
+
* @private utility of the avatar rendering system
|
|
25933
|
+
*/
|
|
25934
|
+
const IDLE_AVATAR_INTERACTION_STATE = {
|
|
25935
|
+
gazeX: 0,
|
|
25936
|
+
gazeY: 0,
|
|
25937
|
+
bodyOffsetX: 0,
|
|
25938
|
+
bodyOffsetY: 0,
|
|
25939
|
+
intensity: 0,
|
|
25940
|
+
isPointerActive: false,
|
|
25941
|
+
pointerType: 'idle',
|
|
25942
|
+
};
|
|
25943
|
+
/**
|
|
25944
|
+
* Creates one stable cache key from the meaningful avatar-definition fields.
|
|
25945
|
+
*
|
|
25946
|
+
* @param avatarDefinition Normalized or raw avatar definition.
|
|
25947
|
+
* @returns Stable cache key that ignores object identity churn.
|
|
25948
|
+
*
|
|
25949
|
+
* @private utility of the avatar rendering system
|
|
25950
|
+
*/
|
|
25951
|
+
function createAvatarDefinitionKey(avatarDefinition) {
|
|
25952
|
+
const normalizedAvatarDefinition = normalizeAvatarDefinition(avatarDefinition);
|
|
25953
|
+
return [
|
|
25954
|
+
normalizedAvatarDefinition.agentName,
|
|
25955
|
+
normalizedAvatarDefinition.agentHash,
|
|
25956
|
+
normalizedAvatarDefinition.colors.join('|'),
|
|
25957
|
+
].join('::');
|
|
25958
|
+
}
|
|
25959
|
+
/**
|
|
25960
|
+
* Returns the neutral interaction state used by static/server-side renders.
|
|
25961
|
+
*
|
|
25962
|
+
* @returns Zeroed interaction state.
|
|
25963
|
+
*
|
|
25964
|
+
* @private utility of the avatar rendering system
|
|
25965
|
+
*/
|
|
25966
|
+
function createIdleAvatarInteractionState() {
|
|
25967
|
+
return IDLE_AVATAR_INTERACTION_STATE;
|
|
25968
|
+
}
|
|
25969
|
+
/**
|
|
25970
|
+
* Creates a fresh runtime state for the interactive animation loop.
|
|
25971
|
+
*
|
|
25972
|
+
* @returns Runtime interaction state with neutral values.
|
|
25973
|
+
*
|
|
25974
|
+
* @private utility of the avatar rendering system
|
|
25975
|
+
*/
|
|
25976
|
+
function createAvatarInteractionRuntimeState() {
|
|
25977
|
+
return {
|
|
25978
|
+
...IDLE_AVATAR_INTERACTION_STATE,
|
|
25979
|
+
lastFrameMs: null,
|
|
25980
|
+
};
|
|
25981
|
+
}
|
|
25982
|
+
/**
|
|
25983
|
+
* Converts the shared viewport pointer state into one avatar-local gaze target.
|
|
25984
|
+
*
|
|
25985
|
+
* @param avatarBounds Canvas bounds in viewport coordinates.
|
|
25986
|
+
* @param pointerSnapshot Latest shared pointer sample.
|
|
25987
|
+
* @returns Local target used to steer eyes and subtle body lean.
|
|
25988
|
+
*
|
|
25989
|
+
* @private utility of the avatar rendering system
|
|
25990
|
+
*/
|
|
25991
|
+
function resolveAvatarPointerTarget(avatarBounds, pointerSnapshot) {
|
|
25992
|
+
if (!pointerSnapshot || !pointerSnapshot.isPointerActive) {
|
|
25993
|
+
return {
|
|
25994
|
+
...IDLE_AVATAR_INTERACTION_STATE,
|
|
25995
|
+
};
|
|
25996
|
+
}
|
|
25997
|
+
const centerX = avatarBounds.left + avatarBounds.width / 2;
|
|
25998
|
+
const centerY = avatarBounds.top + avatarBounds.height / 2;
|
|
25999
|
+
const normalizedX = (pointerSnapshot.clientX - centerX) / Math.max(avatarBounds.width / 2, 1);
|
|
26000
|
+
const normalizedY = (pointerSnapshot.clientY - centerY) / Math.max(avatarBounds.height / 2, 1);
|
|
26001
|
+
const normalizedLength = Math.hypot(normalizedX, normalizedY) || 1;
|
|
26002
|
+
const clampedLength = Math.min(1, normalizedLength);
|
|
26003
|
+
const targetX = (normalizedX / normalizedLength) * clampedLength;
|
|
26004
|
+
const targetY = (normalizedY / normalizedLength) * clampedLength;
|
|
26005
|
+
const intensity = clamp01$1(clampedLength);
|
|
26006
|
+
return {
|
|
26007
|
+
gazeX: targetX * MAX_GAZE_OFFSET,
|
|
26008
|
+
gazeY: targetY * MAX_GAZE_OFFSET,
|
|
26009
|
+
bodyOffsetX: targetX * MAX_BODY_OFFSET,
|
|
26010
|
+
bodyOffsetY: targetY * MAX_BODY_OFFSET,
|
|
26011
|
+
intensity,
|
|
26012
|
+
isPointerActive: true,
|
|
26013
|
+
pointerType: pointerSnapshot.pointerType,
|
|
26014
|
+
};
|
|
26015
|
+
}
|
|
26016
|
+
/**
|
|
26017
|
+
* Advances the smoothed interaction state toward the latest pointer target.
|
|
26018
|
+
*
|
|
26019
|
+
* @param runtimeState Previous animation-frame state.
|
|
26020
|
+
* @param pointerTarget Latest local pointer target.
|
|
26021
|
+
* @param nowMs Current animation-frame timestamp.
|
|
26022
|
+
* @returns Next runtime state to keep in the animation loop.
|
|
26023
|
+
*
|
|
26024
|
+
* @private utility of the avatar rendering system
|
|
26025
|
+
*/
|
|
26026
|
+
function stepAvatarInteractionRuntimeState(runtimeState, pointerTarget, nowMs) {
|
|
26027
|
+
const deltaMs = runtimeState.lastFrameMs === null
|
|
26028
|
+
? 16
|
|
26029
|
+
: Math.min(MAX_INTERACTION_FRAME_DELTA_MS, Math.max(8, nowMs - runtimeState.lastFrameMs));
|
|
26030
|
+
const smoothingWindowMs = pointerTarget.isPointerActive
|
|
26031
|
+
? ACTIVE_INTERACTION_SMOOTHING_MS
|
|
26032
|
+
: IDLE_INTERACTION_SMOOTHING_MS;
|
|
26033
|
+
// This exponential interpolation keeps the gaze response smooth regardless of fluctuating frame rates.
|
|
26034
|
+
return {
|
|
26035
|
+
gazeX: interpolateExponentially(runtimeState.gazeX, pointerTarget.gazeX, deltaMs, smoothingWindowMs),
|
|
26036
|
+
gazeY: interpolateExponentially(runtimeState.gazeY, pointerTarget.gazeY, deltaMs, smoothingWindowMs),
|
|
26037
|
+
bodyOffsetX: interpolateExponentially(runtimeState.bodyOffsetX, pointerTarget.bodyOffsetX, deltaMs, smoothingWindowMs * BODY_INTERACTION_SMOOTHING_MULTIPLIER),
|
|
26038
|
+
bodyOffsetY: interpolateExponentially(runtimeState.bodyOffsetY, pointerTarget.bodyOffsetY, deltaMs, smoothingWindowMs * BODY_INTERACTION_SMOOTHING_MULTIPLIER),
|
|
26039
|
+
intensity: interpolateExponentially(runtimeState.intensity, pointerTarget.intensity, deltaMs, smoothingWindowMs),
|
|
26040
|
+
isPointerActive: pointerTarget.isPointerActive,
|
|
26041
|
+
pointerType: pointerTarget.pointerType,
|
|
26042
|
+
lastFrameMs: nowMs,
|
|
26043
|
+
};
|
|
26044
|
+
}
|
|
26045
|
+
/**
|
|
26046
|
+
* Clamps a scalar into the inclusive `[0, 1]` range.
|
|
26047
|
+
*
|
|
26048
|
+
* @param value Arbitrary scalar.
|
|
26049
|
+
* @returns Clamped scalar.
|
|
26050
|
+
*
|
|
26051
|
+
* @private utility of the avatar rendering system
|
|
26052
|
+
*/
|
|
26053
|
+
function clamp01$1(value) {
|
|
26054
|
+
return Math.min(1, Math.max(0, value));
|
|
26055
|
+
}
|
|
26056
|
+
/**
|
|
26057
|
+
* Interpolates between two values using frame-rate-independent exponential easing.
|
|
26058
|
+
*
|
|
26059
|
+
* @param currentValue Current smoothed value.
|
|
26060
|
+
* @param targetValue Target value.
|
|
26061
|
+
* @param deltaMs Elapsed milliseconds since the previous frame.
|
|
26062
|
+
* @param smoothingWindowMs Time constant controlling responsiveness.
|
|
26063
|
+
* @returns Smoothed next value.
|
|
26064
|
+
*
|
|
26065
|
+
* @private utility of the avatar rendering system
|
|
26066
|
+
*/
|
|
26067
|
+
function interpolateExponentially(currentValue, targetValue, deltaMs, smoothingWindowMs) {
|
|
26068
|
+
const blend = 1 - Math.exp(-deltaMs / Math.max(1, smoothingWindowMs));
|
|
26069
|
+
return currentValue + (targetValue - currentValue) * blend;
|
|
26070
|
+
}
|
|
26071
|
+
|
|
26072
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
26073
|
+
/**
|
|
26074
|
+
* Active avatar instances currently consuming the shared pointer tracker.
|
|
26075
|
+
*
|
|
26076
|
+
* @private utility of the avatar rendering system
|
|
26077
|
+
*/
|
|
26078
|
+
let avatarPointerTrackingConsumerCount = 0;
|
|
26079
|
+
/**
|
|
26080
|
+
* Latest shared viewport pointer sample.
|
|
26081
|
+
*
|
|
26082
|
+
* @private utility of the avatar rendering system
|
|
26083
|
+
*/
|
|
26084
|
+
let currentAvatarPointerSnapshot = null;
|
|
26085
|
+
/**
|
|
26086
|
+
* Cleanup function for the lazily attached global listeners.
|
|
26087
|
+
*
|
|
26088
|
+
* @private utility of the avatar rendering system
|
|
26089
|
+
*/
|
|
26090
|
+
let releaseAvatarPointerTrackingListeners = null;
|
|
26091
|
+
/**
|
|
26092
|
+
* Starts the shared pointer tracker and returns a disposer for the caller.
|
|
26093
|
+
*
|
|
26094
|
+
* @returns Cleanup function that releases one consumer.
|
|
26095
|
+
*
|
|
26096
|
+
* @private utility of the avatar rendering system
|
|
26097
|
+
*/
|
|
26098
|
+
function retainAvatarPointerTracking() {
|
|
26099
|
+
avatarPointerTrackingConsumerCount++;
|
|
26100
|
+
if (avatarPointerTrackingConsumerCount === 1) {
|
|
26101
|
+
releaseAvatarPointerTrackingListeners = attachAvatarPointerTrackingListeners();
|
|
26102
|
+
}
|
|
26103
|
+
return () => {
|
|
26104
|
+
avatarPointerTrackingConsumerCount = Math.max(0, avatarPointerTrackingConsumerCount - 1);
|
|
26105
|
+
if (avatarPointerTrackingConsumerCount === 0) {
|
|
26106
|
+
currentAvatarPointerSnapshot = null;
|
|
26107
|
+
releaseAvatarPointerTrackingListeners === null || releaseAvatarPointerTrackingListeners === void 0 ? void 0 : releaseAvatarPointerTrackingListeners();
|
|
26108
|
+
releaseAvatarPointerTrackingListeners = null;
|
|
26109
|
+
}
|
|
26110
|
+
};
|
|
26111
|
+
}
|
|
26112
|
+
/**
|
|
26113
|
+
* Returns the latest shared viewport pointer sample when available.
|
|
26114
|
+
*
|
|
26115
|
+
* @returns Shared pointer snapshot or `null`.
|
|
26116
|
+
*
|
|
26117
|
+
* @private utility of the avatar rendering system
|
|
26118
|
+
*/
|
|
26119
|
+
function getAvatarPointerSnapshot() {
|
|
26120
|
+
return currentAvatarPointerSnapshot;
|
|
26121
|
+
}
|
|
26122
|
+
/**
|
|
26123
|
+
* Attaches the global pointer/touch listeners used by all live avatar canvases.
|
|
26124
|
+
*
|
|
26125
|
+
* @returns Cleanup function for the attached listeners.
|
|
26126
|
+
*
|
|
26127
|
+
* @private utility of the avatar rendering system
|
|
26128
|
+
*/
|
|
26129
|
+
function attachAvatarPointerTrackingListeners() {
|
|
26130
|
+
if (typeof window === 'undefined') {
|
|
26131
|
+
return () => undefined;
|
|
26132
|
+
}
|
|
26133
|
+
const clearPointerSnapshot = () => {
|
|
26134
|
+
currentAvatarPointerSnapshot = null;
|
|
26135
|
+
};
|
|
26136
|
+
const updatePointerSnapshot = (clientX, clientY, pointerType) => {
|
|
26137
|
+
currentAvatarPointerSnapshot = {
|
|
26138
|
+
clientX,
|
|
26139
|
+
clientY,
|
|
26140
|
+
isPointerActive: true,
|
|
26141
|
+
pointerType,
|
|
26142
|
+
};
|
|
26143
|
+
};
|
|
26144
|
+
const handlePointerMove = (event) => {
|
|
26145
|
+
updatePointerSnapshot(event.clientX, event.clientY, normalizeAvatarPointerType(event.pointerType));
|
|
26146
|
+
};
|
|
26147
|
+
const handlePointerDown = (event) => {
|
|
26148
|
+
updatePointerSnapshot(event.clientX, event.clientY, normalizeAvatarPointerType(event.pointerType));
|
|
26149
|
+
};
|
|
26150
|
+
const handlePointerUp = (event) => {
|
|
26151
|
+
if (normalizeAvatarPointerType(event.pointerType) !== 'mouse') {
|
|
26152
|
+
clearPointerSnapshot();
|
|
26153
|
+
}
|
|
26154
|
+
};
|
|
26155
|
+
const handleMouseOut = (event) => {
|
|
26156
|
+
if (!event.relatedTarget) {
|
|
26157
|
+
clearPointerSnapshot();
|
|
26158
|
+
}
|
|
26159
|
+
};
|
|
26160
|
+
const handleTouchEvent = (event) => {
|
|
26161
|
+
const touch = event.touches[0] || event.changedTouches[0];
|
|
26162
|
+
if (!touch) {
|
|
26163
|
+
clearPointerSnapshot();
|
|
26164
|
+
return;
|
|
26165
|
+
}
|
|
26166
|
+
updatePointerSnapshot(touch.clientX, touch.clientY, 'touch');
|
|
26167
|
+
};
|
|
26168
|
+
window.addEventListener('pointermove', handlePointerMove, { passive: true });
|
|
26169
|
+
window.addEventListener('pointerdown', handlePointerDown, { passive: true });
|
|
26170
|
+
window.addEventListener('pointerup', handlePointerUp, { passive: true });
|
|
26171
|
+
window.addEventListener('pointercancel', clearPointerSnapshot, { passive: true });
|
|
26172
|
+
window.addEventListener('mouseout', handleMouseOut, { passive: true });
|
|
26173
|
+
window.addEventListener('blur', clearPointerSnapshot);
|
|
26174
|
+
window.addEventListener('touchstart', handleTouchEvent, { passive: true });
|
|
26175
|
+
window.addEventListener('touchmove', handleTouchEvent, { passive: true });
|
|
26176
|
+
window.addEventListener('touchend', clearPointerSnapshot, { passive: true });
|
|
26177
|
+
window.addEventListener('touchcancel', clearPointerSnapshot, { passive: true });
|
|
26178
|
+
return () => {
|
|
26179
|
+
window.removeEventListener('pointermove', handlePointerMove);
|
|
26180
|
+
window.removeEventListener('pointerdown', handlePointerDown);
|
|
26181
|
+
window.removeEventListener('pointerup', handlePointerUp);
|
|
26182
|
+
window.removeEventListener('pointercancel', clearPointerSnapshot);
|
|
26183
|
+
window.removeEventListener('mouseout', handleMouseOut);
|
|
26184
|
+
window.removeEventListener('blur', clearPointerSnapshot);
|
|
26185
|
+
window.removeEventListener('touchstart', handleTouchEvent);
|
|
26186
|
+
window.removeEventListener('touchmove', handleTouchEvent);
|
|
26187
|
+
window.removeEventListener('touchend', clearPointerSnapshot);
|
|
26188
|
+
window.removeEventListener('touchcancel', clearPointerSnapshot);
|
|
26189
|
+
};
|
|
26190
|
+
}
|
|
26191
|
+
/**
|
|
26192
|
+
* Normalizes browser pointer-type strings into the shared avatar contract.
|
|
26193
|
+
*
|
|
26194
|
+
* @param pointerType Raw browser pointer type.
|
|
26195
|
+
* @returns Shared pointer type.
|
|
26196
|
+
*
|
|
26197
|
+
* @private utility of the avatar rendering system
|
|
26198
|
+
*/
|
|
26199
|
+
function normalizeAvatarPointerType(pointerType) {
|
|
26200
|
+
if (pointerType === 'touch' || pointerType === 'pen') {
|
|
26201
|
+
return pointerType;
|
|
26202
|
+
}
|
|
26203
|
+
return 'mouse';
|
|
26204
|
+
}
|
|
26205
|
+
|
|
25731
26206
|
/* eslint-disable no-magic-numbers */
|
|
25732
26207
|
/**
|
|
25733
26208
|
* Builds a smoothly morphing octopus-like silhouette from deterministic parameters.
|
|
@@ -25804,8 +26279,9 @@
|
|
|
25804
26279
|
* @private shared geometry helper of `octopus3AvatarVisual` and `asciiOctopusAvatarVisual`
|
|
25805
26280
|
*/
|
|
25806
26281
|
function createOrganicOctopusTentacleShapes(options) {
|
|
25807
|
-
const { size, centerX, centerY, bodyRadius, horizontalStretch, tentacleCount, shapePhase, createRandom, timeMs, saltPrefix, } = options;
|
|
26282
|
+
const { size, centerX, centerY, bodyRadius, horizontalStretch, tentacleCount, shapePhase, createRandom, timeMs, saltPrefix, bodyPoints } = options;
|
|
25808
26283
|
const baseY = centerY + bodyRadius * 0.74;
|
|
26284
|
+
const lowerBodyAnchorPoints = bodyPoints ? resolveTentacleBodyAnchorPoints(bodyPoints, centerY + bodyRadius * 0.04) : null;
|
|
25809
26285
|
return Array.from({ length: tentacleCount }, (_, tentacleIndex) => {
|
|
25810
26286
|
const tentacleRandom = createRandom(`${saltPrefix}-tentacle-${tentacleIndex}`);
|
|
25811
26287
|
const spreadProgress = tentacleCount === 1 ? 0.5 : tentacleIndex / (tentacleCount - 1);
|
|
@@ -25817,10 +26293,21 @@
|
|
|
25817
26293
|
const curlDirection = centeredProgress === 0 ? (tentacleRandom() < 0.5 ? -1 : 1) : Math.sign(centeredProgress);
|
|
25818
26294
|
const lateralReach = centeredProgress * size * (0.1 + tentacleRandom() * 0.1) + temporalSway;
|
|
25819
26295
|
const tipReach = curlDirection * size * (0.025 + tentacleRandom() * 0.07);
|
|
25820
|
-
const
|
|
25821
|
-
|
|
25822
|
-
|
|
25823
|
-
|
|
26296
|
+
const startYOffset = Math.abs(centeredProgress) * size * 0.012 + tentacleRandom() * size * 0.01;
|
|
26297
|
+
const startPoint = lowerBodyAnchorPoints && lowerBodyAnchorPoints.length >= 2
|
|
26298
|
+
? createInsetTentacleStartPoint({
|
|
26299
|
+
bodyPoints: lowerBodyAnchorPoints,
|
|
26300
|
+
anchorProgress: spreadProgress,
|
|
26301
|
+
centerX,
|
|
26302
|
+
centerY,
|
|
26303
|
+
bodyRadius,
|
|
26304
|
+
centeredProgress,
|
|
26305
|
+
startYOffset,
|
|
26306
|
+
})
|
|
26307
|
+
: {
|
|
26308
|
+
x: centerX + centeredProgress * bodyRadius * horizontalStretch * 1.52,
|
|
26309
|
+
y: baseY + startYOffset,
|
|
26310
|
+
};
|
|
25824
26311
|
const controlPointOne = {
|
|
25825
26312
|
x: startPoint.x + centeredProgress * size * 0.045 + temporalSway * 0.4,
|
|
25826
26313
|
y: startPoint.y + flowLength * (0.21 + tentacleRandom() * 0.08),
|
|
@@ -25850,6 +26337,67 @@
|
|
|
25850
26337
|
};
|
|
25851
26338
|
});
|
|
25852
26339
|
}
|
|
26340
|
+
/**
|
|
26341
|
+
* Narrows the body contour to lower anchor points that can safely host tentacle roots.
|
|
26342
|
+
*
|
|
26343
|
+
* @param bodyPoints Generated closed-loop body points.
|
|
26344
|
+
* @param lowerBodyThresholdY Minimum Y coordinate considered part of the lower mantle.
|
|
26345
|
+
* @returns Body points sorted from left to right across the lower silhouette.
|
|
26346
|
+
*
|
|
26347
|
+
* @private shared geometry helper of `octopus3AvatarVisual`
|
|
26348
|
+
*/
|
|
26349
|
+
function resolveTentacleBodyAnchorPoints(bodyPoints, lowerBodyThresholdY) {
|
|
26350
|
+
const lowerBodyPoints = bodyPoints.filter((bodyPoint) => bodyPoint.y >= lowerBodyThresholdY).sort((leftPoint, rightPoint) => leftPoint.x - rightPoint.x);
|
|
26351
|
+
if (lowerBodyPoints.length >= 2) {
|
|
26352
|
+
return lowerBodyPoints;
|
|
26353
|
+
}
|
|
26354
|
+
return [...bodyPoints].sort((leftPoint, rightPoint) => leftPoint.x - rightPoint.x);
|
|
26355
|
+
}
|
|
26356
|
+
/**
|
|
26357
|
+
* Resolves one tentacle root from the provided lower body contour and nudges it inside the mantle.
|
|
26358
|
+
*
|
|
26359
|
+
* @param options Tentacle anchor options.
|
|
26360
|
+
* @returns Tentacle start point safely embedded inside the body silhouette.
|
|
26361
|
+
*
|
|
26362
|
+
* @private shared geometry helper of `octopus3AvatarVisual`
|
|
26363
|
+
*/
|
|
26364
|
+
function createInsetTentacleStartPoint(options) {
|
|
26365
|
+
const { bodyPoints, anchorProgress, centerX, centerY, bodyRadius, centeredProgress, startYOffset } = options;
|
|
26366
|
+
const clampedAnchorProgress = Math.min(0.94, Math.max(0.06, anchorProgress));
|
|
26367
|
+
const bodyAnchorPoint = interpolatePointAlongTentacleAnchors(bodyPoints, clampedAnchorProgress);
|
|
26368
|
+
const inwardX = centerX - bodyAnchorPoint.x;
|
|
26369
|
+
const inwardY = centerY + bodyRadius * 0.08 - bodyAnchorPoint.y;
|
|
26370
|
+
const inwardLength = Math.hypot(inwardX, inwardY) || 1;
|
|
26371
|
+
const insetDistance = bodyRadius * (0.12 + Math.abs(centeredProgress) * 0.05) + startYOffset * 0.32;
|
|
26372
|
+
return {
|
|
26373
|
+
x: bodyAnchorPoint.x + (inwardX / inwardLength) * insetDistance,
|
|
26374
|
+
y: bodyAnchorPoint.y + (inwardY / inwardLength) * insetDistance,
|
|
26375
|
+
};
|
|
26376
|
+
}
|
|
26377
|
+
/**
|
|
26378
|
+
* Interpolates one left-to-right anchor point along the prepared lower body contour.
|
|
26379
|
+
*
|
|
26380
|
+
* @param bodyPoints Lower body contour points sorted from left to right.
|
|
26381
|
+
* @param progress Interpolation progress in the range `[0, 1]`.
|
|
26382
|
+
* @returns Interpolated anchor point.
|
|
26383
|
+
*
|
|
26384
|
+
* @private shared geometry helper of `octopus3AvatarVisual`
|
|
26385
|
+
*/
|
|
26386
|
+
function interpolatePointAlongTentacleAnchors(bodyPoints, progress) {
|
|
26387
|
+
if (bodyPoints.length === 1) {
|
|
26388
|
+
return bodyPoints[0];
|
|
26389
|
+
}
|
|
26390
|
+
const anchorIndex = progress * (bodyPoints.length - 1);
|
|
26391
|
+
const startIndex = Math.floor(anchorIndex);
|
|
26392
|
+
const endIndex = Math.min(bodyPoints.length - 1, startIndex + 1);
|
|
26393
|
+
const blend = anchorIndex - startIndex;
|
|
26394
|
+
const startPoint = bodyPoints[startIndex];
|
|
26395
|
+
const endPoint = bodyPoints[endIndex];
|
|
26396
|
+
return {
|
|
26397
|
+
x: startPoint.x + (endPoint.x - startPoint.x) * blend,
|
|
26398
|
+
y: startPoint.y + (endPoint.y - startPoint.y) * blend,
|
|
26399
|
+
};
|
|
26400
|
+
}
|
|
25853
26401
|
/**
|
|
25854
26402
|
* Samples the cubic tentacle centerline and offsets normals to build a filled ribbon.
|
|
25855
26403
|
*
|
|
@@ -25879,6 +26427,26 @@
|
|
|
25879
26427
|
};
|
|
25880
26428
|
});
|
|
25881
26429
|
}
|
|
26430
|
+
/**
|
|
26431
|
+
* Resolves smooth pupil offsets that blend autonomous idle drift with live viewer tracking.
|
|
26432
|
+
*
|
|
26433
|
+
* @param options Eye motion options.
|
|
26434
|
+
* @returns Resolved pupil offsets.
|
|
26435
|
+
*
|
|
26436
|
+
* @private shared geometry helper of octopus avatar visuals
|
|
26437
|
+
*/
|
|
26438
|
+
function resolveOrganicEyeMotion(options) {
|
|
26439
|
+
const { radiusX, radiusY, timeMs, phase, interaction, autonomousDriftRatioX = 0.12, autonomousDriftRatioY = 0.08, } = options;
|
|
26440
|
+
const autonomousOffsetX = Math.sin(timeMs / 1280 + phase) * radiusX * autonomousDriftRatioX;
|
|
26441
|
+
const autonomousOffsetY = Math.cos(timeMs / 940 + phase) * radiusY * autonomousDriftRatioY;
|
|
26442
|
+
const interactionBlend = Math.min(1, interaction.intensity * 0.9);
|
|
26443
|
+
return {
|
|
26444
|
+
pupilOffsetX: autonomousOffsetX * (1 - interactionBlend) +
|
|
26445
|
+
interaction.gazeX * radiusX * (0.18 + interactionBlend * 0.18),
|
|
26446
|
+
pupilOffsetY: autonomousOffsetY * (1 - interactionBlend) +
|
|
26447
|
+
interaction.gazeY * radiusY * (0.16 + interactionBlend * 0.16),
|
|
26448
|
+
};
|
|
26449
|
+
}
|
|
25882
26450
|
/**
|
|
25883
26451
|
* Samples one point on a cubic Bezier curve.
|
|
25884
26452
|
*
|
|
@@ -25932,13 +26500,14 @@
|
|
|
25932
26500
|
const asciiOctopusAvatarVisual = {
|
|
25933
26501
|
id: 'ascii-octopus',
|
|
25934
26502
|
title: 'AsciiOctopus',
|
|
25935
|
-
description: 'Morphing alien octopus translated into animated ASCII glyphs with
|
|
26503
|
+
description: 'Morphing alien octopus translated into animated ASCII glyphs with responsive eyes and seeded geometry.',
|
|
25936
26504
|
isAnimated: true,
|
|
25937
|
-
|
|
26505
|
+
supportsPointerTracking: true,
|
|
26506
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
25938
26507
|
const gridRandom = createRandom('ascii-octopus-grid');
|
|
25939
26508
|
const staticRandom = createRandom('ascii-octopus-static');
|
|
25940
26509
|
const gridMetrics = createAsciiGridMetrics(size, gridRandom);
|
|
25941
|
-
const layout = createAsciiOctopusLayout(size, timeMs, createRandom, staticRandom);
|
|
26510
|
+
const layout = createAsciiOctopusLayout(size, timeMs, createRandom, staticRandom, interaction);
|
|
25942
26511
|
drawAvatarFrame(context, size, palette);
|
|
25943
26512
|
drawAsciiBackdrop(context, size, palette, layout, timeMs);
|
|
25944
26513
|
context.save();
|
|
@@ -26012,7 +26581,8 @@
|
|
|
26012
26581
|
*/
|
|
26013
26582
|
function resolveAsciiGlyph(options) {
|
|
26014
26583
|
const { point, layout, palette, cellWidth, cellHeight, noise, timeMs } = options;
|
|
26015
|
-
const eyeGlyphDescriptor = resolveEyeGlyph(point, layout.leftEye,
|
|
26584
|
+
const eyeGlyphDescriptor = resolveEyeGlyph(point, layout.leftEye, layout.interaction, palette, timeMs) ||
|
|
26585
|
+
resolveEyeGlyph(point, layout.rightEye, layout.interaction, palette, timeMs);
|
|
26016
26586
|
if (eyeGlyphDescriptor) {
|
|
26017
26587
|
return eyeGlyphDescriptor;
|
|
26018
26588
|
}
|
|
@@ -26057,9 +26627,14 @@
|
|
|
26057
26627
|
*
|
|
26058
26628
|
* @private helper of `asciiOctopusAvatarVisual`
|
|
26059
26629
|
*/
|
|
26060
|
-
function resolveEyeGlyph(point, eyeFeature, palette, timeMs) {
|
|
26061
|
-
const pupilOffsetX =
|
|
26062
|
-
|
|
26630
|
+
function resolveEyeGlyph(point, eyeFeature, interaction, palette, timeMs) {
|
|
26631
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
26632
|
+
radiusX: eyeFeature.radiusX,
|
|
26633
|
+
radiusY: eyeFeature.radiusY,
|
|
26634
|
+
timeMs,
|
|
26635
|
+
phase: eyeFeature.phase,
|
|
26636
|
+
interaction,
|
|
26637
|
+
});
|
|
26063
26638
|
const scleraDistance = measureRotatedEllipseDistance(point, eyeFeature.centerX, eyeFeature.centerY, eyeFeature.radiusX, eyeFeature.radiusY, eyeFeature.rotation);
|
|
26064
26639
|
if (scleraDistance > 1.08) {
|
|
26065
26640
|
return null;
|
|
@@ -26233,9 +26808,9 @@
|
|
|
26233
26808
|
*
|
|
26234
26809
|
* @private helper of `asciiOctopusAvatarVisual`
|
|
26235
26810
|
*/
|
|
26236
|
-
function createAsciiOctopusLayout(size, timeMs, createRandom, staticRandom) {
|
|
26237
|
-
const centerX = size * (0.5 + (staticRandom() - 0.5) * 0.02);
|
|
26238
|
-
const centerY = size * (0.41 + staticRandom() * 0.05);
|
|
26811
|
+
function createAsciiOctopusLayout(size, timeMs, createRandom, staticRandom, interaction) {
|
|
26812
|
+
const centerX = size * (0.5 + (staticRandom() - 0.5) * 0.02) + interaction.bodyOffsetX * size * 0.05;
|
|
26813
|
+
const centerY = size * (0.41 + staticRandom() * 0.05) + interaction.bodyOffsetY * size * 0.035;
|
|
26239
26814
|
const bodyRadius = size * (0.195 + staticRandom() * 0.05);
|
|
26240
26815
|
const horizontalStretch = 1.08 + staticRandom() * 0.22;
|
|
26241
26816
|
const verticalStretch = 0.88 + staticRandom() * 0.14;
|
|
@@ -26275,6 +26850,7 @@
|
|
|
26275
26850
|
createRandom,
|
|
26276
26851
|
timeMs,
|
|
26277
26852
|
saltPrefix: 'ascii-octopus',
|
|
26853
|
+
bodyPoints,
|
|
26278
26854
|
});
|
|
26279
26855
|
const sampledTentacles = tentacleShapes.map(sampleOrganicTentacleRibbonPoints);
|
|
26280
26856
|
const leftEye = {
|
|
@@ -26295,7 +26871,7 @@
|
|
|
26295
26871
|
};
|
|
26296
26872
|
const mouthPoints = sampleQuadraticBezierPoints({ x: centerX - size * 0.074, y: centerY + size * 0.092 }, {
|
|
26297
26873
|
x: centerX,
|
|
26298
|
-
y: centerY + size * (0.142 + Math.sin(timeMs / 620 + shapePhase) * 0.016),
|
|
26874
|
+
y: centerY + size * (0.142 + Math.sin(timeMs / 620 + shapePhase) * 0.016) + interaction.gazeY * size * 0.012,
|
|
26299
26875
|
}, { x: centerX + size * 0.074, y: centerY + size * 0.092 }, 12);
|
|
26300
26876
|
let leftBound = Number.POSITIVE_INFINITY;
|
|
26301
26877
|
let rightBound = Number.NEGATIVE_INFINITY;
|
|
@@ -26321,6 +26897,7 @@
|
|
|
26321
26897
|
bodyRadius,
|
|
26322
26898
|
horizontalStretch,
|
|
26323
26899
|
shapePhase,
|
|
26900
|
+
interaction,
|
|
26324
26901
|
bodyPoints,
|
|
26325
26902
|
sampledTentacles,
|
|
26326
26903
|
leftEye,
|
|
@@ -27041,15 +27618,16 @@
|
|
|
27041
27618
|
const octopusAvatarVisual = {
|
|
27042
27619
|
id: 'octopus',
|
|
27043
27620
|
title: 'Octopus',
|
|
27044
|
-
description: 'Playful underwater mascot with animated tentacles, bubbles, and
|
|
27621
|
+
description: 'Playful underwater mascot with cursor-following eyes, animated tentacles, bubbles, and seeded markings.',
|
|
27045
27622
|
isAnimated: true,
|
|
27046
|
-
|
|
27623
|
+
supportsPointerTracking: true,
|
|
27624
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
27047
27625
|
const staticRandom = createRandom('octopus-static');
|
|
27048
27626
|
const bubbleRandom = createRandom('octopus-bubbles');
|
|
27049
27627
|
const bubbleCount = 8;
|
|
27050
27628
|
const bubbleRadiusBase = size * 0.02;
|
|
27051
|
-
const centerX = size * 0.5;
|
|
27052
|
-
const centerY = size * 0.42;
|
|
27629
|
+
const centerX = size * 0.5 + interaction.bodyOffsetX * size * 0.035;
|
|
27630
|
+
const centerY = size * 0.42 + interaction.bodyOffsetY * size * 0.024;
|
|
27053
27631
|
const headRadius = size * (0.19 + staticRandom() * 0.03);
|
|
27054
27632
|
const mantleHeight = headRadius * 1.18;
|
|
27055
27633
|
const tentacleLength = size * (0.18 + staticRandom() * 0.06);
|
|
@@ -27129,11 +27707,9 @@
|
|
|
27129
27707
|
}
|
|
27130
27708
|
const eyeOffsetX = headRadius * 0.42;
|
|
27131
27709
|
const eyeY = centerY + headRadius * 0.04;
|
|
27132
|
-
const pupilDriftX = Math.sin(timeMs / 850) * headRadius * 0.05;
|
|
27133
|
-
const pupilDriftY = Math.cos(timeMs / 930) * headRadius * 0.03;
|
|
27134
27710
|
const eyeRadius = headRadius * 0.22;
|
|
27135
|
-
drawEye(context, centerX - eyeOffsetX, eyeY, eyeRadius, palette,
|
|
27136
|
-
drawEye(context, centerX + eyeOffsetX, eyeY, eyeRadius, palette,
|
|
27711
|
+
drawEye(context, centerX - eyeOffsetX, eyeY, eyeRadius, palette, timeMs, interaction, 0);
|
|
27712
|
+
drawEye(context, centerX + eyeOffsetX, eyeY, eyeRadius, palette, timeMs, interaction, Math.PI / 5);
|
|
27137
27713
|
context.beginPath();
|
|
27138
27714
|
context.arc(centerX - headRadius * 0.28, centerY + headRadius * 0.3, headRadius * 0.12, 0, Math.PI * 2);
|
|
27139
27715
|
context.arc(centerX + headRadius * 0.28, centerY + headRadius * 0.3, headRadius * 0.12, 0, Math.PI * 2);
|
|
@@ -27156,22 +27732,32 @@
|
|
|
27156
27732
|
* @param centerY Eye center Y coordinate.
|
|
27157
27733
|
* @param radius Eye radius.
|
|
27158
27734
|
* @param palette Derived avatar palette.
|
|
27159
|
-
* @param
|
|
27160
|
-
* @param
|
|
27735
|
+
* @param timeMs Current animation time in milliseconds.
|
|
27736
|
+
* @param interaction Smoothed avatar interaction state.
|
|
27737
|
+
* @param phase Seed-based phase offset.
|
|
27161
27738
|
*
|
|
27162
27739
|
* @private helper of `octopusAvatarVisual`
|
|
27163
27740
|
*/
|
|
27164
|
-
function drawEye(context, centerX, centerY, radius, palette,
|
|
27741
|
+
function drawEye(context, centerX, centerY, radius, palette, timeMs, interaction, phase) {
|
|
27742
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
27743
|
+
radiusX: radius,
|
|
27744
|
+
radiusY: radius,
|
|
27745
|
+
timeMs,
|
|
27746
|
+
phase,
|
|
27747
|
+
interaction,
|
|
27748
|
+
autonomousDriftRatioX: 0.05,
|
|
27749
|
+
autonomousDriftRatioY: 0.03,
|
|
27750
|
+
});
|
|
27165
27751
|
context.beginPath();
|
|
27166
27752
|
context.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
27167
27753
|
context.fillStyle = '#ffffff';
|
|
27168
27754
|
context.fill();
|
|
27169
27755
|
context.beginPath();
|
|
27170
|
-
context.arc(centerX +
|
|
27756
|
+
context.arc(centerX + pupilOffsetX, centerY + pupilOffsetY, radius * 0.45, 0, Math.PI * 2);
|
|
27171
27757
|
context.fillStyle = palette.ink;
|
|
27172
27758
|
context.fill();
|
|
27173
27759
|
context.beginPath();
|
|
27174
|
-
context.arc(centerX +
|
|
27760
|
+
context.arc(centerX + pupilOffsetX - radius * 0.12, centerY + pupilOffsetY - radius * 0.12, radius * 0.15, 0, Math.PI * 2);
|
|
27175
27761
|
context.fillStyle = '#ffffff';
|
|
27176
27762
|
context.fill();
|
|
27177
27763
|
context.beginPath();
|
|
@@ -27190,12 +27776,13 @@
|
|
|
27190
27776
|
const octopus2AvatarVisual = {
|
|
27191
27777
|
id: 'octopus2',
|
|
27192
27778
|
title: 'Octopus2',
|
|
27193
|
-
description: 'Organic alien octopus rendered as one continuously morphing blob with luminous eyes
|
|
27779
|
+
description: 'Organic alien octopus rendered as one continuously morphing blob with responsive luminous eyes.',
|
|
27194
27780
|
isAnimated: true,
|
|
27195
|
-
|
|
27781
|
+
supportsPointerTracking: true,
|
|
27782
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
27196
27783
|
const staticRandom = createRandom('octopus2-static');
|
|
27197
|
-
const centerX = size * 0.5;
|
|
27198
|
-
const centerY = size * (0.48 + staticRandom() * 0.03);
|
|
27784
|
+
const centerX = size * 0.5 + interaction.bodyOffsetX * size * 0.042;
|
|
27785
|
+
const centerY = size * (0.48 + staticRandom() * 0.03) + interaction.bodyOffsetY * size * 0.028;
|
|
27199
27786
|
const bodyRadius = size * (0.25 + staticRandom() * 0.035);
|
|
27200
27787
|
const horizontalStretch = 1.04 + staticRandom() * 0.16;
|
|
27201
27788
|
const verticalStretch = 0.94 + staticRandom() * 0.12;
|
|
@@ -27266,11 +27853,11 @@
|
|
|
27266
27853
|
const eyeCenterY = centerY - size * 0.02;
|
|
27267
27854
|
const eyeRadiusX = size * 0.072;
|
|
27268
27855
|
const eyeRadiusY = size * 0.086;
|
|
27269
|
-
drawAlienEye(context, centerX - eyeOffsetX, eyeCenterY, eyeRadiusX, eyeRadiusY, palette, timeMs, shapePhase);
|
|
27270
|
-
drawAlienEye(context, centerX + eyeOffsetX, eyeCenterY, eyeRadiusX, eyeRadiusY, palette, timeMs, shapePhase + Math.PI / 5);
|
|
27856
|
+
drawAlienEye(context, centerX - eyeOffsetX, eyeCenterY, eyeRadiusX, eyeRadiusY, palette, timeMs, shapePhase, interaction);
|
|
27857
|
+
drawAlienEye(context, centerX + eyeOffsetX, eyeCenterY, eyeRadiusX, eyeRadiusY, palette, timeMs, shapePhase + Math.PI / 5, interaction);
|
|
27271
27858
|
context.beginPath();
|
|
27272
27859
|
context.moveTo(centerX - size * 0.08, centerY + size * 0.12);
|
|
27273
|
-
context.quadraticCurveTo(centerX, centerY + size * (0.175 + Math.sin(timeMs / 520 + shapePhase) * 0.012), centerX + size * 0.08, centerY + size * 0.12);
|
|
27860
|
+
context.quadraticCurveTo(centerX, centerY + size * (0.175 + Math.sin(timeMs / 520 + shapePhase) * 0.012) + interaction.gazeY * size * 0.01, centerX + size * 0.08, centerY + size * 0.12);
|
|
27274
27861
|
context.strokeStyle = `${palette.ink}b3`;
|
|
27275
27862
|
context.lineWidth = size * 0.013;
|
|
27276
27863
|
context.lineCap = 'round';
|
|
@@ -27348,12 +27935,19 @@
|
|
|
27348
27935
|
* @param palette Derived avatar palette.
|
|
27349
27936
|
* @param timeMs Current animation time in milliseconds.
|
|
27350
27937
|
* @param phase Seed-based animation phase.
|
|
27938
|
+
* @param interaction Smoothed avatar interaction state.
|
|
27351
27939
|
*
|
|
27352
27940
|
* @private helper of `octopus2AvatarVisual`
|
|
27353
27941
|
*/
|
|
27354
|
-
function drawAlienEye(context, centerX, centerY, radiusX, radiusY, palette, timeMs, phase) {
|
|
27355
|
-
const pupilOffsetX =
|
|
27356
|
-
|
|
27942
|
+
function drawAlienEye(context, centerX, centerY, radiusX, radiusY, palette, timeMs, phase, interaction) {
|
|
27943
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
27944
|
+
radiusX,
|
|
27945
|
+
radiusY,
|
|
27946
|
+
timeMs,
|
|
27947
|
+
phase,
|
|
27948
|
+
interaction,
|
|
27949
|
+
autonomousDriftRatioY: 0.1,
|
|
27950
|
+
});
|
|
27357
27951
|
context.save();
|
|
27358
27952
|
context.beginPath();
|
|
27359
27953
|
context.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, Math.PI * 2);
|
|
@@ -27393,12 +27987,13 @@
|
|
|
27393
27987
|
const octopus3AvatarVisual = {
|
|
27394
27988
|
id: 'octopus3',
|
|
27395
27989
|
title: 'Octopus3',
|
|
27396
|
-
description: 'Gelatinous alien octopus with a morphing mantle,
|
|
27990
|
+
description: 'Gelatinous alien octopus with a morphing mantle, responsive eyes, and visible ribbon tentacles.',
|
|
27397
27991
|
isAnimated: true,
|
|
27398
|
-
|
|
27992
|
+
supportsPointerTracking: true,
|
|
27993
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
27399
27994
|
const staticRandom = createRandom('octopus3-static');
|
|
27400
|
-
const centerX = size * (0.5 + (staticRandom() - 0.5) * 0.02);
|
|
27401
|
-
const centerY = size * (0.41 + staticRandom() * 0.05);
|
|
27995
|
+
const centerX = size * (0.5 + (staticRandom() - 0.5) * 0.02) + interaction.bodyOffsetX * size * 0.05;
|
|
27996
|
+
const centerY = size * (0.41 + staticRandom() * 0.05) + interaction.bodyOffsetY * size * 0.035;
|
|
27402
27997
|
const bodyRadius = size * (0.2 + staticRandom() * 0.045);
|
|
27403
27998
|
const horizontalStretch = 1.08 + staticRandom() * 0.22;
|
|
27404
27999
|
const verticalStretch = 0.9 + staticRandom() * 0.12;
|
|
@@ -27438,6 +28033,7 @@
|
|
|
27438
28033
|
createRandom,
|
|
27439
28034
|
timeMs,
|
|
27440
28035
|
saltPrefix: 'octopus3',
|
|
28036
|
+
bodyPoints,
|
|
27441
28037
|
});
|
|
27442
28038
|
drawAvatarFrame(context, size, palette);
|
|
27443
28039
|
drawOctopus3Atmosphere(context, size, palette, centerX, centerY, timeMs, shapePhase);
|
|
@@ -27483,11 +28079,11 @@
|
|
|
27483
28079
|
context.ellipse(centerX, centerY - size * 0.14, size * 0.18, size * 0.062, 0, Math.PI, Math.PI * 2);
|
|
27484
28080
|
context.fillStyle = `${palette.highlight}3d`;
|
|
27485
28081
|
context.fill();
|
|
27486
|
-
drawSeededEye(context, centerX - eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase);
|
|
27487
|
-
drawSeededEye(context, centerX + eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase + Math.PI / 4);
|
|
28082
|
+
drawSeededEye(context, centerX - eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase, interaction);
|
|
28083
|
+
drawSeededEye(context, centerX + eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase + Math.PI / 4, interaction);
|
|
27488
28084
|
context.beginPath();
|
|
27489
28085
|
context.moveTo(centerX - size * 0.07, centerY + size * 0.09);
|
|
27490
|
-
context.quadraticCurveTo(centerX, centerY + size * (0.14 + Math.sin(timeMs / 620 + shapePhase) * 0.016), centerX + size * 0.07, centerY + size * 0.09);
|
|
28086
|
+
context.quadraticCurveTo(centerX, centerY + size * (0.14 + Math.sin(timeMs / 620 + shapePhase) * 0.016) + interaction.gazeY * size * 0.012, centerX + size * 0.07, centerY + size * 0.09);
|
|
27491
28087
|
context.strokeStyle = `${palette.ink}b3`;
|
|
27492
28088
|
context.lineWidth = size * 0.012;
|
|
27493
28089
|
context.lineCap = 'round';
|
|
@@ -27675,12 +28271,18 @@
|
|
|
27675
28271
|
* @param palette Derived avatar palette.
|
|
27676
28272
|
* @param timeMs Current animation time in milliseconds.
|
|
27677
28273
|
* @param phase Seed-based animation phase.
|
|
28274
|
+
* @param interaction Smoothed avatar interaction state.
|
|
27678
28275
|
*
|
|
27679
28276
|
* @private helper of `octopus3AvatarVisual`
|
|
27680
28277
|
*/
|
|
27681
|
-
function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, palette, timeMs, phase) {
|
|
27682
|
-
const pupilOffsetX =
|
|
27683
|
-
|
|
28278
|
+
function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, palette, timeMs, phase, interaction) {
|
|
28279
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
28280
|
+
radiusX,
|
|
28281
|
+
radiusY,
|
|
28282
|
+
timeMs,
|
|
28283
|
+
phase,
|
|
28284
|
+
interaction,
|
|
28285
|
+
});
|
|
27684
28286
|
context.save();
|
|
27685
28287
|
context.translate(centerX, centerY);
|
|
27686
28288
|
context.rotate(rotation);
|
|
@@ -27716,7 +28318,7 @@
|
|
|
27716
28318
|
context.stroke();
|
|
27717
28319
|
context.beginPath();
|
|
27718
28320
|
context.moveTo(-radiusX * 0.88, -radiusY * 0.08);
|
|
27719
|
-
context.quadraticCurveTo(0, -radiusY * 0.9, radiusX * 0.88, -radiusY * 0.08);
|
|
28321
|
+
context.quadraticCurveTo(0, -radiusY * (0.9 - interaction.gazeY * 0.16 + interaction.intensity * 0.08), radiusX * 0.88, -radiusY * 0.08);
|
|
27720
28322
|
context.strokeStyle = `${palette.shadow}73`;
|
|
27721
28323
|
context.lineWidth = radiusX * 0.16;
|
|
27722
28324
|
context.lineCap = 'round';
|
|
@@ -27864,6 +28466,7 @@
|
|
|
27864
28466
|
function renderAvatarVisual(options) {
|
|
27865
28467
|
const normalizedAvatarDefinition = normalizeAvatarDefinition(options.avatarDefinition);
|
|
27866
28468
|
const avatarVisual = getAvatarVisualById(options.visualId);
|
|
28469
|
+
const surface = options.surface || 'framed';
|
|
27867
28470
|
const context = options.canvas.getContext('2d');
|
|
27868
28471
|
if (!context) {
|
|
27869
28472
|
throw new Error('2D canvas rendering context is unavailable.');
|
|
@@ -27876,8 +28479,10 @@
|
|
|
27876
28479
|
devicePixelRatio: options.devicePixelRatio || 1,
|
|
27877
28480
|
timeMs: options.timeMs,
|
|
27878
28481
|
avatarDefinition: normalizedAvatarDefinition,
|
|
27879
|
-
palette: createAvatarPalette(normalizedAvatarDefinition),
|
|
28482
|
+
palette: createAvatarPalette(normalizedAvatarDefinition, surface),
|
|
27880
28483
|
createRandom: createAvatarRandomFactory(normalizedAvatarDefinition),
|
|
28484
|
+
surface,
|
|
28485
|
+
interaction: options.interaction || createIdleAvatarInteractionState(),
|
|
27881
28486
|
});
|
|
27882
28487
|
}
|
|
27883
28488
|
|
|
@@ -27893,42 +28498,74 @@
|
|
|
27893
28498
|
* @private shared component for in-repository avatar previews
|
|
27894
28499
|
*/
|
|
27895
28500
|
function Avatar(props) {
|
|
27896
|
-
const { avatarDefinition, visualId, size = DEFAULT_AVATAR_SIZE, title, className, style } = props;
|
|
28501
|
+
const { avatarDefinition, visualId, surface = 'framed', size = DEFAULT_AVATAR_SIZE, title, className, style } = props;
|
|
27897
28502
|
const canvasRef = react.useRef(null);
|
|
27898
|
-
const
|
|
28503
|
+
const animationStartRef = react.useRef(null);
|
|
28504
|
+
const interactionRuntimeStateRef = react.useRef(createAvatarInteractionRuntimeState());
|
|
28505
|
+
const avatarColorsKey = avatarDefinition.colors.join('|');
|
|
28506
|
+
const normalizedAvatarDefinition = react.useMemo(() => normalizeAvatarDefinition(avatarDefinition), [avatarDefinition.agentHash, avatarDefinition.agentName, avatarColorsKey]);
|
|
28507
|
+
const avatarDefinitionKey = react.useMemo(() => createAvatarDefinitionKey(normalizedAvatarDefinition), [normalizedAvatarDefinition.agentHash, normalizedAvatarDefinition.agentName, normalizedAvatarDefinition.colors.join('|')]);
|
|
27899
28508
|
const avatarVisual = react.useMemo(() => getAvatarVisualById(visualId), [visualId]);
|
|
28509
|
+
react.useEffect(() => {
|
|
28510
|
+
interactionRuntimeStateRef.current = createAvatarInteractionRuntimeState();
|
|
28511
|
+
}, [avatarDefinitionKey, visualId]);
|
|
27900
28512
|
react.useEffect(() => {
|
|
27901
28513
|
const canvas = canvasRef.current;
|
|
27902
28514
|
if (!canvas) {
|
|
27903
28515
|
throw new Error('Avatar canvas is not mounted.');
|
|
27904
28516
|
}
|
|
28517
|
+
const isDynamicAvatar = avatarVisual.isAnimated || avatarVisual.supportsPointerTracking === true;
|
|
28518
|
+
const releasePointerTracking = avatarVisual.supportsPointerTracking ? retainAvatarPointerTracking() : null;
|
|
27905
28519
|
let animationFrameId = null;
|
|
27906
|
-
|
|
28520
|
+
if (animationStartRef.current === null) {
|
|
28521
|
+
animationStartRef.current = performance.now();
|
|
28522
|
+
}
|
|
27907
28523
|
const renderFrame = (now) => {
|
|
28524
|
+
const pointerSnapshot = avatarVisual.supportsPointerTracking ? getAvatarPointerSnapshot() : null;
|
|
28525
|
+
let interactionState = createIdleAvatarInteractionState();
|
|
28526
|
+
if (avatarVisual.supportsPointerTracking && pointerSnapshot) {
|
|
28527
|
+
interactionRuntimeStateRef.current = stepAvatarInteractionRuntimeState(interactionRuntimeStateRef.current, resolveAvatarPointerTarget(canvas.getBoundingClientRect(), pointerSnapshot), now);
|
|
28528
|
+
interactionState = interactionRuntimeStateRef.current;
|
|
28529
|
+
}
|
|
28530
|
+
else if (avatarVisual.supportsPointerTracking) {
|
|
28531
|
+
interactionRuntimeStateRef.current = stepAvatarInteractionRuntimeState(interactionRuntimeStateRef.current, createIdleAvatarInteractionState(), now);
|
|
28532
|
+
interactionState = interactionRuntimeStateRef.current;
|
|
28533
|
+
}
|
|
27908
28534
|
renderAvatarVisual({
|
|
27909
28535
|
canvas,
|
|
27910
28536
|
avatarDefinition: normalizedAvatarDefinition,
|
|
27911
28537
|
visualId,
|
|
28538
|
+
surface,
|
|
27912
28539
|
size,
|
|
27913
|
-
timeMs: now -
|
|
28540
|
+
timeMs: now - animationStartRef.current,
|
|
27914
28541
|
devicePixelRatio: window.devicePixelRatio || 1,
|
|
28542
|
+
interaction: interactionState,
|
|
27915
28543
|
});
|
|
27916
|
-
if (
|
|
28544
|
+
if (isDynamicAvatar) {
|
|
27917
28545
|
animationFrameId = window.requestAnimationFrame(renderFrame);
|
|
27918
28546
|
}
|
|
27919
28547
|
};
|
|
27920
|
-
renderFrame(
|
|
28548
|
+
renderFrame(performance.now());
|
|
27921
28549
|
return () => {
|
|
27922
28550
|
if (animationFrameId !== null) {
|
|
27923
28551
|
window.cancelAnimationFrame(animationFrameId);
|
|
27924
28552
|
}
|
|
28553
|
+
releasePointerTracking === null || releasePointerTracking === void 0 ? void 0 : releasePointerTracking();
|
|
27925
28554
|
};
|
|
27926
|
-
}, [
|
|
28555
|
+
}, [
|
|
28556
|
+
avatarDefinitionKey,
|
|
28557
|
+
avatarVisual.isAnimated,
|
|
28558
|
+
avatarVisual.supportsPointerTracking,
|
|
28559
|
+
normalizedAvatarDefinition,
|
|
28560
|
+
size,
|
|
28561
|
+
surface,
|
|
28562
|
+
visualId,
|
|
28563
|
+
]);
|
|
27927
28564
|
return (jsxRuntime.jsx("canvas", { ref: canvasRef, title: title || `${normalizedAvatarDefinition.agentName} avatar`, className: className, style: {
|
|
27928
28565
|
width: size,
|
|
27929
28566
|
height: size,
|
|
27930
28567
|
display: 'block',
|
|
27931
|
-
borderRadius: size * AVATAR_CANVAS_RADIUS_RATIO,
|
|
28568
|
+
borderRadius: surface === 'transparent' ? 0 : size * AVATAR_CANVAS_RADIUS_RATIO,
|
|
27932
28569
|
...style,
|
|
27933
28570
|
} }));
|
|
27934
28571
|
}
|
|
@@ -27939,9 +28576,9 @@
|
|
|
27939
28576
|
* @private shared component for avatar media rendering
|
|
27940
28577
|
*/
|
|
27941
28578
|
function AvatarOrImage(props) {
|
|
27942
|
-
const { imageUrl, avatarDefinition, visualId, size, alt, className, style } = props;
|
|
28579
|
+
const { imageUrl, avatarDefinition, visualId, surface, size, alt, className, style } = props;
|
|
27943
28580
|
if (avatarDefinition && visualId) {
|
|
27944
|
-
return (jsxRuntime.jsx(Avatar, { avatarDefinition: avatarDefinition, visualId: visualId, size: size, title: alt, className: className, style: style }));
|
|
28581
|
+
return (jsxRuntime.jsx(Avatar, { avatarDefinition: avatarDefinition, visualId: visualId, surface: surface, size: size, title: alt, className: className, style: style }));
|
|
27945
28582
|
}
|
|
27946
28583
|
if (!imageUrl) {
|
|
27947
28584
|
return null;
|
|
@@ -38549,6 +39186,14 @@
|
|
|
38549
39186
|
* Constant for default agent kit model name.
|
|
38550
39187
|
*/
|
|
38551
39188
|
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.4-mini';
|
|
39189
|
+
/**
|
|
39190
|
+
* Default model used for nested DeepSearch tool invocations.
|
|
39191
|
+
*/
|
|
39192
|
+
const DEFAULT_DEEP_SEARCH_MODEL_NAME = 'o4-mini-deep-research';
|
|
39193
|
+
/**
|
|
39194
|
+
* Tool name used by the Book commitment-backed DeepSearch capability.
|
|
39195
|
+
*/
|
|
39196
|
+
const DEEP_SEARCH_TOOL_NAME = 'deep_search';
|
|
38552
39197
|
/**
|
|
38553
39198
|
* Creates one structured log entry for streamed tool-call updates.
|
|
38554
39199
|
*
|
|
@@ -38591,6 +39236,98 @@
|
|
|
38591
39236
|
}
|
|
38592
39237
|
return 'COMPLETE';
|
|
38593
39238
|
}
|
|
39239
|
+
/**
|
|
39240
|
+
* Returns true when one tool definition represents the dedicated DeepSearch capability.
|
|
39241
|
+
*
|
|
39242
|
+
* @param toolDefinition - Tool definition from compiled model requirements.
|
|
39243
|
+
* @returns `true` when the tool should be backed by a nested deep-research agent.
|
|
39244
|
+
*
|
|
39245
|
+
* @private helper of `OpenAiAgentKitExecutionTools`
|
|
39246
|
+
*/
|
|
39247
|
+
function isDeepSearchToolDefinition(toolDefinition) {
|
|
39248
|
+
return toolDefinition.name === DEEP_SEARCH_TOOL_NAME;
|
|
39249
|
+
}
|
|
39250
|
+
/**
|
|
39251
|
+
* Normalizes Promptbook JSON-schema tool parameters for AgentKit function tools.
|
|
39252
|
+
*
|
|
39253
|
+
* @param parameters - Promptbook tool parameters.
|
|
39254
|
+
* @returns AgentKit-compatible JSON schema or `undefined`.
|
|
39255
|
+
*
|
|
39256
|
+
* @private helper of `OpenAiAgentKitExecutionTools`
|
|
39257
|
+
*/
|
|
39258
|
+
function normalizeAgentKitToolParameters(parameters) {
|
|
39259
|
+
var _a, _b;
|
|
39260
|
+
if (!parameters) {
|
|
39261
|
+
return undefined;
|
|
39262
|
+
}
|
|
39263
|
+
return {
|
|
39264
|
+
...parameters,
|
|
39265
|
+
additionalProperties: (_a = parameters.additionalProperties) !== null && _a !== void 0 ? _a : false,
|
|
39266
|
+
required: (_b = parameters.required) !== null && _b !== void 0 ? _b : [],
|
|
39267
|
+
};
|
|
39268
|
+
}
|
|
39269
|
+
/**
|
|
39270
|
+
* Creates instructions for the nested DeepSearch specialist agent.
|
|
39271
|
+
*
|
|
39272
|
+
* @param toolDescription - Model-facing description from the original tool definition.
|
|
39273
|
+
* @returns System instructions for the nested deep-research agent.
|
|
39274
|
+
*
|
|
39275
|
+
* @private helper of `OpenAiAgentKitExecutionTools`
|
|
39276
|
+
*/
|
|
39277
|
+
function createDeepSearchAgentInstructions(toolDescription) {
|
|
39278
|
+
const normalizedDescription = toolDescription.trim();
|
|
39279
|
+
return spacetrim.spaceTrim((block) => `
|
|
39280
|
+
You are a DeepSearch specialist working as a tool for another agent.
|
|
39281
|
+
Perform thorough, source-grounded public-web research based on the provided request.
|
|
39282
|
+
Use web search to gather current information, compare relevant viewpoints, and synthesize a concise research brief.
|
|
39283
|
+
Do not ask follow-up questions. If the request is not specific enough, state the assumptions you had to make.
|
|
39284
|
+
Include citations in the research brief whenever sources were used.
|
|
39285
|
+
${block(normalizedDescription ? `Tool guidance:\n${normalizedDescription}` : '')}
|
|
39286
|
+
`);
|
|
39287
|
+
}
|
|
39288
|
+
/**
|
|
39289
|
+
* Builds the nested DeepSearch prompt from structured tool arguments.
|
|
39290
|
+
*
|
|
39291
|
+
* @param rawInput - Parsed function-tool arguments provided by the outer agent.
|
|
39292
|
+
* @returns Prompt text passed to the nested deep-research agent.
|
|
39293
|
+
*
|
|
39294
|
+
* @private helper of `OpenAiAgentKitExecutionTools`
|
|
39295
|
+
*/
|
|
39296
|
+
function buildDeepSearchToolInput(rawInput) {
|
|
39297
|
+
const input = rawInput && typeof rawInput === 'object' ? rawInput : {};
|
|
39298
|
+
const query = typeof input.query === 'string' ? input.query.trim() : '';
|
|
39299
|
+
const additionalHints = Object.entries(input)
|
|
39300
|
+
.filter(([key, value]) => key !== 'query' && value !== undefined && value !== null && String(value).trim() !== '')
|
|
39301
|
+
.map(([key, value]) => `- ${key}: ${typeof value === 'string' ? value : JSON.stringify(value)}`);
|
|
39302
|
+
return spacetrim.spaceTrim((block) => `
|
|
39303
|
+
Research request:
|
|
39304
|
+
${query || JSON.stringify(input)}
|
|
39305
|
+
${block(additionalHints.length > 0 ? `Execution hints:\n${additionalHints.join('\n')}` : '')}
|
|
39306
|
+
`);
|
|
39307
|
+
}
|
|
39308
|
+
/**
|
|
39309
|
+
* Creates the native Agent SDK tool used for `USE DEEPSEARCH`.
|
|
39310
|
+
*
|
|
39311
|
+
* @param toolDefinition - Promptbook tool definition for `deep_search`.
|
|
39312
|
+
* @returns AgentKit tool backed by a nested deep-research agent.
|
|
39313
|
+
*
|
|
39314
|
+
* @private helper of `OpenAiAgentKitExecutionTools`
|
|
39315
|
+
*/
|
|
39316
|
+
function createDeepSearchAgentKitTool(toolDefinition) {
|
|
39317
|
+
const deepSearchAgent = new agents.Agent({
|
|
39318
|
+
name: 'DeepSearch',
|
|
39319
|
+
model: DEFAULT_DEEP_SEARCH_MODEL_NAME,
|
|
39320
|
+
instructions: createDeepSearchAgentInstructions(toolDefinition.description),
|
|
39321
|
+
tools: [agents.webSearchTool({ searchContextSize: 'high' })],
|
|
39322
|
+
});
|
|
39323
|
+
return deepSearchAgent.asTool({
|
|
39324
|
+
toolName: toolDefinition.name,
|
|
39325
|
+
toolDescription: toolDefinition.description,
|
|
39326
|
+
parameters: normalizeAgentKitToolParameters(toolDefinition.parameters),
|
|
39327
|
+
inputBuilder: ({ params }) => buildDeepSearchToolInput(params),
|
|
39328
|
+
customOutputExtractor: (result) => { var _a; return typeof result.finalOutput === 'string' ? result.finalOutput : JSON.stringify((_a = result.finalOutput) !== null && _a !== void 0 ? _a : ''); },
|
|
39329
|
+
});
|
|
39330
|
+
}
|
|
38594
39331
|
/**
|
|
38595
39332
|
* Constant for default JSON schema name.
|
|
38596
39333
|
*/
|
|
@@ -38931,25 +39668,23 @@
|
|
|
38931
39668
|
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
38932
39669
|
*/
|
|
38933
39670
|
buildAgentKitTools(options) {
|
|
38934
|
-
var _a;
|
|
38935
39671
|
const { tools, vectorStoreId } = options;
|
|
38936
39672
|
const agentKitTools = [];
|
|
38937
39673
|
if (vectorStoreId) {
|
|
38938
39674
|
agentKitTools.push(agents.fileSearchTool(vectorStoreId));
|
|
38939
39675
|
}
|
|
38940
39676
|
if (tools && tools.length > 0) {
|
|
38941
|
-
|
|
39677
|
+
let scriptTools = null;
|
|
38942
39678
|
for (const toolDefinition of tools) {
|
|
39679
|
+
if (isDeepSearchToolDefinition(toolDefinition)) {
|
|
39680
|
+
agentKitTools.push(createDeepSearchAgentKitTool(toolDefinition));
|
|
39681
|
+
continue;
|
|
39682
|
+
}
|
|
39683
|
+
scriptTools !== null && scriptTools !== void 0 ? scriptTools : (scriptTools = this.resolveScriptTools());
|
|
38943
39684
|
agentKitTools.push(agents.tool({
|
|
38944
39685
|
name: toolDefinition.name,
|
|
38945
39686
|
description: toolDefinition.description,
|
|
38946
|
-
parameters: toolDefinition.parameters
|
|
38947
|
-
? {
|
|
38948
|
-
...toolDefinition.parameters,
|
|
38949
|
-
additionalProperties: false,
|
|
38950
|
-
required: (_a = toolDefinition.parameters.required) !== null && _a !== void 0 ? _a : [],
|
|
38951
|
-
}
|
|
38952
|
-
: undefined,
|
|
39687
|
+
parameters: normalizeAgentKitToolParameters(toolDefinition.parameters),
|
|
38953
39688
|
strict: false,
|
|
38954
39689
|
execute: async (input, runContext, details) => {
|
|
38955
39690
|
var _a, _b, _c, _d;
|
|
@@ -45136,6 +45871,7 @@
|
|
|
45136
45871
|
delete_wallet_record: { title: 'Deleting wallet', emoji: '👛' },
|
|
45137
45872
|
request_wallet_record: { title: 'Requesting wallet', emoji: '👛' },
|
|
45138
45873
|
web_search: { title: 'Searching the web', emoji: '🔎' },
|
|
45874
|
+
deep_search: { title: 'Deep research', emoji: '🔬' },
|
|
45139
45875
|
useSearchEngine: { title: 'Searching the web', emoji: '🔎' },
|
|
45140
45876
|
search: { title: 'Searching the web', emoji: '🔎' },
|
|
45141
45877
|
useBrowser: { title: 'Browsing the web', emoji: '🌐' },
|
|
@@ -48097,7 +48833,7 @@
|
|
|
48097
48833
|
* @private function of ChatToolCallModal
|
|
48098
48834
|
*/
|
|
48099
48835
|
function isSearchToolCallName(toolName) {
|
|
48100
|
-
return toolName === 'web_search' || toolName === 'useSearchEngine' || toolName === 'search';
|
|
48836
|
+
return toolName === 'web_search' || toolName === 'deep_search' || toolName === 'useSearchEngine' || toolName === 'search';
|
|
48101
48837
|
}
|
|
48102
48838
|
/**
|
|
48103
48839
|
* Checks whether a tool name should use the time renderer.
|
|
@@ -48797,6 +49533,12 @@
|
|
|
48797
49533
|
});
|
|
48798
49534
|
}
|
|
48799
49535
|
}
|
|
49536
|
+
const staticConversationDelayConfig = {
|
|
49537
|
+
...FAST_FLOW,
|
|
49538
|
+
beforeFirstMessage: 0,
|
|
49539
|
+
// Show the full internal exchange immediately so the modal never opens as a blank panel.
|
|
49540
|
+
showIntermediateMessages: messages.length,
|
|
49541
|
+
};
|
|
48800
49542
|
const agentName = ((_c = (_b = teamResult.conversation) === null || _b === void 0 ? void 0 : _b.find((entry) => entry.sender === 'AGENT' || entry.role === 'AGENT')) === null || _c === void 0 ? void 0 : _c.name) || 'Agent';
|
|
48801
49543
|
const teammateConversationName = ((_e = (_d = teamResult.conversation) === null || _d === void 0 ? void 0 : _d.find((entry) => entry.sender === 'TEAMMATE' || entry.role === 'TEAMMATE')) === null || _e === void 0 ? void 0 : _e.name) || '';
|
|
48802
49544
|
const teammateProfile = teammateUrl ? teamProfiles[teammateUrl] : undefined;
|
|
@@ -48833,7 +49575,7 @@
|
|
|
48833
49575
|
avatarSrc: resolvedTeammateAvatar || undefined,
|
|
48834
49576
|
},
|
|
48835
49577
|
];
|
|
48836
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: classNames(styles$5.searchModalHeader, styles$5.teamModalHeader), children: jsxRuntime.jsxs("div", { className: styles$5.teamHeaderParticipants, children: [jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedAgentLabel, avatarSrc: resolvedAgentAvatar, avatarDefinition: resolvedAgentAvatarDefinition, avatarVisualId: resolvedAgentAvatarVisualId, fallbackColor: resolvedAgentHeaderColor }), jsxRuntime.jsx("span", { className: styles$5.teamHeaderDivider, children: "talking with" }), jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedTeammateLabel, avatarSrc: resolvedTeammateAvatar, fallbackColor: "#0ea5e9", href: teammateLink })] }) }), jsxRuntime.jsxs("div", { className: styles$5.searchModalContent, children: [messages.length > 0 ? (jsxRuntime.jsx("div", { className: styles$5.teamChatContainer, children: jsxRuntime.jsx(MockedChat, { title: `Chat between ${resolvedAgentLabel} and ${resolvedTeammateLabel}`, messages: messages, participants: participants, isResettable: false, isPausable: false, isSaveButtonEnabled: false, isCopyButtonEnabled: false, visual: "STANDALONE", delayConfig:
|
|
49578
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: classNames(styles$5.searchModalHeader, styles$5.teamModalHeader), children: jsxRuntime.jsxs("div", { className: styles$5.teamHeaderParticipants, children: [jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedAgentLabel, avatarSrc: resolvedAgentAvatar, avatarDefinition: resolvedAgentAvatarDefinition, avatarVisualId: resolvedAgentAvatarVisualId, fallbackColor: resolvedAgentHeaderColor }), jsxRuntime.jsx("span", { className: styles$5.teamHeaderDivider, children: "talking with" }), jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedTeammateLabel, avatarSrc: resolvedTeammateAvatar, fallbackColor: "#0ea5e9", href: teammateLink })] }) }), jsxRuntime.jsxs("div", { className: styles$5.searchModalContent, children: [messages.length > 0 ? (jsxRuntime.jsx("div", { className: styles$5.teamChatContainer, children: jsxRuntime.jsx(MockedChat, { title: `Chat between ${resolvedAgentLabel} and ${resolvedTeammateLabel}`, messages: messages, participants: participants, isResettable: false, isPausable: false, isSaveButtonEnabled: false, isCopyButtonEnabled: false, visual: "STANDALONE", delayConfig: staticConversationDelayConfig }) })) : (jsxRuntime.jsx("div", { className: styles$5.noResults, children: "No teammate conversation available." })), (hasTeamToolCalls || hasTeamCitations) && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallSection, children: [hasTeamToolCalls && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallGroup, children: [jsxRuntime.jsx("div", { className: styles$5.teamToolCallHeading, children: "Actions" }), jsxRuntime.jsx("div", { className: styles$5.teamToolCallChips, children: teamToolCalls.map((toolCallEntry, index) => {
|
|
48837
49579
|
const chipletInfo = getToolCallChipletInfo(toolCallEntry.toolCall, undefined, toolTitles);
|
|
48838
49580
|
const chipletText = buildToolCallChipText(chipletInfo);
|
|
48839
49581
|
return (jsxRuntime.jsxs("button", { className: styles$5.completedToolCall, onClick: () => {
|