@webless/agent 0.2.14 → 0.3.0
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/README.md +26 -0
- package/dist/{chunk-6FNE65AR.js → chunk-MRSLWREA.js} +650 -251
- package/dist/chunk-MRSLWREA.js.map +1 -0
- package/dist/embed.cjs +722 -294
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +199 -21
- package/dist/embed.css.map +1 -1
- package/dist/embed.d.cts +3 -31
- package/dist/embed.d.ts +3 -31
- package/dist/embed.js +33 -3
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +123 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +123 -12
- package/dist/index.js.map +1 -1
- package/dist/manifest-oc_3zCSC.d.cts +79 -0
- package/dist/manifest-oc_3zCSC.d.ts +79 -0
- package/dist/react.cjs +684 -304
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +199 -21
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +12 -5
- package/dist/react.d.ts +12 -5
- package/dist/react.js +2 -19
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6FNE65AR.js.map +0 -1
- package/dist/placement-CXW_83AF.d.cts +0 -25
- package/dist/placement-CXW_83AF.d.ts +0 -25
package/dist/react.cjs
CHANGED
|
@@ -34,10 +34,90 @@ __export(react_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(react_exports);
|
|
35
35
|
|
|
36
36
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
37
|
-
var
|
|
37
|
+
var import_react6 = require("react");
|
|
38
38
|
|
|
39
|
-
// src/react/
|
|
39
|
+
// src/react/page-shift.ts
|
|
40
40
|
var import_react = require("react");
|
|
41
|
+
var PAGE_SHIFT_CLASS = "webless-agent-page-shift";
|
|
42
|
+
var DEFAULT_RAIL_WIDTH_PX = 450;
|
|
43
|
+
function shouldApplyPageShift(input) {
|
|
44
|
+
return input.pageShift && !input.isMobile && !input.railCollapsed && !input.railExpanded;
|
|
45
|
+
}
|
|
46
|
+
function resolvePageShiftWidth(railWidth) {
|
|
47
|
+
if (typeof railWidth === "number" && railWidth > 0) {
|
|
48
|
+
return railWidth;
|
|
49
|
+
}
|
|
50
|
+
if (typeof document !== "undefined") {
|
|
51
|
+
const token = getComputedStyle(document.documentElement).getPropertyValue("--as-rail-max-width").trim();
|
|
52
|
+
const parsed = Number.parseFloat(token);
|
|
53
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
54
|
+
return parsed;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return DEFAULT_RAIL_WIDTH_PX;
|
|
58
|
+
}
|
|
59
|
+
var savedPageMargin = null;
|
|
60
|
+
function readPageMarginSnapshot(style) {
|
|
61
|
+
return {
|
|
62
|
+
value: style.getPropertyValue("margin-right"),
|
|
63
|
+
priority: style.getPropertyPriority("margin-right")
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function restorePageMargin(style, snapshot) {
|
|
67
|
+
if (snapshot.value) {
|
|
68
|
+
style.setProperty("margin-right", snapshot.value, snapshot.priority || void 0);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
style.removeProperty("margin-right");
|
|
72
|
+
}
|
|
73
|
+
function snapshotPageMarginIfNeeded() {
|
|
74
|
+
if (savedPageMargin !== null) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
savedPageMargin = readPageMarginSnapshot(document.documentElement.style);
|
|
78
|
+
}
|
|
79
|
+
function setPageMargin(margin) {
|
|
80
|
+
snapshotPageMarginIfNeeded();
|
|
81
|
+
document.documentElement.style.setProperty("margin-right", margin, "important");
|
|
82
|
+
}
|
|
83
|
+
function clearPageMargin() {
|
|
84
|
+
if (savedPageMargin === null) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
restorePageMargin(document.documentElement.style, savedPageMargin);
|
|
88
|
+
savedPageMargin = null;
|
|
89
|
+
}
|
|
90
|
+
function usePageShift(input) {
|
|
91
|
+
const { active, railSlotRef } = input;
|
|
92
|
+
(0, import_react.useEffect)(() => {
|
|
93
|
+
if (typeof document === "undefined") {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!active) {
|
|
97
|
+
document.documentElement.classList.remove(PAGE_SHIFT_CLASS);
|
|
98
|
+
clearPageMargin();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
document.documentElement.classList.add(PAGE_SHIFT_CLASS);
|
|
102
|
+
function applyMargin() {
|
|
103
|
+
const rail = railSlotRef.current?.querySelector(".agent-rail");
|
|
104
|
+
const width = resolvePageShiftWidth(
|
|
105
|
+
rail instanceof HTMLElement ? rail.offsetWidth : null
|
|
106
|
+
);
|
|
107
|
+
setPageMargin(`${width}px`);
|
|
108
|
+
}
|
|
109
|
+
applyMargin();
|
|
110
|
+
const frame = requestAnimationFrame(applyMargin);
|
|
111
|
+
return () => {
|
|
112
|
+
cancelAnimationFrame(frame);
|
|
113
|
+
document.documentElement.classList.remove(PAGE_SHIFT_CLASS);
|
|
114
|
+
clearPageMargin();
|
|
115
|
+
};
|
|
116
|
+
}, [active, railSlotRef]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/react/hooks/useAgentChat.ts
|
|
120
|
+
var import_react2 = require("react");
|
|
41
121
|
|
|
42
122
|
// src/runtime/client.ts
|
|
43
123
|
var import_client2 = require("eve/client");
|
|
@@ -255,9 +335,8 @@ function clearPersistedAgentSession(visitorSessionId, options) {
|
|
|
255
335
|
function isTurnBoundary(event) {
|
|
256
336
|
return event.type === "session.waiting" || event.type === "session.completed" || event.type === "session.failed";
|
|
257
337
|
}
|
|
258
|
-
function applyMessageEvent(event, rendered, handlers) {
|
|
259
|
-
|
|
260
|
-
if (step) handlers.onStep?.(step.label, step.detail);
|
|
338
|
+
function applyMessageEvent(event, rendered, handlers, workItems) {
|
|
339
|
+
applyWorkEvent(event, handlers, workItems);
|
|
261
340
|
if (event.type === "session.failed") {
|
|
262
341
|
throw new Error(event.data.message || event.data.code);
|
|
263
342
|
}
|
|
@@ -300,13 +379,120 @@ function renderTurn(events) {
|
|
|
300
379
|
}
|
|
301
380
|
return rendered;
|
|
302
381
|
}
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
382
|
+
function emitWorkItem(item, handlers, workItems) {
|
|
383
|
+
workItems.set(item.id, item);
|
|
384
|
+
handlers.onWork?.(item);
|
|
385
|
+
handlers.onStep?.(item.label, item.detail);
|
|
386
|
+
}
|
|
387
|
+
function completePlanning(handlers, workItems) {
|
|
388
|
+
const planning = workItems.get("planning");
|
|
389
|
+
if (!planning || planning.state !== "active") return;
|
|
390
|
+
emitWorkItem(
|
|
391
|
+
{
|
|
392
|
+
...planning,
|
|
393
|
+
detail: "Picked the best way to help",
|
|
394
|
+
state: "completed"
|
|
395
|
+
},
|
|
396
|
+
handlers,
|
|
397
|
+
workItems
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
function specialistNameFromInput(input) {
|
|
401
|
+
const message = input.message;
|
|
402
|
+
if (typeof message !== "string") return void 0;
|
|
403
|
+
const match = /^Webless-Agent-Name:\s*(.+)$/imu.exec(message);
|
|
404
|
+
return match?.[1]?.trim() || void 0;
|
|
405
|
+
}
|
|
406
|
+
function requestedWorkItem(action) {
|
|
407
|
+
if (action.kind === "tool-call" && action.toolName === "search_discovery") {
|
|
408
|
+
return {
|
|
409
|
+
id: action.callId,
|
|
410
|
+
kind: "search",
|
|
411
|
+
label: "Search & Discovery",
|
|
412
|
+
detail: "Searching this site",
|
|
413
|
+
state: "active"
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (action.kind === "subagent-call" || action.kind === "remote-agent-call" || action.kind === "tool-call" && action.toolName === "agent") {
|
|
417
|
+
const name = specialistNameFromInput(action.input) ?? "Specialist";
|
|
418
|
+
return {
|
|
419
|
+
id: action.callId,
|
|
420
|
+
kind: "specialist",
|
|
421
|
+
label: name,
|
|
422
|
+
detail: "Reviewing your question",
|
|
423
|
+
state: "active"
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
function applyWorkEvent(event, handlers, workItems) {
|
|
429
|
+
if (event.type === "step.started" && workItems.size === 0) {
|
|
430
|
+
emitWorkItem(
|
|
431
|
+
{
|
|
432
|
+
id: "planning",
|
|
433
|
+
kind: "planning",
|
|
434
|
+
label: "Understanding your question",
|
|
435
|
+
state: "active"
|
|
436
|
+
},
|
|
437
|
+
handlers,
|
|
438
|
+
workItems
|
|
439
|
+
);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (event.type === "actions.requested") {
|
|
443
|
+
completePlanning(handlers, workItems);
|
|
444
|
+
for (const action of event.data.actions) {
|
|
445
|
+
const item = requestedWorkItem(action);
|
|
446
|
+
if (item) emitWorkItem(item, handlers, workItems);
|
|
447
|
+
}
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (event.type === "subagent.called") {
|
|
451
|
+
completePlanning(handlers, workItems);
|
|
452
|
+
const current2 = workItems.get(event.data.callId);
|
|
453
|
+
if (!current2) {
|
|
454
|
+
emitWorkItem(
|
|
455
|
+
{
|
|
456
|
+
id: event.data.callId,
|
|
457
|
+
kind: "specialist",
|
|
458
|
+
label: event.data.name || "Specialist",
|
|
459
|
+
detail: "Reviewing your question",
|
|
460
|
+
state: "active"
|
|
461
|
+
},
|
|
462
|
+
handlers,
|
|
463
|
+
workItems
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (event.type === "subagent.completed") {
|
|
469
|
+
const current2 = workItems.get(event.data.callId);
|
|
470
|
+
if (!current2) return;
|
|
471
|
+
emitWorkItem(
|
|
472
|
+
{
|
|
473
|
+
...current2,
|
|
474
|
+
detail: "Guidance received",
|
|
475
|
+
state: "completed"
|
|
476
|
+
},
|
|
477
|
+
handlers,
|
|
478
|
+
workItems
|
|
479
|
+
);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (event.type !== "action.result") return;
|
|
483
|
+
const { result, status } = event.data;
|
|
484
|
+
const current = workItems.get(result.callId);
|
|
485
|
+
if (!current) return;
|
|
486
|
+
const failed = status !== "completed" || result.isError === true;
|
|
487
|
+
emitWorkItem(
|
|
488
|
+
{
|
|
489
|
+
...current,
|
|
490
|
+
detail: failed ? "Couldn\u2019t complete; continuing with available information" : current.kind === "search" ? "Found relevant site content" : "Guidance received",
|
|
491
|
+
state: failed ? "error" : "completed"
|
|
492
|
+
},
|
|
493
|
+
handlers,
|
|
494
|
+
workItems
|
|
495
|
+
);
|
|
310
496
|
}
|
|
311
497
|
var AgentSession = class {
|
|
312
498
|
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, getUnpublishedPreviewGrant) {
|
|
@@ -424,10 +610,11 @@ var AgentSession = class {
|
|
|
424
610
|
this.activeResponse = response;
|
|
425
611
|
let streamIndex = session?.state.streamIndex ?? 0;
|
|
426
612
|
let rendered = "";
|
|
613
|
+
const workItems = /* @__PURE__ */ new Map();
|
|
427
614
|
try {
|
|
428
615
|
for await (const event of response) {
|
|
429
616
|
if (signal.aborted) break;
|
|
430
|
-
rendered = applyMessageEvent(event, rendered, handlers);
|
|
617
|
+
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
431
618
|
streamIndex += 1;
|
|
432
619
|
if (session) {
|
|
433
620
|
savePersistedAgentSession(
|
|
@@ -469,6 +656,10 @@ var AgentSession = class {
|
|
|
469
656
|
return null;
|
|
470
657
|
}
|
|
471
658
|
let rendered = renderTurn(turnEvents);
|
|
659
|
+
const workItems = /* @__PURE__ */ new Map();
|
|
660
|
+
for (const event of turnEvents) {
|
|
661
|
+
applyWorkEvent(event, handlers, workItems);
|
|
662
|
+
}
|
|
472
663
|
if (rendered.startsWith(initialText)) {
|
|
473
664
|
const missedText = rendered.slice(initialText.length);
|
|
474
665
|
if (missedText) handlers.onDelta(missedText);
|
|
@@ -503,7 +694,7 @@ var AgentSession = class {
|
|
|
503
694
|
let streamIndex = snapshot.session.streamIndex;
|
|
504
695
|
for await (const event of session.stream({ signal })) {
|
|
505
696
|
if (signal.aborted) break;
|
|
506
|
-
rendered = applyMessageEvent(event, rendered, handlers);
|
|
697
|
+
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
507
698
|
streamIndex += 1;
|
|
508
699
|
savePersistedAgentSession(
|
|
509
700
|
this.visitorSessionId,
|
|
@@ -656,57 +847,54 @@ function clearPersistedAgentConversation(storageKeyPrefix, visitorSessionId) {
|
|
|
656
847
|
}
|
|
657
848
|
|
|
658
849
|
// src/react/hooks/useAgentChat.ts
|
|
659
|
-
var
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
850
|
+
var DEFAULT_GREETING = "Hi! I can search this site or bring in a specialist when it helps. What would you like to know?";
|
|
851
|
+
function createInitialState(greeting = DEFAULT_GREETING) {
|
|
852
|
+
return {
|
|
853
|
+
phase: "idle",
|
|
854
|
+
messages: [
|
|
855
|
+
{
|
|
856
|
+
id: "greeting",
|
|
857
|
+
role: "agent",
|
|
858
|
+
text: greeting,
|
|
859
|
+
createdAt: 0
|
|
860
|
+
}
|
|
861
|
+
],
|
|
862
|
+
toolSteps: [],
|
|
863
|
+
journey: null,
|
|
864
|
+
followUps: [],
|
|
865
|
+
streamingText: "",
|
|
866
|
+
error: null
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function stateFromConversation(conversation, initialState) {
|
|
870
|
+
if (!conversation || conversation.messages.length === 0) return initialState;
|
|
676
871
|
return {
|
|
677
|
-
...
|
|
872
|
+
...initialState,
|
|
678
873
|
messages: conversation.messages,
|
|
679
874
|
phase: conversation.pending ? conversation.streamingText ? "streaming" : "thinking" : "complete",
|
|
680
875
|
streamingText: conversation.streamingText
|
|
681
876
|
};
|
|
682
877
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
reject(new DOMException("Aborted", "AbortError"));
|
|
695
|
-
},
|
|
696
|
-
{ once: true }
|
|
697
|
-
);
|
|
698
|
-
});
|
|
878
|
+
function upsertToolStep(steps, item) {
|
|
879
|
+
const next = {
|
|
880
|
+
id: item.id,
|
|
881
|
+
kind: item.kind,
|
|
882
|
+
label: item.label,
|
|
883
|
+
state: item.state,
|
|
884
|
+
...item.detail ? { detail: item.detail } : {}
|
|
885
|
+
};
|
|
886
|
+
const index = steps.findIndex((step) => step.id === item.id);
|
|
887
|
+
if (index < 0) return [...steps, next];
|
|
888
|
+
return steps.map((step, stepIndex) => stepIndex === index ? next : step);
|
|
699
889
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
await delay(item.ms, signal);
|
|
709
|
-
}
|
|
890
|
+
function completeActivePlanning(steps) {
|
|
891
|
+
return steps.map(
|
|
892
|
+
(step) => step.kind === "planning" && step.state === "active" ? {
|
|
893
|
+
...step,
|
|
894
|
+
detail: "Prepared a response",
|
|
895
|
+
state: "completed"
|
|
896
|
+
} : step
|
|
897
|
+
);
|
|
710
898
|
}
|
|
711
899
|
function useAgentChat({
|
|
712
900
|
customerId,
|
|
@@ -715,9 +903,14 @@ function useAgentChat({
|
|
|
715
903
|
version,
|
|
716
904
|
runtimeOrigin,
|
|
717
905
|
visitorSessionId,
|
|
718
|
-
storageKeyPrefix
|
|
906
|
+
storageKeyPrefix,
|
|
907
|
+
greeting
|
|
719
908
|
}) {
|
|
720
|
-
const
|
|
909
|
+
const initialState = (0, import_react2.useMemo)(
|
|
910
|
+
() => createInitialState(greeting?.trim() || DEFAULT_GREETING),
|
|
911
|
+
[greeting]
|
|
912
|
+
);
|
|
913
|
+
const previewGrantProviderRef = (0, import_react2.useRef)(getUnpublishedPreviewGrant);
|
|
721
914
|
previewGrantProviderRef.current = getUnpublishedPreviewGrant;
|
|
722
915
|
const resolveUnpublishedPreviewGrant = () => {
|
|
723
916
|
const provider = previewGrantProviderRef.current;
|
|
@@ -730,7 +923,7 @@ function useAgentChat({
|
|
|
730
923
|
}
|
|
731
924
|
return provider();
|
|
732
925
|
};
|
|
733
|
-
const resolvedStorageKeyPrefix = (0,
|
|
926
|
+
const resolvedStorageKeyPrefix = (0, import_react2.useMemo)(
|
|
734
927
|
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({
|
|
735
928
|
customerId,
|
|
736
929
|
indexId,
|
|
@@ -739,19 +932,20 @@ function useAgentChat({
|
|
|
739
932
|
}),
|
|
740
933
|
[customerId, indexId, runtimeOrigin, storageKeyPrefix, version]
|
|
741
934
|
);
|
|
742
|
-
const visitorId = (0,
|
|
935
|
+
const visitorId = (0, import_react2.useMemo)(
|
|
743
936
|
() => visitorSessionId?.trim() || getOrCreateVisitorSessionId({
|
|
744
937
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
745
938
|
}),
|
|
746
939
|
[resolvedStorageKeyPrefix, visitorSessionId]
|
|
747
940
|
);
|
|
748
|
-
const [state, setState] = (0,
|
|
941
|
+
const [state, setState] = (0, import_react2.useState)(
|
|
749
942
|
() => stateFromConversation(
|
|
750
|
-
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
|
|
943
|
+
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId),
|
|
944
|
+
initialState
|
|
751
945
|
)
|
|
752
946
|
);
|
|
753
|
-
const runRef = (0,
|
|
754
|
-
const clientRef = (0,
|
|
947
|
+
const runRef = (0, import_react2.useRef)(null);
|
|
948
|
+
const clientRef = (0, import_react2.useRef)(
|
|
755
949
|
createAgentClient({
|
|
756
950
|
customerId,
|
|
757
951
|
getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
|
|
@@ -762,9 +956,9 @@ function useAgentChat({
|
|
|
762
956
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
763
957
|
})
|
|
764
958
|
);
|
|
765
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
766
|
-
const identityRef = (0,
|
|
767
|
-
(0,
|
|
959
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
960
|
+
const identityRef = (0, import_react2.useRef)(identityKey);
|
|
961
|
+
(0, import_react2.useEffect)(() => {
|
|
768
962
|
if (identityRef.current === identityKey) {
|
|
769
963
|
return;
|
|
770
964
|
}
|
|
@@ -782,19 +976,21 @@ function useAgentChat({
|
|
|
782
976
|
});
|
|
783
977
|
setState(
|
|
784
978
|
stateFromConversation(
|
|
785
|
-
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
|
|
979
|
+
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId),
|
|
980
|
+
initialState
|
|
786
981
|
)
|
|
787
982
|
);
|
|
788
983
|
}, [
|
|
789
984
|
customerId,
|
|
790
985
|
identityKey,
|
|
791
986
|
indexId,
|
|
987
|
+
initialState,
|
|
792
988
|
runtimeOrigin,
|
|
793
989
|
resolvedStorageKeyPrefix,
|
|
794
990
|
version,
|
|
795
991
|
visitorId
|
|
796
992
|
]);
|
|
797
|
-
(0,
|
|
993
|
+
(0, import_react2.useEffect)(() => {
|
|
798
994
|
if (!hasVisitorMessages(state.messages)) return;
|
|
799
995
|
savePersistedAgentConversation(resolvedStorageKeyPrefix, visitorId, {
|
|
800
996
|
messages: state.messages,
|
|
@@ -808,14 +1004,14 @@ function useAgentChat({
|
|
|
808
1004
|
state.streamingText,
|
|
809
1005
|
visitorId
|
|
810
1006
|
]);
|
|
811
|
-
const reset = (0,
|
|
1007
|
+
const reset = (0, import_react2.useCallback)(() => {
|
|
812
1008
|
runRef.current?.abort();
|
|
813
1009
|
runRef.current = null;
|
|
814
1010
|
clientRef.current.reset();
|
|
815
1011
|
clearPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId);
|
|
816
|
-
setState(
|
|
817
|
-
}, [resolvedStorageKeyPrefix, visitorId]);
|
|
818
|
-
const runTurn = (0,
|
|
1012
|
+
setState(initialState);
|
|
1013
|
+
}, [initialState, resolvedStorageKeyPrefix, visitorId]);
|
|
1014
|
+
const runTurn = (0, import_react2.useCallback)(
|
|
819
1015
|
async (input) => {
|
|
820
1016
|
const { controller, initialText = "", resume, visitorText } = input;
|
|
821
1017
|
const { signal } = controller;
|
|
@@ -823,35 +1019,23 @@ function useAgentChat({
|
|
|
823
1019
|
try {
|
|
824
1020
|
let streamStarted = Boolean(initialText);
|
|
825
1021
|
let streamed = initialText;
|
|
826
|
-
const planningPromise = resume ? Promise.resolve() : runStatusSequence(signal, (step) => {
|
|
827
|
-
if (streamStarted || !isActiveRun()) return;
|
|
828
|
-
setState((prev) => ({
|
|
829
|
-
...prev,
|
|
830
|
-
phase: "running-tools",
|
|
831
|
-
toolSteps: [step]
|
|
832
|
-
}));
|
|
833
|
-
});
|
|
834
1022
|
const handlers = {
|
|
835
|
-
|
|
836
|
-
if (
|
|
1023
|
+
onWork: (item) => {
|
|
1024
|
+
if (!isActiveRun()) return;
|
|
837
1025
|
setState((prev) => ({
|
|
838
1026
|
...prev,
|
|
839
|
-
phase: "running-tools",
|
|
840
|
-
toolSteps:
|
|
841
|
-
{ id: `step-${label}`, label, detail, state: "active" }
|
|
842
|
-
]
|
|
1027
|
+
phase: item.state === "active" ? "running-tools" : prev.phase,
|
|
1028
|
+
toolSteps: upsertToolStep(prev.toolSteps, item)
|
|
843
1029
|
}));
|
|
844
1030
|
},
|
|
845
1031
|
onDelta: (delta) => {
|
|
846
1032
|
if (!isActiveRun()) return;
|
|
847
|
-
void planningPromise.catch(() => {
|
|
848
|
-
});
|
|
849
1033
|
if (!streamStarted) {
|
|
850
1034
|
streamStarted = true;
|
|
851
1035
|
setState((prev) => ({
|
|
852
1036
|
...prev,
|
|
853
1037
|
phase: "streaming",
|
|
854
|
-
toolSteps:
|
|
1038
|
+
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
855
1039
|
streamingText: ""
|
|
856
1040
|
}));
|
|
857
1041
|
}
|
|
@@ -879,8 +1063,6 @@ function useAgentChat({
|
|
|
879
1063
|
signal
|
|
880
1064
|
});
|
|
881
1065
|
}
|
|
882
|
-
await planningPromise.catch(() => {
|
|
883
|
-
});
|
|
884
1066
|
if (!isActiveRun() || finalText === null) return;
|
|
885
1067
|
const agentMessage = {
|
|
886
1068
|
id: `agent-${Date.now()}`,
|
|
@@ -892,7 +1074,7 @@ function useAgentChat({
|
|
|
892
1074
|
...prev,
|
|
893
1075
|
phase: "complete",
|
|
894
1076
|
messages: [...prev.messages, agentMessage],
|
|
895
|
-
toolSteps:
|
|
1077
|
+
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
896
1078
|
streamingText: "",
|
|
897
1079
|
followUps: [],
|
|
898
1080
|
journey: null
|
|
@@ -907,7 +1089,13 @@ function useAgentChat({
|
|
|
907
1089
|
setState((prev) => ({
|
|
908
1090
|
...prev,
|
|
909
1091
|
phase: "complete",
|
|
910
|
-
toolSteps:
|
|
1092
|
+
toolSteps: prev.toolSteps.map(
|
|
1093
|
+
(step) => step.state === "active" ? {
|
|
1094
|
+
...step,
|
|
1095
|
+
detail: "Couldn\u2019t complete this step",
|
|
1096
|
+
state: "error"
|
|
1097
|
+
} : step
|
|
1098
|
+
),
|
|
911
1099
|
streamingText: "",
|
|
912
1100
|
error: message
|
|
913
1101
|
}));
|
|
@@ -916,7 +1104,7 @@ function useAgentChat({
|
|
|
916
1104
|
},
|
|
917
1105
|
[]
|
|
918
1106
|
);
|
|
919
|
-
const submit = (0,
|
|
1107
|
+
const submit = (0, import_react2.useCallback)(
|
|
920
1108
|
async (visitorText) => {
|
|
921
1109
|
if (runRef.current) {
|
|
922
1110
|
runRef.current.abort();
|
|
@@ -935,7 +1123,12 @@ function useAgentChat({
|
|
|
935
1123
|
phase: "thinking",
|
|
936
1124
|
messages: [...prev.messages, visitorMessage],
|
|
937
1125
|
toolSteps: [
|
|
938
|
-
{
|
|
1126
|
+
{
|
|
1127
|
+
id: "planning",
|
|
1128
|
+
kind: "planning",
|
|
1129
|
+
label: "Understanding your question",
|
|
1130
|
+
state: "active"
|
|
1131
|
+
}
|
|
939
1132
|
],
|
|
940
1133
|
journey: null,
|
|
941
1134
|
followUps: [],
|
|
@@ -946,7 +1139,7 @@ function useAgentChat({
|
|
|
946
1139
|
},
|
|
947
1140
|
[runTurn]
|
|
948
1141
|
);
|
|
949
|
-
(0,
|
|
1142
|
+
(0, import_react2.useEffect)(() => {
|
|
950
1143
|
const conversation = loadPersistedAgentConversation(
|
|
951
1144
|
resolvedStorageKeyPrefix,
|
|
952
1145
|
visitorId
|
|
@@ -969,7 +1162,7 @@ function useAgentChat({
|
|
|
969
1162
|
controller.abort();
|
|
970
1163
|
};
|
|
971
1164
|
}, [identityKey, resolvedStorageKeyPrefix, runTurn, visitorId]);
|
|
972
|
-
(0,
|
|
1165
|
+
(0, import_react2.useEffect)(() => {
|
|
973
1166
|
return () => {
|
|
974
1167
|
runRef.current?.abort();
|
|
975
1168
|
runRef.current = null;
|
|
@@ -998,12 +1191,12 @@ function isAgentBusy(phase) {
|
|
|
998
1191
|
}
|
|
999
1192
|
|
|
1000
1193
|
// src/react/hooks/useIsMobile.ts
|
|
1001
|
-
var
|
|
1194
|
+
var import_react3 = require("react");
|
|
1002
1195
|
function useIsMobile(breakpoint = 767) {
|
|
1003
|
-
const [isMobile, setIsMobile] = (0,
|
|
1196
|
+
const [isMobile, setIsMobile] = (0, import_react3.useState)(
|
|
1004
1197
|
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
1005
1198
|
);
|
|
1006
|
-
(0,
|
|
1199
|
+
(0, import_react3.useEffect)(() => {
|
|
1007
1200
|
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1008
1201
|
const onChange = () => setIsMobile(media.matches);
|
|
1009
1202
|
onChange();
|
|
@@ -1040,81 +1233,95 @@ function unregisterAgentPanelController(customerId) {
|
|
|
1040
1233
|
}
|
|
1041
1234
|
|
|
1042
1235
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
1043
|
-
var
|
|
1236
|
+
var import_react5 = require("react");
|
|
1044
1237
|
|
|
1045
|
-
// src/react/
|
|
1238
|
+
// src/react/types/conversation.ts
|
|
1239
|
+
var defaultAgentRailTheme = {
|
|
1240
|
+
railMaxWidth: "450px",
|
|
1241
|
+
brand: "#6f16ff",
|
|
1242
|
+
brandSoft: "#f3edff",
|
|
1243
|
+
brandDeep: "#12043e",
|
|
1244
|
+
surface: "#ffffff",
|
|
1245
|
+
surfaceMuted: "#f4f6fb",
|
|
1246
|
+
text: "#171b2a",
|
|
1247
|
+
textMuted: "#5a6378",
|
|
1248
|
+
textSubtle: "#8a94a8",
|
|
1249
|
+
border: "rgb(42 51 70 / 0.1)",
|
|
1250
|
+
visitorBubble: "#6f16ff",
|
|
1251
|
+
visitorText: "#ffffff",
|
|
1252
|
+
success: "#18794e",
|
|
1253
|
+
danger: "#c94b63",
|
|
1254
|
+
fontBody: '"Mulish", "Avenir Next", "Segoe UI", sans-serif',
|
|
1255
|
+
fontDisplay: '"Space Grotesk", sans-serif'
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
1046
1259
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1047
|
-
function
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
if (active) return active;
|
|
1056
|
-
const error = steps.find((step) => step.state === "error");
|
|
1057
|
-
if (error) return error;
|
|
1058
|
-
const pending = steps.find((step) => step.state === "pending");
|
|
1059
|
-
if (pending) return pending;
|
|
1060
|
-
return steps.at(-1) ?? null;
|
|
1061
|
-
}
|
|
1062
|
-
function ToolTimeline({
|
|
1063
|
-
steps,
|
|
1064
|
-
streamingText,
|
|
1065
|
-
showStreaming = false,
|
|
1066
|
-
inline = false
|
|
1067
|
-
}) {
|
|
1068
|
-
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
1069
|
-
const currentStep = getCurrentStep(steps);
|
|
1070
|
-
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
1071
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1072
|
-
"div",
|
|
1073
|
-
{
|
|
1074
|
-
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
1075
|
-
role: "status",
|
|
1076
|
-
"aria-live": "polite",
|
|
1077
|
-
"aria-label": "Agent progress",
|
|
1078
|
-
children: [
|
|
1079
|
-
showStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status", children: [
|
|
1080
|
-
currentStep.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon agent-status__icon--error", "aria-hidden": "true", children: "!" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerIcon, {}) }),
|
|
1081
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status__copy", children: [
|
|
1082
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__label", children: currentStep.label }),
|
|
1083
|
-
currentStep.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
1084
|
-
] })
|
|
1085
|
-
] }, currentStep.id) : null,
|
|
1086
|
-
showStreaming && streamingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "tool-timeline__streaming-text", children: [
|
|
1087
|
-
streamingText,
|
|
1088
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
1089
|
-
] }) : null
|
|
1090
|
-
]
|
|
1091
|
-
}
|
|
1260
|
+
function workSummary(steps) {
|
|
1261
|
+
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1262
|
+
if (active?.kind === "specialist") return `Working with ${active.label}`;
|
|
1263
|
+
if (active?.kind === "search") return "Searching this site";
|
|
1264
|
+
if (active) return active.label;
|
|
1265
|
+
const hasError = steps.some((step) => step.state === "error");
|
|
1266
|
+
const specialists = steps.filter(
|
|
1267
|
+
(step) => step.kind === "specialist" && step.state === "completed"
|
|
1092
1268
|
);
|
|
1269
|
+
const searched = steps.some(
|
|
1270
|
+
(step) => step.kind === "search" && step.state === "completed"
|
|
1271
|
+
);
|
|
1272
|
+
if (hasError) return "Answered with available information";
|
|
1273
|
+
if (specialists.length > 1)
|
|
1274
|
+
return `Consulted ${specialists.length} specialists`;
|
|
1275
|
+
if (specialists.length === 1) return `Consulted ${specialists[0]?.label}`;
|
|
1276
|
+
if (searched) return "Searched this site";
|
|
1277
|
+
return "Prepared a response";
|
|
1093
1278
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
steps
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1279
|
+
function AgentActivityBubble({ steps }) {
|
|
1280
|
+
const active = steps.some((step) => step.state === "active");
|
|
1281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1283
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1284
|
+
"span",
|
|
1285
|
+
{
|
|
1286
|
+
className: `agent-activity-bubble__pulse${active ? " is-active" : ""}`,
|
|
1287
|
+
"aria-hidden": "true"
|
|
1288
|
+
}
|
|
1289
|
+
),
|
|
1290
|
+
workSummary(steps)
|
|
1291
|
+
] }),
|
|
1292
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "agent-activity-bubble__details", open: active, children: [
|
|
1293
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "Work details" }),
|
|
1294
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1295
|
+
"li",
|
|
1296
|
+
{
|
|
1297
|
+
className: "agent-activity-bubble__step",
|
|
1298
|
+
"data-state": step.state,
|
|
1299
|
+
children: [
|
|
1300
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1301
|
+
"span",
|
|
1302
|
+
{
|
|
1303
|
+
className: "agent-activity-bubble__step-icon",
|
|
1304
|
+
"aria-hidden": "true",
|
|
1305
|
+
children: step.state === "completed" ? "\u2713" : step.state === "error" ? "!" : ""
|
|
1306
|
+
}
|
|
1307
|
+
),
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: step.label }),
|
|
1310
|
+
step.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: step.detail }) : null
|
|
1311
|
+
] })
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
step.id
|
|
1315
|
+
)) })
|
|
1316
|
+
] })
|
|
1317
|
+
] });
|
|
1111
1318
|
}
|
|
1112
1319
|
|
|
1113
1320
|
// src/react/components/Composer/Composer.tsx
|
|
1114
|
-
var
|
|
1115
|
-
var
|
|
1321
|
+
var import_react4 = require("react");
|
|
1322
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1116
1323
|
function SendIcon() {
|
|
1117
|
-
return /* @__PURE__ */ (0,
|
|
1324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8 12V4M8 4l-3 3M8 4l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
1118
1325
|
}
|
|
1119
1326
|
function Composer({
|
|
1120
1327
|
disabled = false,
|
|
@@ -1122,8 +1329,8 @@ function Composer({
|
|
|
1122
1329
|
variant = "default",
|
|
1123
1330
|
onSubmit
|
|
1124
1331
|
}) {
|
|
1125
|
-
const [value, setValue] = (0,
|
|
1126
|
-
const inputRef = (0,
|
|
1332
|
+
const [value, setValue] = (0, import_react4.useState)("");
|
|
1333
|
+
const inputRef = (0, import_react4.useRef)(null);
|
|
1127
1334
|
function submitCurrent() {
|
|
1128
1335
|
const trimmed = value.trim();
|
|
1129
1336
|
if (!trimmed || disabled) return;
|
|
@@ -1141,8 +1348,8 @@ function Composer({
|
|
|
1141
1348
|
submitCurrent();
|
|
1142
1349
|
}
|
|
1143
1350
|
}
|
|
1144
|
-
return /* @__PURE__ */ (0,
|
|
1145
|
-
/* @__PURE__ */ (0,
|
|
1351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("form", { className: `composer${variant === "dock" ? " composer--dock" : ""}`, onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__field", children: [
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1146
1353
|
"textarea",
|
|
1147
1354
|
{
|
|
1148
1355
|
ref: inputRef,
|
|
@@ -1156,21 +1363,21 @@ function Composer({
|
|
|
1156
1363
|
onKeyDown: handleKeyDown
|
|
1157
1364
|
}
|
|
1158
1365
|
),
|
|
1159
|
-
/* @__PURE__ */ (0,
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1160
1367
|
"button",
|
|
1161
1368
|
{
|
|
1162
1369
|
type: "submit",
|
|
1163
1370
|
className: "composer__send",
|
|
1164
1371
|
disabled: disabled || !value.trim(),
|
|
1165
1372
|
"aria-label": "Send message",
|
|
1166
|
-
children: /* @__PURE__ */ (0,
|
|
1373
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
|
|
1167
1374
|
}
|
|
1168
1375
|
)
|
|
1169
1376
|
] }) });
|
|
1170
1377
|
}
|
|
1171
1378
|
|
|
1172
1379
|
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
1173
|
-
var
|
|
1380
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1174
1381
|
function FollowUpChips({
|
|
1175
1382
|
suggestions,
|
|
1176
1383
|
disabled = false,
|
|
@@ -1180,7 +1387,7 @@ function FollowUpChips({
|
|
|
1180
1387
|
}) {
|
|
1181
1388
|
if (suggestions.length === 0) return null;
|
|
1182
1389
|
if (variant === "dock") {
|
|
1183
|
-
return /* @__PURE__ */ (0,
|
|
1390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1184
1391
|
"button",
|
|
1185
1392
|
{
|
|
1186
1393
|
type: "button",
|
|
@@ -1192,9 +1399,9 @@ function FollowUpChips({
|
|
|
1192
1399
|
suggestion.id
|
|
1193
1400
|
)) }) });
|
|
1194
1401
|
}
|
|
1195
|
-
return /* @__PURE__ */ (0,
|
|
1196
|
-
/* @__PURE__ */ (0,
|
|
1197
|
-
/* @__PURE__ */ (0,
|
|
1402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "followups", children: [
|
|
1403
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "followups__label", children: label }),
|
|
1404
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1198
1405
|
"button",
|
|
1199
1406
|
{
|
|
1200
1407
|
type: "button",
|
|
@@ -1211,12 +1418,12 @@ function FollowUpChips({
|
|
|
1211
1418
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
1212
1419
|
var import_streamdown = require("streamdown");
|
|
1213
1420
|
var import_styles = require("streamdown/styles.css");
|
|
1214
|
-
var
|
|
1421
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1215
1422
|
function MessageBubble({ message }) {
|
|
1216
1423
|
if (message.role === "visitor") {
|
|
1217
|
-
return /* @__PURE__ */ (0,
|
|
1424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "message-bubble__text", children: message.text }) });
|
|
1218
1425
|
}
|
|
1219
|
-
return /* @__PURE__ */ (0,
|
|
1426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("article", { className: "message-bubble message-bubble--agent", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "message-bubble__text", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1220
1427
|
import_streamdown.Streamdown,
|
|
1221
1428
|
{
|
|
1222
1429
|
animated: true,
|
|
@@ -1233,12 +1440,20 @@ function MessageBubble({ message }) {
|
|
|
1233
1440
|
}
|
|
1234
1441
|
|
|
1235
1442
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
1236
|
-
var
|
|
1443
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1237
1444
|
function MinimizeIcon() {
|
|
1238
|
-
return /* @__PURE__ */ (0,
|
|
1445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1446
|
+
"path",
|
|
1447
|
+
{
|
|
1448
|
+
d: "M3.5 8h9",
|
|
1449
|
+
stroke: "currentColor",
|
|
1450
|
+
strokeWidth: "1.7",
|
|
1451
|
+
strokeLinecap: "round"
|
|
1452
|
+
}
|
|
1453
|
+
) });
|
|
1239
1454
|
}
|
|
1240
1455
|
function ExpandIcon() {
|
|
1241
|
-
return /* @__PURE__ */ (0,
|
|
1456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1242
1457
|
"path",
|
|
1243
1458
|
{
|
|
1244
1459
|
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
@@ -1250,7 +1465,7 @@ function ExpandIcon() {
|
|
|
1250
1465
|
) });
|
|
1251
1466
|
}
|
|
1252
1467
|
function RestoreIcon() {
|
|
1253
|
-
return /* @__PURE__ */ (0,
|
|
1468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1254
1469
|
"path",
|
|
1255
1470
|
{
|
|
1256
1471
|
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
@@ -1265,6 +1480,7 @@ function AgentRail({
|
|
|
1265
1480
|
state,
|
|
1266
1481
|
theme,
|
|
1267
1482
|
brandLabel = "Webless Assist",
|
|
1483
|
+
brandLogoUrl,
|
|
1268
1484
|
poweredByLabel = "Powered by Webless",
|
|
1269
1485
|
composerPlaceholder = "Ask anything\u2026",
|
|
1270
1486
|
mobileFullscreen = false,
|
|
@@ -1275,11 +1491,32 @@ function AgentRail({
|
|
|
1275
1491
|
onSubmit,
|
|
1276
1492
|
onFollowUpSelect
|
|
1277
1493
|
}) {
|
|
1278
|
-
const transcriptRef = (0,
|
|
1279
|
-
const
|
|
1494
|
+
const transcriptRef = (0, import_react5.useRef)(null);
|
|
1495
|
+
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1496
|
+
const railStyle = {
|
|
1497
|
+
"--rail-width": resolvedTheme.railMaxWidth,
|
|
1498
|
+
"--as-rail-max-width": resolvedTheme.railMaxWidth,
|
|
1499
|
+
"--as-brand": resolvedTheme.brand,
|
|
1500
|
+
"--as-brand-soft": resolvedTheme.brandSoft,
|
|
1501
|
+
"--as-brand-deep": resolvedTheme.brandDeep,
|
|
1502
|
+
"--as-surface": resolvedTheme.surface,
|
|
1503
|
+
"--as-surface-muted": resolvedTheme.surfaceMuted,
|
|
1504
|
+
"--as-text": resolvedTheme.text,
|
|
1505
|
+
"--as-text-muted": resolvedTheme.textMuted,
|
|
1506
|
+
"--as-text-subtle": resolvedTheme.textSubtle,
|
|
1507
|
+
"--as-border": resolvedTheme.border,
|
|
1508
|
+
"--as-visitor-bubble": resolvedTheme.visitorBubble,
|
|
1509
|
+
"--as-visitor-text": resolvedTheme.visitorText,
|
|
1510
|
+
"--as-success": resolvedTheme.success,
|
|
1511
|
+
"--as-danger": resolvedTheme.danger,
|
|
1512
|
+
"--as-font-body": resolvedTheme.fontBody,
|
|
1513
|
+
"--as-font-display": resolvedTheme.fontDisplay
|
|
1514
|
+
};
|
|
1280
1515
|
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
1281
|
-
const showActivity = state.toolSteps.length > 0
|
|
1282
|
-
const hasVisitorMessages2 = state.messages.some(
|
|
1516
|
+
const showActivity = state.toolSteps.length > 0;
|
|
1517
|
+
const hasVisitorMessages2 = state.messages.some(
|
|
1518
|
+
(message) => message.role === "visitor"
|
|
1519
|
+
);
|
|
1283
1520
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1284
1521
|
const showDockFollowUps = expanded && showIdleFollowUps;
|
|
1285
1522
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
@@ -1289,46 +1526,77 @@ function AgentRail({
|
|
|
1289
1526
|
streaming: true,
|
|
1290
1527
|
text: state.streamingText
|
|
1291
1528
|
} : null;
|
|
1292
|
-
(0,
|
|
1529
|
+
(0, import_react5.useEffect)(() => {
|
|
1293
1530
|
const node = transcriptRef.current;
|
|
1294
1531
|
if (!node) return;
|
|
1295
1532
|
node.scrollTop = node.scrollHeight;
|
|
1296
|
-
}, [
|
|
1297
|
-
|
|
1533
|
+
}, [
|
|
1534
|
+
state.messages,
|
|
1535
|
+
state.toolSteps,
|
|
1536
|
+
state.streamingText,
|
|
1537
|
+
state.followUps,
|
|
1538
|
+
state.journey
|
|
1539
|
+
]);
|
|
1540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1298
1541
|
"aside",
|
|
1299
1542
|
{
|
|
1300
1543
|
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
1301
1544
|
style: railStyle,
|
|
1302
1545
|
"aria-label": "Agent conversation",
|
|
1303
1546
|
children: [
|
|
1304
|
-
/* @__PURE__ */ (0,
|
|
1305
|
-
onCollapse ? /* @__PURE__ */ (0,
|
|
1547
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__brand-row", children: [
|
|
1548
|
+
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1306
1549
|
"button",
|
|
1307
1550
|
{
|
|
1308
1551
|
type: "button",
|
|
1309
1552
|
className: "agent-rail__collapse",
|
|
1310
1553
|
"aria-label": "Collapse assist",
|
|
1311
1554
|
onClick: onCollapse,
|
|
1312
|
-
children: /* @__PURE__ */ (0,
|
|
1555
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MinimizeIcon, {})
|
|
1556
|
+
}
|
|
1557
|
+
) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1558
|
+
"button",
|
|
1559
|
+
{
|
|
1560
|
+
type: "button",
|
|
1561
|
+
className: "agent-rail__close",
|
|
1562
|
+
"aria-label": "Close agent",
|
|
1563
|
+
onClick: onClose,
|
|
1564
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MinimizeIcon, {})
|
|
1313
1565
|
}
|
|
1314
|
-
) :
|
|
1315
|
-
/* @__PURE__ */ (0,
|
|
1316
|
-
|
|
1566
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: [
|
|
1569
|
+
brandLabel.slice(0, 1).toUpperCase(),
|
|
1570
|
+
brandLogoUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1571
|
+
"img",
|
|
1572
|
+
{
|
|
1573
|
+
className: "agent-rail__brand-logo",
|
|
1574
|
+
src: brandLogoUrl,
|
|
1575
|
+
alt: "",
|
|
1576
|
+
onError: (event) => {
|
|
1577
|
+
event.currentTarget.hidden = true;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
) : null
|
|
1581
|
+
] }),
|
|
1582
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1583
|
+
] }),
|
|
1584
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1317
1585
|
"button",
|
|
1318
1586
|
{
|
|
1319
1587
|
type: "button",
|
|
1320
1588
|
className: "agent-rail__expand",
|
|
1321
1589
|
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
1322
1590
|
onClick: onExpandToggle,
|
|
1323
|
-
children: expanded ? /* @__PURE__ */ (0,
|
|
1591
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpandIcon, {})
|
|
1324
1592
|
}
|
|
1325
|
-
) : /* @__PURE__ */ (0,
|
|
1593
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
1326
1594
|
] }) }),
|
|
1327
|
-
/* @__PURE__ */ (0,
|
|
1328
|
-
state.messages.map((message) => /* @__PURE__ */ (0,
|
|
1329
|
-
streamingMessage ? /* @__PURE__ */ (0,
|
|
1330
|
-
showActivity ? /* @__PURE__ */ (0,
|
|
1331
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0,
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
1596
|
+
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1597
|
+
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
1598
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AgentActivityBubble, { steps: state.toolSteps }) : null,
|
|
1599
|
+
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1332
1600
|
FollowUpChips,
|
|
1333
1601
|
{
|
|
1334
1602
|
suggestions: state.followUps,
|
|
@@ -1337,10 +1605,17 @@ function AgentRail({
|
|
|
1337
1605
|
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1338
1606
|
}
|
|
1339
1607
|
) }) : null,
|
|
1340
|
-
state.error ? /* @__PURE__ */ (0,
|
|
1608
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1609
|
+
"p",
|
|
1610
|
+
{
|
|
1611
|
+
role: "alert",
|
|
1612
|
+
style: { fontSize: 13, color: "var(--as-danger)", margin: 0 },
|
|
1613
|
+
children: state.error
|
|
1614
|
+
}
|
|
1615
|
+
) : null
|
|
1341
1616
|
] }),
|
|
1342
|
-
expanded ? /* @__PURE__ */ (0,
|
|
1343
|
-
showDockFollowUps ? /* @__PURE__ */ (0,
|
|
1617
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
1618
|
+
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1344
1619
|
FollowUpChips,
|
|
1345
1620
|
{
|
|
1346
1621
|
variant: "dock",
|
|
@@ -1349,7 +1624,7 @@ function AgentRail({
|
|
|
1349
1624
|
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1350
1625
|
}
|
|
1351
1626
|
) }) : null,
|
|
1352
|
-
/* @__PURE__ */ (0,
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1353
1628
|
Composer,
|
|
1354
1629
|
{
|
|
1355
1630
|
variant: "dock",
|
|
@@ -1358,12 +1633,12 @@ function AgentRail({
|
|
|
1358
1633
|
onSubmit
|
|
1359
1634
|
}
|
|
1360
1635
|
) }),
|
|
1361
|
-
/* @__PURE__ */ (0,
|
|
1362
|
-
/* @__PURE__ */ (0,
|
|
1363
|
-
/* @__PURE__ */ (0,
|
|
1636
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
1637
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1364
1639
|
] })
|
|
1365
|
-
] }) : /* @__PURE__ */ (0,
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
1640
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1367
1642
|
Composer,
|
|
1368
1643
|
{
|
|
1369
1644
|
disabled: isBusy,
|
|
@@ -1371,9 +1646,9 @@ function AgentRail({
|
|
|
1371
1646
|
onSubmit
|
|
1372
1647
|
}
|
|
1373
1648
|
),
|
|
1374
|
-
/* @__PURE__ */ (0,
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1377
1652
|
] })
|
|
1378
1653
|
] })
|
|
1379
1654
|
]
|
|
@@ -1382,22 +1657,67 @@ function AgentRail({
|
|
|
1382
1657
|
}
|
|
1383
1658
|
|
|
1384
1659
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
1385
|
-
var
|
|
1660
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1386
1661
|
function SparklesIcon() {
|
|
1387
|
-
return /* @__PURE__ */ (0,
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1663
|
+
"svg",
|
|
1664
|
+
{
|
|
1665
|
+
className: "assist-edge-tab__sparkles",
|
|
1666
|
+
viewBox: "0 0 18 16",
|
|
1667
|
+
fill: "none",
|
|
1668
|
+
"aria-hidden": "true",
|
|
1669
|
+
children: [
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1671
|
+
"path",
|
|
1672
|
+
{
|
|
1673
|
+
d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z",
|
|
1674
|
+
fill: "currentColor"
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1678
|
+
"path",
|
|
1679
|
+
{
|
|
1680
|
+
d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z",
|
|
1681
|
+
fill: "currentColor"
|
|
1682
|
+
}
|
|
1683
|
+
),
|
|
1684
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1685
|
+
"path",
|
|
1686
|
+
{
|
|
1687
|
+
d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z",
|
|
1688
|
+
fill: "currentColor"
|
|
1689
|
+
}
|
|
1690
|
+
)
|
|
1691
|
+
]
|
|
1692
|
+
}
|
|
1693
|
+
);
|
|
1392
1694
|
}
|
|
1393
1695
|
function ChevronLeftIcon() {
|
|
1394
|
-
return /* @__PURE__ */ (0,
|
|
1696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1697
|
+
"path",
|
|
1698
|
+
{
|
|
1699
|
+
d: "M10 4L6 8l4 4",
|
|
1700
|
+
stroke: "currentColor",
|
|
1701
|
+
strokeWidth: "1.6",
|
|
1702
|
+
strokeLinecap: "round",
|
|
1703
|
+
strokeLinejoin: "round"
|
|
1704
|
+
}
|
|
1705
|
+
) });
|
|
1395
1706
|
}
|
|
1396
1707
|
function ChevronDownIcon() {
|
|
1397
|
-
return /* @__PURE__ */ (0,
|
|
1708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1709
|
+
"path",
|
|
1710
|
+
{
|
|
1711
|
+
d: "M4 6l4 4 4-4",
|
|
1712
|
+
stroke: "currentColor",
|
|
1713
|
+
strokeWidth: "1.6",
|
|
1714
|
+
strokeLinecap: "round",
|
|
1715
|
+
strokeLinejoin: "round"
|
|
1716
|
+
}
|
|
1717
|
+
) });
|
|
1398
1718
|
}
|
|
1399
1719
|
function DragDots() {
|
|
1400
|
-
return /* @__PURE__ */ (0,
|
|
1720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", {}, index)) });
|
|
1401
1721
|
}
|
|
1402
1722
|
var VARIANT_COPY = {
|
|
1403
1723
|
outline: { label: "Assist", aria: "Open Assist" },
|
|
@@ -1410,38 +1730,71 @@ function AssistEdgeTab({
|
|
|
1410
1730
|
along,
|
|
1411
1731
|
inset,
|
|
1412
1732
|
visible,
|
|
1733
|
+
label,
|
|
1734
|
+
logoUrl,
|
|
1735
|
+
brandColor,
|
|
1736
|
+
fontFamily,
|
|
1413
1737
|
onOpen
|
|
1414
1738
|
}) {
|
|
1415
1739
|
const copy = VARIANT_COPY[variant];
|
|
1740
|
+
const visibleLabel = label?.trim() || copy.label;
|
|
1416
1741
|
const style = {
|
|
1417
1742
|
"--tab-along": `${along}%`,
|
|
1418
|
-
"--tab-inset": `${inset}px
|
|
1743
|
+
"--tab-inset": `${inset}px`,
|
|
1744
|
+
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1745
|
+
...fontFamily ? { "--as-font-display": fontFamily } : {}
|
|
1419
1746
|
};
|
|
1420
|
-
return /* @__PURE__ */ (0,
|
|
1747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1421
1748
|
"button",
|
|
1422
1749
|
{
|
|
1423
1750
|
type: "button",
|
|
1424
1751
|
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
1425
1752
|
style,
|
|
1426
|
-
"aria-label":
|
|
1753
|
+
"aria-label": `Open ${visibleLabel}`,
|
|
1427
1754
|
"aria-hidden": !visible,
|
|
1428
1755
|
tabIndex: visible ? 0 : -1,
|
|
1429
1756
|
onClick: onOpen,
|
|
1430
1757
|
children: [
|
|
1431
|
-
variant === "outline" ? /* @__PURE__ */ (0,
|
|
1432
|
-
/* @__PURE__ */ (0,
|
|
1433
|
-
|
|
1434
|
-
|
|
1758
|
+
variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1759
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1761
|
+
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1762
|
+
"img",
|
|
1763
|
+
{
|
|
1764
|
+
className: "assist-edge-tab__logo",
|
|
1765
|
+
src: logoUrl,
|
|
1766
|
+
alt: "",
|
|
1767
|
+
onError: (event) => {
|
|
1768
|
+
event.currentTarget.hidden = true;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
) : null
|
|
1772
|
+
] }),
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronDownIcon, {})
|
|
1435
1775
|
] }) : null,
|
|
1436
|
-
variant === "ask" ? /* @__PURE__ */ (0,
|
|
1437
|
-
/* @__PURE__ */ (0,
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1439
|
-
/* @__PURE__ */ (0,
|
|
1776
|
+
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronLeftIcon, {}),
|
|
1778
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1779
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DragDots, {})
|
|
1440
1780
|
] }) : null,
|
|
1441
|
-
variant === "fill" ? /* @__PURE__ */ (0,
|
|
1442
|
-
/* @__PURE__ */ (0,
|
|
1443
|
-
|
|
1444
|
-
|
|
1781
|
+
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1783
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1784
|
+
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1785
|
+
"img",
|
|
1786
|
+
{
|
|
1787
|
+
className: "assist-edge-tab__logo",
|
|
1788
|
+
src: logoUrl,
|
|
1789
|
+
alt: "",
|
|
1790
|
+
onError: (event) => {
|
|
1791
|
+
event.currentTarget.hidden = true;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
) : null
|
|
1795
|
+
] }),
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1797
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronLeftIcon, {})
|
|
1445
1798
|
] }) : null
|
|
1446
1799
|
]
|
|
1447
1800
|
}
|
|
@@ -1449,7 +1802,7 @@ function AssistEdgeTab({
|
|
|
1449
1802
|
}
|
|
1450
1803
|
|
|
1451
1804
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
1452
|
-
var
|
|
1805
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1453
1806
|
function AgentWidget({
|
|
1454
1807
|
indexId,
|
|
1455
1808
|
customerId,
|
|
@@ -1458,21 +1811,53 @@ function AgentWidget({
|
|
|
1458
1811
|
runtimeOrigin,
|
|
1459
1812
|
placement: placementInput,
|
|
1460
1813
|
defaultCollapsed = true,
|
|
1461
|
-
|
|
1814
|
+
pageShift = true,
|
|
1815
|
+
registerPanelController = false,
|
|
1816
|
+
branding
|
|
1462
1817
|
}) {
|
|
1463
1818
|
const isMobile = useIsMobile();
|
|
1464
1819
|
const placement = normalizeAgentPlacement(placementInput);
|
|
1465
|
-
const
|
|
1466
|
-
const [
|
|
1820
|
+
const railSlotRef = (0, import_react6.useRef)(null);
|
|
1821
|
+
const [railCollapsed, setRailCollapsed] = (0, import_react6.useState)(defaultCollapsed);
|
|
1822
|
+
const [railExpanded, setRailExpanded] = (0, import_react6.useState)(false);
|
|
1823
|
+
const pageShiftActive = shouldApplyPageShift({
|
|
1824
|
+
pageShift,
|
|
1825
|
+
isMobile,
|
|
1826
|
+
railCollapsed,
|
|
1827
|
+
railExpanded
|
|
1828
|
+
});
|
|
1829
|
+
usePageShift({
|
|
1830
|
+
active: pageShiftActive,
|
|
1831
|
+
railSlotRef
|
|
1832
|
+
});
|
|
1467
1833
|
const { state, submit } = useAgentChat({
|
|
1468
1834
|
customerId,
|
|
1469
1835
|
getUnpublishedPreviewGrant,
|
|
1470
1836
|
indexId,
|
|
1471
1837
|
version,
|
|
1472
|
-
runtimeOrigin
|
|
1838
|
+
runtimeOrigin,
|
|
1839
|
+
greeting: branding?.greeting
|
|
1473
1840
|
});
|
|
1841
|
+
const agentName = branding?.agentName ?? "Webless Guide";
|
|
1842
|
+
const theme = {
|
|
1843
|
+
...branding?.fontFamily ? { fontBody: branding.fontFamily, fontDisplay: branding.fontFamily } : {},
|
|
1844
|
+
...branding?.colors?.primary ? {
|
|
1845
|
+
brand: branding.colors.primary,
|
|
1846
|
+
visitorBubble: branding.colors.primary
|
|
1847
|
+
} : {},
|
|
1848
|
+
...branding?.colors?.primarySoft ? { brandSoft: branding.colors.primarySoft } : {},
|
|
1849
|
+
...branding?.colors?.primaryForeground ? { visitorText: branding.colors.primaryForeground } : {},
|
|
1850
|
+
...branding?.colors?.surface ? { surface: branding.colors.surface } : {},
|
|
1851
|
+
...branding?.colors?.surfaceMuted ? { surfaceMuted: branding.colors.surfaceMuted } : {},
|
|
1852
|
+
...branding?.colors?.text ? { text: branding.colors.text } : {},
|
|
1853
|
+
...branding?.colors?.textMuted ? {
|
|
1854
|
+
textMuted: branding.colors.textMuted,
|
|
1855
|
+
textSubtle: branding.colors.textMuted
|
|
1856
|
+
} : {},
|
|
1857
|
+
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
1858
|
+
};
|
|
1474
1859
|
const idle = state.phase === "idle" && !hasVisitorMessages(state.messages);
|
|
1475
|
-
(0,
|
|
1860
|
+
(0, import_react6.useEffect)(() => {
|
|
1476
1861
|
if (!registerPanelController) return;
|
|
1477
1862
|
registerAgentPanelController(customerId, {
|
|
1478
1863
|
open: () => setRailCollapsed(false),
|
|
@@ -1487,47 +1872,56 @@ function AgentWidget({
|
|
|
1487
1872
|
if (isMobile) setRailCollapsed(false);
|
|
1488
1873
|
await submit(message);
|
|
1489
1874
|
}
|
|
1490
|
-
return /* @__PURE__ */ (0,
|
|
1491
|
-
/* @__PURE__ */ (0,
|
|
1875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1876
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1492
1877
|
"div",
|
|
1493
1878
|
{
|
|
1494
1879
|
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
1495
|
-
children:
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1880
|
+
children: [
|
|
1881
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1882
|
+
"div",
|
|
1883
|
+
{
|
|
1884
|
+
ref: railSlotRef,
|
|
1885
|
+
className: "webless-agent-root__rail-slot",
|
|
1886
|
+
inert: railCollapsed || void 0,
|
|
1887
|
+
"aria-hidden": railCollapsed,
|
|
1888
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1889
|
+
AgentRail,
|
|
1890
|
+
{
|
|
1891
|
+
theme,
|
|
1892
|
+
brandLabel: agentName,
|
|
1893
|
+
brandLogoUrl: branding?.logoUrl,
|
|
1894
|
+
composerPlaceholder: branding?.composerPlaceholder ?? `Ask ${agentName}\u2026`,
|
|
1895
|
+
poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
|
|
1896
|
+
state: idle ? {
|
|
1897
|
+
...state,
|
|
1898
|
+
followUps: createIdleSuggestions()
|
|
1899
|
+
} : state,
|
|
1900
|
+
mobileFullscreen: isMobile && !railCollapsed,
|
|
1901
|
+
expanded: railExpanded,
|
|
1902
|
+
onCollapse: !isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1903
|
+
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1904
|
+
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1905
|
+
onSubmit: handleSubmit,
|
|
1906
|
+
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1907
|
+
}
|
|
1908
|
+
)
|
|
1909
|
+
}
|
|
1910
|
+
),
|
|
1911
|
+
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1912
|
+
"button",
|
|
1913
|
+
{
|
|
1914
|
+
type: "button",
|
|
1915
|
+
className: "webless-agent-root__backdrop",
|
|
1916
|
+
tabIndex: -1,
|
|
1917
|
+
"aria-label": "Close expanded assist",
|
|
1918
|
+
onClick: () => setRailExpanded(false)
|
|
1919
|
+
}
|
|
1920
|
+
) : null
|
|
1921
|
+
]
|
|
1519
1922
|
}
|
|
1520
1923
|
),
|
|
1521
|
-
|
|
1522
|
-
"button",
|
|
1523
|
-
{
|
|
1524
|
-
type: "button",
|
|
1525
|
-
className: "webless-agent-root__backdrop",
|
|
1526
|
-
"aria-label": "Close expanded assist",
|
|
1527
|
-
onClick: () => setRailExpanded(false)
|
|
1528
|
-
}
|
|
1529
|
-
) : null,
|
|
1530
|
-
railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1924
|
+
railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1531
1925
|
AssistEdgeTab,
|
|
1532
1926
|
{
|
|
1533
1927
|
variant: placement.variant,
|
|
@@ -1535,29 +1929,15 @@ function AgentWidget({
|
|
|
1535
1929
|
along: placement.along,
|
|
1536
1930
|
inset: placement.inset,
|
|
1537
1931
|
visible: true,
|
|
1932
|
+
label: agentName,
|
|
1933
|
+
logoUrl: branding?.logoUrl,
|
|
1934
|
+
brandColor: branding?.colors?.primary,
|
|
1935
|
+
fontFamily: branding?.fontFamily,
|
|
1538
1936
|
onOpen: () => setRailCollapsed(false)
|
|
1539
1937
|
}
|
|
1540
1938
|
) : null
|
|
1541
1939
|
] });
|
|
1542
1940
|
}
|
|
1543
|
-
|
|
1544
|
-
// src/react/types/conversation.ts
|
|
1545
|
-
var defaultAgentRailTheme = {
|
|
1546
|
-
railMaxWidth: "450px",
|
|
1547
|
-
brand: "#6f16ff",
|
|
1548
|
-
brandSoft: "#f3edff",
|
|
1549
|
-
brandDeep: "#12043e",
|
|
1550
|
-
surface: "#ffffff",
|
|
1551
|
-
surfaceMuted: "#f4f6fb",
|
|
1552
|
-
text: "#171b2a",
|
|
1553
|
-
textMuted: "#5a6378",
|
|
1554
|
-
textSubtle: "#8a94a8",
|
|
1555
|
-
border: "rgb(42 51 70 / 0.1)",
|
|
1556
|
-
visitorBubble: "#6f16ff",
|
|
1557
|
-
visitorText: "#ffffff",
|
|
1558
|
-
success: "#18794e",
|
|
1559
|
-
danger: "#c94b63"
|
|
1560
|
-
};
|
|
1561
1941
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1562
1942
|
0 && (module.exports = {
|
|
1563
1943
|
AgentRail,
|