@agents24/chat-react 0.2.0 → 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/README.md +7 -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 +295 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +288 -126
- package/dist/index.js.map +1 -1
- package/dist/mcp-oauth.d.ts +2 -0
- package/dist/types.d.ts +46 -18
- package/dist/ui/agent-response-timeline.d.ts +3 -3
- package/dist/ui/hitl-presentation.d.ts +4 -0
- package/dist/ui/index.cjs +177 -163
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +174 -163
- 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),
|
|
@@ -883,20 +824,47 @@ var MessageResponse = React3.memo(
|
|
|
883
824
|
);
|
|
884
825
|
MessageResponse.displayName = "MessageResponse";
|
|
885
826
|
|
|
886
|
-
// src/ui/
|
|
887
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
888
|
-
var CONNECT_DECISION = "connect";
|
|
889
|
-
var HITL_DECISIONS = ["approve", "edit", "reject", "respond", "connect"];
|
|
890
|
-
function asRecord(value) {
|
|
891
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
892
|
-
}
|
|
827
|
+
// src/ui/hitl-presentation.ts
|
|
893
828
|
function optionalString(value) {
|
|
894
829
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
895
830
|
}
|
|
831
|
+
function hitlActionLabel(part, action) {
|
|
832
|
+
if (action === "approve") return ["tool_review", "app_data_permission"].includes(part.hitlKind) ? "Allow once" : "Approve";
|
|
833
|
+
if (action === "reject") return ["tool_review", "app_data_permission"].includes(part.hitlKind) ? "Don\u2019t allow" : "Reject";
|
|
834
|
+
if (action === "connect") return "Connect";
|
|
835
|
+
return "Skip";
|
|
836
|
+
}
|
|
837
|
+
function hitlTitle(part) {
|
|
838
|
+
const presentation = part.presentation || {};
|
|
839
|
+
if (part.hitlKind === "tool_review") return `Run ${optionalString(presentation.tool_name) || "this tool"}?`;
|
|
840
|
+
if (part.hitlKind === "mcp_auth") return `Connect ${optionalString(presentation.server_name) || "this service"} to continue`;
|
|
841
|
+
if (part.hitlKind === "app_data_permission") return "Allow this data change?";
|
|
842
|
+
return part.message;
|
|
843
|
+
}
|
|
844
|
+
function resolvedHitlLabel(part) {
|
|
845
|
+
const outcome = String(part.resolution?.outcome || part.status).trim().toLowerCase();
|
|
846
|
+
return {
|
|
847
|
+
approved: part.hitlKind === "user_approval" ? "Approved" : "Allowed",
|
|
848
|
+
rejected: part.hitlKind === "user_approval" ? "Rejected" : "Not allowed",
|
|
849
|
+
connected: "Connected",
|
|
850
|
+
skipped: "Skipped",
|
|
851
|
+
timeout: "Timed out",
|
|
852
|
+
expired: "Timed out",
|
|
853
|
+
cancelled: "Cancelled",
|
|
854
|
+
invalidated: "No longer available",
|
|
855
|
+
policy_denied: "Not allowed"
|
|
856
|
+
}[outcome] || outcome.replace(/_/g, " ");
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/ui/agent-response-timeline.tsx
|
|
860
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
861
|
+
function optionalString2(value) {
|
|
862
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
863
|
+
}
|
|
896
864
|
function presentationValue(part, key) {
|
|
897
865
|
const presentation = part.presentation || {};
|
|
898
866
|
const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
899
|
-
return
|
|
867
|
+
return optionalString2(presentation[key]) || optionalString2(presentation[snakeKey]);
|
|
900
868
|
}
|
|
901
869
|
function groupKey(part) {
|
|
902
870
|
return presentationValue(part, "groupKey");
|
|
@@ -914,7 +882,7 @@ function isActiveTool(part, activeToolId) {
|
|
|
914
882
|
return part.id === activeToolId || part.toolCallId === activeToolId || part.state === "input-available" || part.state === "input-streaming";
|
|
915
883
|
}
|
|
916
884
|
function Shimmer({ children, className }) {
|
|
917
|
-
return /* @__PURE__ */
|
|
885
|
+
return /* @__PURE__ */ jsx6("span", { className: cn("inline-block animate-pulse", className), children });
|
|
918
886
|
}
|
|
919
887
|
function CompactTask({
|
|
920
888
|
children,
|
|
@@ -926,12 +894,12 @@ function CompactTask({
|
|
|
926
894
|
}) {
|
|
927
895
|
const [open, setOpen] = React4.useState(defaultOpen);
|
|
928
896
|
const expandable = Boolean(children || detail);
|
|
929
|
-
const content = loading ? /* @__PURE__ */
|
|
897
|
+
const content = loading ? /* @__PURE__ */ jsx6(Shimmer, { children: label }) : /* @__PURE__ */ jsx6("span", { children: label });
|
|
930
898
|
if (!expandable) {
|
|
931
|
-
return /* @__PURE__ */
|
|
899
|
+
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
900
|
}
|
|
933
|
-
return /* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
901
|
+
return /* @__PURE__ */ jsxs3("div", { className: "w-full", children: [
|
|
902
|
+
/* @__PURE__ */ jsxs3(
|
|
935
903
|
"button",
|
|
936
904
|
{
|
|
937
905
|
"aria-expanded": open,
|
|
@@ -943,12 +911,12 @@ function CompactTask({
|
|
|
943
911
|
type: "button",
|
|
944
912
|
children: [
|
|
945
913
|
content,
|
|
946
|
-
open ? /* @__PURE__ */
|
|
914
|
+
open ? /* @__PURE__ */ jsx6(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx6(ChevronRight, { className: "size-3 opacity-70" })
|
|
947
915
|
]
|
|
948
916
|
}
|
|
949
917
|
),
|
|
950
|
-
open ? /* @__PURE__ */
|
|
951
|
-
detail ? /* @__PURE__ */
|
|
918
|
+
open ? /* @__PURE__ */ jsxs3("div", { className: "mt-1 pl-4 text-sm text-muted-foreground", children: [
|
|
919
|
+
detail ? /* @__PURE__ */ jsx6("div", { children: detail }) : null,
|
|
952
920
|
children
|
|
953
921
|
] }) : null
|
|
954
922
|
] });
|
|
@@ -957,7 +925,7 @@ function ToolPartRow({
|
|
|
957
925
|
activeToolId,
|
|
958
926
|
part
|
|
959
927
|
}) {
|
|
960
|
-
return /* @__PURE__ */
|
|
928
|
+
return /* @__PURE__ */ jsx6("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsx6(
|
|
961
929
|
CompactTask,
|
|
962
930
|
{
|
|
963
931
|
defaultOpen: part.state === "output-error",
|
|
@@ -973,41 +941,18 @@ function ToolGroup({
|
|
|
973
941
|
parts
|
|
974
942
|
}) {
|
|
975
943
|
const loading = parts.some((part) => isActiveTool(part, activeToolId));
|
|
976
|
-
return /* @__PURE__ */
|
|
944
|
+
return /* @__PURE__ */ jsx6(CompactTask, { label: groupLabel(parts[0]), loading, children: /* @__PURE__ */ jsx6("div", { className: "space-y-1", children: parts.map((part) => /* @__PURE__ */ jsxs3(
|
|
977
945
|
"div",
|
|
978
946
|
{
|
|
979
947
|
className: cn("text-sm", part.state === "output-error" ? "text-destructive" : "text-muted-foreground"),
|
|
980
948
|
children: [
|
|
981
|
-
isActiveTool(part, activeToolId) ? /* @__PURE__ */
|
|
982
|
-
toolDetail(part) ? /* @__PURE__ */
|
|
949
|
+
isActiveTool(part, activeToolId) ? /* @__PURE__ */ jsx6(Shimmer, { children: toolLabel(part) }) : toolLabel(part),
|
|
950
|
+
toolDetail(part) ? /* @__PURE__ */ jsx6("span", { className: "ml-1 text-xs text-muted-foreground/75", children: toolDetail(part) }) : null
|
|
983
951
|
]
|
|
984
952
|
},
|
|
985
953
|
part.id
|
|
986
954
|
)) }) });
|
|
987
955
|
}
|
|
988
|
-
function collectHitlDecisions(part) {
|
|
989
|
-
const configs = Array.isArray(part.hitl.review_configs) ? part.hitl.review_configs : [];
|
|
990
|
-
const decisions = configs.flatMap((config) => {
|
|
991
|
-
const record = asRecord(config);
|
|
992
|
-
const allowed = Array.isArray(record?.allowed_decisions) ? record?.allowed_decisions : [];
|
|
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";
|
|
1010
|
-
}
|
|
1011
956
|
function HitlPartRow({
|
|
1012
957
|
getHitlActionState,
|
|
1013
958
|
isLoading,
|
|
@@ -1015,36 +960,40 @@ function HitlPartRow({
|
|
|
1015
960
|
part
|
|
1016
961
|
}) {
|
|
1017
962
|
const state = getHitlActionState?.(part);
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
963
|
+
const [comment, setComment] = React4.useState("");
|
|
964
|
+
const presentation = part.presentation || {};
|
|
965
|
+
const requireComment = presentation.require_comment === true;
|
|
966
|
+
const isTerminal = part.status !== "pending";
|
|
967
|
+
if (isTerminal) {
|
|
968
|
+
return /* @__PURE__ */ jsx6("div", { className: "px-1 py-1 text-sm text-muted-foreground", children: resolvedHitlLabel(part) });
|
|
969
|
+
}
|
|
970
|
+
return /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 rounded-lg bg-muted/45 px-3 py-2.5", children: [
|
|
971
|
+
/* @__PURE__ */ jsx6("div", { className: "text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
|
|
972
|
+
requireComment ? /* @__PURE__ */ jsx6(
|
|
973
|
+
"textarea",
|
|
1022
974
|
{
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
975
|
+
"aria-label": "Approval comment",
|
|
976
|
+
className: "min-h-20 w-full resize-y rounded-md border border-border/60 bg-background px-3 py-2 text-sm outline-none focus-visible:border-neutral-300 focus-visible:ring-0 dark:focus-visible:border-neutral-600",
|
|
977
|
+
onChange: (event) => setComment(event.target.value),
|
|
978
|
+
placeholder: "Comment required",
|
|
979
|
+
value: comment
|
|
1028
980
|
}
|
|
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(
|
|
981
|
+
) : null,
|
|
982
|
+
state?.error ? /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: state.error }) : null,
|
|
983
|
+
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx6(
|
|
1036
984
|
"button",
|
|
1037
985
|
{
|
|
986
|
+
"aria-label": hitlActionLabel(part, action),
|
|
1038
987
|
className: cn(
|
|
1039
|
-
"min-
|
|
1040
|
-
|
|
988
|
+
"min-h-10 rounded-md px-3 text-sm font-medium transition-[background-color,color,opacity,transform] duration-150 ease-out active:scale-[0.96] disabled:pointer-events-none disabled:opacity-60",
|
|
989
|
+
action === "approve" || action === "connect" ? "bg-neutral-900 text-white hover:bg-neutral-800 dark:bg-neutral-100 dark:text-neutral-900 dark:hover:bg-white" : "bg-transparent text-muted-foreground hover:bg-background/80 hover:text-foreground"
|
|
1041
990
|
),
|
|
1042
|
-
disabled: !onHitlAction || isLoading || state?.status === "connecting" || state?.status === "resuming",
|
|
1043
|
-
onClick: () => onHitlAction?.(part,
|
|
991
|
+
disabled: !onHitlAction || isLoading || state?.status === "connecting" || state?.status === "resuming" || requireComment && !comment.trim(),
|
|
992
|
+
onClick: () => onHitlAction?.(part, action, comment.trim() || void 0),
|
|
1044
993
|
type: "button",
|
|
1045
|
-
children:
|
|
994
|
+
children: hitlActionLabel(part, action)
|
|
1046
995
|
},
|
|
1047
|
-
|
|
996
|
+
action
|
|
1048
997
|
)) })
|
|
1049
998
|
] });
|
|
1050
999
|
}
|
|
@@ -1056,20 +1005,20 @@ function DefaultPartRow({
|
|
|
1056
1005
|
onHitlAction,
|
|
1057
1006
|
part
|
|
1058
1007
|
}) {
|
|
1059
|
-
if (part.kind === "text") return /* @__PURE__ */
|
|
1060
|
-
if (part.kind === "tool") return /* @__PURE__ */
|
|
1008
|
+
if (part.kind === "text") return /* @__PURE__ */ jsx6(MessageResponse, { children: part.text });
|
|
1009
|
+
if (part.kind === "tool") return /* @__PURE__ */ jsx6(ToolPartRow, { activeToolId, part });
|
|
1061
1010
|
if (part.kind === "reasoning") {
|
|
1062
1011
|
const label = part.text || part.label || "Thinking";
|
|
1063
|
-
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */
|
|
1012
|
+
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
1013
|
}
|
|
1065
1014
|
if (part.kind === "ui-blocks") {
|
|
1066
1015
|
if (part.state === "output-error") {
|
|
1067
|
-
return /* @__PURE__ */
|
|
1016
|
+
return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
|
|
1068
1017
|
}
|
|
1069
|
-
return /* @__PURE__ */
|
|
1018
|
+
return /* @__PURE__ */ jsx6(CompactTask, { label: part.state === "input-streaming" ? "Rendering UI block" : "Rendered UI block", loading: part.state === "input-streaming" });
|
|
1070
1019
|
}
|
|
1071
1020
|
if (part.kind === "hitl") {
|
|
1072
|
-
return /* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ jsx6(
|
|
1073
1022
|
HitlPartRow,
|
|
1074
1023
|
{
|
|
1075
1024
|
getHitlActionState,
|
|
@@ -1079,8 +1028,8 @@ function DefaultPartRow({
|
|
|
1079
1028
|
}
|
|
1080
1029
|
);
|
|
1081
1030
|
}
|
|
1082
|
-
if (part.kind === "error") return /* @__PURE__ */
|
|
1083
|
-
if (part.kind === "data") return /* @__PURE__ */
|
|
1031
|
+
if (part.kind === "error") return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText });
|
|
1032
|
+
if (part.kind === "data") return /* @__PURE__ */ jsx6("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
|
|
1084
1033
|
return null;
|
|
1085
1034
|
}
|
|
1086
1035
|
function AgentResponseTimeline({
|
|
@@ -1105,11 +1054,11 @@ function AgentResponseTimeline({
|
|
|
1105
1054
|
group.push(candidate);
|
|
1106
1055
|
index += 1;
|
|
1107
1056
|
}
|
|
1108
|
-
rendered.push(group.length === 1 ? /* @__PURE__ */
|
|
1057
|
+
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
1058
|
continue;
|
|
1110
1059
|
}
|
|
1111
1060
|
rendered.push(
|
|
1112
|
-
/* @__PURE__ */
|
|
1061
|
+
/* @__PURE__ */ jsx6(React4.Fragment, { children: renderPart ? renderPart(part, message) : /* @__PURE__ */ jsx6(
|
|
1113
1062
|
DefaultPartRow,
|
|
1114
1063
|
{
|
|
1115
1064
|
activeToolId,
|
|
@@ -1124,16 +1073,16 @@ function AgentResponseTimeline({
|
|
|
1124
1073
|
index += 1;
|
|
1125
1074
|
}
|
|
1126
1075
|
if (rendered.length === 0 && message.content) {
|
|
1127
|
-
rendered.push(/* @__PURE__ */
|
|
1076
|
+
rendered.push(/* @__PURE__ */ jsx6(MessageResponse, { children: message.content }, `${message.id}-fallback`));
|
|
1128
1077
|
}
|
|
1129
1078
|
if (rendered.length === 0 && isLoading) {
|
|
1130
|
-
rendered.push(/* @__PURE__ */
|
|
1079
|
+
rendered.push(/* @__PURE__ */ jsx6("div", { className: "text-sm text-muted-foreground", children: "Thinking" }, `${message.id}-thinking`));
|
|
1131
1080
|
}
|
|
1132
|
-
return /* @__PURE__ */
|
|
1081
|
+
return /* @__PURE__ */ jsx6("div", { className: "space-y-3", children: rendered });
|
|
1133
1082
|
}
|
|
1134
1083
|
|
|
1135
1084
|
// src/ui/agent-chat-message.tsx
|
|
1136
|
-
import { jsx as
|
|
1085
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1137
1086
|
var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
|
|
1138
1087
|
var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
|
|
1139
1088
|
function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
|
|
@@ -1156,9 +1105,9 @@ function AgentChatUserMessageContent({
|
|
|
1156
1105
|
display: "-webkit-box",
|
|
1157
1106
|
overflow: "hidden"
|
|
1158
1107
|
} : void 0;
|
|
1159
|
-
return /* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1161
|
-
shouldCollapse ? /* @__PURE__ */
|
|
1108
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
1109
|
+
/* @__PURE__ */ jsx7("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
|
|
1110
|
+
shouldCollapse ? /* @__PURE__ */ jsxs4(
|
|
1162
1111
|
"button",
|
|
1163
1112
|
{
|
|
1164
1113
|
"aria-controls": contentId,
|
|
@@ -1171,7 +1120,7 @@ function AgentChatUserMessageContent({
|
|
|
1171
1120
|
type: "button",
|
|
1172
1121
|
children: [
|
|
1173
1122
|
isExpanded ? showLessLabel : showMoreLabel,
|
|
1174
|
-
/* @__PURE__ */
|
|
1123
|
+
/* @__PURE__ */ jsx7(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
|
|
1175
1124
|
]
|
|
1176
1125
|
}
|
|
1177
1126
|
) : null
|
|
@@ -1203,9 +1152,9 @@ function AgentChatMessage({
|
|
|
1203
1152
|
const resolvedUserContent = userMessageContent ?? message.content;
|
|
1204
1153
|
const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
|
|
1205
1154
|
const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
|
|
1206
|
-
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */
|
|
1207
|
-
return /* @__PURE__ */
|
|
1208
|
-
showAttachments ? /* @__PURE__ */
|
|
1155
|
+
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx7(AgentChatDefaultActions, { handlers: actionHandlers, message }) : null);
|
|
1156
|
+
return /* @__PURE__ */ jsxs4(ChatMessage, { className, dir, from: message.role, children: [
|
|
1157
|
+
showAttachments ? /* @__PURE__ */ jsx7(ChatAttachments, { className: "mb-2", dir, children: message.attachments?.map((attachment, index) => /* @__PURE__ */ jsx7(
|
|
1209
1158
|
ChatAttachment,
|
|
1210
1159
|
{
|
|
1211
1160
|
data: attachment,
|
|
@@ -1213,13 +1162,13 @@ function AgentChatMessage({
|
|
|
1213
1162
|
},
|
|
1214
1163
|
String(attachment.url || attachment.filename || index)
|
|
1215
1164
|
)) }) : null,
|
|
1216
|
-
shouldRenderContent ? /* @__PURE__ */
|
|
1165
|
+
shouldRenderContent ? /* @__PURE__ */ jsxs4(
|
|
1217
1166
|
ChatMessageContent,
|
|
1218
1167
|
{
|
|
1219
1168
|
className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
|
|
1220
1169
|
dir,
|
|
1221
1170
|
children: [
|
|
1222
|
-
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */
|
|
1171
|
+
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx7(
|
|
1223
1172
|
AgentResponseTimeline,
|
|
1224
1173
|
{
|
|
1225
1174
|
getHitlActionState,
|
|
@@ -1229,7 +1178,7 @@ function AgentChatMessage({
|
|
|
1229
1178
|
renderPart
|
|
1230
1179
|
}
|
|
1231
1180
|
) : null,
|
|
1232
|
-
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */
|
|
1181
|
+
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx7(
|
|
1233
1182
|
AgentChatUserMessageContent,
|
|
1234
1183
|
{
|
|
1235
1184
|
collapsedLines: userMessageCollapsedLines,
|
|
@@ -1242,16 +1191,16 @@ function AgentChatMessage({
|
|
|
1242
1191
|
]
|
|
1243
1192
|
}
|
|
1244
1193
|
) : null,
|
|
1245
|
-
renderedActions ? /* @__PURE__ */
|
|
1194
|
+
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
1195
|
] });
|
|
1247
1196
|
}
|
|
1248
1197
|
|
|
1249
1198
|
// src/ui/bubble.tsx
|
|
1250
1199
|
import { cva as cva2 } from "class-variance-authority";
|
|
1251
1200
|
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
1252
|
-
import { jsx as
|
|
1201
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1253
1202
|
function BubbleGroup({ className, ...props }) {
|
|
1254
|
-
return /* @__PURE__ */
|
|
1203
|
+
return /* @__PURE__ */ jsx8(
|
|
1255
1204
|
"div",
|
|
1256
1205
|
{
|
|
1257
1206
|
"data-slot": "bubble-group",
|
|
@@ -1285,7 +1234,7 @@ function Bubble({
|
|
|
1285
1234
|
className,
|
|
1286
1235
|
...props
|
|
1287
1236
|
}) {
|
|
1288
|
-
return /* @__PURE__ */
|
|
1237
|
+
return /* @__PURE__ */ jsx8(
|
|
1289
1238
|
"div",
|
|
1290
1239
|
{
|
|
1291
1240
|
"data-slot": "bubble",
|
|
@@ -1302,7 +1251,7 @@ function BubbleContent({
|
|
|
1302
1251
|
...props
|
|
1303
1252
|
}) {
|
|
1304
1253
|
const Comp = asChild ? Slot2 : "div";
|
|
1305
|
-
return /* @__PURE__ */
|
|
1254
|
+
return /* @__PURE__ */ jsx8(
|
|
1306
1255
|
Comp,
|
|
1307
1256
|
{
|
|
1308
1257
|
"data-slot": "bubble-content",
|
|
@@ -1339,7 +1288,7 @@ function BubbleReactions({
|
|
|
1339
1288
|
className,
|
|
1340
1289
|
...props
|
|
1341
1290
|
}) {
|
|
1342
|
-
return /* @__PURE__ */
|
|
1291
|
+
return /* @__PURE__ */ jsx8(
|
|
1343
1292
|
"div",
|
|
1344
1293
|
{
|
|
1345
1294
|
"data-slot": "bubble-reactions",
|
|
@@ -1354,7 +1303,7 @@ function BubbleReactions({
|
|
|
1354
1303
|
// src/ui/marker.tsx
|
|
1355
1304
|
import { cva as cva3 } from "class-variance-authority";
|
|
1356
1305
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
1357
|
-
import { jsx as
|
|
1306
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1358
1307
|
var markerVariants = cva3(
|
|
1359
1308
|
"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
1309
|
{
|
|
@@ -1374,7 +1323,7 @@ function Marker({
|
|
|
1374
1323
|
...props
|
|
1375
1324
|
}) {
|
|
1376
1325
|
const Comp = asChild ? Slot3 : "div";
|
|
1377
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsx9(
|
|
1378
1327
|
Comp,
|
|
1379
1328
|
{
|
|
1380
1329
|
"data-slot": "marker",
|
|
@@ -1385,7 +1334,7 @@ function Marker({
|
|
|
1385
1334
|
);
|
|
1386
1335
|
}
|
|
1387
1336
|
function MarkerIcon({ className, ...props }) {
|
|
1388
|
-
return /* @__PURE__ */
|
|
1337
|
+
return /* @__PURE__ */ jsx9(
|
|
1389
1338
|
"span",
|
|
1390
1339
|
{
|
|
1391
1340
|
"data-slot": "marker-icon",
|
|
@@ -1399,7 +1348,7 @@ function MarkerIcon({ className, ...props }) {
|
|
|
1399
1348
|
);
|
|
1400
1349
|
}
|
|
1401
1350
|
function MarkerContent({ className, ...props }) {
|
|
1402
|
-
return /* @__PURE__ */
|
|
1351
|
+
return /* @__PURE__ */ jsx9(
|
|
1403
1352
|
"span",
|
|
1404
1353
|
{
|
|
1405
1354
|
"data-slot": "marker-content",
|
|
@@ -1411,6 +1360,65 @@ function MarkerContent({ className, ...props }) {
|
|
|
1411
1360
|
}
|
|
1412
1361
|
);
|
|
1413
1362
|
}
|
|
1363
|
+
|
|
1364
|
+
// src/ui/mcp-connect-required-card.tsx
|
|
1365
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1366
|
+
var STATUS_LABELS = {
|
|
1367
|
+
pending: "Connect",
|
|
1368
|
+
connecting: "Connecting",
|
|
1369
|
+
connected: "Connected",
|
|
1370
|
+
resuming: "Resuming",
|
|
1371
|
+
error: "Try again"
|
|
1372
|
+
};
|
|
1373
|
+
function McpConnectRequiredCard({
|
|
1374
|
+
serverName,
|
|
1375
|
+
providerKey,
|
|
1376
|
+
message,
|
|
1377
|
+
status = "pending",
|
|
1378
|
+
disabled = false,
|
|
1379
|
+
loading = false,
|
|
1380
|
+
error,
|
|
1381
|
+
onConnect,
|
|
1382
|
+
className,
|
|
1383
|
+
...props
|
|
1384
|
+
}) {
|
|
1385
|
+
const label = String(serverName || providerKey || "MCP server").trim();
|
|
1386
|
+
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
1387
|
+
const isConnected = status === "connected";
|
|
1388
|
+
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
1389
|
+
return /* @__PURE__ */ jsx10(
|
|
1390
|
+
"div",
|
|
1391
|
+
{
|
|
1392
|
+
"data-agents24-mcp-connect-card": true,
|
|
1393
|
+
"data-status": status,
|
|
1394
|
+
className: cn(
|
|
1395
|
+
"w-full rounded-lg border border-border/50 bg-muted/25 p-3 text-sm text-foreground",
|
|
1396
|
+
className
|
|
1397
|
+
),
|
|
1398
|
+
...props,
|
|
1399
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
1400
|
+
/* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
|
|
1401
|
+
/* @__PURE__ */ jsx10("div", { className: "truncate text-sm font-medium", children: label }),
|
|
1402
|
+
/* @__PURE__ */ jsx10("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
1403
|
+
status === "error" && error ? /* @__PURE__ */ jsx10("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
1404
|
+
] }),
|
|
1405
|
+
/* @__PURE__ */ jsx10(
|
|
1406
|
+
"button",
|
|
1407
|
+
{
|
|
1408
|
+
type: "button",
|
|
1409
|
+
className: cn(
|
|
1410
|
+
"shrink-0 rounded-md border px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-60",
|
|
1411
|
+
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"
|
|
1412
|
+
),
|
|
1413
|
+
disabled: buttonDisabled,
|
|
1414
|
+
onClick: onConnect,
|
|
1415
|
+
children: STATUS_LABELS[status]
|
|
1416
|
+
}
|
|
1417
|
+
)
|
|
1418
|
+
] })
|
|
1419
|
+
}
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1414
1422
|
export {
|
|
1415
1423
|
AgentChatComposer,
|
|
1416
1424
|
AgentChatDefaultActions,
|
|
@@ -1458,7 +1466,10 @@ export {
|
|
|
1458
1466
|
attachmentVariants,
|
|
1459
1467
|
bubbleVariants,
|
|
1460
1468
|
cn,
|
|
1469
|
+
hitlActionLabel,
|
|
1470
|
+
hitlTitle,
|
|
1461
1471
|
markerVariants,
|
|
1472
|
+
resolvedHitlLabel,
|
|
1462
1473
|
shouldCollapseUserMessage
|
|
1463
1474
|
};
|
|
1464
1475
|
//# sourceMappingURL=index.js.map
|