@zero-library/chat-copilot 3.1.6 → 3.1.8
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/dist/index.cjs.js +300 -103
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +301 -104
- package/dist/index.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs.js
CHANGED
|
@@ -854,8 +854,8 @@ var ChatSender_default = React10.forwardRef(
|
|
|
854
854
|
const isFocusedRef = React10.useRef(false);
|
|
855
855
|
const commandConfigRef = React10.useRef(commandConfig);
|
|
856
856
|
commandConfigRef.current = commandConfig;
|
|
857
|
-
const inputComponent = React10.
|
|
858
|
-
(inputProps) => /* @__PURE__ */ jsxRuntime.jsx(ChatInput_default, { ...inputProps, commandConfig: commandConfigRef.current }),
|
|
857
|
+
const inputComponent = React10.useMemo(
|
|
858
|
+
() => React10.forwardRef((inputProps, ref2) => /* @__PURE__ */ jsxRuntime.jsx(ChatInput_default, { ...inputProps, ref: ref2, commandConfig: commandConfigRef.current })),
|
|
859
859
|
[]
|
|
860
860
|
);
|
|
861
861
|
React10.useEffect(() => {
|
|
@@ -3291,6 +3291,135 @@ var A2uiComponents = {
|
|
|
3291
3291
|
ReportViewer
|
|
3292
3292
|
};
|
|
3293
3293
|
|
|
3294
|
+
// src/components/CustomComponents/A2uiRuntime/controller/extract.ts
|
|
3295
|
+
var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
|
|
3296
|
+
function hasA2uiTag(text) {
|
|
3297
|
+
return typeof text === "string" && text.includes("<A2UI");
|
|
3298
|
+
}
|
|
3299
|
+
function parseA2uiTagsFromText(text) {
|
|
3300
|
+
if (!hasA2uiTag(text)) return [];
|
|
3301
|
+
const tags = [];
|
|
3302
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3303
|
+
let match;
|
|
3304
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3305
|
+
const tagId = match[1];
|
|
3306
|
+
const json = match[2].trim();
|
|
3307
|
+
if (!json) continue;
|
|
3308
|
+
try {
|
|
3309
|
+
const parsed = JSON.parse(json);
|
|
3310
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3311
|
+
if (commands.length) tags.push({ tagId, commands });
|
|
3312
|
+
} catch {
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
return tags;
|
|
3316
|
+
}
|
|
3317
|
+
function stripA2uiTags(text) {
|
|
3318
|
+
if (!hasA2uiTag(text)) return text;
|
|
3319
|
+
let result = text.replace(A2UI_TAG_REGEX, "");
|
|
3320
|
+
result = result.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3321
|
+
return result.trim();
|
|
3322
|
+
}
|
|
3323
|
+
function splitA2uiTextSegments(text) {
|
|
3324
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) {
|
|
3325
|
+
return text ? [{ type: "text", content: text }] : [];
|
|
3326
|
+
}
|
|
3327
|
+
const segments = [];
|
|
3328
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3329
|
+
let lastIndex = 0;
|
|
3330
|
+
let match;
|
|
3331
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3332
|
+
if (match.index > lastIndex) {
|
|
3333
|
+
const before = text.slice(lastIndex, match.index);
|
|
3334
|
+
if (before) segments.push({ type: "text", content: before });
|
|
3335
|
+
}
|
|
3336
|
+
const json = match[2].trim();
|
|
3337
|
+
if (json) {
|
|
3338
|
+
try {
|
|
3339
|
+
const parsed = JSON.parse(json);
|
|
3340
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3341
|
+
const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
|
|
3342
|
+
if (surfaceIds.length) {
|
|
3343
|
+
segments.push({ type: "a2ui", surfaceIds });
|
|
3344
|
+
}
|
|
3345
|
+
} catch {
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
lastIndex = regex.lastIndex;
|
|
3349
|
+
}
|
|
3350
|
+
if (lastIndex < text.length) {
|
|
3351
|
+
let remaining = text.slice(lastIndex);
|
|
3352
|
+
remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3353
|
+
if (remaining) segments.push({ type: "text", content: remaining });
|
|
3354
|
+
}
|
|
3355
|
+
return segments.length ? segments : [];
|
|
3356
|
+
}
|
|
3357
|
+
function extractInlineSurfaceIdsFromMessage(message2) {
|
|
3358
|
+
const surfaceIds = /* @__PURE__ */ new Set();
|
|
3359
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3360
|
+
for (const item of items) {
|
|
3361
|
+
if (item?.type !== "text") continue;
|
|
3362
|
+
const text = item.messageContent || item.text || "";
|
|
3363
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3364
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3365
|
+
for (const tag of tags) {
|
|
3366
|
+
for (const cmd of tag.commands) {
|
|
3367
|
+
const sid = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3368
|
+
if (sid) surfaceIds.add(sid);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
return surfaceIds;
|
|
3373
|
+
}
|
|
3374
|
+
function extractDismissedSurfaceIdsFromMessages(messages) {
|
|
3375
|
+
const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
|
|
3376
|
+
const lastActionIndexBySurface = /* @__PURE__ */ new Map();
|
|
3377
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
|
|
3378
|
+
const message2 = messages[messageIndex];
|
|
3379
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3380
|
+
for (const item of items) {
|
|
3381
|
+
if (message2?.role !== 1) {
|
|
3382
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
3383
|
+
const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
|
|
3384
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3385
|
+
}
|
|
3386
|
+
if (item?.type === "text") {
|
|
3387
|
+
const text = item.messageContent || item.text || "";
|
|
3388
|
+
if (typeof text === "string" && text.includes("<A2UI")) {
|
|
3389
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3390
|
+
for (const tag of tags) {
|
|
3391
|
+
for (const cmd of tag.commands) {
|
|
3392
|
+
const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3393
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
if (message2?.role === 1 && item?.type === "text") {
|
|
3400
|
+
const text = item.messageContent || item.text || "";
|
|
3401
|
+
if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
|
|
3402
|
+
try {
|
|
3403
|
+
const parsed = JSON.parse(text.trim());
|
|
3404
|
+
if (parsed?.type !== "a2ui_action.v1") continue;
|
|
3405
|
+
const surfaceId = String(parsed.surfaceId || "").trim();
|
|
3406
|
+
if (!surfaceId) continue;
|
|
3407
|
+
lastActionIndexBySurface.set(surfaceId, messageIndex);
|
|
3408
|
+
} catch {
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
const dismissed = [];
|
|
3414
|
+
for (const [surfaceId, actionIndex] of lastActionIndexBySurface) {
|
|
3415
|
+
const createIndex = lastCreateIndexBySurface.get(surfaceId);
|
|
3416
|
+
if (createIndex === void 0 || actionIndex > createIndex) {
|
|
3417
|
+
dismissed.push(surfaceId);
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
return dismissed;
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3294
3423
|
// src/components/CustomComponents/A2uiRuntime/controller/meta.ts
|
|
3295
3424
|
function readProp(current, props, key) {
|
|
3296
3425
|
return current[key] ?? props?.[key];
|
|
@@ -3458,19 +3587,8 @@ function inferModelPathFromSurfaceCommands(surfaceId, commands) {
|
|
|
3458
3587
|
});
|
|
3459
3588
|
return commonParentPath(paths);
|
|
3460
3589
|
}
|
|
3461
|
-
function isSubmitLikeActionName(name) {
|
|
3462
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3463
|
-
return trimmed === "submit" || trimmed === "confirm" || trimmed.startsWith("submit_") || trimmed.endsWith(".confirm");
|
|
3464
|
-
}
|
|
3465
|
-
function isCancelLikeActionName(name) {
|
|
3466
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3467
|
-
return trimmed === "cancel" || trimmed === "qf.cancel" || trimmed.endsWith(".cancel");
|
|
3468
|
-
}
|
|
3469
3590
|
function shouldOptimisticallyDismissSurface(actionName, context) {
|
|
3470
|
-
|
|
3471
|
-
if (actionName === "qf.submit" || actionName === "qf.cancel") return true;
|
|
3472
|
-
const submitFlag = context?.submit;
|
|
3473
|
-
return submitFlag === true;
|
|
3591
|
+
return true;
|
|
3474
3592
|
}
|
|
3475
3593
|
function buildDispatchContext(surfaceId, rawContext, commands) {
|
|
3476
3594
|
let normalizedContext = normalizeActionContext(rawContext);
|
|
@@ -3769,6 +3887,7 @@ function buildWizardUpdateComponentsCommand(schema, stepId) {
|
|
|
3769
3887
|
function createA2uiRuntimeState() {
|
|
3770
3888
|
return {
|
|
3771
3889
|
processedMessageCursors: [],
|
|
3890
|
+
processedTagIds: [],
|
|
3772
3891
|
serverCommands: [],
|
|
3773
3892
|
localCommands: [],
|
|
3774
3893
|
anchorIndexBySurface: {},
|
|
@@ -3790,6 +3909,15 @@ function extractSurfaceId2(command) {
|
|
|
3790
3909
|
function getA2uiRuntimeCommands(state) {
|
|
3791
3910
|
return [...state.serverCommands, ...state.localCommands];
|
|
3792
3911
|
}
|
|
3912
|
+
function sanitizeA2uiCommands(commands) {
|
|
3913
|
+
return commands.map((cmd) => {
|
|
3914
|
+
if (!cmd || typeof cmd !== "object" || !cmd.updateDataModel) return cmd;
|
|
3915
|
+
const { path } = cmd.updateDataModel;
|
|
3916
|
+
if (typeof path === "string" && path.trim()) return cmd;
|
|
3917
|
+
const { updateDataModel: _, ...rest } = cmd;
|
|
3918
|
+
return rest;
|
|
3919
|
+
});
|
|
3920
|
+
}
|
|
3793
3921
|
function diffConversationMessages(messages, prevCursors) {
|
|
3794
3922
|
if (messages.length < prevCursors.length) {
|
|
3795
3923
|
return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
|
|
@@ -3828,6 +3956,57 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
|
|
|
3828
3956
|
nextWizardSteps[surfaceId] = firstStepId.trim();
|
|
3829
3957
|
}
|
|
3830
3958
|
}
|
|
3959
|
+
function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
|
|
3960
|
+
nextState.serverCommands.push(cmd);
|
|
3961
|
+
nextState.lastA2uiHost = { id: messageId, index: messageIndex };
|
|
3962
|
+
const surfaceId = extractSurfaceId2(cmd);
|
|
3963
|
+
if (!surfaceId) return;
|
|
3964
|
+
if (cmd?.createSurface) {
|
|
3965
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3966
|
+
} else if (nextState.anchorIndexBySurface[surfaceId] === void 0 && !cmd?.deleteSurface) {
|
|
3967
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3968
|
+
}
|
|
3969
|
+
if (cmd?.createSurface) {
|
|
3970
|
+
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3971
|
+
nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
|
|
3972
|
+
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3973
|
+
}
|
|
3974
|
+
if (cmd?.updateDataModel) {
|
|
3975
|
+
const { path, value } = cmd.updateDataModel;
|
|
3976
|
+
if (typeof path === "string" && path.trim() && value && typeof value === "object" && !Array.isArray(value)) {
|
|
3977
|
+
effects.push({ type: "write-model", modelPath: path, values: value });
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3980
|
+
if (cmd?.deleteSurface) {
|
|
3981
|
+
deletedSurfaceIds.add(surfaceId);
|
|
3982
|
+
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3983
|
+
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3984
|
+
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3985
|
+
delete nextState.modelPathBySurface[surfaceId];
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
function scanA2uiTagsFromMessages(messages, processedTagIds) {
|
|
3989
|
+
const newTags = [];
|
|
3990
|
+
const newTagIds = [];
|
|
3991
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
3992
|
+
const message2 = messages[messageIndex];
|
|
3993
|
+
const messageId = String(message2?.messageId ?? messageIndex);
|
|
3994
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3995
|
+
for (const item of items) {
|
|
3996
|
+
if (item?.type !== "text") continue;
|
|
3997
|
+
const text = item.messageContent || item.text || "";
|
|
3998
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3999
|
+
const tags = parseA2uiTagsFromText(text);
|
|
4000
|
+
for (const tag of tags) {
|
|
4001
|
+
if (processedTagIds.has(tag.tagId)) continue;
|
|
4002
|
+
processedTagIds.add(tag.tagId);
|
|
4003
|
+
newTagIds.push(tag.tagId);
|
|
4004
|
+
newTags.push({ commands: tag.commands, messageIndex, messageId });
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
return { newTags, newTagIds };
|
|
4009
|
+
}
|
|
3831
4010
|
function reduceA2uiRuntimeMessages(state, messages) {
|
|
3832
4011
|
const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
|
|
3833
4012
|
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
|
|
@@ -3835,11 +4014,14 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3835
4014
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3836
4015
|
return items.map((item) => ({ messageIndex, messageId, item }));
|
|
3837
4016
|
}) : pendingItems;
|
|
3838
|
-
|
|
4017
|
+
const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
|
|
4018
|
+
const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
|
|
4019
|
+
if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
|
|
3839
4020
|
return { state, effects: [] };
|
|
3840
4021
|
}
|
|
3841
4022
|
const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
|
|
3842
4023
|
nextState.processedMessageCursors = shouldReplayAll ? [] : [...state.processedMessageCursors];
|
|
4024
|
+
nextState.processedTagIds = shouldReplayAll ? [] : [...state.processedTagIds, ...newTagIds];
|
|
3843
4025
|
nextState.serverCommands = shouldReplayAll ? [] : [...state.serverCommands];
|
|
3844
4026
|
nextState.localCommands = shouldReplayAll ? [] : [...state.localCommands];
|
|
3845
4027
|
nextState.anchorIndexBySurface = shouldReplayAll ? {} : { ...state.anchorIndexBySurface };
|
|
@@ -3862,24 +4044,13 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3862
4044
|
}
|
|
3863
4045
|
return;
|
|
3864
4046
|
}
|
|
3865
|
-
if (item?.type
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
nextState
|
|
3872
|
-
}
|
|
3873
|
-
if (item.command?.createSurface) {
|
|
3874
|
-
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3875
|
-
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3876
|
-
}
|
|
3877
|
-
if (item.command?.deleteSurface) {
|
|
3878
|
-
deletedSurfaceIds.add(surfaceId);
|
|
3879
|
-
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3880
|
-
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3881
|
-
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3882
|
-
delete nextState.modelPathBySurface[surfaceId];
|
|
4047
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4048
|
+
processA2uiCommand(item.command, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
4049
|
+
}
|
|
4050
|
+
});
|
|
4051
|
+
newTags.forEach(({ commands, messageIndex, messageId }) => {
|
|
4052
|
+
for (const cmd of commands) {
|
|
4053
|
+
processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
3883
4054
|
}
|
|
3884
4055
|
});
|
|
3885
4056
|
nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
@@ -3899,7 +4070,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3899
4070
|
return { state: nextState, effects };
|
|
3900
4071
|
}
|
|
3901
4072
|
function reduceA2uiRuntimeAction(state, input) {
|
|
3902
|
-
const { surfaceId, actionName
|
|
4073
|
+
const { surfaceId, actionName} = input;
|
|
3903
4074
|
if (!surfaceId) {
|
|
3904
4075
|
return { state, handled: actionName === "wizard.next" || actionName === "wizard.back" };
|
|
3905
4076
|
}
|
|
@@ -3929,9 +4100,6 @@ function reduceA2uiRuntimeAction(state, input) {
|
|
|
3929
4100
|
if (actionName === "wizard.next" || actionName === "wizard.back") {
|
|
3930
4101
|
return { state, handled: true };
|
|
3931
4102
|
}
|
|
3932
|
-
if (!shouldOptimisticallyDismissSurface(actionName, rawContext)) {
|
|
3933
|
-
return { state, handled: false };
|
|
3934
|
-
}
|
|
3935
4103
|
if (state.optimisticallyDismissedSurfaceIds.includes(surfaceId)) {
|
|
3936
4104
|
return { state, handled: false };
|
|
3937
4105
|
}
|
|
@@ -3947,7 +4115,7 @@ function selectA2uiRuntimeView(state, dismissedSurfaceIds) {
|
|
|
3947
4115
|
const mergedDismissedSurfaceIds = Array.from(
|
|
3948
4116
|
new Set([...dismissedSurfaceIds || [], ...state.optimisticallyDismissedSurfaceIds].filter((surfaceId) => surfaceId?.trim?.()))
|
|
3949
4117
|
);
|
|
3950
|
-
const commands = getA2uiRuntimeCommands(state);
|
|
4118
|
+
const commands = sanitizeA2uiCommands(getA2uiRuntimeCommands(state));
|
|
3951
4119
|
const visibleSurfaceIds = resolveVisibleSurfaceIds(commands, mergedDismissedSurfaceIds);
|
|
3952
4120
|
const anchoredSurfaceIdsByMessageIndex = {};
|
|
3953
4121
|
visibleSurfaceIds.forEach((surfaceId) => {
|
|
@@ -3996,12 +4164,20 @@ function useA2uiController(params) {
|
|
|
3996
4164
|
applyA2uiRuntimeEffects(result.effects);
|
|
3997
4165
|
setRuntimeState(result.state);
|
|
3998
4166
|
}, [conversationMessages, conversationId]);
|
|
3999
|
-
const
|
|
4167
|
+
const permanentDismissedSurfaceIds = React10.useMemo(
|
|
4168
|
+
() => extractDismissedSurfaceIdsFromMessages(conversationMessages || []),
|
|
4169
|
+
[conversationMessages]
|
|
4170
|
+
);
|
|
4171
|
+
const mergedDismissedSurfaceIds = React10.useMemo(
|
|
4172
|
+
() => Array.from(/* @__PURE__ */ new Set([...dismissedSurfaceIds || [], ...permanentDismissedSurfaceIds])),
|
|
4173
|
+
[dismissedSurfaceIds, permanentDismissedSurfaceIds]
|
|
4174
|
+
);
|
|
4175
|
+
const view = React10.useMemo(() => selectA2uiRuntimeView(runtimeState, mergedDismissedSurfaceIds), [runtimeState, mergedDismissedSurfaceIds]);
|
|
4000
4176
|
const handleRuntimeAction = React10.useCallback((payload) => {
|
|
4001
4177
|
const surfaceId = String(payload?.surfaceId || payload?.cardId || "");
|
|
4002
4178
|
const name = String(payload?.name || payload?.event?.name || "").trim();
|
|
4003
4179
|
const rawContext = payload?.context || payload?.event?.context || {};
|
|
4004
|
-
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name
|
|
4180
|
+
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name});
|
|
4005
4181
|
if (runtimeActionResult.state !== runtimeRef.current) {
|
|
4006
4182
|
runtimeRef.current = runtimeActionResult.state;
|
|
4007
4183
|
setRuntimeState(runtimeActionResult.state);
|
|
@@ -4028,26 +4204,26 @@ var A2uiRuntimeContext = React10__namespace.default.createContext({
|
|
|
4028
4204
|
function useA2uiRuntimeView() {
|
|
4029
4205
|
return React10__namespace.default.useContext(A2uiRuntimeContext);
|
|
4030
4206
|
}
|
|
4031
|
-
function A2uiMessageCards({ messageIndex }) {
|
|
4207
|
+
function A2uiMessageCards({ messageIndex, message: message2 }) {
|
|
4032
4208
|
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
4033
|
-
const
|
|
4209
|
+
const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
|
|
4210
|
+
const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
|
|
4211
|
+
const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
|
|
4034
4212
|
if (!surfaceIds.length) return null;
|
|
4035
4213
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
|
|
4036
4214
|
}
|
|
4037
4215
|
|
|
4038
4216
|
// src/components/CustomComponents/A2uiRuntime/renderer/protocol.ts
|
|
4039
|
-
function
|
|
4217
|
+
function isSubmitLikeActionName(name) {
|
|
4040
4218
|
const normalized = String(name || "").trim();
|
|
4041
4219
|
return normalized === "submit" || normalized === "confirm" || normalized.startsWith("submit_") || normalized.endsWith(".confirm");
|
|
4042
4220
|
}
|
|
4043
|
-
function
|
|
4221
|
+
function isCancelLikeActionName(name) {
|
|
4044
4222
|
const normalized = String(name || "").trim();
|
|
4045
4223
|
return normalized === "cancel" || normalized === "qf.cancel" || normalized.endsWith(".cancel");
|
|
4046
4224
|
}
|
|
4047
4225
|
function shouldDismissA2uiSurface(name, context) {
|
|
4048
|
-
|
|
4049
|
-
if (name === "qf.submit" || name === "qf.cancel") return true;
|
|
4050
|
-
return context?.submit === true;
|
|
4226
|
+
return true;
|
|
4051
4227
|
}
|
|
4052
4228
|
function normalizeA2uiActionPayload(payload) {
|
|
4053
4229
|
return {
|
|
@@ -4081,7 +4257,7 @@ function isQuestionActionPayload(payload) {
|
|
|
4081
4257
|
const mode = payload.context?.form_mode;
|
|
4082
4258
|
if (payload.name === "qf.submit" || payload.name === "qf.cancel") return true;
|
|
4083
4259
|
if (payload.name.startsWith("qf.")) return true;
|
|
4084
|
-
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ?
|
|
4260
|
+
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ? isSubmitLikeActionName(payload.name) || isCancelLikeActionName(payload.name) : false;
|
|
4085
4261
|
}
|
|
4086
4262
|
function formatActionValue(value, displayOverride) {
|
|
4087
4263
|
if (typeof displayOverride === "string" && displayOverride.trim()) return displayOverride.trim();
|
|
@@ -4091,7 +4267,7 @@ function formatActionValue(value, displayOverride) {
|
|
|
4091
4267
|
return String(value);
|
|
4092
4268
|
}
|
|
4093
4269
|
function buildQuestionSummary(payload) {
|
|
4094
|
-
if (
|
|
4270
|
+
if (isCancelLikeActionName(payload.name)) return "Question: \u5DF2\u53D6\u6D88";
|
|
4095
4271
|
const values = payload.context.values && typeof payload.context.values === "object" && !Array.isArray(payload.context.values) ? payload.context.values : payload.context;
|
|
4096
4272
|
const labels = payload.context.labels && typeof payload.context.labels === "object" && !Array.isArray(payload.context.labels) ? payload.context.labels : {};
|
|
4097
4273
|
const valueLabels = payload.context.valueLabels && typeof payload.context.valueLabels === "object" && !Array.isArray(payload.context.valueLabels) ? payload.context.valueLabels : {};
|
|
@@ -4113,10 +4289,22 @@ function formatA2uiActionDisplayText(payload) {
|
|
|
4113
4289
|
back_to_params: "\u5DF2\u8FD4\u56DE\u4FEE\u6539\u53C2\u6570",
|
|
4114
4290
|
confirm: "\u5DF2\u786E\u8BA4\u521B\u5EFA"
|
|
4115
4291
|
};
|
|
4116
|
-
|
|
4292
|
+
let actionLabel = actionLabels[payload.name];
|
|
4293
|
+
if (!actionLabel) {
|
|
4294
|
+
if (payload.name.startsWith("confirm_")) {
|
|
4295
|
+
actionLabel = "\u5DF2\u9009\u62E9";
|
|
4296
|
+
} else if (payload.name.startsWith("submit_")) {
|
|
4297
|
+
actionLabel = "\u5DF2\u63D0\u4EA4";
|
|
4298
|
+
} else {
|
|
4299
|
+
actionLabel = `\u5DF2\u63D0\u4EA4\u52A8\u4F5C (${payload.name})`;
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
const isConfirmLike = payload.name.startsWith("confirm_");
|
|
4117
4303
|
const details = Object.entries(values).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([key, value]) => {
|
|
4304
|
+
const formatted = formatActionValue(value, valueLabels[key]);
|
|
4305
|
+
if (isConfirmLike) return formatted;
|
|
4118
4306
|
const label = typeof labels[key] === "string" && String(labels[key]).trim() ? String(labels[key]).trim() : key;
|
|
4119
|
-
return `${label}: ${
|
|
4307
|
+
return `${label}: ${formatted}`;
|
|
4120
4308
|
});
|
|
4121
4309
|
return details.length ? `${actionLabel}\uFF1A${details.join("\uFF1B ")}` : actionLabel;
|
|
4122
4310
|
}
|
|
@@ -4214,66 +4402,46 @@ function readContextModelPath(context) {
|
|
|
4214
4402
|
const path = context?.model && typeof context.model === "object" ? context.model.path : "";
|
|
4215
4403
|
return typeof path === "string" ? path.trim() : "";
|
|
4216
4404
|
}
|
|
4217
|
-
function
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
const nextCursors = [];
|
|
4222
|
-
const pendingItems = [];
|
|
4223
|
-
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
4224
|
-
const message2 = messages[messageIndex];
|
|
4225
|
-
const messageId = String(message2?.messageId ?? messageIndex);
|
|
4405
|
+
function buildLatestCommandIndexBySurface(messages) {
|
|
4406
|
+
const indexBySurface = {};
|
|
4407
|
+
let commandIndex = -1;
|
|
4408
|
+
for (const message2 of messages) {
|
|
4226
4409
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4227
|
-
const
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4410
|
+
for (const item of items) {
|
|
4411
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4412
|
+
commandIndex += 1;
|
|
4413
|
+
const surfaceId = extractSurfaceId3(item.command);
|
|
4414
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4415
|
+
continue;
|
|
4416
|
+
}
|
|
4417
|
+
if (item?.type === "text") {
|
|
4418
|
+
const text = item.messageContent || item.text || "";
|
|
4419
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
4420
|
+
const tags = parseA2uiTagsFromText(text);
|
|
4421
|
+
for (const tag of tags) {
|
|
4422
|
+
for (const cmd of tag.commands) {
|
|
4423
|
+
commandIndex += 1;
|
|
4424
|
+
const surfaceId = extractSurfaceId3(cmd);
|
|
4425
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
}
|
|
4234
4429
|
}
|
|
4235
|
-
nextCursors.push({ messageId, contentLength: items.length });
|
|
4236
4430
|
}
|
|
4237
|
-
return
|
|
4431
|
+
return indexBySurface;
|
|
4238
4432
|
}
|
|
4239
4433
|
function A2uiRuntimeProvider({ messages, children }) {
|
|
4240
4434
|
const chatStore = useChatStore();
|
|
4241
4435
|
const conversationState = valtio.useSnapshot(chatStore.conversation);
|
|
4242
4436
|
const conversationId = conversationState.active.id;
|
|
4243
|
-
const processedMessageCursorsRef = React10__namespace.default.useRef([]);
|
|
4244
|
-
const latestCommandIndexBySurfaceRef = React10__namespace.default.useRef({});
|
|
4245
|
-
const commandIndexRef = React10__namespace.default.useRef(-1);
|
|
4246
4437
|
const [latestCommandIndexBySurface, setLatestCommandIndexBySurface] = React10__namespace.default.useState({});
|
|
4247
4438
|
const [dismissedAtBySurface, setDismissedAtBySurface] = React10__namespace.default.useState({});
|
|
4248
4439
|
React10__namespace.default.useEffect(() => {
|
|
4249
|
-
processedMessageCursorsRef.current = [];
|
|
4250
|
-
latestCommandIndexBySurfaceRef.current = {};
|
|
4251
|
-
commandIndexRef.current = -1;
|
|
4252
4440
|
setLatestCommandIndexBySurface({});
|
|
4253
4441
|
setDismissedAtBySurface({});
|
|
4254
4442
|
}, [conversationId]);
|
|
4255
4443
|
React10__namespace.default.useEffect(() => {
|
|
4256
|
-
|
|
4257
|
-
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2) => {
|
|
4258
|
-
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4259
|
-
return items.map((item) => ({ item }));
|
|
4260
|
-
}) : pendingItems;
|
|
4261
|
-
if (!shouldReplayAll && itemsToProcess.length === 0) return;
|
|
4262
|
-
const nextLatestCommandIndexBySurface = shouldReplayAll ? {} : { ...latestCommandIndexBySurfaceRef.current };
|
|
4263
|
-
let nextCommandIndex = shouldReplayAll ? -1 : commandIndexRef.current;
|
|
4264
|
-
itemsToProcess.forEach(({ item }) => {
|
|
4265
|
-
if (item?.type !== "a2uiCommand" || !item.command) return;
|
|
4266
|
-
nextCommandIndex += 1;
|
|
4267
|
-
const surfaceId = extractSurfaceId3(item.command);
|
|
4268
|
-
if (surfaceId) nextLatestCommandIndexBySurface[surfaceId] = nextCommandIndex;
|
|
4269
|
-
});
|
|
4270
|
-
processedMessageCursorsRef.current = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
4271
|
-
messageId: String(message2?.messageId ?? messageIndex),
|
|
4272
|
-
contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
|
|
4273
|
-
})) : nextCursors;
|
|
4274
|
-
latestCommandIndexBySurfaceRef.current = nextLatestCommandIndexBySurface;
|
|
4275
|
-
commandIndexRef.current = nextCommandIndex;
|
|
4276
|
-
setLatestCommandIndexBySurface(nextLatestCommandIndexBySurface);
|
|
4444
|
+
setLatestCommandIndexBySurface(buildLatestCommandIndexBySurface(messages));
|
|
4277
4445
|
}, [messages]);
|
|
4278
4446
|
const dismissedSurfaceIds = React10__namespace.default.useMemo(() => {
|
|
4279
4447
|
return Object.entries(dismissedAtBySurface).filter(([surfaceId, dismissedAt]) => (latestCommandIndexBySurface[surfaceId] ?? -1) <= dismissedAt).map(([surfaceId]) => surfaceId);
|
|
@@ -4402,14 +4570,37 @@ function QuestionSummary({ content }) {
|
|
|
4402
4570
|
] });
|
|
4403
4571
|
}
|
|
4404
4572
|
var TextNode2 = React10__namespace.default.memo(
|
|
4405
|
-
({
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4573
|
+
({
|
|
4574
|
+
item,
|
|
4575
|
+
role,
|
|
4576
|
+
customComponents,
|
|
4577
|
+
message: message2,
|
|
4578
|
+
messageIndex = -1
|
|
4579
|
+
}) => {
|
|
4580
|
+
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
4581
|
+
const rawContent = toA2uiDisplayText(role, item?.messageContent);
|
|
4582
|
+
const segments = splitA2uiTextSegments(rawContent);
|
|
4583
|
+
const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
|
|
4584
|
+
const firstSeg = segments[0];
|
|
4585
|
+
const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
|
|
4586
|
+
if (isPureText) {
|
|
4587
|
+
const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
|
|
4588
|
+
if (typeof content === "string" && content.startsWith("Question:")) {
|
|
4589
|
+
return /* @__PURE__ */ jsxRuntime.jsx(QuestionSummary, { content });
|
|
4590
|
+
}
|
|
4591
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4592
|
+
!!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4593
|
+
!!content && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content })
|
|
4594
|
+
] });
|
|
4409
4595
|
}
|
|
4410
4596
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4411
4597
|
!!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4412
|
-
|
|
4598
|
+
segments.map((seg, i) => {
|
|
4599
|
+
if (seg.type === "text") {
|
|
4600
|
+
return seg.content.trim() ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
|
|
4601
|
+
}
|
|
4602
|
+
return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
|
|
4603
|
+
})
|
|
4413
4604
|
] });
|
|
4414
4605
|
}
|
|
4415
4606
|
);
|
|
@@ -4637,6 +4828,12 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4637
4828
|
if (item.type === "plan") {
|
|
4638
4829
|
return !shouldHideA2uiPlan(item);
|
|
4639
4830
|
}
|
|
4831
|
+
if (item.type === "text") {
|
|
4832
|
+
const rawText = item.messageContent || item.text || "";
|
|
4833
|
+
const visibleText = stripA2uiTags(rawText);
|
|
4834
|
+
const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
|
|
4835
|
+
return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
|
|
4836
|
+
}
|
|
4640
4837
|
return true;
|
|
4641
4838
|
});
|
|
4642
4839
|
}, [loading, message2.content]);
|
|
@@ -4665,7 +4862,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4665
4862
|
content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4666
4863
|
item.type === "runStarted" && /* @__PURE__ */ jsxRuntime.jsx(RunStartedNode, { loading }, `flow-start-${index}`),
|
|
4667
4864
|
(item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsxRuntime.jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
|
|
4668
|
-
item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message2.role, customComponents, message: message2 }, `message-${index}`),
|
|
4865
|
+
item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
|
|
4669
4866
|
item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
|
|
4670
4867
|
item.type === "files" && /* @__PURE__ */ jsxRuntime.jsx(FilesNode, { item }, `files-${index}`),
|
|
4671
4868
|
item.type === "plan" && /* @__PURE__ */ jsxRuntime.jsx(A2uiPlanNode, { item }, `plan-${index}`)
|
|
@@ -4675,7 +4872,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4675
4872
|
);
|
|
4676
4873
|
}),
|
|
4677
4874
|
quoteMsg && /* @__PURE__ */ jsxRuntime.jsx(QuoteMsgNode, { quoteMsg, role }),
|
|
4678
|
-
messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex }) : null
|
|
4875
|
+
messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
|
|
4679
4876
|
] });
|
|
4680
4877
|
});
|
|
4681
4878
|
var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
|