@agents24/chat-react 0.2.0 → 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 +4 -3
- package/dist/controller-hitl.d.ts +22 -0
- package/dist/controller-options.d.ts +15 -0
- package/dist/controller-thread-events.d.ts +7 -0
- package/dist/controller.d.ts +4 -16
- package/dist/index.cjs +217 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +205 -118
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +36 -18
- package/dist/ui/agent-response-timeline.d.ts +3 -3
- package/dist/ui/index.cjs +169 -156
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +169 -156
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.js
CHANGED
|
@@ -712,69 +712,10 @@ import { ChevronDown as ChevronDown2, ChevronUp } from "lucide-react";
|
|
|
712
712
|
import * as React4 from "react";
|
|
713
713
|
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
714
714
|
|
|
715
|
-
// src/ui/mcp-connect-required-card.tsx
|
|
716
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
717
|
-
var STATUS_LABELS = {
|
|
718
|
-
pending: "Connect",
|
|
719
|
-
connecting: "Connecting",
|
|
720
|
-
connected: "Connected",
|
|
721
|
-
resuming: "Resuming",
|
|
722
|
-
error: "Try again"
|
|
723
|
-
};
|
|
724
|
-
function McpConnectRequiredCard({
|
|
725
|
-
serverName,
|
|
726
|
-
providerKey,
|
|
727
|
-
message,
|
|
728
|
-
status = "pending",
|
|
729
|
-
disabled = false,
|
|
730
|
-
loading = false,
|
|
731
|
-
error,
|
|
732
|
-
onConnect,
|
|
733
|
-
className,
|
|
734
|
-
...props
|
|
735
|
-
}) {
|
|
736
|
-
const label = String(serverName || providerKey || "MCP server").trim();
|
|
737
|
-
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
738
|
-
const isConnected = status === "connected";
|
|
739
|
-
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
740
|
-
return /* @__PURE__ */ jsx5(
|
|
741
|
-
"div",
|
|
742
|
-
{
|
|
743
|
-
"data-agents24-mcp-connect-card": true,
|
|
744
|
-
"data-status": status,
|
|
745
|
-
className: cn(
|
|
746
|
-
"w-full rounded-lg border border-border/50 bg-muted/25 p-3 text-sm text-foreground",
|
|
747
|
-
className
|
|
748
|
-
),
|
|
749
|
-
...props,
|
|
750
|
-
children: /* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
751
|
-
/* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
|
|
752
|
-
/* @__PURE__ */ jsx5("div", { className: "truncate text-sm font-medium", children: label }),
|
|
753
|
-
/* @__PURE__ */ jsx5("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
754
|
-
status === "error" && error ? /* @__PURE__ */ jsx5("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
755
|
-
] }),
|
|
756
|
-
/* @__PURE__ */ jsx5(
|
|
757
|
-
"button",
|
|
758
|
-
{
|
|
759
|
-
type: "button",
|
|
760
|
-
className: cn(
|
|
761
|
-
"shrink-0 rounded-md border px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-60",
|
|
762
|
-
status === "pending" || status === "error" ? "border-neutral-900 bg-neutral-900 text-white hover:bg-neutral-800" : "border-border bg-background text-foreground hover:bg-muted"
|
|
763
|
-
),
|
|
764
|
-
disabled: buttonDisabled,
|
|
765
|
-
onClick: onConnect,
|
|
766
|
-
children: STATUS_LABELS[status]
|
|
767
|
-
}
|
|
768
|
-
)
|
|
769
|
-
] })
|
|
770
|
-
}
|
|
771
|
-
);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
715
|
// src/ui/message-response.tsx
|
|
775
716
|
import * as React3 from "react";
|
|
776
717
|
import { defaultRehypePlugins, Streamdown } from "streamdown";
|
|
777
|
-
import { Fragment, jsx as
|
|
718
|
+
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
778
719
|
var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
|
|
779
720
|
"blockquote",
|
|
780
721
|
"div",
|
|
@@ -817,12 +758,12 @@ function MessageMarkdownParagraph({
|
|
|
817
758
|
);
|
|
818
759
|
const isImageOnly = childArray.length === 1 && React3.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
|
|
819
760
|
if (isImageOnly) {
|
|
820
|
-
return /* @__PURE__ */
|
|
761
|
+
return /* @__PURE__ */ jsx5(Fragment, { children });
|
|
821
762
|
}
|
|
822
763
|
if (childArray.some(hasBlockMarkdownChild)) {
|
|
823
|
-
return /* @__PURE__ */
|
|
764
|
+
return /* @__PURE__ */ jsx5("div", { ...domProps, children });
|
|
824
765
|
}
|
|
825
|
-
return /* @__PURE__ */
|
|
766
|
+
return /* @__PURE__ */ jsx5("p", { ...domProps, children });
|
|
826
767
|
}
|
|
827
768
|
var MESSAGE_RESPONSE_COMPONENTS = {
|
|
828
769
|
p: MessageMarkdownParagraph
|
|
@@ -868,7 +809,7 @@ var MessageResponse = React3.memo(
|
|
|
868
809
|
() => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
|
|
869
810
|
[components]
|
|
870
811
|
);
|
|
871
|
-
return /* @__PURE__ */
|
|
812
|
+
return /* @__PURE__ */ jsx5(
|
|
872
813
|
Streamdown,
|
|
873
814
|
{
|
|
874
815
|
className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
|
|
@@ -884,9 +825,7 @@ var MessageResponse = React3.memo(
|
|
|
884
825
|
MessageResponse.displayName = "MessageResponse";
|
|
885
826
|
|
|
886
827
|
// src/ui/agent-response-timeline.tsx
|
|
887
|
-
import { jsx as
|
|
888
|
-
var CONNECT_DECISION = "connect";
|
|
889
|
-
var HITL_DECISIONS = ["approve", "edit", "reject", "respond", "connect"];
|
|
828
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
890
829
|
function asRecord(value) {
|
|
891
830
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
892
831
|
}
|
|
@@ -914,7 +853,7 @@ function isActiveTool(part, activeToolId) {
|
|
|
914
853
|
return part.id === activeToolId || part.toolCallId === activeToolId || part.state === "input-available" || part.state === "input-streaming";
|
|
915
854
|
}
|
|
916
855
|
function Shimmer({ children, className }) {
|
|
917
|
-
return /* @__PURE__ */
|
|
856
|
+
return /* @__PURE__ */ jsx6("span", { className: cn("inline-block animate-pulse", className), children });
|
|
918
857
|
}
|
|
919
858
|
function CompactTask({
|
|
920
859
|
children,
|
|
@@ -926,12 +865,12 @@ function CompactTask({
|
|
|
926
865
|
}) {
|
|
927
866
|
const [open, setOpen] = React4.useState(defaultOpen);
|
|
928
867
|
const expandable = Boolean(children || detail);
|
|
929
|
-
const content = loading ? /* @__PURE__ */
|
|
868
|
+
const content = loading ? /* @__PURE__ */ jsx6(Shimmer, { children: label }) : /* @__PURE__ */ jsx6("span", { children: label });
|
|
930
869
|
if (!expandable) {
|
|
931
|
-
return /* @__PURE__ */
|
|
870
|
+
return /* @__PURE__ */ jsx6("div", { className: cn("flex min-w-0 items-center gap-1.5 text-sm", error ? "text-destructive" : "text-muted-foreground"), children: content });
|
|
932
871
|
}
|
|
933
|
-
return /* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
872
|
+
return /* @__PURE__ */ jsxs3("div", { className: "w-full", children: [
|
|
873
|
+
/* @__PURE__ */ jsxs3(
|
|
935
874
|
"button",
|
|
936
875
|
{
|
|
937
876
|
"aria-expanded": open,
|
|
@@ -943,12 +882,12 @@ function CompactTask({
|
|
|
943
882
|
type: "button",
|
|
944
883
|
children: [
|
|
945
884
|
content,
|
|
946
|
-
open ? /* @__PURE__ */
|
|
885
|
+
open ? /* @__PURE__ */ jsx6(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx6(ChevronRight, { className: "size-3 opacity-70" })
|
|
947
886
|
]
|
|
948
887
|
}
|
|
949
888
|
),
|
|
950
|
-
open ? /* @__PURE__ */
|
|
951
|
-
detail ? /* @__PURE__ */
|
|
889
|
+
open ? /* @__PURE__ */ jsxs3("div", { className: "mt-1 pl-4 text-sm text-muted-foreground", children: [
|
|
890
|
+
detail ? /* @__PURE__ */ jsx6("div", { children: detail }) : null,
|
|
952
891
|
children
|
|
953
892
|
] }) : null
|
|
954
893
|
] });
|
|
@@ -957,7 +896,7 @@ function ToolPartRow({
|
|
|
957
896
|
activeToolId,
|
|
958
897
|
part
|
|
959
898
|
}) {
|
|
960
|
-
return /* @__PURE__ */
|
|
899
|
+
return /* @__PURE__ */ jsx6("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsx6(
|
|
961
900
|
CompactTask,
|
|
962
901
|
{
|
|
963
902
|
defaultOpen: part.state === "output-error",
|
|
@@ -973,40 +912,23 @@ function ToolGroup({
|
|
|
973
912
|
parts
|
|
974
913
|
}) {
|
|
975
914
|
const loading = parts.some((part) => isActiveTool(part, activeToolId));
|
|
976
|
-
return /* @__PURE__ */
|
|
915
|
+
return /* @__PURE__ */ jsx6(CompactTask, { label: groupLabel(parts[0]), loading, children: /* @__PURE__ */ jsx6("div", { className: "space-y-1", children: parts.map((part) => /* @__PURE__ */ jsxs3(
|
|
977
916
|
"div",
|
|
978
917
|
{
|
|
979
918
|
className: cn("text-sm", part.state === "output-error" ? "text-destructive" : "text-muted-foreground"),
|
|
980
919
|
children: [
|
|
981
|
-
isActiveTool(part, activeToolId) ? /* @__PURE__ */
|
|
982
|
-
toolDetail(part) ? /* @__PURE__ */
|
|
920
|
+
isActiveTool(part, activeToolId) ? /* @__PURE__ */ jsx6(Shimmer, { children: toolLabel(part) }) : toolLabel(part),
|
|
921
|
+
toolDetail(part) ? /* @__PURE__ */ jsx6("span", { className: "ml-1 text-xs text-muted-foreground/75", children: toolDetail(part) }) : null
|
|
983
922
|
]
|
|
984
923
|
},
|
|
985
924
|
part.id
|
|
986
925
|
)) }) });
|
|
987
926
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
return allowed.filter((item) => HITL_DECISIONS.includes(String(item)));
|
|
994
|
-
});
|
|
995
|
-
return Array.from(new Set(decisions));
|
|
996
|
-
}
|
|
997
|
-
function isMcpConnectHitl(part) {
|
|
998
|
-
const kind = `${part.hitlKind || optionalString(part.hitl.kind) || ""}`.toLowerCase();
|
|
999
|
-
const decisions = collectHitlDecisions(part);
|
|
1000
|
-
return decisions.includes(CONNECT_DECISION) || kind.includes("mcp") || kind.includes("connection");
|
|
1001
|
-
}
|
|
1002
|
-
function mcpConnectLabel(part) {
|
|
1003
|
-
const payload = asRecord(part.hitl.client_safe_payload);
|
|
1004
|
-
const origin = asRecord(part.hitl.origin);
|
|
1005
|
-
return optionalString(part.hitl.server_name) || optionalString(part.hitl.provider_name) || optionalString(payload?.server_name) || optionalString(payload?.provider_name) || optionalString(origin?.server_name) || optionalString(origin?.provider_name) || "MCP server";
|
|
1006
|
-
}
|
|
1007
|
-
function normalizedMcpStatus(status) {
|
|
1008
|
-
if (status === "connecting" || status === "connected" || status === "resuming" || status === "error") return status;
|
|
1009
|
-
return "pending";
|
|
927
|
+
function actionLabel(part, action) {
|
|
928
|
+
if (action === "approve") return part.hitlKind === "tool_review" ? "Allow once" : "Approve";
|
|
929
|
+
if (action === "reject") return part.hitlKind === "tool_review" ? "Don\u2019t allow" : "Reject";
|
|
930
|
+
if (action === "connect") return "Connect";
|
|
931
|
+
return "Skip";
|
|
1010
932
|
}
|
|
1011
933
|
function HitlPartRow({
|
|
1012
934
|
getHitlActionState,
|
|
@@ -1015,36 +937,68 @@ function HitlPartRow({
|
|
|
1015
937
|
part
|
|
1016
938
|
}) {
|
|
1017
939
|
const state = getHitlActionState?.(part);
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
940
|
+
const [comment, setComment] = React4.useState("");
|
|
941
|
+
const presentation = part.presentation || {};
|
|
942
|
+
const details = asRecord(presentation.sanitized_arguments);
|
|
943
|
+
const requireComment = presentation.require_comment === true;
|
|
944
|
+
const isTerminal = part.status !== "pending";
|
|
945
|
+
if (isTerminal) {
|
|
946
|
+
return /* @__PURE__ */ jsxs3("div", { className: "rounded-xl border border-border/60 bg-muted/30 px-3 py-2 text-sm text-muted-foreground", children: [
|
|
947
|
+
/* @__PURE__ */ jsx6("span", { className: "font-medium text-foreground", children: part.resolution?.outcome || part.status }),
|
|
948
|
+
part.resolution?.reason ? /* @__PURE__ */ jsxs3("span", { className: "ml-1", children: [
|
|
949
|
+
"\xB7 ",
|
|
950
|
+
part.resolution.reason
|
|
951
|
+
] }) : null
|
|
952
|
+
] });
|
|
953
|
+
}
|
|
954
|
+
return /* @__PURE__ */ jsxs3("div", { className: "space-y-3 rounded-xl border border-amber-500/30 bg-amber-500/5 p-3", children: [
|
|
955
|
+
/* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
|
|
956
|
+
/* @__PURE__ */ jsx6("div", { className: "text-sm font-semibold text-foreground", children: optionalString(presentation.tool_name) || optionalString(presentation.server_name) || "Action required" }),
|
|
957
|
+
/* @__PURE__ */ jsx6(MessageResponse, { children: part.message }),
|
|
958
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
959
|
+
optionalString(presentation.source) ? /* @__PURE__ */ jsxs3("span", { children: [
|
|
960
|
+
"Source: ",
|
|
961
|
+
optionalString(presentation.source)
|
|
962
|
+
] }) : null,
|
|
963
|
+
optionalString(presentation.risk) ? /* @__PURE__ */ jsxs3("span", { children: [
|
|
964
|
+
"Risk: ",
|
|
965
|
+
optionalString(presentation.risk)
|
|
966
|
+
] }) : null,
|
|
967
|
+
optionalString(presentation.credential_scope) ? /* @__PURE__ */ jsxs3("span", { children: [
|
|
968
|
+
"Credentials: ",
|
|
969
|
+
optionalString(presentation.credential_scope)
|
|
970
|
+
] }) : null
|
|
971
|
+
] })
|
|
972
|
+
] }),
|
|
973
|
+
details ? /* @__PURE__ */ jsxs3("details", { className: "text-xs text-muted-foreground", children: [
|
|
974
|
+
/* @__PURE__ */ jsx6("summary", { className: "cursor-pointer select-none font-medium", children: "Details" }),
|
|
975
|
+
/* @__PURE__ */ jsx6("pre", { className: "mt-2 max-h-48 overflow-auto rounded-lg bg-background/80 p-2 text-[11px]", children: JSON.stringify(details, null, 2) })
|
|
976
|
+
] }) : null,
|
|
977
|
+
requireComment ? /* @__PURE__ */ jsx6(
|
|
978
|
+
"textarea",
|
|
1022
979
|
{
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
980
|
+
"aria-label": "Approval comment",
|
|
981
|
+
className: "min-h-20 w-full resize-y rounded-lg border border-border bg-background px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
982
|
+
onChange: (event) => setComment(event.target.value),
|
|
983
|
+
placeholder: "Comment required",
|
|
984
|
+
value: comment
|
|
1028
985
|
}
|
|
1029
|
-
)
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
return /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
|
|
1033
|
-
/* @__PURE__ */ jsx7(MessageResponse, { children: message }),
|
|
1034
|
-
state?.error ? /* @__PURE__ */ jsx7("div", { className: "text-sm text-destructive", children: state.error }) : null,
|
|
1035
|
-
/* @__PURE__ */ jsx7("div", { className: "flex flex-wrap items-center gap-2", children: decisions.map((decision) => /* @__PURE__ */ jsx7(
|
|
986
|
+
) : null,
|
|
987
|
+
state?.error ? /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: state.error }) : null,
|
|
988
|
+
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-2", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx6(
|
|
1036
989
|
"button",
|
|
1037
990
|
{
|
|
991
|
+
"aria-label": actionLabel(part, action),
|
|
1038
992
|
className: cn(
|
|
1039
993
|
"min-w-24 rounded-md border px-3 py-1.5 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-60",
|
|
1040
|
-
|
|
994
|
+
action === "approve" || action === "connect" ? "border-neutral-900 bg-neutral-900 text-white hover:bg-neutral-800" : "border-border bg-background text-foreground hover:bg-muted"
|
|
1041
995
|
),
|
|
1042
|
-
disabled: !onHitlAction || isLoading || state?.status === "connecting" || state?.status === "resuming",
|
|
1043
|
-
onClick: () => onHitlAction?.(part,
|
|
996
|
+
disabled: !onHitlAction || isLoading || state?.status === "connecting" || state?.status === "resuming" || requireComment && !comment.trim(),
|
|
997
|
+
onClick: () => onHitlAction?.(part, action, comment.trim() || void 0),
|
|
1044
998
|
type: "button",
|
|
1045
|
-
children:
|
|
999
|
+
children: actionLabel(part, action)
|
|
1046
1000
|
},
|
|
1047
|
-
|
|
1001
|
+
action
|
|
1048
1002
|
)) })
|
|
1049
1003
|
] });
|
|
1050
1004
|
}
|
|
@@ -1056,20 +1010,20 @@ function DefaultPartRow({
|
|
|
1056
1010
|
onHitlAction,
|
|
1057
1011
|
part
|
|
1058
1012
|
}) {
|
|
1059
|
-
if (part.kind === "text") return /* @__PURE__ */
|
|
1060
|
-
if (part.kind === "tool") return /* @__PURE__ */
|
|
1013
|
+
if (part.kind === "text") return /* @__PURE__ */ jsx6(MessageResponse, { children: part.text });
|
|
1014
|
+
if (part.kind === "tool") return /* @__PURE__ */ jsx6(ToolPartRow, { activeToolId, part });
|
|
1061
1015
|
if (part.kind === "reasoning") {
|
|
1062
1016
|
const label = part.text || part.label || "Thinking";
|
|
1063
|
-
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */
|
|
1017
|
+
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ jsx6(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ jsx6("div", { className: "text-sm text-muted-foreground", children: label });
|
|
1064
1018
|
}
|
|
1065
1019
|
if (part.kind === "ui-blocks") {
|
|
1066
1020
|
if (part.state === "output-error") {
|
|
1067
|
-
return /* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
|
|
1068
1022
|
}
|
|
1069
|
-
return /* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsx6(CompactTask, { label: part.state === "input-streaming" ? "Rendering UI block" : "Rendered UI block", loading: part.state === "input-streaming" });
|
|
1070
1024
|
}
|
|
1071
1025
|
if (part.kind === "hitl") {
|
|
1072
|
-
return /* @__PURE__ */
|
|
1026
|
+
return /* @__PURE__ */ jsx6(
|
|
1073
1027
|
HitlPartRow,
|
|
1074
1028
|
{
|
|
1075
1029
|
getHitlActionState,
|
|
@@ -1079,8 +1033,8 @@ function DefaultPartRow({
|
|
|
1079
1033
|
}
|
|
1080
1034
|
);
|
|
1081
1035
|
}
|
|
1082
|
-
if (part.kind === "error") return /* @__PURE__ */
|
|
1083
|
-
if (part.kind === "data") return /* @__PURE__ */
|
|
1036
|
+
if (part.kind === "error") return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText });
|
|
1037
|
+
if (part.kind === "data") return /* @__PURE__ */ jsx6("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
|
|
1084
1038
|
return null;
|
|
1085
1039
|
}
|
|
1086
1040
|
function AgentResponseTimeline({
|
|
@@ -1105,11 +1059,11 @@ function AgentResponseTimeline({
|
|
|
1105
1059
|
group.push(candidate);
|
|
1106
1060
|
index += 1;
|
|
1107
1061
|
}
|
|
1108
|
-
rendered.push(group.length === 1 ? /* @__PURE__ */
|
|
1062
|
+
rendered.push(group.length === 1 ? /* @__PURE__ */ jsx6(ToolPartRow, { activeToolId, part: group[0] }, group[0].id) : /* @__PURE__ */ jsx6(ToolGroup, { activeToolId, parts: group }, `tool-group-${key}-${group[0].id}`));
|
|
1109
1063
|
continue;
|
|
1110
1064
|
}
|
|
1111
1065
|
rendered.push(
|
|
1112
|
-
/* @__PURE__ */
|
|
1066
|
+
/* @__PURE__ */ jsx6(React4.Fragment, { children: renderPart ? renderPart(part, message) : /* @__PURE__ */ jsx6(
|
|
1113
1067
|
DefaultPartRow,
|
|
1114
1068
|
{
|
|
1115
1069
|
activeToolId,
|
|
@@ -1124,16 +1078,16 @@ function AgentResponseTimeline({
|
|
|
1124
1078
|
index += 1;
|
|
1125
1079
|
}
|
|
1126
1080
|
if (rendered.length === 0 && message.content) {
|
|
1127
|
-
rendered.push(/* @__PURE__ */
|
|
1081
|
+
rendered.push(/* @__PURE__ */ jsx6(MessageResponse, { children: message.content }, `${message.id}-fallback`));
|
|
1128
1082
|
}
|
|
1129
1083
|
if (rendered.length === 0 && isLoading) {
|
|
1130
|
-
rendered.push(/* @__PURE__ */
|
|
1084
|
+
rendered.push(/* @__PURE__ */ jsx6("div", { className: "text-sm text-muted-foreground", children: "Thinking" }, `${message.id}-thinking`));
|
|
1131
1085
|
}
|
|
1132
|
-
return /* @__PURE__ */
|
|
1086
|
+
return /* @__PURE__ */ jsx6("div", { className: "space-y-3", children: rendered });
|
|
1133
1087
|
}
|
|
1134
1088
|
|
|
1135
1089
|
// src/ui/agent-chat-message.tsx
|
|
1136
|
-
import { jsx as
|
|
1090
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1137
1091
|
var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
|
|
1138
1092
|
var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
|
|
1139
1093
|
function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
|
|
@@ -1156,9 +1110,9 @@ function AgentChatUserMessageContent({
|
|
|
1156
1110
|
display: "-webkit-box",
|
|
1157
1111
|
overflow: "hidden"
|
|
1158
1112
|
} : void 0;
|
|
1159
|
-
return /* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1161
|
-
shouldCollapse ? /* @__PURE__ */
|
|
1113
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
1114
|
+
/* @__PURE__ */ jsx7("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
|
|
1115
|
+
shouldCollapse ? /* @__PURE__ */ jsxs4(
|
|
1162
1116
|
"button",
|
|
1163
1117
|
{
|
|
1164
1118
|
"aria-controls": contentId,
|
|
@@ -1171,7 +1125,7 @@ function AgentChatUserMessageContent({
|
|
|
1171
1125
|
type: "button",
|
|
1172
1126
|
children: [
|
|
1173
1127
|
isExpanded ? showLessLabel : showMoreLabel,
|
|
1174
|
-
/* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx7(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
|
|
1175
1129
|
]
|
|
1176
1130
|
}
|
|
1177
1131
|
) : null
|
|
@@ -1203,9 +1157,9 @@ function AgentChatMessage({
|
|
|
1203
1157
|
const resolvedUserContent = userMessageContent ?? message.content;
|
|
1204
1158
|
const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
|
|
1205
1159
|
const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
|
|
1206
|
-
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */
|
|
1207
|
-
return /* @__PURE__ */
|
|
1208
|
-
showAttachments ? /* @__PURE__ */
|
|
1160
|
+
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx7(AgentChatDefaultActions, { handlers: actionHandlers, message }) : null);
|
|
1161
|
+
return /* @__PURE__ */ jsxs4(ChatMessage, { className, dir, from: message.role, children: [
|
|
1162
|
+
showAttachments ? /* @__PURE__ */ jsx7(ChatAttachments, { className: "mb-2", dir, children: message.attachments?.map((attachment, index) => /* @__PURE__ */ jsx7(
|
|
1209
1163
|
ChatAttachment,
|
|
1210
1164
|
{
|
|
1211
1165
|
data: attachment,
|
|
@@ -1213,13 +1167,13 @@ function AgentChatMessage({
|
|
|
1213
1167
|
},
|
|
1214
1168
|
String(attachment.url || attachment.filename || index)
|
|
1215
1169
|
)) }) : null,
|
|
1216
|
-
shouldRenderContent ? /* @__PURE__ */
|
|
1170
|
+
shouldRenderContent ? /* @__PURE__ */ jsxs4(
|
|
1217
1171
|
ChatMessageContent,
|
|
1218
1172
|
{
|
|
1219
1173
|
className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
|
|
1220
1174
|
dir,
|
|
1221
1175
|
children: [
|
|
1222
|
-
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */
|
|
1176
|
+
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx7(
|
|
1223
1177
|
AgentResponseTimeline,
|
|
1224
1178
|
{
|
|
1225
1179
|
getHitlActionState,
|
|
@@ -1229,7 +1183,7 @@ function AgentChatMessage({
|
|
|
1229
1183
|
renderPart
|
|
1230
1184
|
}
|
|
1231
1185
|
) : null,
|
|
1232
|
-
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */
|
|
1186
|
+
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx7(
|
|
1233
1187
|
AgentChatUserMessageContent,
|
|
1234
1188
|
{
|
|
1235
1189
|
collapsedLines: userMessageCollapsedLines,
|
|
@@ -1242,16 +1196,16 @@ function AgentChatMessage({
|
|
|
1242
1196
|
]
|
|
1243
1197
|
}
|
|
1244
1198
|
) : null,
|
|
1245
|
-
renderedActions ? /* @__PURE__ */
|
|
1199
|
+
renderedActions ? /* @__PURE__ */ jsx7("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full translate-x-2" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
|
|
1246
1200
|
] });
|
|
1247
1201
|
}
|
|
1248
1202
|
|
|
1249
1203
|
// src/ui/bubble.tsx
|
|
1250
1204
|
import { cva as cva2 } from "class-variance-authority";
|
|
1251
1205
|
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
1252
|
-
import { jsx as
|
|
1206
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1253
1207
|
function BubbleGroup({ className, ...props }) {
|
|
1254
|
-
return /* @__PURE__ */
|
|
1208
|
+
return /* @__PURE__ */ jsx8(
|
|
1255
1209
|
"div",
|
|
1256
1210
|
{
|
|
1257
1211
|
"data-slot": "bubble-group",
|
|
@@ -1285,7 +1239,7 @@ function Bubble({
|
|
|
1285
1239
|
className,
|
|
1286
1240
|
...props
|
|
1287
1241
|
}) {
|
|
1288
|
-
return /* @__PURE__ */
|
|
1242
|
+
return /* @__PURE__ */ jsx8(
|
|
1289
1243
|
"div",
|
|
1290
1244
|
{
|
|
1291
1245
|
"data-slot": "bubble",
|
|
@@ -1302,7 +1256,7 @@ function BubbleContent({
|
|
|
1302
1256
|
...props
|
|
1303
1257
|
}) {
|
|
1304
1258
|
const Comp = asChild ? Slot2 : "div";
|
|
1305
|
-
return /* @__PURE__ */
|
|
1259
|
+
return /* @__PURE__ */ jsx8(
|
|
1306
1260
|
Comp,
|
|
1307
1261
|
{
|
|
1308
1262
|
"data-slot": "bubble-content",
|
|
@@ -1339,7 +1293,7 @@ function BubbleReactions({
|
|
|
1339
1293
|
className,
|
|
1340
1294
|
...props
|
|
1341
1295
|
}) {
|
|
1342
|
-
return /* @__PURE__ */
|
|
1296
|
+
return /* @__PURE__ */ jsx8(
|
|
1343
1297
|
"div",
|
|
1344
1298
|
{
|
|
1345
1299
|
"data-slot": "bubble-reactions",
|
|
@@ -1354,7 +1308,7 @@ function BubbleReactions({
|
|
|
1354
1308
|
// src/ui/marker.tsx
|
|
1355
1309
|
import { cva as cva3 } from "class-variance-authority";
|
|
1356
1310
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
1357
|
-
import { jsx as
|
|
1311
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1358
1312
|
var markerVariants = cva3(
|
|
1359
1313
|
"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground",
|
|
1360
1314
|
{
|
|
@@ -1374,7 +1328,7 @@ function Marker({
|
|
|
1374
1328
|
...props
|
|
1375
1329
|
}) {
|
|
1376
1330
|
const Comp = asChild ? Slot3 : "div";
|
|
1377
|
-
return /* @__PURE__ */
|
|
1331
|
+
return /* @__PURE__ */ jsx9(
|
|
1378
1332
|
Comp,
|
|
1379
1333
|
{
|
|
1380
1334
|
"data-slot": "marker",
|
|
@@ -1385,7 +1339,7 @@ function Marker({
|
|
|
1385
1339
|
);
|
|
1386
1340
|
}
|
|
1387
1341
|
function MarkerIcon({ className, ...props }) {
|
|
1388
|
-
return /* @__PURE__ */
|
|
1342
|
+
return /* @__PURE__ */ jsx9(
|
|
1389
1343
|
"span",
|
|
1390
1344
|
{
|
|
1391
1345
|
"data-slot": "marker-icon",
|
|
@@ -1399,7 +1353,7 @@ function MarkerIcon({ className, ...props }) {
|
|
|
1399
1353
|
);
|
|
1400
1354
|
}
|
|
1401
1355
|
function MarkerContent({ className, ...props }) {
|
|
1402
|
-
return /* @__PURE__ */
|
|
1356
|
+
return /* @__PURE__ */ jsx9(
|
|
1403
1357
|
"span",
|
|
1404
1358
|
{
|
|
1405
1359
|
"data-slot": "marker-content",
|
|
@@ -1411,6 +1365,65 @@ function MarkerContent({ className, ...props }) {
|
|
|
1411
1365
|
}
|
|
1412
1366
|
);
|
|
1413
1367
|
}
|
|
1368
|
+
|
|
1369
|
+
// src/ui/mcp-connect-required-card.tsx
|
|
1370
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1371
|
+
var STATUS_LABELS = {
|
|
1372
|
+
pending: "Connect",
|
|
1373
|
+
connecting: "Connecting",
|
|
1374
|
+
connected: "Connected",
|
|
1375
|
+
resuming: "Resuming",
|
|
1376
|
+
error: "Try again"
|
|
1377
|
+
};
|
|
1378
|
+
function McpConnectRequiredCard({
|
|
1379
|
+
serverName,
|
|
1380
|
+
providerKey,
|
|
1381
|
+
message,
|
|
1382
|
+
status = "pending",
|
|
1383
|
+
disabled = false,
|
|
1384
|
+
loading = false,
|
|
1385
|
+
error,
|
|
1386
|
+
onConnect,
|
|
1387
|
+
className,
|
|
1388
|
+
...props
|
|
1389
|
+
}) {
|
|
1390
|
+
const label = String(serverName || providerKey || "MCP server").trim();
|
|
1391
|
+
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
1392
|
+
const isConnected = status === "connected";
|
|
1393
|
+
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
1394
|
+
return /* @__PURE__ */ jsx10(
|
|
1395
|
+
"div",
|
|
1396
|
+
{
|
|
1397
|
+
"data-agents24-mcp-connect-card": true,
|
|
1398
|
+
"data-status": status,
|
|
1399
|
+
className: cn(
|
|
1400
|
+
"w-full rounded-lg border border-border/50 bg-muted/25 p-3 text-sm text-foreground",
|
|
1401
|
+
className
|
|
1402
|
+
),
|
|
1403
|
+
...props,
|
|
1404
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
1405
|
+
/* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
|
|
1406
|
+
/* @__PURE__ */ jsx10("div", { className: "truncate text-sm font-medium", children: label }),
|
|
1407
|
+
/* @__PURE__ */ jsx10("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
1408
|
+
status === "error" && error ? /* @__PURE__ */ jsx10("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
1409
|
+
] }),
|
|
1410
|
+
/* @__PURE__ */ jsx10(
|
|
1411
|
+
"button",
|
|
1412
|
+
{
|
|
1413
|
+
type: "button",
|
|
1414
|
+
className: cn(
|
|
1415
|
+
"shrink-0 rounded-md border px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-60",
|
|
1416
|
+
status === "pending" || status === "error" ? "border-neutral-900 bg-neutral-900 text-white hover:bg-neutral-800" : "border-border bg-background text-foreground hover:bg-muted"
|
|
1417
|
+
),
|
|
1418
|
+
disabled: buttonDisabled,
|
|
1419
|
+
onClick: onConnect,
|
|
1420
|
+
children: STATUS_LABELS[status]
|
|
1421
|
+
}
|
|
1422
|
+
)
|
|
1423
|
+
] })
|
|
1424
|
+
}
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1414
1427
|
export {
|
|
1415
1428
|
AgentChatComposer,
|
|
1416
1429
|
AgentChatDefaultActions,
|