@webless/agent 0.2.15 → 0.3.1
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/{chunk-7IR64MFS.js → chunk-MMYSBSHG.js} +569 -253
- package/dist/chunk-MMYSBSHG.js.map +1 -0
- package/dist/embed.cjs +613 -270
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +190 -22
- package/dist/embed.css.map +1 -1
- package/dist/embed.d.cts +3 -33
- package/dist/embed.d.ts +3 -33
- package/dist/embed.js +31 -3
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +136 -15
- 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 +136 -15
- 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 +579 -282
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +190 -22
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +11 -5
- package/dist/react.d.ts +11 -5
- package/dist/react.js +2 -19
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7IR64MFS.js.map +0 -1
- package/dist/placement-CXW_83AF.d.cts +0 -25
- package/dist/placement-CXW_83AF.d.ts +0 -25
|
@@ -220,9 +220,8 @@ function clearPersistedAgentSession(visitorSessionId, options) {
|
|
|
220
220
|
function isTurnBoundary(event) {
|
|
221
221
|
return event.type === "session.waiting" || event.type === "session.completed" || event.type === "session.failed";
|
|
222
222
|
}
|
|
223
|
-
function applyMessageEvent(event, rendered, handlers) {
|
|
224
|
-
|
|
225
|
-
if (step) handlers.onStep?.(step.label, step.detail);
|
|
223
|
+
function applyMessageEvent(event, rendered, handlers, workItems) {
|
|
224
|
+
applyWorkEvent(event, handlers, workItems);
|
|
226
225
|
if (event.type === "session.failed") {
|
|
227
226
|
throw new Error(event.data.message || event.data.code);
|
|
228
227
|
}
|
|
@@ -265,13 +264,120 @@ function renderTurn(events) {
|
|
|
265
264
|
}
|
|
266
265
|
return rendered;
|
|
267
266
|
}
|
|
268
|
-
function
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
267
|
+
function emitWorkItem(item, handlers, workItems) {
|
|
268
|
+
workItems.set(item.id, item);
|
|
269
|
+
handlers.onWork?.(item);
|
|
270
|
+
handlers.onStep?.(item.label, item.detail);
|
|
271
|
+
}
|
|
272
|
+
function completePlanning(handlers, workItems) {
|
|
273
|
+
const planning = workItems.get("planning");
|
|
274
|
+
if (!planning || planning.state !== "active") return;
|
|
275
|
+
emitWorkItem(
|
|
276
|
+
{
|
|
277
|
+
...planning,
|
|
278
|
+
detail: "Picked the best way to help",
|
|
279
|
+
state: "completed"
|
|
280
|
+
},
|
|
281
|
+
handlers,
|
|
282
|
+
workItems
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
function specialistNameFromInput(input) {
|
|
286
|
+
const message = input.message;
|
|
287
|
+
if (typeof message !== "string") return void 0;
|
|
288
|
+
const match = /^Webless-Agent-Name:\s*(.+)$/imu.exec(message);
|
|
289
|
+
return match?.[1]?.trim() || void 0;
|
|
290
|
+
}
|
|
291
|
+
function requestedWorkItem(action) {
|
|
292
|
+
if (action.kind === "tool-call" && action.toolName === "search_discovery") {
|
|
293
|
+
return {
|
|
294
|
+
id: action.callId,
|
|
295
|
+
kind: "search",
|
|
296
|
+
label: "Search & Discovery",
|
|
297
|
+
detail: "Searching this site",
|
|
298
|
+
state: "active"
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
if (action.kind === "subagent-call" || action.kind === "remote-agent-call" || action.kind === "tool-call" && action.toolName === "agent") {
|
|
302
|
+
const name = specialistNameFromInput(action.input) ?? "Specialist";
|
|
303
|
+
return {
|
|
304
|
+
id: action.callId,
|
|
305
|
+
kind: "specialist",
|
|
306
|
+
label: name,
|
|
307
|
+
detail: "Reviewing your question",
|
|
308
|
+
state: "active"
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
function applyWorkEvent(event, handlers, workItems) {
|
|
314
|
+
if (event.type === "step.started" && workItems.size === 0) {
|
|
315
|
+
emitWorkItem(
|
|
316
|
+
{
|
|
317
|
+
id: "planning",
|
|
318
|
+
kind: "planning",
|
|
319
|
+
label: "Understanding your question",
|
|
320
|
+
state: "active"
|
|
321
|
+
},
|
|
322
|
+
handlers,
|
|
323
|
+
workItems
|
|
324
|
+
);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (event.type === "actions.requested") {
|
|
328
|
+
completePlanning(handlers, workItems);
|
|
329
|
+
for (const action of event.data.actions) {
|
|
330
|
+
const item = requestedWorkItem(action);
|
|
331
|
+
if (item) emitWorkItem(item, handlers, workItems);
|
|
332
|
+
}
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (event.type === "subagent.called") {
|
|
336
|
+
completePlanning(handlers, workItems);
|
|
337
|
+
const current2 = workItems.get(event.data.callId);
|
|
338
|
+
if (!current2) {
|
|
339
|
+
emitWorkItem(
|
|
340
|
+
{
|
|
341
|
+
id: event.data.callId,
|
|
342
|
+
kind: "specialist",
|
|
343
|
+
label: event.data.name || "Specialist",
|
|
344
|
+
detail: "Reviewing your question",
|
|
345
|
+
state: "active"
|
|
346
|
+
},
|
|
347
|
+
handlers,
|
|
348
|
+
workItems
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (event.type === "subagent.completed") {
|
|
354
|
+
const current2 = workItems.get(event.data.callId);
|
|
355
|
+
if (!current2) return;
|
|
356
|
+
emitWorkItem(
|
|
357
|
+
{
|
|
358
|
+
...current2,
|
|
359
|
+
detail: "Guidance received",
|
|
360
|
+
state: "completed"
|
|
361
|
+
},
|
|
362
|
+
handlers,
|
|
363
|
+
workItems
|
|
364
|
+
);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (event.type !== "action.result") return;
|
|
368
|
+
const { result, status } = event.data;
|
|
369
|
+
const current = workItems.get(result.callId);
|
|
370
|
+
if (!current) return;
|
|
371
|
+
const failed = status !== "completed" || result.isError === true;
|
|
372
|
+
emitWorkItem(
|
|
373
|
+
{
|
|
374
|
+
...current,
|
|
375
|
+
detail: failed ? "Couldn\u2019t complete; continuing with available information" : current.kind === "search" ? "Found relevant site content" : "Guidance received",
|
|
376
|
+
state: failed ? "error" : "completed"
|
|
377
|
+
},
|
|
378
|
+
handlers,
|
|
379
|
+
workItems
|
|
380
|
+
);
|
|
275
381
|
}
|
|
276
382
|
var AgentSession = class {
|
|
277
383
|
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, getUnpublishedPreviewGrant) {
|
|
@@ -389,10 +495,11 @@ var AgentSession = class {
|
|
|
389
495
|
this.activeResponse = response;
|
|
390
496
|
let streamIndex = session?.state.streamIndex ?? 0;
|
|
391
497
|
let rendered = "";
|
|
498
|
+
const workItems = /* @__PURE__ */ new Map();
|
|
392
499
|
try {
|
|
393
500
|
for await (const event of response) {
|
|
394
501
|
if (signal.aborted) break;
|
|
395
|
-
rendered = applyMessageEvent(event, rendered, handlers);
|
|
502
|
+
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
396
503
|
streamIndex += 1;
|
|
397
504
|
if (session) {
|
|
398
505
|
savePersistedAgentSession(
|
|
@@ -434,6 +541,10 @@ var AgentSession = class {
|
|
|
434
541
|
return null;
|
|
435
542
|
}
|
|
436
543
|
let rendered = renderTurn(turnEvents);
|
|
544
|
+
const workItems = /* @__PURE__ */ new Map();
|
|
545
|
+
for (const event of turnEvents) {
|
|
546
|
+
applyWorkEvent(event, handlers, workItems);
|
|
547
|
+
}
|
|
437
548
|
if (rendered.startsWith(initialText)) {
|
|
438
549
|
const missedText = rendered.slice(initialText.length);
|
|
439
550
|
if (missedText) handlers.onDelta(missedText);
|
|
@@ -468,7 +579,7 @@ var AgentSession = class {
|
|
|
468
579
|
let streamIndex = snapshot.session.streamIndex;
|
|
469
580
|
for await (const event of session.stream({ signal })) {
|
|
470
581
|
if (signal.aborted) break;
|
|
471
|
-
rendered = applyMessageEvent(event, rendered, handlers);
|
|
582
|
+
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
472
583
|
streamIndex += 1;
|
|
473
584
|
savePersistedAgentSession(
|
|
474
585
|
this.visitorSessionId,
|
|
@@ -548,6 +659,11 @@ function createAgentClient(options) {
|
|
|
548
659
|
|
|
549
660
|
// src/runtime/errors.ts
|
|
550
661
|
import { ClientError as ClientError3 } from "eve/client";
|
|
662
|
+
var TRANSIENT_AGENT_ERROR_MESSAGE = "I couldn\u2019t finish that answer. Please try again.";
|
|
663
|
+
function isTransientRuntimeMessage(message) {
|
|
664
|
+
const normalized = message.trim().toLowerCase();
|
|
665
|
+
return normalized.includes("empty response from runtime") || normalized.includes("failed to fetch") || normalized.includes("networkerror") || normalized.includes("load failed");
|
|
666
|
+
}
|
|
551
667
|
function formatAgentError(error) {
|
|
552
668
|
if (error instanceof ClientError3) {
|
|
553
669
|
if (error.status === 401 && error.code === "index_required") {
|
|
@@ -559,13 +675,18 @@ function formatAgentError(error) {
|
|
|
559
675
|
if (error.status === 409 && error.code === "session_not_active") {
|
|
560
676
|
return "Session expired \u2014 send a new message to start again.";
|
|
561
677
|
}
|
|
562
|
-
|
|
678
|
+
if (error.status >= 500 || error.message && isTransientRuntimeMessage(error.message)) {
|
|
679
|
+
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
680
|
+
}
|
|
681
|
+
return error.message || "This assistant is unavailable right now.";
|
|
563
682
|
}
|
|
564
683
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
565
684
|
return "";
|
|
566
685
|
}
|
|
567
|
-
if (error instanceof Error)
|
|
568
|
-
|
|
686
|
+
if (error instanceof Error) {
|
|
687
|
+
return isTransientRuntimeMessage(error.message) ? TRANSIENT_AGENT_ERROR_MESSAGE : error.message;
|
|
688
|
+
}
|
|
689
|
+
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
569
690
|
}
|
|
570
691
|
|
|
571
692
|
// src/react/persisted-conversation.ts
|
|
@@ -621,57 +742,54 @@ function clearPersistedAgentConversation(storageKeyPrefix, visitorSessionId) {
|
|
|
621
742
|
}
|
|
622
743
|
|
|
623
744
|
// src/react/hooks/useAgentChat.ts
|
|
624
|
-
var
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
745
|
+
var DEFAULT_GREETING = "Hi! I can search this site or bring in a specialist when it helps. What would you like to know?";
|
|
746
|
+
function createInitialState(greeting = DEFAULT_GREETING) {
|
|
747
|
+
return {
|
|
748
|
+
phase: "idle",
|
|
749
|
+
messages: [
|
|
750
|
+
{
|
|
751
|
+
id: "greeting",
|
|
752
|
+
role: "agent",
|
|
753
|
+
text: greeting,
|
|
754
|
+
createdAt: 0
|
|
755
|
+
}
|
|
756
|
+
],
|
|
757
|
+
toolSteps: [],
|
|
758
|
+
journey: null,
|
|
759
|
+
followUps: [],
|
|
760
|
+
streamingText: "",
|
|
761
|
+
error: null
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function stateFromConversation(conversation, initialState) {
|
|
765
|
+
if (!conversation || conversation.messages.length === 0) return initialState;
|
|
641
766
|
return {
|
|
642
|
-
...
|
|
767
|
+
...initialState,
|
|
643
768
|
messages: conversation.messages,
|
|
644
769
|
phase: conversation.pending ? conversation.streamingText ? "streaming" : "thinking" : "complete",
|
|
645
770
|
streamingText: conversation.streamingText
|
|
646
771
|
};
|
|
647
772
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
)
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
id: item.id,
|
|
669
|
-
label: item.label,
|
|
670
|
-
detail: item.detail,
|
|
671
|
-
state: "active"
|
|
672
|
-
});
|
|
673
|
-
await delay(item.ms, signal);
|
|
674
|
-
}
|
|
773
|
+
function upsertToolStep(steps, item) {
|
|
774
|
+
const next = {
|
|
775
|
+
id: item.id,
|
|
776
|
+
kind: item.kind,
|
|
777
|
+
label: item.label,
|
|
778
|
+
state: item.state,
|
|
779
|
+
...item.detail ? { detail: item.detail } : {}
|
|
780
|
+
};
|
|
781
|
+
const index = steps.findIndex((step) => step.id === item.id);
|
|
782
|
+
if (index < 0) return [...steps, next];
|
|
783
|
+
return steps.map((step, stepIndex) => stepIndex === index ? next : step);
|
|
784
|
+
}
|
|
785
|
+
function completeActivePlanning(steps) {
|
|
786
|
+
return steps.map(
|
|
787
|
+
(step) => step.kind === "planning" && step.state === "active" ? {
|
|
788
|
+
...step,
|
|
789
|
+
detail: "Prepared a response",
|
|
790
|
+
state: "completed"
|
|
791
|
+
} : step
|
|
792
|
+
);
|
|
675
793
|
}
|
|
676
794
|
function useAgentChat({
|
|
677
795
|
customerId,
|
|
@@ -680,8 +798,13 @@ function useAgentChat({
|
|
|
680
798
|
version,
|
|
681
799
|
runtimeOrigin,
|
|
682
800
|
visitorSessionId,
|
|
683
|
-
storageKeyPrefix
|
|
801
|
+
storageKeyPrefix,
|
|
802
|
+
greeting
|
|
684
803
|
}) {
|
|
804
|
+
const initialState = useMemo(
|
|
805
|
+
() => createInitialState(greeting?.trim() || DEFAULT_GREETING),
|
|
806
|
+
[greeting]
|
|
807
|
+
);
|
|
685
808
|
const previewGrantProviderRef = useRef(getUnpublishedPreviewGrant);
|
|
686
809
|
previewGrantProviderRef.current = getUnpublishedPreviewGrant;
|
|
687
810
|
const resolveUnpublishedPreviewGrant = () => {
|
|
@@ -712,7 +835,8 @@ function useAgentChat({
|
|
|
712
835
|
);
|
|
713
836
|
const [state, setState] = useState(
|
|
714
837
|
() => stateFromConversation(
|
|
715
|
-
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
|
|
838
|
+
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId),
|
|
839
|
+
initialState
|
|
716
840
|
)
|
|
717
841
|
);
|
|
718
842
|
const runRef = useRef(null);
|
|
@@ -727,7 +851,7 @@ function useAgentChat({
|
|
|
727
851
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
728
852
|
})
|
|
729
853
|
);
|
|
730
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
854
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
731
855
|
const identityRef = useRef(identityKey);
|
|
732
856
|
useEffect(() => {
|
|
733
857
|
if (identityRef.current === identityKey) {
|
|
@@ -747,13 +871,15 @@ function useAgentChat({
|
|
|
747
871
|
});
|
|
748
872
|
setState(
|
|
749
873
|
stateFromConversation(
|
|
750
|
-
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId)
|
|
874
|
+
loadPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId),
|
|
875
|
+
initialState
|
|
751
876
|
)
|
|
752
877
|
);
|
|
753
878
|
}, [
|
|
754
879
|
customerId,
|
|
755
880
|
identityKey,
|
|
756
881
|
indexId,
|
|
882
|
+
initialState,
|
|
757
883
|
runtimeOrigin,
|
|
758
884
|
resolvedStorageKeyPrefix,
|
|
759
885
|
version,
|
|
@@ -778,8 +904,8 @@ function useAgentChat({
|
|
|
778
904
|
runRef.current = null;
|
|
779
905
|
clientRef.current.reset();
|
|
780
906
|
clearPersistedAgentConversation(resolvedStorageKeyPrefix, visitorId);
|
|
781
|
-
setState(
|
|
782
|
-
}, [resolvedStorageKeyPrefix, visitorId]);
|
|
907
|
+
setState(initialState);
|
|
908
|
+
}, [initialState, resolvedStorageKeyPrefix, visitorId]);
|
|
783
909
|
const runTurn = useCallback(
|
|
784
910
|
async (input) => {
|
|
785
911
|
const { controller, initialText = "", resume, visitorText } = input;
|
|
@@ -788,35 +914,23 @@ function useAgentChat({
|
|
|
788
914
|
try {
|
|
789
915
|
let streamStarted = Boolean(initialText);
|
|
790
916
|
let streamed = initialText;
|
|
791
|
-
const planningPromise = resume ? Promise.resolve() : runStatusSequence(signal, (step) => {
|
|
792
|
-
if (streamStarted || !isActiveRun()) return;
|
|
793
|
-
setState((prev) => ({
|
|
794
|
-
...prev,
|
|
795
|
-
phase: "running-tools",
|
|
796
|
-
toolSteps: [step]
|
|
797
|
-
}));
|
|
798
|
-
});
|
|
799
917
|
const handlers = {
|
|
800
|
-
|
|
801
|
-
if (
|
|
918
|
+
onWork: (item) => {
|
|
919
|
+
if (!isActiveRun()) return;
|
|
802
920
|
setState((prev) => ({
|
|
803
921
|
...prev,
|
|
804
|
-
phase: "running-tools",
|
|
805
|
-
toolSteps:
|
|
806
|
-
{ id: `step-${label}`, label, detail, state: "active" }
|
|
807
|
-
]
|
|
922
|
+
phase: item.state === "active" ? "running-tools" : prev.phase,
|
|
923
|
+
toolSteps: upsertToolStep(prev.toolSteps, item)
|
|
808
924
|
}));
|
|
809
925
|
},
|
|
810
926
|
onDelta: (delta) => {
|
|
811
927
|
if (!isActiveRun()) return;
|
|
812
|
-
void planningPromise.catch(() => {
|
|
813
|
-
});
|
|
814
928
|
if (!streamStarted) {
|
|
815
929
|
streamStarted = true;
|
|
816
930
|
setState((prev) => ({
|
|
817
931
|
...prev,
|
|
818
932
|
phase: "streaming",
|
|
819
|
-
toolSteps:
|
|
933
|
+
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
820
934
|
streamingText: ""
|
|
821
935
|
}));
|
|
822
936
|
}
|
|
@@ -844,8 +958,6 @@ function useAgentChat({
|
|
|
844
958
|
signal
|
|
845
959
|
});
|
|
846
960
|
}
|
|
847
|
-
await planningPromise.catch(() => {
|
|
848
|
-
});
|
|
849
961
|
if (!isActiveRun() || finalText === null) return;
|
|
850
962
|
const agentMessage = {
|
|
851
963
|
id: `agent-${Date.now()}`,
|
|
@@ -857,7 +969,7 @@ function useAgentChat({
|
|
|
857
969
|
...prev,
|
|
858
970
|
phase: "complete",
|
|
859
971
|
messages: [...prev.messages, agentMessage],
|
|
860
|
-
toolSteps:
|
|
972
|
+
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
861
973
|
streamingText: "",
|
|
862
974
|
followUps: [],
|
|
863
975
|
journey: null
|
|
@@ -872,7 +984,13 @@ function useAgentChat({
|
|
|
872
984
|
setState((prev) => ({
|
|
873
985
|
...prev,
|
|
874
986
|
phase: "complete",
|
|
875
|
-
toolSteps:
|
|
987
|
+
toolSteps: prev.toolSteps.map(
|
|
988
|
+
(step) => step.state === "active" ? {
|
|
989
|
+
...step,
|
|
990
|
+
detail: "Couldn\u2019t complete this step",
|
|
991
|
+
state: "error"
|
|
992
|
+
} : step
|
|
993
|
+
),
|
|
876
994
|
streamingText: "",
|
|
877
995
|
error: message
|
|
878
996
|
}));
|
|
@@ -900,7 +1018,12 @@ function useAgentChat({
|
|
|
900
1018
|
phase: "thinking",
|
|
901
1019
|
messages: [...prev.messages, visitorMessage],
|
|
902
1020
|
toolSteps: [
|
|
903
|
-
{
|
|
1021
|
+
{
|
|
1022
|
+
id: "planning",
|
|
1023
|
+
kind: "planning",
|
|
1024
|
+
label: "Understanding your question",
|
|
1025
|
+
state: "active"
|
|
1026
|
+
}
|
|
904
1027
|
],
|
|
905
1028
|
journey: null,
|
|
906
1029
|
followUps: [],
|
|
@@ -979,82 +1102,96 @@ function normalizeAgentPlacement(placement) {
|
|
|
979
1102
|
};
|
|
980
1103
|
}
|
|
981
1104
|
|
|
1105
|
+
// src/react/types/conversation.ts
|
|
1106
|
+
var defaultAgentRailTheme = {
|
|
1107
|
+
railMaxWidth: "450px",
|
|
1108
|
+
brand: "#6f16ff",
|
|
1109
|
+
brandSoft: "#f3edff",
|
|
1110
|
+
brandDeep: "#12043e",
|
|
1111
|
+
surface: "#ffffff",
|
|
1112
|
+
surfaceMuted: "#f4f6fb",
|
|
1113
|
+
text: "#171b2a",
|
|
1114
|
+
textMuted: "#5a6378",
|
|
1115
|
+
textSubtle: "#8a94a8",
|
|
1116
|
+
border: "rgb(42 51 70 / 0.1)",
|
|
1117
|
+
visitorBubble: "#6f16ff",
|
|
1118
|
+
visitorText: "#ffffff",
|
|
1119
|
+
success: "#18794e",
|
|
1120
|
+
danger: "#c94b63",
|
|
1121
|
+
fontBody: '"Mulish", "Avenir Next", "Segoe UI", sans-serif',
|
|
1122
|
+
fontDisplay: '"Space Grotesk", sans-serif'
|
|
1123
|
+
};
|
|
1124
|
+
|
|
982
1125
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
983
1126
|
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
984
1127
|
|
|
985
|
-
// src/react/components/
|
|
1128
|
+
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
986
1129
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
if (active) return active;
|
|
996
|
-
const error = steps.find((step) => step.state === "error");
|
|
997
|
-
if (error) return error;
|
|
998
|
-
const pending = steps.find((step) => step.state === "pending");
|
|
999
|
-
if (pending) return pending;
|
|
1000
|
-
return steps.at(-1) ?? null;
|
|
1001
|
-
}
|
|
1002
|
-
function ToolTimeline({
|
|
1003
|
-
steps,
|
|
1004
|
-
streamingText,
|
|
1005
|
-
showStreaming = false,
|
|
1006
|
-
inline = false
|
|
1007
|
-
}) {
|
|
1008
|
-
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
1009
|
-
const currentStep = getCurrentStep(steps);
|
|
1010
|
-
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
1011
|
-
return /* @__PURE__ */ jsxs(
|
|
1012
|
-
"div",
|
|
1013
|
-
{
|
|
1014
|
-
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
1015
|
-
role: "status",
|
|
1016
|
-
"aria-live": "polite",
|
|
1017
|
-
"aria-label": "Agent progress",
|
|
1018
|
-
children: [
|
|
1019
|
-
showStatus ? /* @__PURE__ */ jsxs("div", { className: "agent-status", children: [
|
|
1020
|
-
currentStep.state === "error" ? /* @__PURE__ */ jsx("span", { className: "agent-status__icon agent-status__icon--error", "aria-hidden": "true", children: "!" }) : /* @__PURE__ */ jsx("span", { className: "agent-status__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(SpinnerIcon, {}) }),
|
|
1021
|
-
/* @__PURE__ */ jsxs("div", { className: "agent-status__copy", children: [
|
|
1022
|
-
/* @__PURE__ */ jsx("span", { className: "agent-status__label", children: currentStep.label }),
|
|
1023
|
-
currentStep.detail ? /* @__PURE__ */ jsx("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
1024
|
-
] })
|
|
1025
|
-
] }, currentStep.id) : null,
|
|
1026
|
-
showStreaming && streamingText ? /* @__PURE__ */ jsxs("p", { className: "tool-timeline__streaming-text", children: [
|
|
1027
|
-
streamingText,
|
|
1028
|
-
/* @__PURE__ */ jsx("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
1029
|
-
] }) : null
|
|
1030
|
-
]
|
|
1031
|
-
}
|
|
1130
|
+
function workSummary(steps) {
|
|
1131
|
+
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1132
|
+
if (active?.kind === "specialist") return `Working with ${active.label}`;
|
|
1133
|
+
if (active?.kind === "search") return "Searching this site";
|
|
1134
|
+
if (active) return active.label;
|
|
1135
|
+
const hasError = steps.some((step) => step.state === "error");
|
|
1136
|
+
const specialists = steps.filter(
|
|
1137
|
+
(step) => step.kind === "specialist" && step.state === "completed"
|
|
1032
1138
|
);
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1139
|
+
const searched = steps.some(
|
|
1140
|
+
(step) => step.kind === "search" && step.state === "completed"
|
|
1141
|
+
);
|
|
1142
|
+
if (hasError) return "Answered with available information";
|
|
1143
|
+
if (specialists.length > 1)
|
|
1144
|
+
return `Consulted ${specialists.length} specialists`;
|
|
1145
|
+
if (specialists.length === 1) return `Consulted ${specialists[0]?.label}`;
|
|
1146
|
+
if (searched) return "Searched this site";
|
|
1147
|
+
return "Prepared a response";
|
|
1148
|
+
}
|
|
1149
|
+
function AgentActivityBubble({ steps }) {
|
|
1150
|
+
const active = steps.some((step) => step.state === "active");
|
|
1151
|
+
return /* @__PURE__ */ jsxs("article", { className: "agent-activity-bubble", children: [
|
|
1152
|
+
/* @__PURE__ */ jsxs("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1153
|
+
/* @__PURE__ */ jsx(
|
|
1154
|
+
"span",
|
|
1155
|
+
{
|
|
1156
|
+
className: `agent-activity-bubble__pulse${active ? " is-active" : ""}`,
|
|
1157
|
+
"aria-hidden": "true"
|
|
1158
|
+
}
|
|
1159
|
+
),
|
|
1160
|
+
workSummary(steps)
|
|
1161
|
+
] }),
|
|
1162
|
+
/* @__PURE__ */ jsxs("details", { className: "agent-activity-bubble__details", open: active, children: [
|
|
1163
|
+
/* @__PURE__ */ jsx("summary", { children: "Work details" }),
|
|
1164
|
+
/* @__PURE__ */ jsx("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => /* @__PURE__ */ jsxs(
|
|
1165
|
+
"li",
|
|
1166
|
+
{
|
|
1167
|
+
className: "agent-activity-bubble__step",
|
|
1168
|
+
"data-state": step.state,
|
|
1169
|
+
children: [
|
|
1170
|
+
/* @__PURE__ */ jsx(
|
|
1171
|
+
"span",
|
|
1172
|
+
{
|
|
1173
|
+
className: "agent-activity-bubble__step-icon",
|
|
1174
|
+
"aria-hidden": "true",
|
|
1175
|
+
children: step.state === "completed" ? "\u2713" : step.state === "error" ? "!" : ""
|
|
1176
|
+
}
|
|
1177
|
+
),
|
|
1178
|
+
/* @__PURE__ */ jsxs("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
1179
|
+
/* @__PURE__ */ jsx("strong", { children: step.label }),
|
|
1180
|
+
step.detail ? /* @__PURE__ */ jsx("small", { children: step.detail }) : null
|
|
1181
|
+
] })
|
|
1182
|
+
]
|
|
1183
|
+
},
|
|
1184
|
+
step.id
|
|
1185
|
+
)) })
|
|
1186
|
+
] })
|
|
1187
|
+
] });
|
|
1051
1188
|
}
|
|
1052
1189
|
|
|
1053
1190
|
// src/react/components/Composer/Composer.tsx
|
|
1054
1191
|
import { useRef as useRef2, useState as useState2 } from "react";
|
|
1055
|
-
import { jsx as
|
|
1192
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1056
1193
|
function SendIcon() {
|
|
1057
|
-
return /* @__PURE__ */
|
|
1194
|
+
return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M8 12V4M8 4l-3 3M8 4l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
1058
1195
|
}
|
|
1059
1196
|
function Composer({
|
|
1060
1197
|
disabled = false,
|
|
@@ -1081,8 +1218,8 @@ function Composer({
|
|
|
1081
1218
|
submitCurrent();
|
|
1082
1219
|
}
|
|
1083
1220
|
}
|
|
1084
|
-
return /* @__PURE__ */
|
|
1085
|
-
/* @__PURE__ */
|
|
1221
|
+
return /* @__PURE__ */ jsx2("form", { className: `composer${variant === "dock" ? " composer--dock" : ""}`, onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs2("div", { className: "composer__field", children: [
|
|
1222
|
+
/* @__PURE__ */ jsx2(
|
|
1086
1223
|
"textarea",
|
|
1087
1224
|
{
|
|
1088
1225
|
ref: inputRef,
|
|
@@ -1096,21 +1233,21 @@ function Composer({
|
|
|
1096
1233
|
onKeyDown: handleKeyDown
|
|
1097
1234
|
}
|
|
1098
1235
|
),
|
|
1099
|
-
/* @__PURE__ */
|
|
1236
|
+
/* @__PURE__ */ jsx2(
|
|
1100
1237
|
"button",
|
|
1101
1238
|
{
|
|
1102
1239
|
type: "submit",
|
|
1103
1240
|
className: "composer__send",
|
|
1104
1241
|
disabled: disabled || !value.trim(),
|
|
1105
1242
|
"aria-label": "Send message",
|
|
1106
|
-
children: /* @__PURE__ */
|
|
1243
|
+
children: /* @__PURE__ */ jsx2(SendIcon, {})
|
|
1107
1244
|
}
|
|
1108
1245
|
)
|
|
1109
1246
|
] }) });
|
|
1110
1247
|
}
|
|
1111
1248
|
|
|
1112
1249
|
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
1113
|
-
import { jsx as
|
|
1250
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1114
1251
|
function FollowUpChips({
|
|
1115
1252
|
suggestions,
|
|
1116
1253
|
disabled = false,
|
|
@@ -1120,7 +1257,7 @@ function FollowUpChips({
|
|
|
1120
1257
|
}) {
|
|
1121
1258
|
if (suggestions.length === 0) return null;
|
|
1122
1259
|
if (variant === "dock") {
|
|
1123
|
-
return /* @__PURE__ */
|
|
1260
|
+
return /* @__PURE__ */ jsx3("div", { className: "followups followups--dock", children: /* @__PURE__ */ jsx3("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx3(
|
|
1124
1261
|
"button",
|
|
1125
1262
|
{
|
|
1126
1263
|
type: "button",
|
|
@@ -1133,8 +1270,8 @@ function FollowUpChips({
|
|
|
1133
1270
|
)) }) });
|
|
1134
1271
|
}
|
|
1135
1272
|
return /* @__PURE__ */ jsxs3("div", { className: "followups", children: [
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
/* @__PURE__ */
|
|
1273
|
+
/* @__PURE__ */ jsx3("span", { className: "followups__label", children: label }),
|
|
1274
|
+
/* @__PURE__ */ jsx3("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx3(
|
|
1138
1275
|
"button",
|
|
1139
1276
|
{
|
|
1140
1277
|
type: "button",
|
|
@@ -1151,12 +1288,12 @@ function FollowUpChips({
|
|
|
1151
1288
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
1152
1289
|
import { Streamdown } from "streamdown";
|
|
1153
1290
|
import "streamdown/styles.css";
|
|
1154
|
-
import { jsx as
|
|
1291
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1155
1292
|
function MessageBubble({ message }) {
|
|
1156
1293
|
if (message.role === "visitor") {
|
|
1157
|
-
return /* @__PURE__ */
|
|
1294
|
+
return /* @__PURE__ */ jsx4("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ jsx4("p", { className: "message-bubble__text", children: message.text }) });
|
|
1158
1295
|
}
|
|
1159
|
-
return /* @__PURE__ */
|
|
1296
|
+
return /* @__PURE__ */ jsx4("article", { className: "message-bubble message-bubble--agent", children: /* @__PURE__ */ jsx4("div", { className: "message-bubble__text", children: /* @__PURE__ */ jsx4(
|
|
1160
1297
|
Streamdown,
|
|
1161
1298
|
{
|
|
1162
1299
|
animated: true,
|
|
@@ -1173,12 +1310,20 @@ function MessageBubble({ message }) {
|
|
|
1173
1310
|
}
|
|
1174
1311
|
|
|
1175
1312
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
1176
|
-
import { jsx as
|
|
1313
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1177
1314
|
function MinimizeIcon() {
|
|
1178
|
-
return /* @__PURE__ */
|
|
1315
|
+
return /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(
|
|
1316
|
+
"path",
|
|
1317
|
+
{
|
|
1318
|
+
d: "M3.5 8h9",
|
|
1319
|
+
stroke: "currentColor",
|
|
1320
|
+
strokeWidth: "1.7",
|
|
1321
|
+
strokeLinecap: "round"
|
|
1322
|
+
}
|
|
1323
|
+
) });
|
|
1179
1324
|
}
|
|
1180
1325
|
function ExpandIcon() {
|
|
1181
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(
|
|
1182
1327
|
"path",
|
|
1183
1328
|
{
|
|
1184
1329
|
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
@@ -1190,7 +1335,7 @@ function ExpandIcon() {
|
|
|
1190
1335
|
) });
|
|
1191
1336
|
}
|
|
1192
1337
|
function RestoreIcon() {
|
|
1193
|
-
return /* @__PURE__ */
|
|
1338
|
+
return /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(
|
|
1194
1339
|
"path",
|
|
1195
1340
|
{
|
|
1196
1341
|
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
@@ -1205,6 +1350,7 @@ function AgentRail({
|
|
|
1205
1350
|
state,
|
|
1206
1351
|
theme,
|
|
1207
1352
|
brandLabel = "Webless Assist",
|
|
1353
|
+
brandLogoUrl,
|
|
1208
1354
|
poweredByLabel = "Powered by Webless",
|
|
1209
1355
|
composerPlaceholder = "Ask anything\u2026",
|
|
1210
1356
|
mobileFullscreen = false,
|
|
@@ -1216,10 +1362,31 @@ function AgentRail({
|
|
|
1216
1362
|
onFollowUpSelect
|
|
1217
1363
|
}) {
|
|
1218
1364
|
const transcriptRef = useRef3(null);
|
|
1219
|
-
const
|
|
1365
|
+
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1366
|
+
const railStyle = {
|
|
1367
|
+
"--rail-width": resolvedTheme.railMaxWidth,
|
|
1368
|
+
"--as-rail-max-width": resolvedTheme.railMaxWidth,
|
|
1369
|
+
"--as-brand": resolvedTheme.brand,
|
|
1370
|
+
"--as-brand-soft": resolvedTheme.brandSoft,
|
|
1371
|
+
"--as-brand-deep": resolvedTheme.brandDeep,
|
|
1372
|
+
"--as-surface": resolvedTheme.surface,
|
|
1373
|
+
"--as-surface-muted": resolvedTheme.surfaceMuted,
|
|
1374
|
+
"--as-text": resolvedTheme.text,
|
|
1375
|
+
"--as-text-muted": resolvedTheme.textMuted,
|
|
1376
|
+
"--as-text-subtle": resolvedTheme.textSubtle,
|
|
1377
|
+
"--as-border": resolvedTheme.border,
|
|
1378
|
+
"--as-visitor-bubble": resolvedTheme.visitorBubble,
|
|
1379
|
+
"--as-visitor-text": resolvedTheme.visitorText,
|
|
1380
|
+
"--as-success": resolvedTheme.success,
|
|
1381
|
+
"--as-danger": resolvedTheme.danger,
|
|
1382
|
+
"--as-font-body": resolvedTheme.fontBody,
|
|
1383
|
+
"--as-font-display": resolvedTheme.fontDisplay
|
|
1384
|
+
};
|
|
1220
1385
|
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
1221
|
-
const showActivity = state.toolSteps.length > 0
|
|
1222
|
-
const hasVisitorMessages2 = state.messages.some(
|
|
1386
|
+
const showActivity = state.toolSteps.length > 0;
|
|
1387
|
+
const hasVisitorMessages2 = state.messages.some(
|
|
1388
|
+
(message) => message.role === "visitor"
|
|
1389
|
+
);
|
|
1223
1390
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1224
1391
|
const showDockFollowUps = expanded && showIdleFollowUps;
|
|
1225
1392
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
@@ -1233,7 +1400,13 @@ function AgentRail({
|
|
|
1233
1400
|
const node = transcriptRef.current;
|
|
1234
1401
|
if (!node) return;
|
|
1235
1402
|
node.scrollTop = node.scrollHeight;
|
|
1236
|
-
}, [
|
|
1403
|
+
}, [
|
|
1404
|
+
state.messages,
|
|
1405
|
+
state.toolSteps,
|
|
1406
|
+
state.streamingText,
|
|
1407
|
+
state.followUps,
|
|
1408
|
+
state.journey
|
|
1409
|
+
]);
|
|
1237
1410
|
return /* @__PURE__ */ jsxs4(
|
|
1238
1411
|
"aside",
|
|
1239
1412
|
{
|
|
@@ -1241,34 +1414,59 @@ function AgentRail({
|
|
|
1241
1414
|
style: railStyle,
|
|
1242
1415
|
"aria-label": "Agent conversation",
|
|
1243
1416
|
children: [
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
onCollapse ? /* @__PURE__ */
|
|
1417
|
+
/* @__PURE__ */ jsx5("header", { className: "agent-rail__header", children: /* @__PURE__ */ jsxs4("div", { className: "agent-rail__brand-row", children: [
|
|
1418
|
+
onCollapse ? /* @__PURE__ */ jsx5(
|
|
1246
1419
|
"button",
|
|
1247
1420
|
{
|
|
1248
1421
|
type: "button",
|
|
1249
1422
|
className: "agent-rail__collapse",
|
|
1250
1423
|
"aria-label": "Collapse assist",
|
|
1251
1424
|
onClick: onCollapse,
|
|
1252
|
-
children: /* @__PURE__ */
|
|
1425
|
+
children: /* @__PURE__ */ jsx5(MinimizeIcon, {})
|
|
1253
1426
|
}
|
|
1254
|
-
) : onClose ? /* @__PURE__ */
|
|
1255
|
-
|
|
1256
|
-
|
|
1427
|
+
) : onClose ? /* @__PURE__ */ jsx5(
|
|
1428
|
+
"button",
|
|
1429
|
+
{
|
|
1430
|
+
type: "button",
|
|
1431
|
+
className: "agent-rail__close",
|
|
1432
|
+
"aria-label": "Close agent",
|
|
1433
|
+
onClick: onClose,
|
|
1434
|
+
children: /* @__PURE__ */ jsx5(MinimizeIcon, {})
|
|
1435
|
+
}
|
|
1436
|
+
) : /* @__PURE__ */ jsx5("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1437
|
+
/* @__PURE__ */ jsxs4("span", { className: "agent-rail__identity", children: [
|
|
1438
|
+
/* @__PURE__ */ jsxs4("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: [
|
|
1439
|
+
brandLabel.slice(0, 1).toUpperCase(),
|
|
1440
|
+
brandLogoUrl ? /* @__PURE__ */ jsx5(
|
|
1441
|
+
"img",
|
|
1442
|
+
{
|
|
1443
|
+
className: "agent-rail__brand-logo",
|
|
1444
|
+
src: brandLogoUrl,
|
|
1445
|
+
alt: "",
|
|
1446
|
+
onError: (event) => {
|
|
1447
|
+
event.currentTarget.hidden = true;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
) : null
|
|
1451
|
+
] }),
|
|
1452
|
+
/* @__PURE__ */ jsx5("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1453
|
+
] }),
|
|
1454
|
+
onExpandToggle ? /* @__PURE__ */ jsx5(
|
|
1257
1455
|
"button",
|
|
1258
1456
|
{
|
|
1259
1457
|
type: "button",
|
|
1260
1458
|
className: "agent-rail__expand",
|
|
1261
1459
|
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
1262
1460
|
onClick: onExpandToggle,
|
|
1263
|
-
children: expanded ? /* @__PURE__ */
|
|
1461
|
+
children: expanded ? /* @__PURE__ */ jsx5(RestoreIcon, {}) : /* @__PURE__ */ jsx5(ExpandIcon, {})
|
|
1264
1462
|
}
|
|
1265
|
-
) : /* @__PURE__ */
|
|
1463
|
+
) : /* @__PURE__ */ jsx5("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
1266
1464
|
] }) }),
|
|
1267
1465
|
/* @__PURE__ */ jsxs4("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
1268
|
-
state.messages.map((message) => /* @__PURE__ */
|
|
1269
|
-
streamingMessage ? /* @__PURE__ */
|
|
1270
|
-
showActivity ? /* @__PURE__ */
|
|
1271
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */
|
|
1466
|
+
state.messages.map((message) => /* @__PURE__ */ jsx5(MessageBubble, { message }, message.id)),
|
|
1467
|
+
streamingMessage ? /* @__PURE__ */ jsx5(MessageBubble, { message: streamingMessage }) : null,
|
|
1468
|
+
showActivity ? /* @__PURE__ */ jsx5(AgentActivityBubble, { steps: state.toolSteps }) : null,
|
|
1469
|
+
!expanded && showIdleFollowUps ? /* @__PURE__ */ jsx5("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ jsx5(
|
|
1272
1470
|
FollowUpChips,
|
|
1273
1471
|
{
|
|
1274
1472
|
suggestions: state.followUps,
|
|
@@ -1277,10 +1475,17 @@ function AgentRail({
|
|
|
1277
1475
|
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1278
1476
|
}
|
|
1279
1477
|
) }) : null,
|
|
1280
|
-
state.error ? /* @__PURE__ */
|
|
1478
|
+
state.error ? /* @__PURE__ */ jsx5(
|
|
1479
|
+
"p",
|
|
1480
|
+
{
|
|
1481
|
+
role: "alert",
|
|
1482
|
+
style: { fontSize: 13, color: "var(--as-danger)", margin: 0 },
|
|
1483
|
+
children: state.error
|
|
1484
|
+
}
|
|
1485
|
+
) : null
|
|
1281
1486
|
] }),
|
|
1282
1487
|
expanded ? /* @__PURE__ */ jsxs4("div", { className: "agent-rail__dock-wrap", children: [
|
|
1283
|
-
showDockFollowUps ? /* @__PURE__ */
|
|
1488
|
+
showDockFollowUps ? /* @__PURE__ */ jsx5("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ jsx5(
|
|
1284
1489
|
FollowUpChips,
|
|
1285
1490
|
{
|
|
1286
1491
|
variant: "dock",
|
|
@@ -1289,7 +1494,7 @@ function AgentRail({
|
|
|
1289
1494
|
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1290
1495
|
}
|
|
1291
1496
|
) }) : null,
|
|
1292
|
-
/* @__PURE__ */
|
|
1497
|
+
/* @__PURE__ */ jsx5("div", { className: "agent-rail__dock", children: /* @__PURE__ */ jsx5(
|
|
1293
1498
|
Composer,
|
|
1294
1499
|
{
|
|
1295
1500
|
variant: "dock",
|
|
@@ -1299,11 +1504,11 @@ function AgentRail({
|
|
|
1299
1504
|
}
|
|
1300
1505
|
) }),
|
|
1301
1506
|
/* @__PURE__ */ jsxs4("div", { className: "agent-rail__footer", children: [
|
|
1302
|
-
/* @__PURE__ */
|
|
1303
|
-
/* @__PURE__ */
|
|
1507
|
+
/* @__PURE__ */ jsx5("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1508
|
+
/* @__PURE__ */ jsx5("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1304
1509
|
] })
|
|
1305
1510
|
] }) : /* @__PURE__ */ jsxs4("div", { className: "agent-rail__composer-wrap", children: [
|
|
1306
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx5(
|
|
1307
1512
|
Composer,
|
|
1308
1513
|
{
|
|
1309
1514
|
disabled: isBusy,
|
|
@@ -1312,8 +1517,8 @@ function AgentRail({
|
|
|
1312
1517
|
}
|
|
1313
1518
|
),
|
|
1314
1519
|
/* @__PURE__ */ jsxs4("div", { className: "agent-rail__footer", children: [
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1520
|
+
/* @__PURE__ */ jsx5("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1521
|
+
/* @__PURE__ */ jsx5("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1317
1522
|
] })
|
|
1318
1523
|
] })
|
|
1319
1524
|
]
|
|
@@ -1322,22 +1527,67 @@ function AgentRail({
|
|
|
1322
1527
|
}
|
|
1323
1528
|
|
|
1324
1529
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
1325
|
-
import { Fragment, jsx as
|
|
1530
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1326
1531
|
function SparklesIcon() {
|
|
1327
|
-
return /* @__PURE__ */ jsxs5(
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1532
|
+
return /* @__PURE__ */ jsxs5(
|
|
1533
|
+
"svg",
|
|
1534
|
+
{
|
|
1535
|
+
className: "assist-edge-tab__sparkles",
|
|
1536
|
+
viewBox: "0 0 18 16",
|
|
1537
|
+
fill: "none",
|
|
1538
|
+
"aria-hidden": "true",
|
|
1539
|
+
children: [
|
|
1540
|
+
/* @__PURE__ */ jsx6(
|
|
1541
|
+
"path",
|
|
1542
|
+
{
|
|
1543
|
+
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",
|
|
1544
|
+
fill: "currentColor"
|
|
1545
|
+
}
|
|
1546
|
+
),
|
|
1547
|
+
/* @__PURE__ */ jsx6(
|
|
1548
|
+
"path",
|
|
1549
|
+
{
|
|
1550
|
+
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",
|
|
1551
|
+
fill: "currentColor"
|
|
1552
|
+
}
|
|
1553
|
+
),
|
|
1554
|
+
/* @__PURE__ */ jsx6(
|
|
1555
|
+
"path",
|
|
1556
|
+
{
|
|
1557
|
+
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",
|
|
1558
|
+
fill: "currentColor"
|
|
1559
|
+
}
|
|
1560
|
+
)
|
|
1561
|
+
]
|
|
1562
|
+
}
|
|
1563
|
+
);
|
|
1332
1564
|
}
|
|
1333
1565
|
function ChevronLeftIcon() {
|
|
1334
|
-
return /* @__PURE__ */
|
|
1566
|
+
return /* @__PURE__ */ jsx6("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx6(
|
|
1567
|
+
"path",
|
|
1568
|
+
{
|
|
1569
|
+
d: "M10 4L6 8l4 4",
|
|
1570
|
+
stroke: "currentColor",
|
|
1571
|
+
strokeWidth: "1.6",
|
|
1572
|
+
strokeLinecap: "round",
|
|
1573
|
+
strokeLinejoin: "round"
|
|
1574
|
+
}
|
|
1575
|
+
) });
|
|
1335
1576
|
}
|
|
1336
1577
|
function ChevronDownIcon() {
|
|
1337
|
-
return /* @__PURE__ */
|
|
1578
|
+
return /* @__PURE__ */ jsx6("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx6(
|
|
1579
|
+
"path",
|
|
1580
|
+
{
|
|
1581
|
+
d: "M4 6l4 4 4-4",
|
|
1582
|
+
stroke: "currentColor",
|
|
1583
|
+
strokeWidth: "1.6",
|
|
1584
|
+
strokeLinecap: "round",
|
|
1585
|
+
strokeLinejoin: "round"
|
|
1586
|
+
}
|
|
1587
|
+
) });
|
|
1338
1588
|
}
|
|
1339
1589
|
function DragDots() {
|
|
1340
|
-
return /* @__PURE__ */
|
|
1590
|
+
return /* @__PURE__ */ jsx6("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ jsx6("i", {}, index)) });
|
|
1341
1591
|
}
|
|
1342
1592
|
var VARIANT_COPY = {
|
|
1343
1593
|
outline: { label: "Assist", aria: "Open Assist" },
|
|
@@ -1350,12 +1600,19 @@ function AssistEdgeTab({
|
|
|
1350
1600
|
along,
|
|
1351
1601
|
inset,
|
|
1352
1602
|
visible,
|
|
1603
|
+
label,
|
|
1604
|
+
logoUrl,
|
|
1605
|
+
brandColor,
|
|
1606
|
+
fontFamily,
|
|
1353
1607
|
onOpen
|
|
1354
1608
|
}) {
|
|
1355
1609
|
const copy = VARIANT_COPY[variant];
|
|
1610
|
+
const visibleLabel = label?.trim() || copy.label;
|
|
1356
1611
|
const style = {
|
|
1357
1612
|
"--tab-along": `${along}%`,
|
|
1358
|
-
"--tab-inset": `${inset}px
|
|
1613
|
+
"--tab-inset": `${inset}px`,
|
|
1614
|
+
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1615
|
+
...fontFamily ? { "--as-font-display": fontFamily } : {}
|
|
1359
1616
|
};
|
|
1360
1617
|
return /* @__PURE__ */ jsxs5(
|
|
1361
1618
|
"button",
|
|
@@ -1363,25 +1620,51 @@ function AssistEdgeTab({
|
|
|
1363
1620
|
type: "button",
|
|
1364
1621
|
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
1365
1622
|
style,
|
|
1366
|
-
"aria-label":
|
|
1623
|
+
"aria-label": `Open ${visibleLabel}`,
|
|
1367
1624
|
"aria-hidden": !visible,
|
|
1368
1625
|
tabIndex: visible ? 0 : -1,
|
|
1369
1626
|
onClick: onOpen,
|
|
1370
1627
|
children: [
|
|
1371
1628
|
variant === "outline" ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1372
|
-
/* @__PURE__ */
|
|
1373
|
-
|
|
1374
|
-
|
|
1629
|
+
/* @__PURE__ */ jsxs5("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1630
|
+
/* @__PURE__ */ jsx6(SparklesIcon, {}),
|
|
1631
|
+
logoUrl ? /* @__PURE__ */ jsx6(
|
|
1632
|
+
"img",
|
|
1633
|
+
{
|
|
1634
|
+
className: "assist-edge-tab__logo",
|
|
1635
|
+
src: logoUrl,
|
|
1636
|
+
alt: "",
|
|
1637
|
+
onError: (event) => {
|
|
1638
|
+
event.currentTarget.hidden = true;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
) : null
|
|
1642
|
+
] }),
|
|
1643
|
+
/* @__PURE__ */ jsx6("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1644
|
+
/* @__PURE__ */ jsx6(ChevronDownIcon, {})
|
|
1375
1645
|
] }) : null,
|
|
1376
1646
|
variant === "ask" ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1377
|
-
/* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1379
|
-
/* @__PURE__ */
|
|
1647
|
+
/* @__PURE__ */ jsx6(ChevronLeftIcon, {}),
|
|
1648
|
+
/* @__PURE__ */ jsx6("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1649
|
+
/* @__PURE__ */ jsx6(DragDots, {})
|
|
1380
1650
|
] }) : null,
|
|
1381
1651
|
variant === "fill" ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1382
|
-
/* @__PURE__ */
|
|
1383
|
-
|
|
1384
|
-
|
|
1652
|
+
/* @__PURE__ */ jsxs5("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1653
|
+
/* @__PURE__ */ jsx6(SparklesIcon, {}),
|
|
1654
|
+
logoUrl ? /* @__PURE__ */ jsx6(
|
|
1655
|
+
"img",
|
|
1656
|
+
{
|
|
1657
|
+
className: "assist-edge-tab__logo",
|
|
1658
|
+
src: logoUrl,
|
|
1659
|
+
alt: "",
|
|
1660
|
+
onError: (event) => {
|
|
1661
|
+
event.currentTarget.hidden = true;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
) : null
|
|
1665
|
+
] }),
|
|
1666
|
+
/* @__PURE__ */ jsx6("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
1667
|
+
/* @__PURE__ */ jsx6(ChevronLeftIcon, {})
|
|
1385
1668
|
] }) : null
|
|
1386
1669
|
]
|
|
1387
1670
|
}
|
|
@@ -1503,7 +1786,7 @@ function closeAgentPanel(customerId) {
|
|
|
1503
1786
|
}
|
|
1504
1787
|
|
|
1505
1788
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
1506
|
-
import { jsx as
|
|
1789
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1507
1790
|
function AgentWidget({
|
|
1508
1791
|
indexId,
|
|
1509
1792
|
customerId,
|
|
@@ -1513,7 +1796,8 @@ function AgentWidget({
|
|
|
1513
1796
|
placement: placementInput,
|
|
1514
1797
|
defaultCollapsed = true,
|
|
1515
1798
|
pageShift = true,
|
|
1516
|
-
registerPanelController = false
|
|
1799
|
+
registerPanelController = false,
|
|
1800
|
+
branding
|
|
1517
1801
|
}) {
|
|
1518
1802
|
const isMobile = useIsMobile();
|
|
1519
1803
|
const placement = normalizeAgentPlacement(placementInput);
|
|
@@ -1535,8 +1819,27 @@ function AgentWidget({
|
|
|
1535
1819
|
getUnpublishedPreviewGrant,
|
|
1536
1820
|
indexId,
|
|
1537
1821
|
version,
|
|
1538
|
-
runtimeOrigin
|
|
1822
|
+
runtimeOrigin,
|
|
1823
|
+
greeting: branding?.greeting
|
|
1539
1824
|
});
|
|
1825
|
+
const agentName = branding?.agentName ?? "Webless Guide";
|
|
1826
|
+
const theme = {
|
|
1827
|
+
...branding?.fontFamily ? { fontBody: branding.fontFamily, fontDisplay: branding.fontFamily } : {},
|
|
1828
|
+
...branding?.colors?.primary ? {
|
|
1829
|
+
brand: branding.colors.primary,
|
|
1830
|
+
visitorBubble: branding.colors.primary
|
|
1831
|
+
} : {},
|
|
1832
|
+
...branding?.colors?.primarySoft ? { brandSoft: branding.colors.primarySoft } : {},
|
|
1833
|
+
...branding?.colors?.primaryForeground ? { visitorText: branding.colors.primaryForeground } : {},
|
|
1834
|
+
...branding?.colors?.surface ? { surface: branding.colors.surface } : {},
|
|
1835
|
+
...branding?.colors?.surfaceMuted ? { surfaceMuted: branding.colors.surfaceMuted } : {},
|
|
1836
|
+
...branding?.colors?.text ? { text: branding.colors.text } : {},
|
|
1837
|
+
...branding?.colors?.textMuted ? {
|
|
1838
|
+
textMuted: branding.colors.textMuted,
|
|
1839
|
+
textSubtle: branding.colors.textMuted
|
|
1840
|
+
} : {},
|
|
1841
|
+
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
1842
|
+
};
|
|
1540
1843
|
const idle = state.phase === "idle" && !hasVisitorMessages(state.messages);
|
|
1541
1844
|
useEffect5(() => {
|
|
1542
1845
|
if (!registerPanelController) return;
|
|
@@ -1554,47 +1857,55 @@ function AgentWidget({
|
|
|
1554
1857
|
await submit(message);
|
|
1555
1858
|
}
|
|
1556
1859
|
return /* @__PURE__ */ jsxs6("div", { className: "webless-agent-root", children: [
|
|
1557
|
-
/* @__PURE__ */
|
|
1860
|
+
/* @__PURE__ */ jsxs6(
|
|
1558
1861
|
"div",
|
|
1559
1862
|
{
|
|
1560
1863
|
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
1561
|
-
children:
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1864
|
+
children: [
|
|
1865
|
+
/* @__PURE__ */ jsx7(
|
|
1866
|
+
"div",
|
|
1867
|
+
{
|
|
1868
|
+
ref: railSlotRef,
|
|
1869
|
+
className: "webless-agent-root__rail-slot",
|
|
1870
|
+
inert: railCollapsed || void 0,
|
|
1871
|
+
"aria-hidden": railCollapsed,
|
|
1872
|
+
children: /* @__PURE__ */ jsx7(
|
|
1873
|
+
AgentRail,
|
|
1874
|
+
{
|
|
1875
|
+
theme,
|
|
1876
|
+
brandLabel: agentName,
|
|
1877
|
+
brandLogoUrl: branding?.logoUrl,
|
|
1878
|
+
composerPlaceholder: branding?.composerPlaceholder ?? `Ask ${agentName}\u2026`,
|
|
1879
|
+
poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
|
|
1880
|
+
state: idle ? {
|
|
1881
|
+
...state,
|
|
1882
|
+
followUps: createIdleSuggestions()
|
|
1883
|
+
} : state,
|
|
1884
|
+
mobileFullscreen: isMobile && !railCollapsed,
|
|
1885
|
+
expanded: railExpanded,
|
|
1886
|
+
onCollapse: !isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1887
|
+
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1888
|
+
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1889
|
+
onSubmit: handleSubmit,
|
|
1890
|
+
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1891
|
+
}
|
|
1892
|
+
)
|
|
1893
|
+
}
|
|
1894
|
+
),
|
|
1895
|
+
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ jsx7(
|
|
1896
|
+
"button",
|
|
1897
|
+
{
|
|
1898
|
+
type: "button",
|
|
1899
|
+
className: "webless-agent-root__backdrop",
|
|
1900
|
+
tabIndex: -1,
|
|
1901
|
+
"aria-label": "Close expanded assist",
|
|
1902
|
+
onClick: () => setRailExpanded(false)
|
|
1903
|
+
}
|
|
1904
|
+
) : null
|
|
1905
|
+
]
|
|
1586
1906
|
}
|
|
1587
1907
|
),
|
|
1588
|
-
|
|
1589
|
-
"button",
|
|
1590
|
-
{
|
|
1591
|
-
type: "button",
|
|
1592
|
-
className: "webless-agent-root__backdrop",
|
|
1593
|
-
"aria-label": "Close expanded assist",
|
|
1594
|
-
onClick: () => setRailExpanded(false)
|
|
1595
|
-
}
|
|
1596
|
-
) : null,
|
|
1597
|
-
railCollapsed ? /* @__PURE__ */ jsx8(
|
|
1908
|
+
railCollapsed ? /* @__PURE__ */ jsx7(
|
|
1598
1909
|
AssistEdgeTab,
|
|
1599
1910
|
{
|
|
1600
1911
|
variant: placement.variant,
|
|
@@ -1602,6 +1913,10 @@ function AgentWidget({
|
|
|
1602
1913
|
along: placement.along,
|
|
1603
1914
|
inset: placement.inset,
|
|
1604
1915
|
visible: true,
|
|
1916
|
+
label: agentName,
|
|
1917
|
+
logoUrl: branding?.logoUrl,
|
|
1918
|
+
brandColor: branding?.colors?.primary,
|
|
1919
|
+
fontFamily: branding?.fontFamily,
|
|
1605
1920
|
onOpen: () => setRailCollapsed(false)
|
|
1606
1921
|
}
|
|
1607
1922
|
) : null
|
|
@@ -1619,8 +1934,9 @@ export {
|
|
|
1619
1934
|
normalizeAgentPlacement,
|
|
1620
1935
|
openAgentPanel,
|
|
1621
1936
|
closeAgentPanel,
|
|
1937
|
+
defaultAgentRailTheme,
|
|
1622
1938
|
AgentRail,
|
|
1623
1939
|
AssistEdgeTab,
|
|
1624
1940
|
AgentWidget
|
|
1625
1941
|
};
|
|
1626
|
-
//# sourceMappingURL=chunk-
|
|
1942
|
+
//# sourceMappingURL=chunk-MMYSBSHG.js.map
|