@promptbook/components 0.112.0-70 → 0.112.0-72
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 +1172 -380
- package/esm/index.es.js.map +1 -1
- package/esm/src/book-3.0/Book.d.ts +6 -0
- package/esm/src/book-components/Chat/utils/getToolCallChipletInfo.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agent/agentRunCliOptions.d.ts +12 -2
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -0
- package/esm/src/cli/cli-commands/run/prepareRunCommandResources.d.ts +20 -0
- package/esm/src/cli/cli-commands/run/resolveRunInputParameters.d.ts +12 -0
- package/esm/src/cli/cli-commands/run/runCommandAction.d.ts +21 -0
- package/esm/src/cli/cli-commands/run/runPipelineExecution.d.ts +14 -0
- package/esm/src/cli/cli-commands/run.d.ts +1 -1
- package/esm/src/conversion/parsePipeline/applyPipelineHead.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/createInitialPipelineJson.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/createUniqueSectionNameResolver.d.ts +14 -0
- package/esm/src/conversion/parsePipeline/defineParameter.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/extractPipelineDescription.d.ts +6 -0
- package/esm/src/conversion/parsePipeline/finalizeParsedPipeline.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/getPipelineIdentification.d.ts +7 -0
- package/esm/src/conversion/parsePipeline/parsePreparedPipelineSections.d.ts +18 -0
- package/esm/src/conversion/parsePipeline/preparePipelineString.d.ts +8 -0
- package/esm/src/conversion/parsePipeline/processPipelineSection.d.ts +9 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +1172 -380
- package/umd/index.umd.js.map +1 -1
- package/umd/src/book-3.0/Book.d.ts +6 -0
- package/umd/src/book-components/Chat/utils/getToolCallChipletInfo.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agent/agentRunCliOptions.d.ts +12 -2
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -0
- package/umd/src/cli/cli-commands/run/prepareRunCommandResources.d.ts +20 -0
- package/umd/src/cli/cli-commands/run/resolveRunInputParameters.d.ts +12 -0
- package/umd/src/cli/cli-commands/run/runCommandAction.d.ts +21 -0
- package/umd/src/cli/cli-commands/run/runPipelineExecution.d.ts +14 -0
- package/umd/src/cli/cli-commands/run.d.ts +1 -1
- package/umd/src/conversion/parsePipeline/applyPipelineHead.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/createInitialPipelineJson.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/createUniqueSectionNameResolver.d.ts +14 -0
- package/umd/src/conversion/parsePipeline/defineParameter.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/extractPipelineDescription.d.ts +6 -0
- package/umd/src/conversion/parsePipeline/finalizeParsedPipeline.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/getPipelineIdentification.d.ts +7 -0
- package/umd/src/conversion/parsePipeline/parsePreparedPipelineSections.d.ts +18 -0
- package/umd/src/conversion/parsePipeline/preparePipelineString.d.ts +8 -0
- package/umd/src/conversion/parsePipeline/processPipelineSection.d.ts +9 -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-72';
|
|
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
|
|
@@ -4513,7 +4513,9 @@
|
|
|
4513
4513
|
};
|
|
4514
4514
|
const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
|
|
4515
4515
|
const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
|
|
4516
|
-
const mantleRadiusZ = size *
|
|
4516
|
+
const mantleRadiusZ = size *
|
|
4517
|
+
morphologyProfile.body.bodyRadiusRatio *
|
|
4518
|
+
(0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
|
|
4517
4519
|
const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
|
|
4518
4520
|
const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
|
|
4519
4521
|
const underbodyRadiusZ = mantleRadiusZ * 0.78;
|
|
@@ -4599,7 +4601,11 @@
|
|
|
4599
4601
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
4600
4602
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
4601
4603
|
drawProjectedMouth(context, [
|
|
4602
|
-
{
|
|
4604
|
+
{
|
|
4605
|
+
x: -mouthHalfWidth,
|
|
4606
|
+
y: mouthY,
|
|
4607
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
|
|
4608
|
+
},
|
|
4603
4609
|
{
|
|
4604
4610
|
x: size * morphologyProfile.face.mouthCenterOffsetRatio,
|
|
4605
4611
|
y: mouthY +
|
|
@@ -4608,7 +4614,11 @@
|
|
|
4608
4614
|
interaction.gazeY * size * 0.01,
|
|
4609
4615
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
|
|
4610
4616
|
},
|
|
4611
|
-
{
|
|
4617
|
+
{
|
|
4618
|
+
x: mouthHalfWidth,
|
|
4619
|
+
y: mouthY,
|
|
4620
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
|
|
4621
|
+
},
|
|
4612
4622
|
], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
|
|
4613
4623
|
},
|
|
4614
4624
|
};
|
|
@@ -4769,7 +4779,8 @@
|
|
|
4769
4779
|
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
|
|
4770
4780
|
};
|
|
4771
4781
|
const controlPointTwo = {
|
|
4772
|
-
x: anchorPoint.x +
|
|
4782
|
+
x: anchorPoint.x +
|
|
4783
|
+
Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
|
|
4773
4784
|
y: anchorPoint.y + flowLength * 0.66,
|
|
4774
4785
|
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
|
|
4775
4786
|
};
|
|
@@ -4834,8 +4845,7 @@
|
|
|
4834
4845
|
context.beginPath();
|
|
4835
4846
|
context.moveTo(startPoint.x, startPoint.y);
|
|
4836
4847
|
context.lineTo(endPoint.x, endPoint.y);
|
|
4837
|
-
context.strokeStyle =
|
|
4838
|
-
tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
|
|
4848
|
+
context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
|
|
4839
4849
|
context.lineWidth = width;
|
|
4840
4850
|
context.lineCap = 'round';
|
|
4841
4851
|
context.stroke();
|
|
@@ -17523,6 +17533,212 @@
|
|
|
17523
17533
|
* @private internal USE TIMEOUT constant
|
|
17524
17534
|
*/
|
|
17525
17535
|
const MAX_LIST_TIMEOUTS_LIMIT = 100;
|
|
17536
|
+
/**
|
|
17537
|
+
* Creates one formatted timeout-argument validation error.
|
|
17538
|
+
*
|
|
17539
|
+
* @private internal utility of USE TIMEOUT
|
|
17540
|
+
*/
|
|
17541
|
+
function createTimeoutToolArgsError(message) {
|
|
17542
|
+
return new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17543
|
+
${message}
|
|
17544
|
+
`));
|
|
17545
|
+
}
|
|
17546
|
+
/**
|
|
17547
|
+
* Normalizes one optional timeout id string.
|
|
17548
|
+
*
|
|
17549
|
+
* @private internal utility of USE TIMEOUT
|
|
17550
|
+
*/
|
|
17551
|
+
function normalizeOptionalTimeoutId(value) {
|
|
17552
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
17553
|
+
}
|
|
17554
|
+
/**
|
|
17555
|
+
* Parses timeout target selection for tools that accept either `timeoutId` or `allActive: true`.
|
|
17556
|
+
*
|
|
17557
|
+
* @private internal utility of USE TIMEOUT
|
|
17558
|
+
*/
|
|
17559
|
+
function parseTimeoutTargetSelection(args, options) {
|
|
17560
|
+
const timeoutId = normalizeOptionalTimeoutId(args.timeoutId);
|
|
17561
|
+
const allActive = args.allActive === true;
|
|
17562
|
+
if (timeoutId && allActive) {
|
|
17563
|
+
throw createTimeoutToolArgsError(options.bothMessage);
|
|
17564
|
+
}
|
|
17565
|
+
if (allActive) {
|
|
17566
|
+
return { allActive: true };
|
|
17567
|
+
}
|
|
17568
|
+
if (!timeoutId) {
|
|
17569
|
+
throw createTimeoutToolArgsError(options.missingMessage);
|
|
17570
|
+
}
|
|
17571
|
+
return {
|
|
17572
|
+
timeoutId,
|
|
17573
|
+
allActive: false,
|
|
17574
|
+
};
|
|
17575
|
+
}
|
|
17576
|
+
/**
|
|
17577
|
+
* Parses one explicit `dueAt` update value.
|
|
17578
|
+
*
|
|
17579
|
+
* @private internal utility of USE TIMEOUT
|
|
17580
|
+
*/
|
|
17581
|
+
function parseOptionalTimeoutDueAt(value) {
|
|
17582
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
17583
|
+
return undefined;
|
|
17584
|
+
}
|
|
17585
|
+
const normalizedDueAt = value.trim();
|
|
17586
|
+
const dueAtTimestamp = Date.parse(normalizedDueAt);
|
|
17587
|
+
if (!Number.isFinite(dueAtTimestamp)) {
|
|
17588
|
+
throw createTimeoutToolArgsError('Timeout `dueAt` must be one valid ISO timestamp.');
|
|
17589
|
+
}
|
|
17590
|
+
return new Date(dueAtTimestamp).toISOString();
|
|
17591
|
+
}
|
|
17592
|
+
/**
|
|
17593
|
+
* Parses one explicit `extendByMs` update value.
|
|
17594
|
+
*
|
|
17595
|
+
* @private internal utility of USE TIMEOUT
|
|
17596
|
+
*/
|
|
17597
|
+
function parseOptionalTimeoutExtendByMs(value) {
|
|
17598
|
+
if (typeof value !== 'number') {
|
|
17599
|
+
return undefined;
|
|
17600
|
+
}
|
|
17601
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
17602
|
+
throw createTimeoutToolArgsError('Timeout `extendByMs` must be a positive number of milliseconds.');
|
|
17603
|
+
}
|
|
17604
|
+
return Math.floor(value);
|
|
17605
|
+
}
|
|
17606
|
+
/**
|
|
17607
|
+
* Parses one explicit `recurrenceIntervalMs` update value.
|
|
17608
|
+
*
|
|
17609
|
+
* @private internal utility of USE TIMEOUT
|
|
17610
|
+
*/
|
|
17611
|
+
function parseOptionalTimeoutRecurrenceInterval(value) {
|
|
17612
|
+
if (value === null) {
|
|
17613
|
+
return null;
|
|
17614
|
+
}
|
|
17615
|
+
if (typeof value !== 'number') {
|
|
17616
|
+
return undefined;
|
|
17617
|
+
}
|
|
17618
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
17619
|
+
throw createTimeoutToolArgsError('Timeout `recurrenceIntervalMs` must be a positive number of milliseconds or `null`.');
|
|
17620
|
+
}
|
|
17621
|
+
return Math.floor(value);
|
|
17622
|
+
}
|
|
17623
|
+
/**
|
|
17624
|
+
* Parses one explicit `message` update value.
|
|
17625
|
+
*
|
|
17626
|
+
* @private internal utility of USE TIMEOUT
|
|
17627
|
+
*/
|
|
17628
|
+
function parseOptionalTimeoutMessage(value) {
|
|
17629
|
+
if (value === null) {
|
|
17630
|
+
return null;
|
|
17631
|
+
}
|
|
17632
|
+
if (typeof value !== 'string') {
|
|
17633
|
+
return undefined;
|
|
17634
|
+
}
|
|
17635
|
+
const normalizedMessage = value.trim();
|
|
17636
|
+
return normalizedMessage.length > 0 ? normalizedMessage : null;
|
|
17637
|
+
}
|
|
17638
|
+
/**
|
|
17639
|
+
* Parses one explicit `parameters` update value.
|
|
17640
|
+
*
|
|
17641
|
+
* @private internal utility of USE TIMEOUT
|
|
17642
|
+
*/
|
|
17643
|
+
function parseOptionalTimeoutParameters(value) {
|
|
17644
|
+
if (value === undefined) {
|
|
17645
|
+
return undefined;
|
|
17646
|
+
}
|
|
17647
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
17648
|
+
throw createTimeoutToolArgsError('Timeout `parameters` must be one JSON object.');
|
|
17649
|
+
}
|
|
17650
|
+
return value;
|
|
17651
|
+
}
|
|
17652
|
+
/**
|
|
17653
|
+
* Parses one explicit `paused` update value.
|
|
17654
|
+
*
|
|
17655
|
+
* @private internal utility of USE TIMEOUT
|
|
17656
|
+
*/
|
|
17657
|
+
function parseOptionalTimeoutPaused(value) {
|
|
17658
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
17659
|
+
}
|
|
17660
|
+
/**
|
|
17661
|
+
* Parses patch fields for `update_timeout`.
|
|
17662
|
+
*
|
|
17663
|
+
* @private internal utility of USE TIMEOUT
|
|
17664
|
+
*/
|
|
17665
|
+
function parseTimeoutUpdatePatch(args) {
|
|
17666
|
+
const patch = {};
|
|
17667
|
+
const dueAt = parseOptionalTimeoutDueAt(args.dueAt);
|
|
17668
|
+
const extendByMs = parseOptionalTimeoutExtendByMs(args.extendByMs);
|
|
17669
|
+
const recurrenceIntervalMs = parseOptionalTimeoutRecurrenceInterval(args.recurrenceIntervalMs);
|
|
17670
|
+
const message = parseOptionalTimeoutMessage(args.message);
|
|
17671
|
+
const parameters = parseOptionalTimeoutParameters(args.parameters);
|
|
17672
|
+
const paused = parseOptionalTimeoutPaused(args.paused);
|
|
17673
|
+
if (dueAt !== undefined) {
|
|
17674
|
+
patch.dueAt = dueAt;
|
|
17675
|
+
}
|
|
17676
|
+
if (extendByMs !== undefined) {
|
|
17677
|
+
patch.extendByMs = extendByMs;
|
|
17678
|
+
}
|
|
17679
|
+
if (patch.dueAt !== undefined && patch.extendByMs !== undefined) {
|
|
17680
|
+
throw createTimeoutToolArgsError('Timeout update cannot include both `dueAt` and `extendByMs`.');
|
|
17681
|
+
}
|
|
17682
|
+
if (recurrenceIntervalMs !== undefined) {
|
|
17683
|
+
patch.recurrenceIntervalMs = recurrenceIntervalMs;
|
|
17684
|
+
}
|
|
17685
|
+
if (message !== undefined) {
|
|
17686
|
+
patch.message = message;
|
|
17687
|
+
}
|
|
17688
|
+
if (parameters !== undefined) {
|
|
17689
|
+
patch.parameters = parameters;
|
|
17690
|
+
}
|
|
17691
|
+
if (paused !== undefined) {
|
|
17692
|
+
patch.paused = paused;
|
|
17693
|
+
}
|
|
17694
|
+
return patch;
|
|
17695
|
+
}
|
|
17696
|
+
/**
|
|
17697
|
+
* Determines whether the patch contains fields that are only supported for single-timeout updates.
|
|
17698
|
+
*
|
|
17699
|
+
* @private internal utility of USE TIMEOUT
|
|
17700
|
+
*/
|
|
17701
|
+
function hasSingleTimeoutOnlyPatchFields(patch) {
|
|
17702
|
+
return (patch.dueAt !== undefined ||
|
|
17703
|
+
patch.extendByMs !== undefined ||
|
|
17704
|
+
patch.recurrenceIntervalMs !== undefined ||
|
|
17705
|
+
patch.message !== undefined ||
|
|
17706
|
+
patch.parameters !== undefined);
|
|
17707
|
+
}
|
|
17708
|
+
/**
|
|
17709
|
+
* Parses bulk timeout update arguments.
|
|
17710
|
+
*
|
|
17711
|
+
* @private internal utility of USE TIMEOUT
|
|
17712
|
+
*/
|
|
17713
|
+
function parseBulkTimeoutUpdateArgs(patch) {
|
|
17714
|
+
if (patch.paused === undefined) {
|
|
17715
|
+
throw createTimeoutToolArgsError('Bulk timeout update with `allActive: true` requires `paused` to be explicitly set.');
|
|
17716
|
+
}
|
|
17717
|
+
if (hasSingleTimeoutOnlyPatchFields(patch)) {
|
|
17718
|
+
throw createTimeoutToolArgsError('Bulk timeout update only supports the `paused` field.');
|
|
17719
|
+
}
|
|
17720
|
+
return {
|
|
17721
|
+
allActive: true,
|
|
17722
|
+
paused: patch.paused,
|
|
17723
|
+
};
|
|
17724
|
+
}
|
|
17725
|
+
/**
|
|
17726
|
+
* Parses single-timeout update arguments.
|
|
17727
|
+
*
|
|
17728
|
+
* @private internal utility of USE TIMEOUT
|
|
17729
|
+
*/
|
|
17730
|
+
function parseSingleTimeoutUpdateArgs(timeoutId, patch) {
|
|
17731
|
+
if (!timeoutId) {
|
|
17732
|
+
throw createTimeoutToolArgsError('Timeout `timeoutId` is required for single-timeout updates.');
|
|
17733
|
+
}
|
|
17734
|
+
if (Object.keys(patch).length === 0) {
|
|
17735
|
+
throw createTimeoutToolArgsError('Timeout update must include at least one editable field.');
|
|
17736
|
+
}
|
|
17737
|
+
return {
|
|
17738
|
+
timeoutId,
|
|
17739
|
+
patch,
|
|
17740
|
+
};
|
|
17741
|
+
}
|
|
17526
17742
|
/**
|
|
17527
17743
|
* Parses and validates `USE TIMEOUT` tool arguments.
|
|
17528
17744
|
*
|
|
@@ -17549,22 +17765,14 @@
|
|
|
17549
17765
|
* Parses `cancel_timeout` input.
|
|
17550
17766
|
*/
|
|
17551
17767
|
cancel(args) {
|
|
17552
|
-
const
|
|
17553
|
-
|
|
17554
|
-
|
|
17555
|
-
|
|
17556
|
-
|
|
17557
|
-
`));
|
|
17558
|
-
}
|
|
17559
|
-
if (allActive) {
|
|
17768
|
+
const target = parseTimeoutTargetSelection(args, {
|
|
17769
|
+
bothMessage: 'Timeout cancellation must target either one `timeoutId` or `allActive: true`, not both.',
|
|
17770
|
+
missingMessage: 'Timeout `timeoutId` is required unless you pass `allActive: true`.',
|
|
17771
|
+
});
|
|
17772
|
+
if (target.allActive) {
|
|
17560
17773
|
return { allActive: true };
|
|
17561
17774
|
}
|
|
17562
|
-
|
|
17563
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17564
|
-
Timeout \`timeoutId\` is required unless you pass \`allActive: true\`.
|
|
17565
|
-
`));
|
|
17566
|
-
}
|
|
17567
|
-
return { timeoutId };
|
|
17775
|
+
return { timeoutId: target.timeoutId };
|
|
17568
17776
|
},
|
|
17569
17777
|
/**
|
|
17570
17778
|
* Parses `list_timeouts` input.
|
|
@@ -17595,106 +17803,14 @@
|
|
|
17595
17803
|
* Parses `update_timeout` input.
|
|
17596
17804
|
*/
|
|
17597
17805
|
update(args) {
|
|
17598
|
-
const
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
|
|
17606
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17607
|
-
Timeout update requires one \`timeoutId\` or \`allActive: true\`.
|
|
17608
|
-
`));
|
|
17609
|
-
}
|
|
17610
|
-
const patch = {};
|
|
17611
|
-
if (typeof args.dueAt === 'string' && args.dueAt.trim().length > 0) {
|
|
17612
|
-
const normalizedDueAt = args.dueAt.trim();
|
|
17613
|
-
const dueAtTimestamp = Date.parse(normalizedDueAt);
|
|
17614
|
-
if (!Number.isFinite(dueAtTimestamp)) {
|
|
17615
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17616
|
-
Timeout \`dueAt\` must be one valid ISO timestamp.
|
|
17617
|
-
`));
|
|
17618
|
-
}
|
|
17619
|
-
patch.dueAt = new Date(dueAtTimestamp).toISOString();
|
|
17620
|
-
}
|
|
17621
|
-
if (typeof args.extendByMs === 'number') {
|
|
17622
|
-
if (!Number.isFinite(args.extendByMs) || args.extendByMs <= 0) {
|
|
17623
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17624
|
-
Timeout \`extendByMs\` must be a positive number of milliseconds.
|
|
17625
|
-
`));
|
|
17626
|
-
}
|
|
17627
|
-
patch.extendByMs = Math.floor(args.extendByMs);
|
|
17628
|
-
}
|
|
17629
|
-
if (patch.dueAt !== undefined && patch.extendByMs !== undefined) {
|
|
17630
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17631
|
-
Timeout update cannot include both \`dueAt\` and \`extendByMs\`.
|
|
17632
|
-
`));
|
|
17633
|
-
}
|
|
17634
|
-
if (args.recurrenceIntervalMs === null) {
|
|
17635
|
-
patch.recurrenceIntervalMs = null;
|
|
17636
|
-
}
|
|
17637
|
-
else if (typeof args.recurrenceIntervalMs === 'number') {
|
|
17638
|
-
if (!Number.isFinite(args.recurrenceIntervalMs) || args.recurrenceIntervalMs <= 0) {
|
|
17639
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17640
|
-
Timeout \`recurrenceIntervalMs\` must be a positive number of milliseconds or \`null\`.
|
|
17641
|
-
`));
|
|
17642
|
-
}
|
|
17643
|
-
patch.recurrenceIntervalMs = Math.floor(args.recurrenceIntervalMs);
|
|
17644
|
-
}
|
|
17645
|
-
if (args.message === null) {
|
|
17646
|
-
patch.message = null;
|
|
17647
|
-
}
|
|
17648
|
-
else if (typeof args.message === 'string') {
|
|
17649
|
-
const normalizedMessage = args.message.trim();
|
|
17650
|
-
patch.message = normalizedMessage.length > 0 ? normalizedMessage : null;
|
|
17651
|
-
}
|
|
17652
|
-
if (args.parameters !== undefined) {
|
|
17653
|
-
if (!args.parameters || typeof args.parameters !== 'object' || Array.isArray(args.parameters)) {
|
|
17654
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17655
|
-
Timeout \`parameters\` must be one JSON object.
|
|
17656
|
-
`));
|
|
17657
|
-
}
|
|
17658
|
-
patch.parameters = args.parameters;
|
|
17659
|
-
}
|
|
17660
|
-
if (typeof args.paused === 'boolean') {
|
|
17661
|
-
patch.paused = args.paused;
|
|
17662
|
-
}
|
|
17663
|
-
if (allActive) {
|
|
17664
|
-
if (patch.paused === undefined) {
|
|
17665
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17666
|
-
Bulk timeout update with \`allActive: true\` requires \`paused\` to be explicitly set.
|
|
17667
|
-
`));
|
|
17668
|
-
}
|
|
17669
|
-
const hasSingleOnlyPatch = patch.dueAt !== undefined ||
|
|
17670
|
-
patch.extendByMs !== undefined ||
|
|
17671
|
-
patch.recurrenceIntervalMs !== undefined ||
|
|
17672
|
-
patch.message !== undefined ||
|
|
17673
|
-
patch.parameters !== undefined;
|
|
17674
|
-
if (hasSingleOnlyPatch) {
|
|
17675
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17676
|
-
Bulk timeout update only supports the \`paused\` field.
|
|
17677
|
-
`));
|
|
17678
|
-
}
|
|
17679
|
-
return {
|
|
17680
|
-
allActive: true,
|
|
17681
|
-
paused: patch.paused,
|
|
17682
|
-
};
|
|
17683
|
-
}
|
|
17684
|
-
if (!timeoutId) {
|
|
17685
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17686
|
-
Timeout \`timeoutId\` is required for single-timeout updates.
|
|
17687
|
-
`));
|
|
17688
|
-
}
|
|
17689
|
-
if (Object.keys(patch).length === 0) {
|
|
17690
|
-
throw new PipelineExecutionError(spacetrim.spaceTrim(`
|
|
17691
|
-
Timeout update must include at least one editable field.
|
|
17692
|
-
`));
|
|
17693
|
-
}
|
|
17694
|
-
return {
|
|
17695
|
-
timeoutId,
|
|
17696
|
-
patch,
|
|
17697
|
-
};
|
|
17806
|
+
const target = parseTimeoutTargetSelection(args, {
|
|
17807
|
+
bothMessage: 'Timeout update must target either one `timeoutId` or `allActive: true`, not both.',
|
|
17808
|
+
missingMessage: 'Timeout update requires one `timeoutId` or `allActive: true`.',
|
|
17809
|
+
});
|
|
17810
|
+
const patch = parseTimeoutUpdatePatch(args);
|
|
17811
|
+
return target.allActive
|
|
17812
|
+
? parseBulkTimeoutUpdateArgs(patch)
|
|
17813
|
+
: parseSingleTimeoutUpdateArgs(target.timeoutId, patch);
|
|
17698
17814
|
},
|
|
17699
17815
|
};
|
|
17700
17816
|
|
|
@@ -24899,36 +25015,235 @@
|
|
|
24899
25015
|
*/
|
|
24900
25016
|
const DEFAULT_FEEDBACK_ERROR_MESSAGE = 'Failed to save feedback. Please try again.';
|
|
24901
25017
|
/**
|
|
24902
|
-
*
|
|
25018
|
+
* Constant for feedback status timeout.
|
|
25019
|
+
*/
|
|
25020
|
+
const FEEDBACK_STATUS_TIMEOUT_IN_MILLISECONDS = 3000;
|
|
25021
|
+
/**
|
|
25022
|
+
* Resolves the key used to keep one message rating in the local map.
|
|
24903
25023
|
*
|
|
24904
|
-
* @private
|
|
25024
|
+
* @private function of `useChatRatings`
|
|
24905
25025
|
*/
|
|
24906
|
-
function
|
|
24907
|
-
|
|
25026
|
+
function resolveChatRatingMessageKey$1(message) {
|
|
25027
|
+
return message.id || message.content /* <- TODO: [??][??] Is `message.content` good replacement for the ID */;
|
|
25028
|
+
}
|
|
25029
|
+
/**
|
|
25030
|
+
* Normalizes the stored rating for the current feedback mode.
|
|
25031
|
+
*
|
|
25032
|
+
* @private function of `useChatRatings`
|
|
25033
|
+
*/
|
|
25034
|
+
function normalizeChatRatingValue(feedbackMode, rating) {
|
|
25035
|
+
return feedbackMode === 'report_issue' ? 1 : rating;
|
|
25036
|
+
}
|
|
25037
|
+
/**
|
|
25038
|
+
* Creates the next message-rating map with one updated message entry.
|
|
25039
|
+
*
|
|
25040
|
+
* @private function of `useChatRatings`
|
|
25041
|
+
*/
|
|
25042
|
+
function createUpdatedMessageRatings(previousRatings, message, rating) {
|
|
25043
|
+
const nextRatings = new Map(previousRatings);
|
|
25044
|
+
nextRatings.set(resolveChatRatingMessageKey$1(message), rating);
|
|
25045
|
+
return nextRatings;
|
|
25046
|
+
}
|
|
25047
|
+
/**
|
|
25048
|
+
* Clears the transient feedback-status timeout when it is active.
|
|
25049
|
+
*
|
|
25050
|
+
* @private function of `useChatRatings`
|
|
25051
|
+
*/
|
|
25052
|
+
function clearFeedbackStatusTimeout(feedbackStatusTimeoutRef) {
|
|
25053
|
+
if (feedbackStatusTimeoutRef.current === null) {
|
|
25054
|
+
return;
|
|
25055
|
+
}
|
|
25056
|
+
clearTimeout(feedbackStatusTimeoutRef.current);
|
|
25057
|
+
feedbackStatusTimeoutRef.current = null;
|
|
25058
|
+
}
|
|
25059
|
+
/**
|
|
25060
|
+
* Resolves the rating currently selected for the message being submitted.
|
|
25061
|
+
*
|
|
25062
|
+
* @private function of `useChatRatings`
|
|
25063
|
+
*/
|
|
25064
|
+
function resolveSelectedMessageRating(params) {
|
|
25065
|
+
const { feedbackMode, selectedMessage, messageRatings } = params;
|
|
25066
|
+
const storedRating = messageRatings.get(resolveChatRatingMessageKey$1(selectedMessage));
|
|
25067
|
+
if (feedbackMode === 'report_issue') {
|
|
25068
|
+
return storedRating || 1;
|
|
25069
|
+
}
|
|
25070
|
+
return storedRating || null;
|
|
25071
|
+
}
|
|
25072
|
+
/**
|
|
25073
|
+
* Serializes the current chat thread into the format expected by feedback handlers.
|
|
25074
|
+
*
|
|
25075
|
+
* @private function of `useChatRatings`
|
|
25076
|
+
*/
|
|
25077
|
+
function createChatFeedbackThread(messages) {
|
|
25078
|
+
return messages.map((message) => `${message.content}`).join('\n\n---\n\n');
|
|
25079
|
+
}
|
|
25080
|
+
/**
|
|
25081
|
+
* Builds the payload submitted to the external feedback callback.
|
|
25082
|
+
*
|
|
25083
|
+
* @private function of `useChatRatings`
|
|
25084
|
+
*/
|
|
25085
|
+
function createChatFeedbackSubmission(params) {
|
|
25086
|
+
const { currentRating, messages, selectedMessage, textRating } = params;
|
|
25087
|
+
return {
|
|
25088
|
+
message: selectedMessage,
|
|
25089
|
+
rating: currentRating,
|
|
25090
|
+
textRating,
|
|
25091
|
+
chatThread: createChatFeedbackThread(messages),
|
|
25092
|
+
expectedAnswer: selectedMessage.expectedAnswer || selectedMessage.content || null,
|
|
25093
|
+
url: window.location.href,
|
|
25094
|
+
};
|
|
25095
|
+
}
|
|
25096
|
+
/**
|
|
25097
|
+
* Resolves whether the current hook state is ready to submit feedback.
|
|
25098
|
+
*
|
|
25099
|
+
* @private function of `useChatRatings`
|
|
25100
|
+
*/
|
|
25101
|
+
function prepareChatFeedbackSubmission(params) {
|
|
25102
|
+
const { feedbackMode, messageRatings, messages, selectedMessage, textRating } = params;
|
|
25103
|
+
if (!selectedMessage || feedbackMode === 'off') {
|
|
25104
|
+
return null;
|
|
25105
|
+
}
|
|
25106
|
+
const currentRating = resolveSelectedMessageRating({
|
|
25107
|
+
feedbackMode,
|
|
25108
|
+
selectedMessage,
|
|
25109
|
+
messageRatings,
|
|
25110
|
+
});
|
|
25111
|
+
if (!currentRating) {
|
|
25112
|
+
return null;
|
|
25113
|
+
}
|
|
25114
|
+
return {
|
|
25115
|
+
currentRating,
|
|
25116
|
+
feedbackData: createChatFeedbackSubmission({
|
|
25117
|
+
currentRating,
|
|
25118
|
+
messages,
|
|
25119
|
+
selectedMessage,
|
|
25120
|
+
textRating,
|
|
25121
|
+
}),
|
|
25122
|
+
};
|
|
25123
|
+
}
|
|
25124
|
+
/**
|
|
25125
|
+
* Resolves the success message shown after a rating or issue report is submitted.
|
|
25126
|
+
*
|
|
25127
|
+
* @private function of `useChatRatings`
|
|
25128
|
+
*/
|
|
25129
|
+
function resolveChatFeedbackSuccessMessage(params) {
|
|
25130
|
+
var _a, _b;
|
|
25131
|
+
const { feedbackMode, feedbackTranslations, feedbackResponse } = params;
|
|
25132
|
+
if (feedbackResponse === null || feedbackResponse === void 0 ? void 0 : feedbackResponse.message) {
|
|
25133
|
+
return feedbackResponse.message;
|
|
25134
|
+
}
|
|
25135
|
+
if (feedbackMode === 'report_issue') {
|
|
25136
|
+
return (_a = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.reportIssueSuccessMessage) !== null && _a !== void 0 ? _a : DEFAULT_REPORT_ISSUE_SUCCESS_MESSAGE;
|
|
25137
|
+
}
|
|
25138
|
+
return (_b = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackSuccessMessage) !== null && _b !== void 0 ? _b : DEFAULT_FEEDBACK_SUCCESS_MESSAGE;
|
|
25139
|
+
}
|
|
25140
|
+
/**
|
|
25141
|
+
* Resolves the error message shown when feedback submission fails.
|
|
25142
|
+
*
|
|
25143
|
+
* @private function of `useChatRatings`
|
|
25144
|
+
*/
|
|
25145
|
+
function resolveChatFeedbackErrorMessage(error, feedbackTranslations) {
|
|
25146
|
+
var _a;
|
|
25147
|
+
if (error instanceof Error) {
|
|
25148
|
+
return error.message;
|
|
25149
|
+
}
|
|
25150
|
+
return (_a = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackErrorMessage) !== null && _a !== void 0 ? _a : DEFAULT_FEEDBACK_ERROR_MESSAGE;
|
|
25151
|
+
}
|
|
25152
|
+
/**
|
|
25153
|
+
* Logs the fallback feedback submission when no external handler is provided.
|
|
25154
|
+
*
|
|
25155
|
+
* @private function of `useChatRatings`
|
|
25156
|
+
*/
|
|
25157
|
+
function logChatFeedbackSubmission(feedbackData) {
|
|
25158
|
+
console.info('Rating submitted:', {
|
|
25159
|
+
rating: '?'.repeat(feedbackData.rating),
|
|
25160
|
+
textRating: feedbackData.textRating,
|
|
25161
|
+
chatThread: feedbackData.chatThread,
|
|
25162
|
+
expectedAnswer: feedbackData.expectedAnswer,
|
|
25163
|
+
url: feedbackData.url,
|
|
25164
|
+
});
|
|
25165
|
+
}
|
|
25166
|
+
/**
|
|
25167
|
+
* Submits feedback through the external callback when present, otherwise logs it locally.
|
|
25168
|
+
*
|
|
25169
|
+
* @private function of `useChatRatings`
|
|
25170
|
+
*/
|
|
25171
|
+
async function submitChatFeedback(params) {
|
|
25172
|
+
const { feedbackData, feedbackMode, feedbackTranslations, onFeedback } = params;
|
|
25173
|
+
const feedbackResponse = onFeedback ? await onFeedback(feedbackData) : undefined;
|
|
25174
|
+
if (!onFeedback) {
|
|
25175
|
+
logChatFeedbackSubmission(feedbackData);
|
|
25176
|
+
}
|
|
25177
|
+
return {
|
|
25178
|
+
message: resolveChatFeedbackSuccessMessage({
|
|
25179
|
+
feedbackMode,
|
|
25180
|
+
feedbackTranslations,
|
|
25181
|
+
feedbackResponse,
|
|
25182
|
+
}),
|
|
25183
|
+
variant: 'success',
|
|
25184
|
+
};
|
|
25185
|
+
}
|
|
25186
|
+
/**
|
|
25187
|
+
* Clears the rating modal state after a successful submission.
|
|
25188
|
+
*
|
|
25189
|
+
* @private function of `useChatRatings`
|
|
25190
|
+
*/
|
|
25191
|
+
function resetChatRatingSubmissionState(params) {
|
|
25192
|
+
const { setRatingModalOpen, setSelectedMessage, setTextRating } = params;
|
|
25193
|
+
setRatingModalOpen(false);
|
|
25194
|
+
setTextRating('');
|
|
25195
|
+
setSelectedMessage(null);
|
|
25196
|
+
}
|
|
25197
|
+
/**
|
|
25198
|
+
* Owns the mutable chat-rating state and the message-rating selection handler.
|
|
25199
|
+
*
|
|
25200
|
+
* @private internal hook of `useChatRatings`
|
|
25201
|
+
*/
|
|
25202
|
+
function useChatRatingState(feedbackMode) {
|
|
24908
25203
|
const [ratingModalOpen, setRatingModalOpen] = react.useState(false);
|
|
24909
25204
|
const [selectedMessage, setSelectedMessage] = react.useState(null);
|
|
24910
25205
|
const [messageRatings, setMessageRatings] = react.useState(new Map());
|
|
24911
25206
|
const [textRating, setTextRating] = react.useState('');
|
|
24912
25207
|
const [hoveredRating, setHoveredRating] = react.useState(0);
|
|
24913
25208
|
const [expandedMessageId, setExpandedMessageId] = react.useState(null);
|
|
24914
|
-
const [feedbackStatus, setFeedbackStatus] = react.useState(null);
|
|
24915
|
-
const feedbackStatusTimeoutRef = react.useRef(null);
|
|
24916
25209
|
const handleRating = react.useCallback((message, newRating) => {
|
|
24917
|
-
const normalizedRating = feedbackMode
|
|
25210
|
+
const normalizedRating = normalizeChatRatingValue(feedbackMode, newRating);
|
|
24918
25211
|
setSelectedMessage(message);
|
|
24919
25212
|
setMessageRatings((previousRatings) => {
|
|
24920
|
-
|
|
24921
|
-
nextRatings.set(message.id ||
|
|
24922
|
-
message.content /* <- TODO: [??][??] Is `message.content` good replacement for the ID */, normalizedRating);
|
|
24923
|
-
return nextRatings;
|
|
25213
|
+
return createUpdatedMessageRatings(previousRatings, message, normalizedRating);
|
|
24924
25214
|
});
|
|
24925
25215
|
setRatingModalOpen(true);
|
|
24926
25216
|
}, [feedbackMode]);
|
|
25217
|
+
return {
|
|
25218
|
+
state: {
|
|
25219
|
+
ratingModalOpen,
|
|
25220
|
+
selectedMessage,
|
|
25221
|
+
messageRatings,
|
|
25222
|
+
textRating,
|
|
25223
|
+
hoveredRating,
|
|
25224
|
+
expandedMessageId,
|
|
25225
|
+
},
|
|
25226
|
+
actions: {
|
|
25227
|
+
setRatingModalOpen,
|
|
25228
|
+
setSelectedMessage,
|
|
25229
|
+
setMessageRatings,
|
|
25230
|
+
setTextRating,
|
|
25231
|
+
setHoveredRating,
|
|
25232
|
+
setExpandedMessageId,
|
|
25233
|
+
handleRating,
|
|
25234
|
+
},
|
|
25235
|
+
};
|
|
25236
|
+
}
|
|
25237
|
+
/**
|
|
25238
|
+
* Owns the transient feedback-status toast state and auto-hide lifecycle.
|
|
25239
|
+
*
|
|
25240
|
+
* @private internal hook of `useChatRatings`
|
|
25241
|
+
*/
|
|
25242
|
+
function useChatFeedbackStatus() {
|
|
25243
|
+
const [feedbackStatus, setFeedbackStatus] = react.useState(null);
|
|
25244
|
+
const feedbackStatusTimeoutRef = react.useRef(null);
|
|
24927
25245
|
const showFeedbackStatus = react.useCallback((status) => {
|
|
24928
|
-
|
|
24929
|
-
clearTimeout(feedbackStatusTimeoutRef.current);
|
|
24930
|
-
feedbackStatusTimeoutRef.current = null;
|
|
24931
|
-
}
|
|
25246
|
+
clearFeedbackStatusTimeout(feedbackStatusTimeoutRef);
|
|
24932
25247
|
setFeedbackStatus(status);
|
|
24933
25248
|
if (!status || typeof window === 'undefined') {
|
|
24934
25249
|
return;
|
|
@@ -24936,111 +25251,122 @@
|
|
|
24936
25251
|
feedbackStatusTimeoutRef.current = window.setTimeout(() => {
|
|
24937
25252
|
setFeedbackStatus(null);
|
|
24938
25253
|
feedbackStatusTimeoutRef.current = null;
|
|
24939
|
-
},
|
|
25254
|
+
}, FEEDBACK_STATUS_TIMEOUT_IN_MILLISECONDS);
|
|
24940
25255
|
}, []);
|
|
24941
25256
|
react.useEffect(() => {
|
|
24942
25257
|
return () => {
|
|
24943
|
-
|
|
24944
|
-
clearTimeout(feedbackStatusTimeoutRef.current);
|
|
24945
|
-
feedbackStatusTimeoutRef.current = null;
|
|
24946
|
-
}
|
|
25258
|
+
clearFeedbackStatusTimeout(feedbackStatusTimeoutRef);
|
|
24947
25259
|
};
|
|
24948
25260
|
}, []);
|
|
24949
|
-
|
|
24950
|
-
|
|
24951
|
-
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
24956
|
-
|
|
24957
|
-
|
|
25261
|
+
return {
|
|
25262
|
+
feedbackStatus,
|
|
25263
|
+
showFeedbackStatus,
|
|
25264
|
+
};
|
|
25265
|
+
}
|
|
25266
|
+
/**
|
|
25267
|
+
* Builds the submit handler that validates, submits, reports status, and resets the modal.
|
|
25268
|
+
*
|
|
25269
|
+
* @private internal hook of `useChatRatings`
|
|
25270
|
+
*/
|
|
25271
|
+
function useChatRatingSubmission(options) {
|
|
25272
|
+
const { feedbackMode, feedbackTranslations, messageRatings, messages, onFeedback, selectedMessage, setRatingModalOpen, setSelectedMessage, setTextRating, showFeedbackStatus, textRating, } = options;
|
|
25273
|
+
return react.useCallback(async () => {
|
|
25274
|
+
const preparedSubmission = prepareChatFeedbackSubmission({
|
|
25275
|
+
feedbackMode,
|
|
25276
|
+
messageRatings,
|
|
25277
|
+
messages,
|
|
25278
|
+
selectedMessage,
|
|
25279
|
+
textRating,
|
|
25280
|
+
});
|
|
25281
|
+
if (!preparedSubmission) {
|
|
24958
25282
|
return;
|
|
24959
25283
|
}
|
|
24960
|
-
|
|
24961
|
-
|
|
24962
|
-
|
|
24963
|
-
|
|
24964
|
-
|
|
24965
|
-
|
|
24966
|
-
expectedAnswer: selectedMessage.expectedAnswer || selectedMessage.content || null,
|
|
24967
|
-
url: window.location.href,
|
|
24968
|
-
};
|
|
24969
|
-
if (onFeedback) {
|
|
24970
|
-
try {
|
|
24971
|
-
const feedbackResponse = await onFeedback(feedbackData);
|
|
24972
|
-
showFeedbackStatus({
|
|
24973
|
-
message: (_a = feedbackResponse === null || feedbackResponse === void 0 ? void 0 : feedbackResponse.message) !== null && _a !== void 0 ? _a : (feedbackMode === 'report_issue'
|
|
24974
|
-
? (_b = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.reportIssueSuccessMessage) !== null && _b !== void 0 ? _b : DEFAULT_REPORT_ISSUE_SUCCESS_MESSAGE
|
|
24975
|
-
: (_c = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackSuccessMessage) !== null && _c !== void 0 ? _c : DEFAULT_FEEDBACK_SUCCESS_MESSAGE),
|
|
24976
|
-
variant: 'success',
|
|
24977
|
-
});
|
|
24978
|
-
}
|
|
24979
|
-
catch (error) {
|
|
24980
|
-
console.error('Error submitting feedback:', error);
|
|
24981
|
-
const message = error instanceof Error
|
|
24982
|
-
? error.message
|
|
24983
|
-
: (_d = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackErrorMessage) !== null && _d !== void 0 ? _d : DEFAULT_FEEDBACK_ERROR_MESSAGE;
|
|
24984
|
-
showFeedbackStatus({ message, variant: 'error' });
|
|
24985
|
-
return;
|
|
24986
|
-
}
|
|
24987
|
-
}
|
|
24988
|
-
else {
|
|
24989
|
-
console.info('Rating submitted:', {
|
|
24990
|
-
rating: '?'.repeat(currentRating),
|
|
24991
|
-
textRating: textRating,
|
|
24992
|
-
chatThread,
|
|
24993
|
-
expectedAnswer: selectedMessage.expectedAnswer || selectedMessage.content || null,
|
|
24994
|
-
url: window.location.href,
|
|
25284
|
+
try {
|
|
25285
|
+
const feedbackStatus = await submitChatFeedback({
|
|
25286
|
+
feedbackData: preparedSubmission.feedbackData,
|
|
25287
|
+
feedbackMode,
|
|
25288
|
+
feedbackTranslations,
|
|
25289
|
+
onFeedback,
|
|
24995
25290
|
});
|
|
25291
|
+
showFeedbackStatus(feedbackStatus);
|
|
25292
|
+
}
|
|
25293
|
+
catch (error) {
|
|
25294
|
+
console.error('Error submitting feedback:', error);
|
|
24996
25295
|
showFeedbackStatus({
|
|
24997
|
-
message:
|
|
24998
|
-
|
|
24999
|
-
: (_f = feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackSuccessMessage) !== null && _f !== void 0 ? _f : DEFAULT_FEEDBACK_SUCCESS_MESSAGE,
|
|
25000
|
-
variant: 'success',
|
|
25296
|
+
message: resolveChatFeedbackErrorMessage(error, feedbackTranslations),
|
|
25297
|
+
variant: 'error',
|
|
25001
25298
|
});
|
|
25299
|
+
return;
|
|
25002
25300
|
}
|
|
25003
|
-
|
|
25004
|
-
|
|
25005
|
-
|
|
25301
|
+
resetChatRatingSubmissionState({
|
|
25302
|
+
setRatingModalOpen,
|
|
25303
|
+
setSelectedMessage,
|
|
25304
|
+
setTextRating,
|
|
25305
|
+
});
|
|
25006
25306
|
}, [
|
|
25007
25307
|
feedbackMode,
|
|
25008
|
-
feedbackTranslations
|
|
25009
|
-
feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.feedbackSuccessMessage,
|
|
25010
|
-
feedbackTranslations === null || feedbackTranslations === void 0 ? void 0 : feedbackTranslations.reportIssueSuccessMessage,
|
|
25011
|
-
messages,
|
|
25308
|
+
feedbackTranslations,
|
|
25012
25309
|
messageRatings,
|
|
25310
|
+
messages,
|
|
25013
25311
|
onFeedback,
|
|
25014
25312
|
selectedMessage,
|
|
25313
|
+
setRatingModalOpen,
|
|
25314
|
+
setSelectedMessage,
|
|
25315
|
+
setTextRating,
|
|
25015
25316
|
showFeedbackStatus,
|
|
25016
25317
|
textRating,
|
|
25017
25318
|
]);
|
|
25319
|
+
}
|
|
25320
|
+
/**
|
|
25321
|
+
* Locks page scrolling while the rating modal is open on mobile layouts.
|
|
25322
|
+
*
|
|
25323
|
+
* @private internal hook of `useChatRatings`
|
|
25324
|
+
*/
|
|
25325
|
+
function useChatRatingModalBodyScrollLock(params) {
|
|
25326
|
+
const { isMobile, ratingModalOpen } = params;
|
|
25018
25327
|
react.useEffect(() => {
|
|
25019
|
-
if (ratingModalOpen && isMobile) {
|
|
25020
|
-
|
|
25021
|
-
return () => {
|
|
25022
|
-
document.body.style.overflow = 'unset';
|
|
25023
|
-
};
|
|
25328
|
+
if (!(ratingModalOpen && isMobile)) {
|
|
25329
|
+
return;
|
|
25024
25330
|
}
|
|
25025
|
-
|
|
25331
|
+
document.body.style.overflow = 'hidden';
|
|
25332
|
+
return () => {
|
|
25333
|
+
document.body.style.overflow = 'unset';
|
|
25334
|
+
};
|
|
25335
|
+
}, [isMobile, ratingModalOpen]);
|
|
25336
|
+
}
|
|
25337
|
+
/**
|
|
25338
|
+
* Hook that centralizes rating state and handlers for Chat.
|
|
25339
|
+
*
|
|
25340
|
+
* @private component of `<Chat/>`
|
|
25341
|
+
*/
|
|
25342
|
+
function useChatRatings(options) {
|
|
25343
|
+
const { messages, onFeedback, feedbackMode, feedbackTranslations, isMobile } = options;
|
|
25344
|
+
const { state, actions } = useChatRatingState(feedbackMode);
|
|
25345
|
+
const { feedbackStatus, showFeedbackStatus } = useChatFeedbackStatus();
|
|
25346
|
+
const submitRating = useChatRatingSubmission({
|
|
25347
|
+
feedbackMode,
|
|
25348
|
+
feedbackTranslations,
|
|
25349
|
+
messageRatings: state.messageRatings,
|
|
25350
|
+
messages,
|
|
25351
|
+
onFeedback,
|
|
25352
|
+
selectedMessage: state.selectedMessage,
|
|
25353
|
+
setRatingModalOpen: actions.setRatingModalOpen,
|
|
25354
|
+
setSelectedMessage: actions.setSelectedMessage,
|
|
25355
|
+
setTextRating: actions.setTextRating,
|
|
25356
|
+
showFeedbackStatus,
|
|
25357
|
+
textRating: state.textRating,
|
|
25358
|
+
});
|
|
25359
|
+
useChatRatingModalBodyScrollLock({
|
|
25360
|
+
isMobile,
|
|
25361
|
+
ratingModalOpen: state.ratingModalOpen,
|
|
25362
|
+
});
|
|
25026
25363
|
return {
|
|
25027
25364
|
state: {
|
|
25028
|
-
|
|
25029
|
-
selectedMessage,
|
|
25030
|
-
messageRatings,
|
|
25031
|
-
textRating,
|
|
25032
|
-
hoveredRating,
|
|
25033
|
-
expandedMessageId,
|
|
25365
|
+
...state,
|
|
25034
25366
|
feedbackStatus,
|
|
25035
25367
|
},
|
|
25036
25368
|
actions: {
|
|
25037
|
-
|
|
25038
|
-
setSelectedMessage,
|
|
25039
|
-
setMessageRatings,
|
|
25040
|
-
setTextRating,
|
|
25041
|
-
setHoveredRating,
|
|
25042
|
-
setExpandedMessageId,
|
|
25043
|
-
handleRating,
|
|
25369
|
+
...actions,
|
|
25044
25370
|
submitRating,
|
|
25045
25371
|
},
|
|
25046
25372
|
};
|
|
@@ -31719,43 +32045,21 @@
|
|
|
31719
32045
|
* @private internal utility of `<Chat/>`
|
|
31720
32046
|
*/
|
|
31721
32047
|
function resolveTimeoutToolCallPresentation(options) {
|
|
31722
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
31723
32048
|
const { toolCallName, args, resultRaw, locale } = options;
|
|
31724
32049
|
if (!isTimeoutToolCallName$1(toolCallName)) {
|
|
31725
32050
|
return null;
|
|
31726
32051
|
}
|
|
31727
|
-
const
|
|
31728
|
-
|
|
31729
|
-
|
|
31730
|
-
|
|
31731
|
-
|
|
31732
|
-
|
|
31733
|
-
:
|
|
31734
|
-
|
|
31735
|
-
|
|
31736
|
-
|
|
31737
|
-
|
|
31738
|
-
const dueAtRaw = (_h = (_g = normalizeStringValue(resultObject === null || resultObject === void 0 ? void 0 : resultObject.dueAt)) !== null && _g !== void 0 ? _g : normalizeStringValue(args.dueAt)) !== null && _h !== void 0 ? _h : null;
|
|
31739
|
-
const dueAtDate = dueAtRaw ? parseDateValue(dueAtRaw) : null;
|
|
31740
|
-
const effectiveCurrentDate = options.currentDate || new Date();
|
|
31741
|
-
const dueAtLabels = dueAtDate
|
|
31742
|
-
? formatToolCallDateTime(dueAtDate, { locale, currentDate: effectiveCurrentDate })
|
|
31743
|
-
: null;
|
|
31744
|
-
return {
|
|
31745
|
-
action,
|
|
31746
|
-
status,
|
|
31747
|
-
milliseconds,
|
|
31748
|
-
timeoutId,
|
|
31749
|
-
message,
|
|
31750
|
-
dueAtDate,
|
|
31751
|
-
dueAtIsoUtc: dueAtDate ? dueAtDate.toISOString() : null,
|
|
31752
|
-
localTimezone: resolveLocalTimezone(),
|
|
31753
|
-
compactDurationLabel: milliseconds !== null ? formatTimeoutDurationCompact(milliseconds) : null,
|
|
31754
|
-
humanDurationLabel: milliseconds !== null ? formatTimeoutDurationHuman(milliseconds) : null,
|
|
31755
|
-
relativeDueLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.relativeTimeLabel) || null,
|
|
31756
|
-
localDueTimeLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.localTimeLabel) || null,
|
|
31757
|
-
localDueDateLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.localDateLabel) || null,
|
|
31758
|
-
};
|
|
32052
|
+
const timeoutToolCallCoreData = resolveTimeoutToolCallCoreData({
|
|
32053
|
+
toolCallName,
|
|
32054
|
+
args,
|
|
32055
|
+
resultObject: resolveTimeoutToolCallResultObject(resultRaw),
|
|
32056
|
+
});
|
|
32057
|
+
const dueAtLabels = resolveTimeoutToolCallDueAtLabels({
|
|
32058
|
+
dueAtDate: timeoutToolCallCoreData.dueAtDate,
|
|
32059
|
+
currentDate: options.currentDate || new Date(),
|
|
32060
|
+
locale,
|
|
32061
|
+
});
|
|
32062
|
+
return createTimeoutToolCallPresentation({ timeoutToolCallCoreData, dueAtLabels });
|
|
31759
32063
|
}
|
|
31760
32064
|
/**
|
|
31761
32065
|
* Builds concise chip text for timeout tool calls.
|
|
@@ -31891,6 +32195,121 @@
|
|
|
31891
32195
|
function formatTimeoutUnit(value, unit) {
|
|
31892
32196
|
return `${value} ${unit}${value === 1 ? '' : 's'}`;
|
|
31893
32197
|
}
|
|
32198
|
+
/**
|
|
32199
|
+
* Normalizes the raw timeout result payload when it is an object.
|
|
32200
|
+
*
|
|
32201
|
+
* @private internal timeout-chat helper
|
|
32202
|
+
*/
|
|
32203
|
+
function resolveTimeoutToolCallResultObject(resultRaw) {
|
|
32204
|
+
return resultRaw && typeof resultRaw === 'object' && !Array.isArray(resultRaw)
|
|
32205
|
+
? resultRaw
|
|
32206
|
+
: null;
|
|
32207
|
+
}
|
|
32208
|
+
/**
|
|
32209
|
+
* Resolves all timeout fields that depend only on arguments and raw result metadata.
|
|
32210
|
+
*
|
|
32211
|
+
* @private internal timeout-chat helper
|
|
32212
|
+
*/
|
|
32213
|
+
function resolveTimeoutToolCallCoreData(options) {
|
|
32214
|
+
const { toolCallName, args, resultObject } = options;
|
|
32215
|
+
return {
|
|
32216
|
+
action: resolveTimeoutToolCallAction(toolCallName, resultObject),
|
|
32217
|
+
status: resolveTimeoutToolCallStatus(resultObject),
|
|
32218
|
+
milliseconds: pickPositiveNumber(args.milliseconds, resultObject === null || resultObject === void 0 ? void 0 : resultObject.milliseconds),
|
|
32219
|
+
timeoutId: pickNormalizedStringValue(resultObject === null || resultObject === void 0 ? void 0 : resultObject.timeoutId, args.timeoutId),
|
|
32220
|
+
message: pickNormalizedStringValue(args.message, resultObject === null || resultObject === void 0 ? void 0 : resultObject.message),
|
|
32221
|
+
dueAtDate: resolveTimeoutToolCallDueAtDate(args, resultObject),
|
|
32222
|
+
};
|
|
32223
|
+
}
|
|
32224
|
+
/**
|
|
32225
|
+
* Resolves the timeout action, preferring an explicit runtime result value.
|
|
32226
|
+
*
|
|
32227
|
+
* @private internal timeout-chat helper
|
|
32228
|
+
*/
|
|
32229
|
+
function resolveTimeoutToolCallAction(toolCallName, resultObject) {
|
|
32230
|
+
if ((resultObject === null || resultObject === void 0 ? void 0 : resultObject.action) === 'cancel' || (resultObject === null || resultObject === void 0 ? void 0 : resultObject.action) === 'set') {
|
|
32231
|
+
return resultObject.action;
|
|
32232
|
+
}
|
|
32233
|
+
return toolCallName === 'cancel_timeout' ? 'cancel' : 'set';
|
|
32234
|
+
}
|
|
32235
|
+
/**
|
|
32236
|
+
* Resolves the timeout status from the runtime result payload.
|
|
32237
|
+
*
|
|
32238
|
+
* @private internal timeout-chat helper
|
|
32239
|
+
*/
|
|
32240
|
+
function resolveTimeoutToolCallStatus(resultObject) {
|
|
32241
|
+
return typeof (resultObject === null || resultObject === void 0 ? void 0 : resultObject.status) === 'string' ? resultObject.status : null;
|
|
32242
|
+
}
|
|
32243
|
+
/**
|
|
32244
|
+
* Resolves the scheduled due date, preferring the runtime result over input arguments.
|
|
32245
|
+
*
|
|
32246
|
+
* @private internal timeout-chat helper
|
|
32247
|
+
*/
|
|
32248
|
+
function resolveTimeoutToolCallDueAtDate(args, resultObject) {
|
|
32249
|
+
const dueAtRaw = pickNormalizedStringValue(resultObject === null || resultObject === void 0 ? void 0 : resultObject.dueAt, args.dueAt);
|
|
32250
|
+
return dueAtRaw ? parseDateValue(dueAtRaw) : null;
|
|
32251
|
+
}
|
|
32252
|
+
/**
|
|
32253
|
+
* Resolves localized due-date labels when a valid due date exists.
|
|
32254
|
+
*
|
|
32255
|
+
* @private internal timeout-chat helper
|
|
32256
|
+
*/
|
|
32257
|
+
function resolveTimeoutToolCallDueAtLabels(options) {
|
|
32258
|
+
const { dueAtDate, currentDate, locale } = options;
|
|
32259
|
+
return dueAtDate ? formatToolCallDateTime(dueAtDate, { locale, currentDate }) : null;
|
|
32260
|
+
}
|
|
32261
|
+
/**
|
|
32262
|
+
* Creates the final timeout presentation payload with derived labels.
|
|
32263
|
+
*
|
|
32264
|
+
* @private internal timeout-chat helper
|
|
32265
|
+
*/
|
|
32266
|
+
function createTimeoutToolCallPresentation(options) {
|
|
32267
|
+
const { timeoutToolCallCoreData, dueAtLabels } = options;
|
|
32268
|
+
const { action, status, milliseconds, timeoutId, message, dueAtDate } = timeoutToolCallCoreData;
|
|
32269
|
+
return {
|
|
32270
|
+
action,
|
|
32271
|
+
status,
|
|
32272
|
+
milliseconds,
|
|
32273
|
+
timeoutId,
|
|
32274
|
+
message,
|
|
32275
|
+
dueAtDate,
|
|
32276
|
+
dueAtIsoUtc: dueAtDate ? dueAtDate.toISOString() : null,
|
|
32277
|
+
localTimezone: resolveLocalTimezone(),
|
|
32278
|
+
compactDurationLabel: milliseconds !== null ? formatTimeoutDurationCompact(milliseconds) : null,
|
|
32279
|
+
humanDurationLabel: milliseconds !== null ? formatTimeoutDurationHuman(milliseconds) : null,
|
|
32280
|
+
relativeDueLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.relativeTimeLabel) || null,
|
|
32281
|
+
localDueTimeLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.localTimeLabel) || null,
|
|
32282
|
+
localDueDateLabel: (dueAtLabels === null || dueAtLabels === void 0 ? void 0 : dueAtLabels.localDateLabel) || null,
|
|
32283
|
+
};
|
|
32284
|
+
}
|
|
32285
|
+
/**
|
|
32286
|
+
* Parses the first positive finite number from a prioritized list of values.
|
|
32287
|
+
*
|
|
32288
|
+
* @private internal timeout-chat helper
|
|
32289
|
+
*/
|
|
32290
|
+
function pickPositiveNumber(...values) {
|
|
32291
|
+
for (const value of values) {
|
|
32292
|
+
const positiveNumber = parsePositiveNumber(value);
|
|
32293
|
+
if (positiveNumber !== null) {
|
|
32294
|
+
return positiveNumber;
|
|
32295
|
+
}
|
|
32296
|
+
}
|
|
32297
|
+
return null;
|
|
32298
|
+
}
|
|
32299
|
+
/**
|
|
32300
|
+
* Resolves the first non-empty trimmed string from a prioritized list of values.
|
|
32301
|
+
*
|
|
32302
|
+
* @private internal timeout-chat helper
|
|
32303
|
+
*/
|
|
32304
|
+
function pickNormalizedStringValue(...values) {
|
|
32305
|
+
for (const value of values) {
|
|
32306
|
+
const normalizedStringValue = normalizeStringValue(value);
|
|
32307
|
+
if (normalizedStringValue !== null) {
|
|
32308
|
+
return normalizedStringValue;
|
|
32309
|
+
}
|
|
32310
|
+
}
|
|
32311
|
+
return null;
|
|
32312
|
+
}
|
|
31894
32313
|
/**
|
|
31895
32314
|
* Parses date-like values into a valid `Date`.
|
|
31896
32315
|
*
|
|
@@ -32231,6 +32650,39 @@
|
|
|
32231
32650
|
* Length of memory chip truncate.
|
|
32232
32651
|
*/
|
|
32233
32652
|
const MEMORY_CHIP_TRUNCATE_LENGTH = 45;
|
|
32653
|
+
/**
|
|
32654
|
+
* Tool names that render a localized current-time chip.
|
|
32655
|
+
*
|
|
32656
|
+
* @private utility of `<Chat/>`
|
|
32657
|
+
*/
|
|
32658
|
+
const TIME_TOOL_CALL_NAMES = new Set(['get_current_time', 'useTime']);
|
|
32659
|
+
/**
|
|
32660
|
+
* Tool names that render the email subject when available.
|
|
32661
|
+
*
|
|
32662
|
+
* @private utility of `<Chat/>`
|
|
32663
|
+
*/
|
|
32664
|
+
const EMAIL_TOOL_CALL_NAMES = new Set(['send_email', 'useEmail']);
|
|
32665
|
+
/**
|
|
32666
|
+
* Tool names that render a memory preview.
|
|
32667
|
+
*
|
|
32668
|
+
* @private utility of `<Chat/>`
|
|
32669
|
+
*/
|
|
32670
|
+
const MEMORY_TOOL_CALL_NAMES = new Set(['retrieve_user_memory', 'store_user_memory']);
|
|
32671
|
+
/**
|
|
32672
|
+
* Ordered specialized chiplet resolvers evaluated before the generic fallback.
|
|
32673
|
+
*
|
|
32674
|
+
* @private utility of `<Chat/>`
|
|
32675
|
+
*/
|
|
32676
|
+
const SPECIALIZED_TOOL_CALL_CHIPLET_RESOLVERS = [
|
|
32677
|
+
resolveWalletCredentialChipletInfo,
|
|
32678
|
+
resolveTeamToolCallChipletInfo,
|
|
32679
|
+
resolveTimeToolCallChipletInfo,
|
|
32680
|
+
resolveEmailToolCallChipletInfo,
|
|
32681
|
+
resolveMemoryToolCallChipletInfo,
|
|
32682
|
+
resolveTimeoutToolCallChipletInfo,
|
|
32683
|
+
resolveQueryToolCallChipletInfo,
|
|
32684
|
+
resolveUrlToolCallChipletInfo,
|
|
32685
|
+
];
|
|
32234
32686
|
/**
|
|
32235
32687
|
* Builds display text for a tool call chiplet.
|
|
32236
32688
|
*
|
|
@@ -32294,96 +32746,310 @@
|
|
|
32294
32746
|
* @private [🧠] Maybe public?
|
|
32295
32747
|
*/
|
|
32296
32748
|
function getToolCallChipletInfo(toolCall, locale, titleOverrides, chipTranslations) {
|
|
32297
|
-
const
|
|
32298
|
-
|
|
32299
|
-
|
|
32749
|
+
const context = createToolCallChipletContext(toolCall, locale, titleOverrides, chipTranslations);
|
|
32750
|
+
return resolveSpecializedToolCallChipletInfo(context) || createDefaultToolCallChipletInfo(context);
|
|
32751
|
+
}
|
|
32752
|
+
/**
|
|
32753
|
+
* Collects the parsed values shared by all chiplet resolution steps.
|
|
32754
|
+
*
|
|
32755
|
+
* @param toolCall - Tool call being rendered.
|
|
32756
|
+
* @param locale - Optional locale used by time-sensitive helpers.
|
|
32757
|
+
* @param titleOverrides - Optional localized title overrides.
|
|
32758
|
+
* @param chipTranslations - Optional localized chip templates reused by specialized resolvers.
|
|
32759
|
+
* @returns Shared chiplet resolution context.
|
|
32760
|
+
*
|
|
32761
|
+
* @private utility of `<Chat/>`
|
|
32762
|
+
*/
|
|
32763
|
+
function createToolCallChipletContext(toolCall, locale, titleOverrides, chipTranslations) {
|
|
32300
32764
|
const args = parseToolCallArguments(toolCall);
|
|
32301
|
-
const isTimeTool = toolCall.name === 'get_current_time' || toolCall.name === 'useTime';
|
|
32302
|
-
const isEmailTool = toolCall.name === 'send_email' || toolCall.name === 'useEmail';
|
|
32303
|
-
const isMemoryTool = toolCall.name === 'retrieve_user_memory' || toolCall.name === 'store_user_memory';
|
|
32304
|
-
const isTimeoutTool = toolCall.name === 'set_timeout' || toolCall.name === 'cancel_timeout';
|
|
32305
32765
|
const resultRaw = parseToolCallResult(toolCall.result);
|
|
32306
|
-
|
|
32307
|
-
|
|
32308
|
-
|
|
32309
|
-
|
|
32310
|
-
|
|
32311
|
-
|
|
32312
|
-
|
|
32313
|
-
|
|
32314
|
-
:
|
|
32315
|
-
|
|
32316
|
-
|
|
32317
|
-
|
|
32318
|
-
|
|
32319
|
-
|
|
32320
|
-
|
|
32766
|
+
return {
|
|
32767
|
+
toolCall,
|
|
32768
|
+
locale,
|
|
32769
|
+
chipTranslations,
|
|
32770
|
+
args,
|
|
32771
|
+
resultRaw,
|
|
32772
|
+
baseTitle: resolveToolCallBaseTitle(toolCall.name, titleOverrides),
|
|
32773
|
+
emoji: resolveToolCallEmoji(toolCall.name),
|
|
32774
|
+
timeoutPresentation: resolveToolCallChipletTimeoutPresentation(toolCall.name, args, resultRaw, locale),
|
|
32775
|
+
};
|
|
32776
|
+
}
|
|
32777
|
+
/**
|
|
32778
|
+
* Resolves the first specialized chiplet branch that matches the tool call.
|
|
32779
|
+
*
|
|
32780
|
+
* @param context - Shared chiplet resolution context.
|
|
32781
|
+
* @returns Specialized chiplet info when any resolver matches, otherwise `null`.
|
|
32782
|
+
*
|
|
32783
|
+
* @private utility of `<Chat/>`
|
|
32784
|
+
*/
|
|
32785
|
+
function resolveSpecializedToolCallChipletInfo(context) {
|
|
32786
|
+
for (const resolveToolCallChipletInfo of SPECIALIZED_TOOL_CALL_CHIPLET_RESOLVERS) {
|
|
32787
|
+
const chipletInfo = resolveToolCallChipletInfo(context);
|
|
32788
|
+
if (chipletInfo) {
|
|
32789
|
+
return chipletInfo;
|
|
32790
|
+
}
|
|
32321
32791
|
}
|
|
32322
|
-
|
|
32323
|
-
|
|
32324
|
-
|
|
32325
|
-
|
|
32326
|
-
|
|
32327
|
-
|
|
32328
|
-
|
|
32329
|
-
|
|
32330
|
-
|
|
32331
|
-
|
|
32792
|
+
return null;
|
|
32793
|
+
}
|
|
32794
|
+
/**
|
|
32795
|
+
* Resolves the human-friendly fallback title for one tool call.
|
|
32796
|
+
*
|
|
32797
|
+
* @param toolName - Raw tool name.
|
|
32798
|
+
* @param titleOverrides - Optional localized title overrides.
|
|
32799
|
+
* @returns Title used when no specialized chip label applies.
|
|
32800
|
+
*
|
|
32801
|
+
* @private utility of `<Chat/>`
|
|
32802
|
+
*/
|
|
32803
|
+
function resolveToolCallBaseTitle(toolName, titleOverrides) {
|
|
32804
|
+
var _a;
|
|
32805
|
+
return (titleOverrides === null || titleOverrides === void 0 ? void 0 : titleOverrides[toolName]) || ((_a = TOOL_TITLES[toolName]) === null || _a === void 0 ? void 0 : _a.title) || toolName;
|
|
32806
|
+
}
|
|
32807
|
+
/**
|
|
32808
|
+
* Resolves the emoji prefix used by standard tool chips.
|
|
32809
|
+
*
|
|
32810
|
+
* @param toolName - Raw tool name.
|
|
32811
|
+
* @returns Emoji shown at the beginning of the chip.
|
|
32812
|
+
*
|
|
32813
|
+
* @private utility of `<Chat/>`
|
|
32814
|
+
*/
|
|
32815
|
+
function resolveToolCallEmoji(toolName) {
|
|
32816
|
+
var _a;
|
|
32817
|
+
return ((_a = TOOL_TITLES[toolName]) === null || _a === void 0 ? void 0 : _a.emoji) || '🛠️';
|
|
32818
|
+
}
|
|
32819
|
+
/**
|
|
32820
|
+
* Resolves timeout presentation metadata only for timeout-aware tools.
|
|
32821
|
+
*
|
|
32822
|
+
* @param toolName - Raw tool name.
|
|
32823
|
+
* @param args - Parsed tool arguments.
|
|
32824
|
+
* @param resultRaw - Parsed tool result payload.
|
|
32825
|
+
* @param locale - Optional locale used for friendly date formatting.
|
|
32826
|
+
* @returns Timeout presentation metadata or `null`.
|
|
32827
|
+
*
|
|
32828
|
+
* @private utility of `<Chat/>`
|
|
32829
|
+
*/
|
|
32830
|
+
function resolveToolCallChipletTimeoutPresentation(toolName, args, resultRaw, locale) {
|
|
32831
|
+
if (!isTimeoutToolCallName$1(toolName)) {
|
|
32832
|
+
return null;
|
|
32332
32833
|
}
|
|
32333
|
-
|
|
32334
|
-
|
|
32335
|
-
|
|
32336
|
-
|
|
32337
|
-
|
|
32338
|
-
|
|
32339
|
-
|
|
32340
|
-
|
|
32341
|
-
|
|
32834
|
+
return resolveTimeoutToolCallPresentation({
|
|
32835
|
+
toolCallName: toolName,
|
|
32836
|
+
args,
|
|
32837
|
+
resultRaw,
|
|
32838
|
+
currentDate: new Date(),
|
|
32839
|
+
locale,
|
|
32840
|
+
});
|
|
32841
|
+
}
|
|
32842
|
+
/**
|
|
32843
|
+
* Resolves a chip label for synthetic wallet-credential tool calls.
|
|
32844
|
+
*
|
|
32845
|
+
* @param context - Shared chiplet resolution context.
|
|
32846
|
+
* @returns Chiplet info when the tool result represents wallet credentials, otherwise `null`.
|
|
32847
|
+
*
|
|
32848
|
+
* @private utility of `<Chat/>`
|
|
32849
|
+
*/
|
|
32850
|
+
function resolveWalletCredentialChipletInfo(context) {
|
|
32851
|
+
const walletCredentialResult = parseWalletCredentialToolCallResult(context.resultRaw);
|
|
32852
|
+
if (!walletCredentialResult) {
|
|
32853
|
+
return null;
|
|
32342
32854
|
}
|
|
32343
|
-
|
|
32344
|
-
|
|
32345
|
-
|
|
32346
|
-
|
|
32347
|
-
|
|
32348
|
-
|
|
32855
|
+
return createEmojiToolCallChipletInfo(context, walletCredentialResult.credentialName);
|
|
32856
|
+
}
|
|
32857
|
+
/**
|
|
32858
|
+
* Resolves a chip label and agent metadata for TEAM tool calls.
|
|
32859
|
+
*
|
|
32860
|
+
* @param context - Shared chiplet resolution context.
|
|
32861
|
+
* @returns Chiplet info when the result contains teammate metadata, otherwise `null`.
|
|
32862
|
+
*
|
|
32863
|
+
* @private utility of `<Chat/>`
|
|
32864
|
+
*/
|
|
32865
|
+
function resolveTeamToolCallChipletInfo(context) {
|
|
32866
|
+
const teamResult = parseTeamToolResult(context.resultRaw);
|
|
32867
|
+
if (!(teamResult === null || teamResult === void 0 ? void 0 : teamResult.teammate)) {
|
|
32868
|
+
return null;
|
|
32349
32869
|
}
|
|
32350
|
-
|
|
32351
|
-
|
|
32352
|
-
|
|
32353
|
-
|
|
32354
|
-
|
|
32355
|
-
|
|
32356
|
-
|
|
32870
|
+
const label = teamResult.teammate.label || teamResult.teammate.url || context.baseTitle;
|
|
32871
|
+
const agentData = {
|
|
32872
|
+
url: teamResult.teammate.url,
|
|
32873
|
+
label,
|
|
32874
|
+
};
|
|
32875
|
+
return {
|
|
32876
|
+
text: label,
|
|
32877
|
+
agentData,
|
|
32878
|
+
};
|
|
32879
|
+
}
|
|
32880
|
+
/**
|
|
32881
|
+
* Resolves the specialized time chip label when the tool returns a valid date.
|
|
32882
|
+
*
|
|
32883
|
+
* @param context - Shared chiplet resolution context.
|
|
32884
|
+
* @returns Chiplet info when a time label can be built, otherwise `null`.
|
|
32885
|
+
*
|
|
32886
|
+
* @private utility of `<Chat/>`
|
|
32887
|
+
*/
|
|
32888
|
+
function resolveTimeToolCallChipletInfo(context) {
|
|
32889
|
+
var _a;
|
|
32890
|
+
if (!isTimeToolCallName$1(context.toolCall.name)) {
|
|
32891
|
+
return null;
|
|
32357
32892
|
}
|
|
32358
|
-
|
|
32359
|
-
|
|
32360
|
-
|
|
32361
|
-
};
|
|
32893
|
+
const resultDate = getToolCallResultDate(context.resultRaw);
|
|
32894
|
+
if (!resultDate) {
|
|
32895
|
+
return null;
|
|
32362
32896
|
}
|
|
32363
|
-
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
|
|
32897
|
+
return createEmojiToolCallChipletInfo(context, formatToolCallTranslationTemplate(((_a = context.chipTranslations) === null || _a === void 0 ? void 0 : _a.toolCallTimeChipLabel) || '{time}', {
|
|
32898
|
+
time: formatToolCallLocalTime(resultDate, context.locale),
|
|
32899
|
+
}));
|
|
32900
|
+
}
|
|
32901
|
+
/**
|
|
32902
|
+
* Resolves the email-subject chip label when a subject is present.
|
|
32903
|
+
*
|
|
32904
|
+
* @param context - Shared chiplet resolution context.
|
|
32905
|
+
* @returns Chiplet info when the email subject can be shown, otherwise `null`.
|
|
32906
|
+
*
|
|
32907
|
+
* @private utility of `<Chat/>`
|
|
32908
|
+
*/
|
|
32909
|
+
function resolveEmailToolCallChipletInfo(context) {
|
|
32910
|
+
if (!isEmailToolCallName$1(context.toolCall.name) || typeof context.args.subject !== 'string') {
|
|
32911
|
+
return null;
|
|
32367
32912
|
}
|
|
32368
|
-
|
|
32369
|
-
|
|
32370
|
-
|
|
32371
|
-
|
|
32372
|
-
|
|
32373
|
-
|
|
32374
|
-
|
|
32375
|
-
|
|
32376
|
-
|
|
32377
|
-
|
|
32378
|
-
|
|
32379
|
-
|
|
32913
|
+
return createEmojiToolCallChipletInfo(context, context.args.subject);
|
|
32914
|
+
}
|
|
32915
|
+
/**
|
|
32916
|
+
* Resolves the memory-preview chip label for MEMORY tools.
|
|
32917
|
+
*
|
|
32918
|
+
* @param context - Shared chiplet resolution context.
|
|
32919
|
+
* @returns Chiplet info when a memory preview is available, otherwise `null`.
|
|
32920
|
+
*
|
|
32921
|
+
* @private utility of `<Chat/>`
|
|
32922
|
+
*/
|
|
32923
|
+
function resolveMemoryToolCallChipletInfo(context) {
|
|
32924
|
+
if (!isMemoryToolCallName(context.toolCall.name)) {
|
|
32925
|
+
return null;
|
|
32926
|
+
}
|
|
32927
|
+
const memoryPreview = getMemoryPreviewText(context.args, context.resultRaw);
|
|
32928
|
+
if (!memoryPreview) {
|
|
32929
|
+
return null;
|
|
32380
32930
|
}
|
|
32931
|
+
return createEmojiToolCallChipletInfo(context, memoryPreview);
|
|
32932
|
+
}
|
|
32933
|
+
/**
|
|
32934
|
+
* Resolves the timeout-specific chip label when timeout presentation metadata is available.
|
|
32935
|
+
*
|
|
32936
|
+
* @param context - Shared chiplet resolution context.
|
|
32937
|
+
* @returns Chiplet info when the tool is a timeout tool, otherwise `null`.
|
|
32938
|
+
*
|
|
32939
|
+
* @private utility of `<Chat/>`
|
|
32940
|
+
*/
|
|
32941
|
+
function resolveTimeoutToolCallChipletInfo(context) {
|
|
32942
|
+
if (!context.timeoutPresentation) {
|
|
32943
|
+
return null;
|
|
32944
|
+
}
|
|
32945
|
+
return createEmojiToolCallChipletInfo(context, buildTimeoutToolCallChipLabel(context.timeoutPresentation, context.chipTranslations));
|
|
32946
|
+
}
|
|
32947
|
+
/**
|
|
32948
|
+
* Resolves a query-based chip label used by search-like tools.
|
|
32949
|
+
*
|
|
32950
|
+
* @param context - Shared chiplet resolution context.
|
|
32951
|
+
* @returns Chiplet info when a query string is present, otherwise `null`.
|
|
32952
|
+
*
|
|
32953
|
+
* @private utility of `<Chat/>`
|
|
32954
|
+
*/
|
|
32955
|
+
function resolveQueryToolCallChipletInfo(context) {
|
|
32956
|
+
if (typeof context.args.query !== 'string') {
|
|
32957
|
+
return null;
|
|
32958
|
+
}
|
|
32959
|
+
return createEmojiToolCallChipletInfo(context, context.args.query);
|
|
32960
|
+
}
|
|
32961
|
+
/**
|
|
32962
|
+
* Resolves a URL-based chip label by preferring the hostname over the raw URL.
|
|
32963
|
+
*
|
|
32964
|
+
* @param context - Shared chiplet resolution context.
|
|
32965
|
+
* @returns Chiplet info when a URL string is present, otherwise `null`.
|
|
32966
|
+
*
|
|
32967
|
+
* @private utility of `<Chat/>`
|
|
32968
|
+
*/
|
|
32969
|
+
function resolveUrlToolCallChipletInfo(context) {
|
|
32970
|
+
if (typeof context.args.url !== 'string') {
|
|
32971
|
+
return null;
|
|
32972
|
+
}
|
|
32973
|
+
return createEmojiToolCallChipletInfo(context, resolveUrlChipLabel(context.args.url));
|
|
32974
|
+
}
|
|
32975
|
+
/**
|
|
32976
|
+
* Builds the final fallback chip label when no specialized branch matches.
|
|
32977
|
+
*
|
|
32978
|
+
* @param context - Shared chiplet resolution context.
|
|
32979
|
+
* @returns Fallback chiplet info.
|
|
32980
|
+
*
|
|
32981
|
+
* @private utility of `<Chat/>`
|
|
32982
|
+
*/
|
|
32983
|
+
function createDefaultToolCallChipletInfo(context) {
|
|
32984
|
+
return createEmojiToolCallChipletInfo(context, context.baseTitle);
|
|
32985
|
+
}
|
|
32986
|
+
/**
|
|
32987
|
+
* Builds a standard emoji-prefixed chip info object.
|
|
32988
|
+
*
|
|
32989
|
+
* @param context - Shared chiplet resolution context.
|
|
32990
|
+
* @param label - User-facing chip label without emoji prefix.
|
|
32991
|
+
* @returns Emoji-prefixed chiplet info.
|
|
32992
|
+
*
|
|
32993
|
+
* @private utility of `<Chat/>`
|
|
32994
|
+
*/
|
|
32995
|
+
function createEmojiToolCallChipletInfo(context, label) {
|
|
32381
32996
|
return {
|
|
32382
|
-
text: `${emoji} ${
|
|
32997
|
+
text: `${context.emoji} ${label}`,
|
|
32383
32998
|
};
|
|
32384
32999
|
}
|
|
33000
|
+
/**
|
|
33001
|
+
* Resolves a friendly URL chip label, preferring the hostname over the raw input.
|
|
33002
|
+
*
|
|
33003
|
+
* @param rawUrl - Raw URL argument value.
|
|
33004
|
+
* @returns Hostname when URL parsing succeeds, otherwise the original string.
|
|
33005
|
+
*
|
|
33006
|
+
* @private utility of `<Chat/>`
|
|
33007
|
+
*/
|
|
33008
|
+
function resolveUrlChipLabel(rawUrl) {
|
|
33009
|
+
try {
|
|
33010
|
+
return new URL(rawUrl).hostname;
|
|
33011
|
+
}
|
|
33012
|
+
catch (_a) {
|
|
33013
|
+
return rawUrl;
|
|
33014
|
+
}
|
|
33015
|
+
}
|
|
33016
|
+
/**
|
|
33017
|
+
* Checks whether a tool name belongs to the time commitment.
|
|
33018
|
+
*
|
|
33019
|
+
* @param toolName - Raw tool name.
|
|
33020
|
+
* @returns `true` when the chip should show a localized time label.
|
|
33021
|
+
*
|
|
33022
|
+
* @private utility of `<Chat/>`
|
|
33023
|
+
*/
|
|
33024
|
+
function isTimeToolCallName$1(toolName) {
|
|
33025
|
+
return TIME_TOOL_CALL_NAMES.has(toolName);
|
|
33026
|
+
}
|
|
33027
|
+
/**
|
|
33028
|
+
* Checks whether a tool name belongs to the email commitment.
|
|
33029
|
+
*
|
|
33030
|
+
* @param toolName - Raw tool name.
|
|
33031
|
+
* @returns `true` when the chip may show an email subject.
|
|
33032
|
+
*
|
|
33033
|
+
* @private utility of `<Chat/>`
|
|
33034
|
+
*/
|
|
33035
|
+
function isEmailToolCallName$1(toolName) {
|
|
33036
|
+
return EMAIL_TOOL_CALL_NAMES.has(toolName);
|
|
33037
|
+
}
|
|
33038
|
+
/**
|
|
33039
|
+
* Checks whether a tool name belongs to the memory commitment.
|
|
33040
|
+
*
|
|
33041
|
+
* @param toolName - Raw tool name.
|
|
33042
|
+
* @returns `true` when the chip may show a memory preview.
|
|
33043
|
+
*
|
|
33044
|
+
* @private utility of `<Chat/>`
|
|
33045
|
+
*/
|
|
33046
|
+
function isMemoryToolCallName(toolName) {
|
|
33047
|
+
return MEMORY_TOOL_CALL_NAMES.has(toolName);
|
|
33048
|
+
}
|
|
32385
33049
|
/**
|
|
32386
33050
|
* Builds memory preview text for MEMORY commitment tool calls.
|
|
33051
|
+
*
|
|
33052
|
+
* @private utility of `<Chat/>`
|
|
32387
33053
|
*/
|
|
32388
33054
|
function getMemoryPreviewText(args, resultRaw) {
|
|
32389
33055
|
var _a, _b, _c;
|
|
@@ -32406,6 +33072,8 @@
|
|
|
32406
33072
|
}
|
|
32407
33073
|
/**
|
|
32408
33074
|
* Shortens long memory content for compact chip display.
|
|
33075
|
+
*
|
|
33076
|
+
* @private utility of `<Chat/>`
|
|
32409
33077
|
*/
|
|
32410
33078
|
function shortenMemoryPreview(content) {
|
|
32411
33079
|
const trimmed = content.trim().replace(/\s+/g, ' ');
|
|
@@ -55449,26 +56117,13 @@
|
|
|
55449
56117
|
styleInject(css_248z);
|
|
55450
56118
|
|
|
55451
56119
|
/**
|
|
55452
|
-
*
|
|
56120
|
+
* Handles controlled/uncontrolled open state for the widget.
|
|
55453
56121
|
*
|
|
55454
|
-
* @private
|
|
56122
|
+
* @private internal hook of PromptbookAgentSeamlessIntegration
|
|
55455
56123
|
*/
|
|
55456
|
-
function
|
|
55457
|
-
var _a, _b;
|
|
55458
|
-
const { agentUrl, meta, onOpenChange, isOpen: controlledIsOpen, defaultOpen = false, className, style, isFocusedOnLoad, isIframeUsed = false, } = props;
|
|
56124
|
+
function usePromptbookAgentSeamlessIntegrationOpenState({ agentUrl, defaultOpen = false, isOpen: controlledIsOpen, onOpenChange, }) {
|
|
55459
56125
|
const [internalIsOpen, setInternalIsOpen] = react.useState(defaultOpen);
|
|
55460
|
-
const [headerElement, setHeaderElement] = react.useState(null);
|
|
55461
|
-
const [isIframeLoaded, setIsIframeLoaded] = react.useState(false);
|
|
55462
|
-
const [isChatConnected, setIsChatConnected] = react.useState(false);
|
|
55463
|
-
const rootElementRef = react.useRef(null);
|
|
55464
|
-
const windowId = react.useId();
|
|
55465
56126
|
const isOpen = controlledIsOpen !== null && controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
55466
|
-
/**
|
|
55467
|
-
* Updates the widget open state and notifies integration callbacks.
|
|
55468
|
-
*
|
|
55469
|
-
* @param nextIsOpen - Target open state.
|
|
55470
|
-
* @private internal utility of PromptbookAgentSeamlessIntegration
|
|
55471
|
-
*/
|
|
55472
56127
|
const setOpen = react.useCallback((nextIsOpen) => {
|
|
55473
56128
|
if (controlledIsOpen === undefined) {
|
|
55474
56129
|
setInternalIsOpen(nextIsOpen);
|
|
@@ -55481,22 +56136,21 @@
|
|
|
55481
56136
|
}
|
|
55482
56137
|
setInternalIsOpen(defaultOpen);
|
|
55483
56138
|
}, [agentUrl, controlledIsOpen, defaultOpen]);
|
|
55484
|
-
|
|
55485
|
-
|
|
55486
|
-
|
|
55487
|
-
|
|
55488
|
-
|
|
55489
|
-
|
|
55490
|
-
|
|
55491
|
-
|
|
55492
|
-
}, [agentUrl]);
|
|
56139
|
+
return { isOpen, setOpen };
|
|
56140
|
+
}
|
|
56141
|
+
/**
|
|
56142
|
+
* Closes the widget when the user presses Escape or clicks outside.
|
|
56143
|
+
*
|
|
56144
|
+
* @private internal hook of PromptbookAgentSeamlessIntegration
|
|
56145
|
+
*/
|
|
56146
|
+
function useClosePromptbookAgentSeamlessIntegrationOnOutsideInteraction({ isOpen, rootElementRef, onClose, }) {
|
|
55493
56147
|
react.useEffect(() => {
|
|
55494
56148
|
if (!isOpen) {
|
|
55495
56149
|
return;
|
|
55496
56150
|
}
|
|
55497
56151
|
const handleKeyDown = (event) => {
|
|
55498
56152
|
if (event.key === 'Escape') {
|
|
55499
|
-
|
|
56153
|
+
onClose();
|
|
55500
56154
|
}
|
|
55501
56155
|
};
|
|
55502
56156
|
const handlePointerDown = (event) => {
|
|
@@ -55508,7 +56162,7 @@
|
|
|
55508
56162
|
if (target instanceof Node && rootElement.contains(target)) {
|
|
55509
56163
|
return;
|
|
55510
56164
|
}
|
|
55511
|
-
|
|
56165
|
+
onClose();
|
|
55512
56166
|
};
|
|
55513
56167
|
window.addEventListener('keydown', handleKeyDown);
|
|
55514
56168
|
window.addEventListener('pointerdown', handlePointerDown);
|
|
@@ -55516,23 +56170,22 @@
|
|
|
55516
56170
|
window.removeEventListener('keydown', handleKeyDown);
|
|
55517
56171
|
window.removeEventListener('pointerdown', handlePointerDown);
|
|
55518
56172
|
};
|
|
55519
|
-
}, [isOpen,
|
|
56173
|
+
}, [isOpen, onClose, rootElementRef]);
|
|
56174
|
+
}
|
|
56175
|
+
/**
|
|
56176
|
+
* Connects to the remote agent and tracks the connection lifecycle.
|
|
56177
|
+
*
|
|
56178
|
+
* @private internal hook of PromptbookAgentSeamlessIntegration
|
|
56179
|
+
*/
|
|
56180
|
+
function useRemotePromptbookAgent(agentUrl) {
|
|
55520
56181
|
const [agent, setAgent] = react.useState(null);
|
|
55521
56182
|
const [error, setError] = react.useState(null);
|
|
55522
|
-
react.
|
|
55523
|
-
if (agent && meta) {
|
|
55524
|
-
if (agent.meta.image && meta.image && agent.meta.image !== meta.image) {
|
|
55525
|
-
console.warn('Conflict in agent meta image:', { server: agent.meta.image, props: meta.image });
|
|
55526
|
-
}
|
|
55527
|
-
if (agent.meta.color && meta.color && agent.meta.color !== meta.color) {
|
|
55528
|
-
console.warn('Conflict in agent meta color:', { server: agent.meta.color, props: meta.color });
|
|
55529
|
-
}
|
|
55530
|
-
}
|
|
55531
|
-
}, [agent, meta]);
|
|
56183
|
+
const [isAgentConnected, setIsAgentConnected] = react.useState(false);
|
|
55532
56184
|
react.useEffect(() => {
|
|
55533
56185
|
let isMounted = true;
|
|
55534
56186
|
setAgent(null);
|
|
55535
56187
|
setError(null);
|
|
56188
|
+
setIsAgentConnected(false);
|
|
55536
56189
|
const connectToAgent = async () => {
|
|
55537
56190
|
try {
|
|
55538
56191
|
// TODO: [🧠] Maybe we should not connect immediately but only when the user clicks the button or hovers?
|
|
@@ -55540,7 +56193,7 @@
|
|
|
55540
56193
|
const connectedAgent = await RemoteAgent.connect({ agentUrl });
|
|
55541
56194
|
if (isMounted) {
|
|
55542
56195
|
setAgent(connectedAgent);
|
|
55543
|
-
|
|
56196
|
+
setIsAgentConnected(true);
|
|
55544
56197
|
}
|
|
55545
56198
|
}
|
|
55546
56199
|
catch (err) {
|
|
@@ -55555,30 +56208,169 @@
|
|
|
55555
56208
|
isMounted = false;
|
|
55556
56209
|
};
|
|
55557
56210
|
}, [agentUrl]);
|
|
55558
|
-
|
|
55559
|
-
|
|
55560
|
-
|
|
55561
|
-
|
|
55562
|
-
|
|
55563
|
-
|
|
55564
|
-
|
|
55565
|
-
|
|
56211
|
+
return { agent, error, isAgentConnected };
|
|
56212
|
+
}
|
|
56213
|
+
/**
|
|
56214
|
+
* Warns when props branding conflicts with the branding returned by the server.
|
|
56215
|
+
*
|
|
56216
|
+
* @private internal hook of PromptbookAgentSeamlessIntegration
|
|
56217
|
+
*/
|
|
56218
|
+
function useWarnAboutPromptbookAgentMetaConflicts(agent, meta) {
|
|
56219
|
+
react.useEffect(() => {
|
|
56220
|
+
if (!agent || !meta) {
|
|
56221
|
+
return;
|
|
56222
|
+
}
|
|
56223
|
+
if (agent.meta.image && meta.image && agent.meta.image !== meta.image) {
|
|
56224
|
+
console.warn('Conflict in agent meta image:', { server: agent.meta.image, props: meta.image });
|
|
56225
|
+
}
|
|
56226
|
+
if (agent.meta.color && meta.color && agent.meta.color !== meta.color) {
|
|
56227
|
+
console.warn('Conflict in agent meta color:', { server: agent.meta.color, props: meta.color });
|
|
56228
|
+
}
|
|
56229
|
+
}, [agent, meta]);
|
|
56230
|
+
}
|
|
56231
|
+
/**
|
|
56232
|
+
* Resolves the avatar, color, and display name shown by the widget.
|
|
56233
|
+
*
|
|
56234
|
+
* @private internal utility of PromptbookAgentSeamlessIntegration
|
|
56235
|
+
*/
|
|
56236
|
+
function resolvePromptbookAgentSeamlessIntegrationDisplayInfo({ agent, agentUrl, meta, }) {
|
|
56237
|
+
var _a, _b;
|
|
56238
|
+
return {
|
|
56239
|
+
image: ((_a = agent === null || agent === void 0 ? void 0 : agent.meta) === null || _a === void 0 ? void 0 : _a.image) ||
|
|
56240
|
+
(meta === null || meta === void 0 ? void 0 : meta.image) ||
|
|
56241
|
+
// Note: [🤹] Using default avatar from the agent server
|
|
56242
|
+
`${agentUrl}/images/default-avatar.png`,
|
|
56243
|
+
color: ((_b = agent === null || agent === void 0 ? void 0 : agent.meta) === null || _b === void 0 ? void 0 : _b.color) || (meta === null || meta === void 0 ? void 0 : meta.color),
|
|
56244
|
+
displayName: (agent === null || agent === void 0 ? void 0 : agent.meta.fullname) || (meta === null || meta === void 0 ? void 0 : meta.fullname) || (agent === null || agent === void 0 ? void 0 : agent.agentName) || 'Chat with Agent',
|
|
56245
|
+
};
|
|
56246
|
+
}
|
|
56247
|
+
/**
|
|
56248
|
+
* Resolves the connection status label and indicator class.
|
|
56249
|
+
*
|
|
56250
|
+
* @private internal utility of PromptbookAgentSeamlessIntegration
|
|
56251
|
+
*/
|
|
56252
|
+
function createPromptbookAgentSeamlessIntegrationConnectionPresentation({ isConnected, error, isIframeUsed, }) {
|
|
55566
56253
|
let connectionStatus = 'pending';
|
|
55567
|
-
if (
|
|
56254
|
+
if (isConnected) {
|
|
55568
56255
|
connectionStatus = 'connected';
|
|
55569
56256
|
}
|
|
55570
56257
|
else if (error && !isIframeUsed) {
|
|
55571
56258
|
connectionStatus = 'error';
|
|
55572
56259
|
}
|
|
55573
|
-
|
|
55574
|
-
|
|
55575
|
-
|
|
55576
|
-
|
|
55577
|
-
|
|
55578
|
-
|
|
55579
|
-
|
|
55580
|
-
|
|
55581
|
-
|
|
56260
|
+
return {
|
|
56261
|
+
connectionStatus,
|
|
56262
|
+
connectionStatusText: connectionStatus === 'connected'
|
|
56263
|
+
? 'Online'
|
|
56264
|
+
: connectionStatus === 'error'
|
|
56265
|
+
? 'Connection issue'
|
|
56266
|
+
: 'Connecting',
|
|
56267
|
+
connectionStatusClassName: getPromptbookAgentSeamlessIntegrationStatusClassName(connectionStatus),
|
|
56268
|
+
};
|
|
56269
|
+
}
|
|
56270
|
+
/**
|
|
56271
|
+
* Resolves the CSS class for the connection status indicator.
|
|
56272
|
+
*
|
|
56273
|
+
* @private internal utility of PromptbookAgentSeamlessIntegration
|
|
56274
|
+
*/
|
|
56275
|
+
function getPromptbookAgentSeamlessIntegrationStatusClassName(connectionStatus) {
|
|
56276
|
+
if (connectionStatus === 'connected') {
|
|
56277
|
+
return styles.PromptbookAgentSeamlessIntegrationStatusConnected;
|
|
56278
|
+
}
|
|
56279
|
+
if (connectionStatus === 'error') {
|
|
56280
|
+
return styles.PromptbookAgentSeamlessIntegrationStatusError;
|
|
56281
|
+
}
|
|
56282
|
+
return styles.PromptbookAgentSeamlessIntegrationStatusPending;
|
|
56283
|
+
}
|
|
56284
|
+
/**
|
|
56285
|
+
* Renders the shared close button used by the widget.
|
|
56286
|
+
*
|
|
56287
|
+
* @private internal subcomponent of PromptbookAgentSeamlessIntegration
|
|
56288
|
+
*/
|
|
56289
|
+
function PromptbookAgentSeamlessIntegrationCloseButton({ onClose, }) {
|
|
56290
|
+
return (jsxRuntime.jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: onClose, title: "Close", "aria-label": "Close chat", children: jsxRuntime.jsx(CloseIcon, {}) }));
|
|
56291
|
+
}
|
|
56292
|
+
/**
|
|
56293
|
+
* Renders the loading state shared by iframe and embedded chat modes.
|
|
56294
|
+
*
|
|
56295
|
+
* @private internal subcomponent of PromptbookAgentSeamlessIntegration
|
|
56296
|
+
*/
|
|
56297
|
+
function PromptbookAgentSeamlessIntegrationLoadingState({ displayName, }) {
|
|
56298
|
+
return (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingShimmer }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingSpinner }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingTitle, children: "Preparing your chat" }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingText, children: ["Connecting to ", displayName, "..."] })] }));
|
|
56299
|
+
}
|
|
56300
|
+
/**
|
|
56301
|
+
* Renders the inline error state for direct chat mode.
|
|
56302
|
+
*
|
|
56303
|
+
* @private internal subcomponent of PromptbookAgentSeamlessIntegration
|
|
56304
|
+
*/
|
|
56305
|
+
function PromptbookAgentSeamlessIntegrationErrorState({ error }) {
|
|
56306
|
+
return (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationError, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorTitle, children: "Failed to connect to the agent" }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorMessage, children: error.message })] }));
|
|
56307
|
+
}
|
|
56308
|
+
/**
|
|
56309
|
+
* Renders the main content area based on the selected integration mode.
|
|
56310
|
+
*
|
|
56311
|
+
* @private internal subcomponent of PromptbookAgentSeamlessIntegration
|
|
56312
|
+
*/
|
|
56313
|
+
function PromptbookAgentSeamlessIntegrationContent({ agent, agentUrl, displayName, error, headerElement, isFocusedOnLoad, isIframeLoaded, isIframeUsed, onClose, onIframeLoad, }) {
|
|
56314
|
+
if (isIframeUsed) {
|
|
56315
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isIframeLoaded && jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationLoadingState, { displayName: displayName }), jsxRuntime.jsx("iframe", { src: agentUrl + '/chat?headless', className: styles.PromptbookAgentSeamlessIntegrationIframe, style: { opacity: isIframeLoaded ? 1 : 0 }, tabIndex: -1, onLoad: onIframeLoad })] }));
|
|
56316
|
+
}
|
|
56317
|
+
if (agent) {
|
|
56318
|
+
return (jsxRuntime.jsx(AgentChat, { agent: agent, actionsContainer: headerElement, isFocusedOnLoad: isFocusedOnLoad, extraActions: jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationCloseButton, { onClose: onClose }), layout: "STANDALONE" }));
|
|
56319
|
+
}
|
|
56320
|
+
if (error) {
|
|
56321
|
+
return jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationErrorState, { error: error });
|
|
56322
|
+
}
|
|
56323
|
+
return jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationLoadingState, { displayName: displayName });
|
|
56324
|
+
}
|
|
56325
|
+
/**
|
|
56326
|
+
* Renders a floating agent button that opens a chat window with the remote agent.
|
|
56327
|
+
*
|
|
56328
|
+
* @private component of PromptbookAgentIntegration
|
|
56329
|
+
*/
|
|
56330
|
+
function PromptbookAgentSeamlessIntegration(props) {
|
|
56331
|
+
const { agentUrl, meta, className, style, isFocusedOnLoad, isIframeUsed = false } = props;
|
|
56332
|
+
const [headerElement, setHeaderElement] = react.useState(null);
|
|
56333
|
+
const [isIframeLoaded, setIsIframeLoaded] = react.useState(false);
|
|
56334
|
+
const rootElementRef = react.useRef(null);
|
|
56335
|
+
const windowId = react.useId();
|
|
56336
|
+
const { isOpen, setOpen } = usePromptbookAgentSeamlessIntegrationOpenState(props);
|
|
56337
|
+
const { agent, error, isAgentConnected } = useRemotePromptbookAgent(agentUrl);
|
|
56338
|
+
const handleClose = react.useCallback(() => {
|
|
56339
|
+
setOpen(false);
|
|
56340
|
+
}, [setOpen]);
|
|
56341
|
+
const handleToggle = react.useCallback(() => {
|
|
56342
|
+
setOpen(!isOpen);
|
|
56343
|
+
}, [isOpen, setOpen]);
|
|
56344
|
+
const handleIframeLoad = react.useCallback(() => {
|
|
56345
|
+
setIsIframeLoaded(true);
|
|
56346
|
+
}, []);
|
|
56347
|
+
react.useEffect(() => {
|
|
56348
|
+
if (!isOpen) {
|
|
56349
|
+
setIsIframeLoaded(false);
|
|
56350
|
+
}
|
|
56351
|
+
}, [isOpen]);
|
|
56352
|
+
react.useEffect(() => {
|
|
56353
|
+
setIsIframeLoaded(false);
|
|
56354
|
+
}, [agentUrl]);
|
|
56355
|
+
useClosePromptbookAgentSeamlessIntegrationOnOutsideInteraction({
|
|
56356
|
+
isOpen,
|
|
56357
|
+
rootElementRef,
|
|
56358
|
+
onClose: handleClose,
|
|
56359
|
+
});
|
|
56360
|
+
useWarnAboutPromptbookAgentMetaConflicts(agent, meta);
|
|
56361
|
+
// TODO: [🧠] Handle loading state better (show spinner or skeleton in the chat window)
|
|
56362
|
+
// TODO: [🧠] Handle error state (show error message in the chat window)
|
|
56363
|
+
const { image, color, displayName } = resolvePromptbookAgentSeamlessIntegrationDisplayInfo({
|
|
56364
|
+
agent,
|
|
56365
|
+
agentUrl,
|
|
56366
|
+
meta,
|
|
56367
|
+
});
|
|
56368
|
+
const { connectionStatusText, connectionStatusClassName } = createPromptbookAgentSeamlessIntegrationConnectionPresentation({
|
|
56369
|
+
isConnected: isAgentConnected || isIframeLoaded,
|
|
56370
|
+
error,
|
|
56371
|
+
isIframeUsed,
|
|
56372
|
+
});
|
|
56373
|
+
return (jsxRuntime.jsxs("div", { className: classNames(`${styles.PromptbookAgentSeamlessIntegration} ${isOpen ? styles.open : styles.closed}`, className), style: style, ref: rootElementRef, children: [jsxRuntime.jsxs("button", { type: "button", className: styles.PromptbookAgentSeamlessIntegrationButton, onClick: handleToggle, style: { backgroundColor: color }, "aria-expanded": isOpen, "aria-controls": windowId, title: isOpen ? `Close chat with ${displayName}` : `Open chat with ${displayName}`, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationAvatar, children: jsxRuntime.jsx("img", { src: image, alt: `${displayName} avatar` }) }), jsxRuntime.jsx("div", { className: classNames(styles.PromptbookAgentSeamlessIntegrationStatus, connectionStatusClassName) }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationText, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLabel, children: "Chat" }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationHint, children: displayName })] }), jsxRuntime.jsx("span", { className: styles.PromptbookAgentSeamlessIntegrationScreenReaderOnly, children: connectionStatusText })] }), isOpen && (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationWindow, id: windowId, children: [jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationHeader, style: { backgroundColor: color }, ref: setHeaderElement, children: [jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationTitleWrap, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationTitle, children: displayName }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationSubtitle, children: connectionStatusText })] }), isIframeUsed && jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationCloseButton, { onClose: handleClose })] }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationContent, children: jsxRuntime.jsx(PromptbookAgentSeamlessIntegrationContent, { agent: agent, agentUrl: agentUrl, displayName: displayName, error: error, headerElement: headerElement, isFocusedOnLoad: isFocusedOnLoad, isIframeLoaded: isIframeLoaded, isIframeUsed: isIframeUsed, onClose: handleClose, onIframeLoad: handleIframeLoad }) })] }))] }));
|
|
55582
56374
|
}
|
|
55583
56375
|
|
|
55584
56376
|
/**
|