@aigentyc/chat-sdk 0.2.4 → 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/bin/aigentyc.mjs +14 -8
- package/bin/lib/add.mjs +1 -1
- package/bin/lib/doctor.mjs +1 -1
- package/bin/lib/skill.mjs +84 -0
- package/claude-skill/README.md +32 -0
- package/claude-skill/aigentyc-chat-sdk/SKILL.md +339 -0
- package/context7.json +1 -1
- package/dist/ChatInterface-B0zbA3Lm.d.cts +64 -0
- package/dist/ChatInterface-f8ftS56n.d.ts +64 -0
- package/dist/{SlotsContext-CBtt36al.d.ts → SlotsContext-BjiX1mRx.d.ts} +17 -2
- package/dist/{SlotsContext-CHvISDJT.d.cts → SlotsContext-CEOBjzfh.d.cts} +17 -2
- package/dist/ai-elements.cjs +114 -393
- package/dist/ai-elements.cjs.map +1 -1
- package/dist/ai-elements.d.cts +2 -31
- package/dist/ai-elements.d.ts +2 -31
- package/dist/ai-elements.js +9 -291
- package/dist/ai-elements.js.map +1 -1
- package/dist/{chunk-5QSXB6UL.cjs → chunk-3HGOLNGG.cjs} +13 -4
- package/dist/chunk-3HGOLNGG.cjs.map +1 -0
- package/dist/{chunk-KVEJAPWA.js → chunk-3KSMOHNY.js} +48 -62
- package/dist/chunk-3KSMOHNY.js.map +1 -0
- package/dist/chunk-4WOBNRRB.cjs +540 -0
- package/dist/chunk-4WOBNRRB.cjs.map +1 -0
- package/dist/chunk-7AZMWPKX.cjs +35 -0
- package/dist/chunk-7AZMWPKX.cjs.map +1 -0
- package/dist/chunk-B27JIQ4Z.js +528 -0
- package/dist/chunk-B27JIQ4Z.js.map +1 -0
- package/dist/{chunk-J2K7EJYP.cjs → chunk-BPV66QNM.cjs} +6 -4
- package/dist/chunk-BPV66QNM.cjs.map +1 -0
- package/dist/{chunk-FYPJSHCL.js → chunk-FPQ3UCCJ.js} +6 -4
- package/dist/chunk-FPQ3UCCJ.js.map +1 -0
- package/dist/{chunk-7L4FS6G7.js → chunk-JHWSG5IB.js} +17 -3
- package/dist/chunk-JHWSG5IB.js.map +1 -0
- package/dist/{chunk-4FBVV64J.js → chunk-M4YRNNGB.js} +13 -4
- package/dist/chunk-M4YRNNGB.js.map +1 -0
- package/dist/{chunk-QDFPJJ5Y.cjs → chunk-OU5OZKYH.cjs} +50 -65
- package/dist/chunk-OU5OZKYH.cjs.map +1 -0
- package/dist/{chunk-MC6QDYB6.cjs → chunk-PPCGZ5MP.cjs} +166 -67
- package/dist/chunk-PPCGZ5MP.cjs.map +1 -0
- package/dist/{chunk-U3FXVLUK.js → chunk-PQCGQ32Q.js} +84 -4
- package/dist/chunk-PQCGQ32Q.js.map +1 -0
- package/dist/{chunk-FOZXDUSZ.js → chunk-SWKWHBBN.js} +151 -54
- package/dist/chunk-SWKWHBBN.js.map +1 -0
- package/dist/{chunk-DMGYQ6NN.cjs → chunk-TLGZSXTU.cjs} +86 -6
- package/dist/chunk-TLGZSXTU.cjs.map +1 -0
- package/dist/{chunk-C24QG43M.cjs → chunk-TZ7EM3EG.cjs} +17 -2
- package/dist/chunk-TZ7EM3EG.cjs.map +1 -0
- package/dist/chunk-XEAAB5ZM.js +32 -0
- package/dist/chunk-XEAAB5ZM.js.map +1 -0
- package/dist/components.cjs +31 -52
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +4 -34
- package/dist/components.d.ts +4 -34
- package/dist/components.js +18 -42
- package/dist/components.js.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/hooks.cjs +6 -6
- package/dist/hooks.d.cts +2 -2
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +2 -2
- package/dist/i18n.d.cts +1 -1
- package/dist/i18n.d.ts +1 -1
- package/dist/index.cjs +45 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -6
- package/dist/index.d.ts +51 -6
- package/dist/index.js +17 -10
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +194 -14
- package/dist/message-feedback-BFh3-qym.d.cts +92 -0
- package/dist/message-feedback-cWR0NVok.d.ts +92 -0
- package/dist/normalize-KzCLLqpU.d.cts +42 -0
- package/dist/normalize-KzCLLqpU.d.ts +42 -0
- package/dist/styles.css +1 -1
- package/dist/theme.d.cts +1 -1
- package/dist/theme.d.ts +1 -1
- package/dist/tools.cjs +14 -5
- package/dist/tools.d.cts +3 -2
- package/dist/tools.d.ts +3 -2
- package/dist/tools.js +3 -2
- package/dist/{types-DKJ_-nbG.d.cts → types-DlNwk-bG.d.cts} +33 -3
- package/dist/{types-DKJ_-nbG.d.ts → types-DlNwk-bG.d.ts} +33 -3
- package/dist/ui.cjs +45 -45
- package/dist/ui.js +2 -2
- package/llms.txt +175 -5
- package/package.json +2 -1
- package/dist/chunk-4FBVV64J.js.map +0 -1
- package/dist/chunk-5QSXB6UL.cjs.map +0 -1
- package/dist/chunk-7L4FS6G7.js.map +0 -1
- package/dist/chunk-A7PCSWIK.js +0 -219
- package/dist/chunk-A7PCSWIK.js.map +0 -1
- package/dist/chunk-C24QG43M.cjs.map +0 -1
- package/dist/chunk-DMGYQ6NN.cjs.map +0 -1
- package/dist/chunk-FOZXDUSZ.js.map +0 -1
- package/dist/chunk-FYPJSHCL.js.map +0 -1
- package/dist/chunk-J2K7EJYP.cjs.map +0 -1
- package/dist/chunk-KVEJAPWA.js.map +0 -1
- package/dist/chunk-MC6QDYB6.cjs.map +0 -1
- package/dist/chunk-QDFPJJ5Y.cjs.map +0 -1
- package/dist/chunk-RTVEBPAJ.cjs +0 -230
- package/dist/chunk-RTVEBPAJ.cjs.map +0 -1
- package/dist/chunk-U3FXVLUK.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// src/tools/normalize.ts
|
|
5
|
+
function normalizeToolRows(input) {
|
|
6
|
+
if (input == null) return [];
|
|
7
|
+
if (typeof input === "object" && !Array.isArray(input) && "rows" in input && Array.isArray(input.rows)) {
|
|
8
|
+
return normalizeToolRows(input.rows);
|
|
9
|
+
}
|
|
10
|
+
if (!Array.isArray(input) && typeof input === "object") {
|
|
11
|
+
return [unwrapRow(input)];
|
|
12
|
+
}
|
|
13
|
+
if (!Array.isArray(input)) return [];
|
|
14
|
+
return input.map((row) => typeof row === "object" && row !== null ? unwrapRow(row) : null).filter((r) => r !== null);
|
|
15
|
+
}
|
|
16
|
+
function unwrapRow(row) {
|
|
17
|
+
const hasDataWrapper = "data" in row && typeof row.data === "object" && row.data !== null && !Array.isArray(row.data);
|
|
18
|
+
if (!hasDataWrapper) return row;
|
|
19
|
+
const meta = { id: row.id, sortOrder: row.sortOrder };
|
|
20
|
+
return {
|
|
21
|
+
...row.data,
|
|
22
|
+
// Preserve id/sortOrder as useful metadata for keys/ordering
|
|
23
|
+
...meta.id !== void 0 ? { _id: meta.id } : {},
|
|
24
|
+
...meta.sortOrder !== void 0 ? { _sortOrder: meta.sortOrder } : {}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getToolDisplayData(result) {
|
|
28
|
+
if (!result) return void 0;
|
|
29
|
+
return result._displayData !== void 0 ? result._displayData : result.data;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
exports.getToolDisplayData = getToolDisplayData;
|
|
33
|
+
exports.normalizeToolRows = normalizeToolRows;
|
|
34
|
+
//# sourceMappingURL=chunk-7AZMWPKX.cjs.map
|
|
35
|
+
//# sourceMappingURL=chunk-7AZMWPKX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/normalize.ts"],"names":[],"mappings":";;;AAiCO,SAAS,kBACd,KAAA,EACgC;AAChC,EAAA,IAAI,KAAA,IAAS,IAAA,EAAM,OAAO,EAAC;AAG3B,EAAA,IACE,OAAO,KAAA,KAAU,QAAA,IACjB,CAAC,MAAM,OAAA,CAAQ,KAAK,CAAA,IACpB,MAAA,IAAW,KAAA,IACX,KAAA,CAAM,OAAA,CAAS,KAAA,CAA4B,IAAI,CAAA,EAC/C;AACA,IAAA,OAAO,iBAAA,CAAmB,MAA8B,IAAI,CAAA;AAAA,EAC9D;AAGA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAO,UAAU,QAAA,EAAU;AACtD,IAAA,OAAO,CAAC,SAAA,CAAU,KAAgC,CAAC,CAAA;AAAA,EACrD;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,SAAU,EAAC;AAEnC,EAAA,OAAO,MACJ,GAAA,CAAI,CAAC,QAAS,OAAO,GAAA,KAAQ,YAAY,GAAA,KAAQ,IAAA,GAAO,SAAA,CAAU,GAA8B,IAAI,IAAK,CAAA,CACzG,OAAO,CAAC,CAAA,KAAoC,MAAM,IAAI,CAAA;AAC3D;AAOA,SAAS,UAAU,GAAA,EAAuD;AACxE,EAAA,MAAM,cAAA,GACJ,MAAA,IAAU,GAAA,IACV,OAAO,IAAI,IAAA,KAAS,QAAA,IACpB,GAAA,CAAI,IAAA,KAAS,IAAA,IACb,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,IAAI,CAAA;AACzB,EAAA,IAAI,CAAC,gBAAgB,OAAO,GAAA;AAC5B,EAAA,MAAM,OAAO,EAAE,EAAA,EAAI,IAAI,EAAA,EAAI,SAAA,EAAW,IAAI,SAAA,EAAU;AACpD,EAAA,OAAO;AAAA,IACL,GAAI,GAAA,CAAI,IAAA;AAAA;AAAA,IAER,GAAI,KAAK,EAAA,KAAO,MAAA,GAAY,EAAE,GAAA,EAAK,IAAA,CAAK,EAAA,EAAG,GAAI,EAAC;AAAA,IAChD,GAAI,KAAK,SAAA,KAAc,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,SAAA,EAAU,GAAI;AAAC,GACvE;AACF;AAOO,SAAS,mBAAmB,MAAA,EAGX;AACtB,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,OAAO,MAAA,CAAO,YAAA,KAAiB,MAAA,GAAY,MAAA,CAAO,eAAe,MAAA,CAAO,IAAA;AAC1E","file":"chunk-7AZMWPKX.cjs","sourcesContent":["\"use client\";\n\n/**\n * Tool result normalization helpers.\n *\n * Tools (especially `data_store`) can return data in a handful of shapes:\n *\n * 1. Projected flat rows (default `rows_only` mode):\n * `[{ name: \"alice\", city: \"haifa\" }, ...]`\n *\n * 2. Full-format wrapper (`responseMode: \"full\"`):\n * `{ storeName, columns, rows: [...], totalMatches, returned }`\n *\n * 3. Raw DB rows (from custom_execute that echoes the DB layer):\n * `[{ id, dataStoreId, data: { name, city }, sortOrder }]`\n *\n * Custom renderers that want to work with any of these shapes can use\n * `normalizeToolRows()` to get a consistent `Array<Record<string, unknown>>`\n * regardless of upstream shape.\n */\n\n/**\n * Normalize a tool result (or `result.data`) into a flat array of row\n * objects, regardless of which shape the backend returned.\n *\n * @example\n * ```tsx\n * function MyRenderer({ result }: ToolRendererProps) {\n * const rows = normalizeToolRows(result?.data);\n * return <Table rows={rows} />;\n * }\n * ```\n */\nexport function normalizeToolRows(\n input: unknown,\n): Array<Record<string, unknown>> {\n if (input == null) return [];\n\n // Shape 2: { rows: [...] } wrapper\n if (\n typeof input === \"object\" &&\n !Array.isArray(input) &&\n \"rows\" in (input as object) &&\n Array.isArray((input as { rows: unknown }).rows)\n ) {\n return normalizeToolRows((input as { rows: unknown[] }).rows);\n }\n\n // Single object → wrap in array\n if (!Array.isArray(input) && typeof input === \"object\") {\n return [unwrapRow(input as Record<string, unknown>)];\n }\n\n if (!Array.isArray(input)) return [];\n\n return input\n .map((row) => (typeof row === \"object\" && row !== null ? unwrapRow(row as Record<string, unknown>) : null))\n .filter((r): r is Record<string, unknown> => r !== null);\n}\n\n/**\n * If the row looks like a raw DB row (`{ id, data: {...}, ...meta }`),\n * return the inner `data` object merged with non-metadata top-level keys.\n * Otherwise return the row as-is.\n */\nfunction unwrapRow(row: Record<string, unknown>): Record<string, unknown> {\n const hasDataWrapper =\n \"data\" in row &&\n typeof row.data === \"object\" &&\n row.data !== null &&\n !Array.isArray(row.data);\n if (!hasDataWrapper) return row;\n const meta = { id: row.id, sortOrder: row.sortOrder };\n return {\n ...(row.data as Record<string, unknown>),\n // Preserve id/sortOrder as useful metadata for keys/ordering\n ...(meta.id !== undefined ? { _id: meta.id } : {}),\n ...(meta.sortOrder !== undefined ? { _sortOrder: meta.sortOrder } : {}),\n };\n}\n\n/**\n * Extract the display payload from a tool result, preferring `_displayData`\n * over `data` (matches the ToolRenderer resolution). Useful when you're\n * rendering from outside the built-in dispatcher.\n */\nexport function getToolDisplayData(result: {\n data?: unknown;\n _displayData?: unknown;\n} | undefined): unknown {\n if (!result) return undefined;\n return result._displayData !== undefined ? result._displayData : result.data;\n}\n"]}
|
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useI18n } from './chunk-QYCEHFAB.js';
|
|
3
|
+
import { Button, Textarea, Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-JHWSG5IB.js';
|
|
4
|
+
import { cn } from './chunk-3RW7O444.js';
|
|
5
|
+
import { ArrowDownIcon, Check, Copy, X, ChevronDownIcon, BookIcon } from 'lucide-react';
|
|
6
|
+
import { useCallback, useState } from 'react';
|
|
7
|
+
import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
|
|
8
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
11
|
+
StickToBottom,
|
|
12
|
+
{
|
|
13
|
+
className: cn("relative flex-1 overflow-y-hidden", className),
|
|
14
|
+
initial: "smooth",
|
|
15
|
+
resize: "smooth",
|
|
16
|
+
role: "log",
|
|
17
|
+
...props
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
var ConversationContent = ({
|
|
21
|
+
className,
|
|
22
|
+
...props
|
|
23
|
+
}) => /* @__PURE__ */ jsx(
|
|
24
|
+
StickToBottom.Content,
|
|
25
|
+
{
|
|
26
|
+
className: cn("flex flex-col gap-8", className),
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
var ConversationEmptyState = ({
|
|
31
|
+
className,
|
|
32
|
+
title = "No messages yet",
|
|
33
|
+
description = "Start a conversation to see messages here",
|
|
34
|
+
icon,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}) => /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
className: cn(
|
|
41
|
+
"flex size-full flex-col items-center justify-center gap-3 p-8 text-center",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
...props,
|
|
45
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
46
|
+
icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: icon }),
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
48
|
+
/* @__PURE__ */ jsx("h3", { className: "font-medium text-sm", children: title }),
|
|
49
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: description })
|
|
50
|
+
] })
|
|
51
|
+
] })
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
var ConversationScrollButton = ({
|
|
55
|
+
className,
|
|
56
|
+
...props
|
|
57
|
+
}) => {
|
|
58
|
+
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
59
|
+
const handleScrollToBottom = useCallback(() => {
|
|
60
|
+
scrollToBottom();
|
|
61
|
+
}, [scrollToBottom]);
|
|
62
|
+
return !isAtBottom && /* @__PURE__ */ jsx(
|
|
63
|
+
Button,
|
|
64
|
+
{
|
|
65
|
+
className: cn(
|
|
66
|
+
"absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full",
|
|
67
|
+
className
|
|
68
|
+
),
|
|
69
|
+
onClick: handleScrollToBottom,
|
|
70
|
+
size: "icon",
|
|
71
|
+
type: "button",
|
|
72
|
+
variant: "outline",
|
|
73
|
+
...props,
|
|
74
|
+
children: /* @__PURE__ */ jsx(ArrowDownIcon, { className: "size-4" })
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// src/core/api/kb-client.ts
|
|
80
|
+
function getDefaultEndpoint() {
|
|
81
|
+
try {
|
|
82
|
+
const env = import.meta.env;
|
|
83
|
+
if (env?.VITE_API_ENDPOINT) return env.VITE_API_ENDPOINT;
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
return "http://localhost:3000";
|
|
87
|
+
}
|
|
88
|
+
async function submitFeedback(request, apiKey, apiEndpoint) {
|
|
89
|
+
const endpoint = apiEndpoint || getDefaultEndpoint();
|
|
90
|
+
const headers = {
|
|
91
|
+
"Content-Type": "application/json"
|
|
92
|
+
};
|
|
93
|
+
if (apiKey) {
|
|
94
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const response = await fetch(`${endpoint}/api/kb/feedback`, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers,
|
|
100
|
+
credentials: "include",
|
|
101
|
+
body: JSON.stringify(request)
|
|
102
|
+
});
|
|
103
|
+
if (!response.ok) {
|
|
104
|
+
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
105
|
+
return { success: false, error: error.error || response.statusText };
|
|
106
|
+
}
|
|
107
|
+
return { success: true };
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
var ThumbsUpIcon = ({ className }) => /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className, children: /* @__PURE__ */ jsx(
|
|
116
|
+
"path",
|
|
117
|
+
{
|
|
118
|
+
d: "M7 11V19C7 19.2652 6.89464 19.5196 6.70711 19.7071C6.51957 19.8946 6.26522 20 6 20H4C3.73478 20 3.48043 19.8946 3.29289 19.7071C3.10536 19.5196 3 19.2652 3 19V12C3 11.7348 3.10536 11.4804 3.29289 11.2929C3.48043 11.1054 3.73478 11 4 11H7ZM7 11C8.06087 11 9.07828 10.5786 9.82843 9.82843C10.5786 9.07828 11 8.06087 11 7V6C11 5.46957 11.2107 4.96086 11.5858 4.58579C11.9609 4.21071 12.4696 4 13 4C13.5304 4 14.0391 4.21071 14.4142 4.58579C14.7893 4.96086 15 5.46957 15 6V11H18C18.5304 11 19.0391 11.2107 19.4142 11.5858C19.7893 11.9609 20 12.4696 20 13L19 18C18.8562 18.6135 18.5834 19.1402 18.2227 19.501C17.8619 19.8617 17.4328 20.0368 17 20H10C9.20435 20 8.44129 19.6839 7.87868 19.1213C7.31607 18.5587 7 17.7956 7 17",
|
|
119
|
+
stroke: "currentColor",
|
|
120
|
+
strokeWidth: "1.5",
|
|
121
|
+
strokeLinecap: "round",
|
|
122
|
+
strokeLinejoin: "round"
|
|
123
|
+
}
|
|
124
|
+
) });
|
|
125
|
+
var ThumbsDownIcon = ({ className }) => /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className, children: /* @__PURE__ */ jsx(
|
|
126
|
+
"path",
|
|
127
|
+
{
|
|
128
|
+
d: "M7 13V4.99999C7 4.73478 6.89464 4.48042 6.70711 4.29289C6.51957 4.10535 6.26522 3.99999 6 3.99999H4C3.73478 3.99999 3.48043 4.10535 3.29289 4.29289C3.10536 4.48042 3 4.73478 3 4.99999V12C3 12.2652 3.10536 12.5196 3.29289 12.7071C3.48043 12.8946 3.73478 13 4 13H7ZM7 13C8.06087 13 9.07828 13.4214 9.82843 14.1716C10.5786 14.9217 11 15.9391 11 17V18C11 18.5304 11.2107 19.0391 11.5858 19.4142C11.9609 19.7893 12.4696 20 13 20C13.5304 20 14.0391 19.7893 14.4142 19.4142C14.7893 19.0391 15 18.5304 15 18V13H18C18.5304 13 19.0391 12.7893 19.4142 12.4142C19.7893 12.0391 20 11.5304 20 11L19 5.99999C18.8562 5.38652 18.5834 4.85975 18.2227 4.49903C17.8619 4.13831 17.4328 3.96317 17 3.99999H10C9.20435 3.99999 8.44129 4.31606 7.87868 4.87867C7.31607 5.44128 7 6.20434 7 6.99999",
|
|
129
|
+
stroke: "currentColor",
|
|
130
|
+
strokeWidth: "1.5",
|
|
131
|
+
strokeLinecap: "round",
|
|
132
|
+
strokeLinejoin: "round"
|
|
133
|
+
}
|
|
134
|
+
) });
|
|
135
|
+
var REVIEW_TYPES = [
|
|
136
|
+
{ value: "wrong_answer", labelKey: "wrongAnswer" },
|
|
137
|
+
{ value: "partial_answer", labelKey: "partialAnswer" },
|
|
138
|
+
{ value: "hallucination", labelKey: "hallucination" },
|
|
139
|
+
{ value: "inappropriate_tone", labelKey: "inappropriateTone" }
|
|
140
|
+
];
|
|
141
|
+
function MessageFeedback({
|
|
142
|
+
messageId,
|
|
143
|
+
projectId,
|
|
144
|
+
sessionId,
|
|
145
|
+
apiKey,
|
|
146
|
+
apiEndpoint,
|
|
147
|
+
textContent,
|
|
148
|
+
trackInteraction,
|
|
149
|
+
className,
|
|
150
|
+
unstyled = false,
|
|
151
|
+
classNames,
|
|
152
|
+
renderActions
|
|
153
|
+
}) {
|
|
154
|
+
const { t } = useI18n();
|
|
155
|
+
const [feedback, setFeedback] = useState(null);
|
|
156
|
+
const [showReviewForm, setShowReviewForm] = useState(false);
|
|
157
|
+
const [reviewType, setReviewType] = useState(null);
|
|
158
|
+
const [reviewText, setReviewText] = useState("");
|
|
159
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
160
|
+
const [copied, setCopied] = useState(false);
|
|
161
|
+
const submitFeedbackToApi = async (feedbackData) => {
|
|
162
|
+
if (!projectId || !messageId || isSubmitting) return;
|
|
163
|
+
setIsSubmitting(true);
|
|
164
|
+
try {
|
|
165
|
+
const request = {
|
|
166
|
+
projectId,
|
|
167
|
+
sessionId,
|
|
168
|
+
messageId,
|
|
169
|
+
isPositive: feedbackData.isPositive,
|
|
170
|
+
issueType: feedbackData.reviewType,
|
|
171
|
+
feedbackText: feedbackData.reviewText
|
|
172
|
+
};
|
|
173
|
+
const result = await submitFeedback(request, apiKey, apiEndpoint);
|
|
174
|
+
if (!result.success) {
|
|
175
|
+
console.error("Failed to submit feedback:", result.error);
|
|
176
|
+
}
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error("Failed to submit feedback:", error);
|
|
179
|
+
} finally {
|
|
180
|
+
setIsSubmitting(false);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const handlePositiveFeedback = () => {
|
|
184
|
+
if (isSubmitting) return;
|
|
185
|
+
setFeedback("positive");
|
|
186
|
+
setShowReviewForm(false);
|
|
187
|
+
submitFeedbackToApi({ isPositive: true });
|
|
188
|
+
trackInteraction?.({
|
|
189
|
+
type: "feedback",
|
|
190
|
+
target: "thumbs_up",
|
|
191
|
+
label: "Positive feedback",
|
|
192
|
+
messageId,
|
|
193
|
+
metadata: { isPositive: true }
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
const handleNegativeFeedback = () => {
|
|
197
|
+
if (isSubmitting) return;
|
|
198
|
+
setFeedback("negative");
|
|
199
|
+
setShowReviewForm(true);
|
|
200
|
+
};
|
|
201
|
+
const handleSubmitReview = () => {
|
|
202
|
+
if (isSubmitting) return;
|
|
203
|
+
const feedbackData = {
|
|
204
|
+
isPositive: false,
|
|
205
|
+
reviewType: reviewType ?? void 0,
|
|
206
|
+
reviewText: reviewText || void 0
|
|
207
|
+
};
|
|
208
|
+
setShowReviewForm(false);
|
|
209
|
+
submitFeedbackToApi(feedbackData);
|
|
210
|
+
trackInteraction?.({
|
|
211
|
+
type: "feedback",
|
|
212
|
+
target: "thumbs_down",
|
|
213
|
+
label: "Negative feedback",
|
|
214
|
+
messageId,
|
|
215
|
+
metadata: { isPositive: false, reviewType, reviewText }
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
const handleCancelReview = () => {
|
|
219
|
+
setFeedback(null);
|
|
220
|
+
setShowReviewForm(false);
|
|
221
|
+
setReviewType(null);
|
|
222
|
+
setReviewText("");
|
|
223
|
+
};
|
|
224
|
+
const handleCopy = async () => {
|
|
225
|
+
if (typeof window === "undefined" || !navigator?.clipboard?.writeText) return;
|
|
226
|
+
try {
|
|
227
|
+
await navigator.clipboard.writeText(textContent);
|
|
228
|
+
setCopied(true);
|
|
229
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
230
|
+
trackInteraction?.({
|
|
231
|
+
type: "copy",
|
|
232
|
+
target: "message",
|
|
233
|
+
label: "Copy response",
|
|
234
|
+
messageId,
|
|
235
|
+
metadata: { contentLength: textContent.length }
|
|
236
|
+
});
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error("Failed to copy:", error);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const actionsState = {
|
|
242
|
+
feedback,
|
|
243
|
+
isSubmitting,
|
|
244
|
+
copied,
|
|
245
|
+
onPositive: handlePositiveFeedback,
|
|
246
|
+
onNegative: handleNegativeFeedback,
|
|
247
|
+
onCopy: handleCopy
|
|
248
|
+
};
|
|
249
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(unstyled ? "" : "mt-4", classNames?.root, className), children: [
|
|
250
|
+
renderActions ? renderActions(actionsState) : /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", classNames?.actions), children: [
|
|
251
|
+
/* @__PURE__ */ jsx(
|
|
252
|
+
"button",
|
|
253
|
+
{
|
|
254
|
+
type: "button",
|
|
255
|
+
onClick: handlePositiveFeedback,
|
|
256
|
+
disabled: isSubmitting,
|
|
257
|
+
className: cn(
|
|
258
|
+
unstyled ? "" : cn(
|
|
259
|
+
"group w-8 h-8 rounded-full flex items-center justify-center transition-all duration-300",
|
|
260
|
+
feedback === "positive" ? "bg-primary/10 text-primary" : "bg-secondary text-muted-foreground hover:bg-primary/10 hover:text-primary",
|
|
261
|
+
isSubmitting && "opacity-50 cursor-not-allowed"
|
|
262
|
+
),
|
|
263
|
+
classNames?.thumbsUp
|
|
264
|
+
),
|
|
265
|
+
title: t("helpful"),
|
|
266
|
+
"aria-label": t("helpful"),
|
|
267
|
+
"aria-pressed": feedback === "positive",
|
|
268
|
+
children: /* @__PURE__ */ jsx(ThumbsUpIcon, {})
|
|
269
|
+
}
|
|
270
|
+
),
|
|
271
|
+
/* @__PURE__ */ jsx(
|
|
272
|
+
"button",
|
|
273
|
+
{
|
|
274
|
+
type: "button",
|
|
275
|
+
onClick: handleNegativeFeedback,
|
|
276
|
+
disabled: isSubmitting,
|
|
277
|
+
className: cn(
|
|
278
|
+
unstyled ? "" : cn(
|
|
279
|
+
"group w-8 h-8 rounded-full flex items-center justify-center transition-all duration-300",
|
|
280
|
+
feedback === "negative" ? "bg-red-100 text-red-500" : "bg-secondary text-muted-foreground hover:bg-red-50 hover:text-red-500",
|
|
281
|
+
isSubmitting && "opacity-50 cursor-not-allowed"
|
|
282
|
+
),
|
|
283
|
+
classNames?.thumbsDown
|
|
284
|
+
),
|
|
285
|
+
title: t("notHelpful"),
|
|
286
|
+
"aria-label": t("notHelpful"),
|
|
287
|
+
"aria-pressed": feedback === "negative",
|
|
288
|
+
children: /* @__PURE__ */ jsx(ThumbsDownIcon, {})
|
|
289
|
+
}
|
|
290
|
+
),
|
|
291
|
+
/* @__PURE__ */ jsx(
|
|
292
|
+
"button",
|
|
293
|
+
{
|
|
294
|
+
type: "button",
|
|
295
|
+
onClick: handleCopy,
|
|
296
|
+
className: cn(
|
|
297
|
+
unstyled ? "" : "group w-8 h-8 rounded-full bg-secondary flex items-center justify-center text-muted-foreground hover:bg-primary/10 hover:text-primary transition-all duration-300",
|
|
298
|
+
classNames?.copy
|
|
299
|
+
),
|
|
300
|
+
title: t("copyResponse"),
|
|
301
|
+
"aria-label": t("copyResponse"),
|
|
302
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-green-600" }) : /* @__PURE__ */ jsx(Copy, { className: "w-4 h-4" })
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
] }),
|
|
306
|
+
showReviewForm && /* @__PURE__ */ jsxs("div", { className: "mt-4 bg-gradient-to-br from-accent to-secondary rounded-2xl border border-border overflow-hidden animate-in slide-in-from-top-2 duration-300", children: [
|
|
307
|
+
/* @__PURE__ */ jsxs("div", { className: "px-5 py-4 border-b border-border flex items-center justify-between", children: [
|
|
308
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
309
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 h-8 rounded-xl bg-card border border-border flex items-center justify-center", children: /* @__PURE__ */ jsx(ThumbsDownIcon, { className: "text-red-500" }) }),
|
|
310
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: t("whatWentWrong") })
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsx(
|
|
313
|
+
"button",
|
|
314
|
+
{
|
|
315
|
+
type: "button",
|
|
316
|
+
onClick: handleCancelReview,
|
|
317
|
+
className: "w-8 h-8 rounded-full bg-card border border-border flex items-center justify-center hover:border-primary transition-colors",
|
|
318
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
] }),
|
|
322
|
+
/* @__PURE__ */ jsxs("div", { className: "p-5 space-y-4", children: [
|
|
323
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: REVIEW_TYPES.map((type) => /* @__PURE__ */ jsx(
|
|
324
|
+
"button",
|
|
325
|
+
{
|
|
326
|
+
type: "button",
|
|
327
|
+
onClick: () => setReviewType(type.value),
|
|
328
|
+
className: cn(
|
|
329
|
+
"px-4 py-2 rounded-full text-xs font-medium transition-all duration-300",
|
|
330
|
+
reviewType === type.value ? "bg-primary text-primary-foreground shadow-md shadow-primary/20" : "bg-card border border-border text-foreground hover:border-primary hover:text-primary"
|
|
331
|
+
),
|
|
332
|
+
children: t(type.labelKey)
|
|
333
|
+
},
|
|
334
|
+
type.value
|
|
335
|
+
)) }),
|
|
336
|
+
/* @__PURE__ */ jsx(
|
|
337
|
+
Textarea,
|
|
338
|
+
{
|
|
339
|
+
placeholder: t("addDetails"),
|
|
340
|
+
value: reviewText,
|
|
341
|
+
onChange: (e) => setReviewText(e.target.value),
|
|
342
|
+
rows: 2,
|
|
343
|
+
className: "text-sm resize-none rounded-xl border-border focus:border-primary focus:ring-primary/20"
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
|
|
347
|
+
"button",
|
|
348
|
+
{
|
|
349
|
+
type: "button",
|
|
350
|
+
onClick: handleSubmitReview,
|
|
351
|
+
disabled: isSubmitting,
|
|
352
|
+
className: "group relative px-5 py-2.5 bg-primary text-primary-foreground rounded-full text-sm font-medium overflow-hidden transition-all duration-300 hover:shadow-lg hover:shadow-primary/25 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
353
|
+
children: [
|
|
354
|
+
/* @__PURE__ */ jsx("span", { className: "relative z-10", children: isSubmitting ? t("submitting") : t("submitFeedback") }),
|
|
355
|
+
/* @__PURE__ */ jsx(
|
|
356
|
+
"div",
|
|
357
|
+
{
|
|
358
|
+
className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity bg-primary/90"
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
) })
|
|
364
|
+
] })
|
|
365
|
+
] }),
|
|
366
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
367
|
+
.animate-in {
|
|
368
|
+
animation: animateIn 0.3s ease-out;
|
|
369
|
+
}
|
|
370
|
+
.slide-in-from-top-2 {
|
|
371
|
+
--tw-enter-translate-y: -0.5rem;
|
|
372
|
+
}
|
|
373
|
+
@keyframes animateIn {
|
|
374
|
+
from {
|
|
375
|
+
opacity: 0;
|
|
376
|
+
transform: translateY(var(--tw-enter-translate-y, 0));
|
|
377
|
+
}
|
|
378
|
+
to {
|
|
379
|
+
opacity: 1;
|
|
380
|
+
transform: translateY(0);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
` })
|
|
384
|
+
] });
|
|
385
|
+
}
|
|
386
|
+
var Loader = ({ className, text = "Thinking...", ...props }) => /* @__PURE__ */ jsxs(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
className: cn(
|
|
390
|
+
"flex items-center gap-2 w-full py-3",
|
|
391
|
+
className
|
|
392
|
+
),
|
|
393
|
+
style: { color: "var(--ac-loader-color, var(--ac-primary, #2f80ed))" },
|
|
394
|
+
...props,
|
|
395
|
+
children: [
|
|
396
|
+
/* @__PURE__ */ jsxs(
|
|
397
|
+
"svg",
|
|
398
|
+
{
|
|
399
|
+
className: "animate-spin",
|
|
400
|
+
width: "20",
|
|
401
|
+
height: "20",
|
|
402
|
+
viewBox: "0 0 20 20",
|
|
403
|
+
fill: "none",
|
|
404
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
405
|
+
children: [
|
|
406
|
+
/* @__PURE__ */ jsx(
|
|
407
|
+
"circle",
|
|
408
|
+
{
|
|
409
|
+
cx: "10",
|
|
410
|
+
cy: "10",
|
|
411
|
+
r: "8",
|
|
412
|
+
stroke: "#E5E5E5",
|
|
413
|
+
strokeWidth: "2",
|
|
414
|
+
fill: "none"
|
|
415
|
+
}
|
|
416
|
+
),
|
|
417
|
+
/* @__PURE__ */ jsx(
|
|
418
|
+
"path",
|
|
419
|
+
{
|
|
420
|
+
d: "M10 2C14.4183 2 18 5.58172 18 10",
|
|
421
|
+
stroke: "currentColor",
|
|
422
|
+
strokeWidth: "2",
|
|
423
|
+
strokeLinecap: "round",
|
|
424
|
+
fill: "none"
|
|
425
|
+
}
|
|
426
|
+
)
|
|
427
|
+
]
|
|
428
|
+
}
|
|
429
|
+
),
|
|
430
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: text })
|
|
431
|
+
]
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
var SpinnerLoader = ({ className, size = 16, ...props }) => /* @__PURE__ */ jsx(
|
|
435
|
+
"div",
|
|
436
|
+
{
|
|
437
|
+
className: cn(
|
|
438
|
+
"inline-flex animate-spin items-center justify-center",
|
|
439
|
+
className
|
|
440
|
+
),
|
|
441
|
+
...props,
|
|
442
|
+
children: /* @__PURE__ */ jsxs(
|
|
443
|
+
"svg",
|
|
444
|
+
{
|
|
445
|
+
height: size,
|
|
446
|
+
strokeLinejoin: "round",
|
|
447
|
+
style: { color: "currentcolor" },
|
|
448
|
+
viewBox: "0 0 16 16",
|
|
449
|
+
width: size,
|
|
450
|
+
children: [
|
|
451
|
+
/* @__PURE__ */ jsx("title", { children: "Loader" }),
|
|
452
|
+
/* @__PURE__ */ jsxs("g", { clipPath: "url(#clip0_2393_1490)", children: [
|
|
453
|
+
/* @__PURE__ */ jsx("path", { d: "M8 0V4", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
454
|
+
/* @__PURE__ */ jsx("path", { d: "M8 16V12", opacity: "0.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
455
|
+
/* @__PURE__ */ jsx("path", { d: "M3.29773 1.52783L5.64887 4.7639", opacity: "0.9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
456
|
+
/* @__PURE__ */ jsx("path", { d: "M12.7023 1.52783L10.3511 4.7639", opacity: "0.1", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
457
|
+
/* @__PURE__ */ jsx("path", { d: "M12.7023 14.472L10.3511 11.236", opacity: "0.4", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
458
|
+
/* @__PURE__ */ jsx("path", { d: "M3.29773 14.472L5.64887 11.236", opacity: "0.6", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
459
|
+
/* @__PURE__ */ jsx("path", { d: "M15.6085 5.52783L11.8043 6.7639", opacity: "0.2", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
460
|
+
/* @__PURE__ */ jsx("path", { d: "M0.391602 10.472L4.19583 9.23598", opacity: "0.7", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
461
|
+
/* @__PURE__ */ jsx("path", { d: "M15.6085 10.4722L11.8043 9.2361", opacity: "0.3", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
462
|
+
/* @__PURE__ */ jsx("path", { d: "M0.391602 5.52783L4.19583 6.7639", opacity: "0.8", stroke: "currentColor", strokeWidth: "1.5" })
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "clip0_2393_1490", children: /* @__PURE__ */ jsx("rect", { fill: "white", height: "16", width: "16" }) }) })
|
|
465
|
+
]
|
|
466
|
+
}
|
|
467
|
+
)
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
var Sources = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
471
|
+
Collapsible,
|
|
472
|
+
{
|
|
473
|
+
className: cn("not-prose mb-4 text-primary text-xs", className),
|
|
474
|
+
...props
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
var SourcesTrigger = ({
|
|
478
|
+
className,
|
|
479
|
+
count,
|
|
480
|
+
children,
|
|
481
|
+
...props
|
|
482
|
+
}) => /* @__PURE__ */ jsx(
|
|
483
|
+
CollapsibleTrigger,
|
|
484
|
+
{
|
|
485
|
+
className: cn("flex items-center gap-2", className),
|
|
486
|
+
...props,
|
|
487
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
488
|
+
/* @__PURE__ */ jsxs("p", { className: "font-medium", children: [
|
|
489
|
+
"Used ",
|
|
490
|
+
count,
|
|
491
|
+
" sources"
|
|
492
|
+
] }),
|
|
493
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4" })
|
|
494
|
+
] })
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
var SourcesContent = ({
|
|
498
|
+
className,
|
|
499
|
+
...props
|
|
500
|
+
}) => /* @__PURE__ */ jsx(
|
|
501
|
+
CollapsibleContent,
|
|
502
|
+
{
|
|
503
|
+
className: cn(
|
|
504
|
+
"mt-3 flex w-fit flex-col gap-2",
|
|
505
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
506
|
+
className
|
|
507
|
+
),
|
|
508
|
+
...props
|
|
509
|
+
}
|
|
510
|
+
);
|
|
511
|
+
var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ jsx(
|
|
512
|
+
"a",
|
|
513
|
+
{
|
|
514
|
+
className: "flex items-center gap-2",
|
|
515
|
+
href,
|
|
516
|
+
rel: "noreferrer",
|
|
517
|
+
target: "_blank",
|
|
518
|
+
...props,
|
|
519
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
520
|
+
/* @__PURE__ */ jsx(BookIcon, { className: "h-4 w-4" }),
|
|
521
|
+
/* @__PURE__ */ jsx("span", { className: "block font-medium", children: title })
|
|
522
|
+
] })
|
|
523
|
+
}
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
export { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, Loader, MessageFeedback, Source, Sources, SourcesContent, SourcesTrigger, SpinnerLoader };
|
|
527
|
+
//# sourceMappingURL=chunk-B27JIQ4Z.js.map
|
|
528
|
+
//# sourceMappingURL=chunk-B27JIQ4Z.js.map
|