@clubmed/usg-chat-ui 1.2.7 → 1.4.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 +36 -0
- package/assets/style.css +1 -1
- package/chunks/react.esm.js +2012 -1997
- package/chunks/react.esm.js.map +1 -1
- package/chunks/vi.2VT5v0um.js +1 -0
- package/config/chatLabels.d.ts +83 -0
- package/config/chatLabels.js +2 -0
- package/config/chatLabels.js.map +1 -0
- package/contexts/ChatLabelsContext.d.ts +13 -0
- package/contexts/ChatLabelsContext.js +24 -0
- package/contexts/ChatLabelsContext.js.map +1 -0
- package/contexts/ChatLabelsContext.test.d.ts +1 -0
- package/contexts/ChatLabelsContext.test.js +23 -0
- package/contexts/ChatLabelsContext.test.js.map +1 -0
- package/molecules/AiElements/Branch.js +45 -44
- package/molecules/AiElements/Branch.js.map +1 -1
- package/molecules/AiElements/PromptInput.js +60 -58
- package/molecules/AiElements/PromptInput.js.map +1 -1
- package/molecules/RichText/useCollaboration.test.js +1 -1
- package/organisms/canvas/CanvasLayout.d.ts +2 -1
- package/organisms/canvas/CanvasLayout.js +1249 -1248
- package/organisms/canvas/CanvasLayout.js.map +1 -1
- package/organisms/chat/Chat.d.ts +7 -1
- package/organisms/chat/Chat.js +70 -69
- package/organisms/chat/Chat.js.map +1 -1
- package/organisms/chat/ChatHeader.d.ts +4 -5
- package/organisms/chat/ChatHeader.js +36 -39
- package/organisms/chat/ChatHeader.js.map +1 -1
- package/organisms/chat/ChatHeader.test.d.ts +1 -0
- package/organisms/chat/ChatHeader.test.js +18 -0
- package/organisms/chat/ChatHeader.test.js.map +1 -0
- package/organisms/chat/ChatMessageList.d.ts +1 -2
- package/organisms/chat/ChatMessageList.js +73 -58
- package/organisms/chat/ChatMessageList.js.map +1 -1
- package/organisms/chat/ChatMessageList.test.d.ts +1 -0
- package/organisms/chat/ChatMessageList.test.js +67 -0
- package/organisms/chat/ChatMessageList.test.js.map +1 -0
- package/organisms/chat/ChatSettingsButton.d.ts +2 -0
- package/organisms/chat/ChatSettingsButton.js +25 -0
- package/organisms/chat/ChatSettingsButton.js.map +1 -0
- package/organisms/chat/ChatSettingsButton.test.d.ts +1 -0
- package/organisms/chat/ChatSettingsButton.test.js +16 -0
- package/organisms/chat/ChatSettingsButton.test.js.map +1 -0
- package/organisms/chat/ConversationSidebar.js +45 -44
- package/organisms/chat/ConversationSidebar.js.map +1 -1
- package/organisms/chat/MessageActions.js +163 -138
- package/organisms/chat/MessageActions.js.map +1 -1
- package/organisms/chat/MessageRenderers.js +1 -1
- package/organisms/chat/PromptComposer.js +19 -14
- package/organisms/chat/PromptComposer.js.map +1 -1
- package/organisms/chat/SidebarToggleButton.d.ts +2 -1
- package/organisms/chat/SidebarToggleButton.js +15 -12
- package/organisms/chat/SidebarToggleButton.js.map +1 -1
- package/organisms/chat/hooks/useChat.d.ts +1 -1
- package/organisms/chat/hooks/useChat.js +83 -83
- package/organisms/chat/hooks/useChat.js.map +1 -1
- package/package.json +1 -1
- package/utils/interpolate.d.ts +5 -0
- package/utils/interpolate.js +13 -0
- package/utils/interpolate.js.map +1 -0
- package/utils/interpolate.test.d.ts +1 -0
- package/utils/interpolate.test.js +21 -0
- package/utils/interpolate.test.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptComposer.js","sources":["../../../lib/organisms/chat/PromptComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n PromptInput,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport type { PromptInputMessage } from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport type { ChangeEvent } from \"react\";\n\ninterface PromptComposerProps {\n value: string;\n isLoading: boolean;\n onChange: (value: string) => void;\n onSubmit: (message: PromptInputMessage) => Promise<void> | void;\n}\n\nexport function PromptComposer({ value, isLoading, onChange, onSubmit }: PromptComposerProps) {\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange(event.target.value);\n };\n\n return (\n <div className=\"p-3 sm:p-4\">\n <PromptInput onSubmit={onSubmit}>\n <PromptInputBody>\n <PromptInputTextarea\n value={value}\n onChange={handleChange}\n placeholder
|
|
1
|
+
{"version":3,"file":"PromptComposer.js","sources":["../../../lib/organisms/chat/PromptComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n PromptInput,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport type { PromptInputMessage } from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport type { ChangeEvent } from \"react\";\nimport {useChatLabels} from \"../../contexts/ChatLabelsContext\";\n\ninterface PromptComposerProps {\n value: string;\n isLoading: boolean;\n onChange: (value: string) => void;\n onSubmit: (message: PromptInputMessage) => Promise<void> | void;\n}\n\nexport function PromptComposer({ value, isLoading, onChange, onSubmit }: PromptComposerProps) {\n const {get} = useChatLabels();\n const promptPlaceholder = get(\n \"promptComposerPlaceholder\",\n \"Décrivez votre besoin ou tapez /help pour l'aide...\"\n );\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange(event.target.value);\n };\n\n return (\n <div className=\"p-3 sm:p-4\">\n <PromptInput onSubmit={onSubmit}>\n <PromptInputBody>\n <PromptInputTextarea\n value={value}\n onChange={handleChange}\n placeholder={promptPlaceholder}\n disabled={isLoading}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !isLoading && value?.trim()) {\n e.preventDefault();\n onSubmit({ text: value });\n }\n }}\n />\n </PromptInputBody>\n <PromptInputFooter>\n <p className=\"text-xs text-muted-foreground hidden sm:block\">\n Commandes: /settings, /help, /clear •{\" \"}\n <kbd className=\"px-1.5 py-0.5 rounded bg-muted text-xs font-mono\">Enter</kbd> pour envoyer\n </p>\n <p className=\"text-xs text-muted-foreground sm:hidden\">\n <kbd className=\"px-1.5 py-0.5 rounded bg-muted text-xs font-mono\">Enter</kbd> pour envoyer\n </p>\n <div className=\"flex-1\" />\n <PromptInputSubmit disabled={isLoading || !value?.trim()} status={isLoading ? \"streaming\" : \"ready\"} />\n </PromptInputFooter>\n </PromptInput>\n </div>\n );\n}\n"],"names":["PromptComposer","value","isLoading","onChange","onSubmit","get","useChatLabels","promptPlaceholder","jsxs","PromptInput","jsx","PromptInputBody","PromptInputTextarea","event","e","PromptInputFooter","PromptInputSubmit"],"mappings":";;;;AAoBO,SAASA,EAAe,EAAE,OAAAC,GAAO,WAAAC,GAAW,UAAAC,GAAU,UAAAC,KAAiC;AAC5F,QAAM,EAAC,KAAAC,EAAA,IAAOC,EAAA,GACRC,IAAoBF;AAAA,IACxB;AAAA,IACA;AAAA,EAAA;AAMF,2BACG,OAAA,EAAI,WAAU,cACb,UAAA,gBAAAG,EAACC,KAAY,UAAAL,GACX,UAAA;AAAA,IAAA,gBAAAM,EAACC,GAAA,EACC,UAAA,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAAX;AAAA,QACA,UAVW,CAACY,MAA4C;AAChE,UAAAV,EAASU,EAAM,OAAO,KAAK;AAAA,QAC7B;AAAA,QASU,aAAaN;AAAA,QACb,UAAUL;AAAA,QACV,WAAW,CAACY,MAAM;AAChB,UAAIA,EAAE,QAAQ,WAAW,CAACA,EAAE,YAAY,CAACZ,MAAaD,KAAA,QAAAA,EAAO,YAC3Da,EAAE,eAAA,GACFV,EAAS,EAAE,MAAMH,GAAO;AAAA,QAE5B;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,sBACCc,GAAA,EACC,UAAA;AAAA,MAAA,gBAAAP,EAAC,KAAA,EAAE,WAAU,iDAAgD,UAAA;AAAA,QAAA;AAAA,QACrB;AAAA,QACtC,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA,SAAK;AAAA,QAAM;AAAA,MAAA,GAC/E;AAAA,MACA,gBAAAF,EAAC,KAAA,EAAE,WAAU,2CACX,UAAA;AAAA,QAAA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA,SAAK;AAAA,QAAM;AAAA,MAAA,GAC/E;AAAA,MACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,SAAA,CAAS;AAAA,MACxB,gBAAAA,EAACM,GAAA,EAAkB,UAAUd,KAAa,EAACD,KAAA,QAAAA,EAAO,SAAQ,QAAQC,IAAY,cAAc,QAAA,CAAS;AAAA,IAAA,EAAA,CACvG;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
interface SidebarToggleButtonProps {
|
|
2
2
|
onOpen: () => void;
|
|
3
|
+
className?: string;
|
|
3
4
|
}
|
|
4
|
-
export declare function SidebarToggleButton({ onOpen }: SidebarToggleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function SidebarToggleButton({ onOpen, className }: SidebarToggleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
5
6
|
export {};
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { cn as
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
3
|
+
import { cn as s } from "../../utils/cn.js";
|
|
4
|
+
import { useChatLabels as i } from "../../contexts/ChatLabelsContext.js";
|
|
5
|
+
import { P as a } from "../../chunks/panel-left.js";
|
|
6
|
+
function m({ onOpen: e, className: o }) {
|
|
7
|
+
const { get: t } = i(), n = t("sidebarOpenHistoryAriaLabel", "Ouvrir l'historique");
|
|
8
|
+
return /* @__PURE__ */ r(
|
|
7
9
|
"button",
|
|
8
10
|
{
|
|
9
|
-
onClick:
|
|
10
|
-
className:
|
|
11
|
-
"group
|
|
11
|
+
onClick: e,
|
|
12
|
+
className: s(
|
|
13
|
+
"group flex h-10 w-10 sm:h-11 sm:w-11 items-center justify-center bg-transparent hover:bg-muted transition-all duration-200 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background rounded-lg p-2",
|
|
14
|
+
o
|
|
12
15
|
),
|
|
13
|
-
"aria-label":
|
|
14
|
-
children: /* @__PURE__ */
|
|
16
|
+
"aria-label": n,
|
|
17
|
+
children: /* @__PURE__ */ r(a, { className: "h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground transition-colors" })
|
|
15
18
|
}
|
|
16
|
-
)
|
|
19
|
+
);
|
|
17
20
|
}
|
|
18
21
|
export {
|
|
19
|
-
|
|
22
|
+
m as SidebarToggleButton
|
|
20
23
|
};
|
|
21
24
|
//# sourceMappingURL=SidebarToggleButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SidebarToggleButton.js","sources":["../../../lib/organisms/chat/SidebarToggleButton.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"file":"SidebarToggleButton.js","sources":["../../../lib/organisms/chat/SidebarToggleButton.tsx"],"sourcesContent":["\"use client\";\n\nimport {PanelLeft} from \"lucide-react\";\nimport {cn} from \"@clubmed/usg-chat-ui/utils/cn\";\nimport {useChatLabels} from \"../../contexts/ChatLabelsContext\";\n\ninterface SidebarToggleButtonProps {\n onOpen: () => void;\n className?: string;\n}\n\nexport function SidebarToggleButton({onOpen, className}: SidebarToggleButtonProps) {\n const {get} = useChatLabels();\n const ariaLabel = get(\"sidebarOpenHistoryAriaLabel\", \"Ouvrir l'historique\");\n\n return (\n <button\n onClick={onOpen}\n className={cn(\n \"group flex h-10 w-10 sm:h-11 sm:w-11 items-center justify-center bg-transparent hover:bg-muted transition-all duration-200 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background rounded-lg p-2\",\n className)}\n aria-label={ariaLabel}\n >\n <PanelLeft className=\"h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground transition-colors\"/>\n </button>)\n ;\n}\n"],"names":["SidebarToggleButton","onOpen","className","get","useChatLabels","ariaLabel","jsx","cn","PanelLeft"],"mappings":";;;;;AAWO,SAASA,EAAoB,EAAC,QAAAC,GAAQ,WAAAC,KAAsC;AACjF,QAAM,EAAC,KAAAC,EAAA,IAAOC,EAAA,GACRC,IAAYF,EAAI,+BAA+B,qBAAqB;AAE1E,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAASL;AAAA,MACT,WAAWM;AAAA,QACT;AAAA,QACAL;AAAA,MAAA;AAAA,MACF,cAAYG;AAAA,MAEZ,UAAA,gBAAAC,EAACE,GAAA,EAAU,WAAU,gEAAA,CAA+D;AAAA,IAAA;AAAA,EAAA;AAG1F;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PromptInputMessage } from '../../../molecules/AiElements/PromptInput';
|
|
2
2
|
import { ChatMessage } from '../types';
|
|
3
3
|
export declare function useChat(): {
|
|
4
|
+
user: import('../../..').ChatUser | null | undefined;
|
|
4
5
|
chatMessages: ChatMessage[];
|
|
5
6
|
settingsOpen: boolean;
|
|
6
7
|
setSettingsOpen: import('react').Dispatch<import('react').SetStateAction<boolean>>;
|
|
@@ -21,5 +22,4 @@ export declare function useChat(): {
|
|
|
21
22
|
handleRegenerate: (messageKey: string) => Promise<void>;
|
|
22
23
|
localInput: string;
|
|
23
24
|
setLocalInput: import('react').Dispatch<import('react').SetStateAction<string>>;
|
|
24
|
-
emptyStateGreeting: string | undefined;
|
|
25
25
|
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useState as
|
|
3
|
-
import { parseChatCommand as
|
|
4
|
-
import { useToast as
|
|
5
|
-
import { useCanvasStore as
|
|
6
|
-
import { useChatApiClient as
|
|
7
|
-
import { useConversations as
|
|
8
|
-
import { useChatJira as
|
|
9
|
-
import { useChatPreferences as
|
|
2
|
+
import { useState as j, useCallback as k } from "react";
|
|
3
|
+
import { parseChatCommand as V, shouldHandleCommand as B, getCommandHelp as G } from "../../../utils/chat-commands.js";
|
|
4
|
+
import { useToast as X } from "../../../molecules/Notifications/useToast.js";
|
|
5
|
+
import { useCanvasStore as Y } from "../../../utils/canvas-store.js";
|
|
6
|
+
import { useChatApiClient as Z, useChatConfig as ee } from "../../../contexts/ChatContext.js";
|
|
7
|
+
import { useConversations as te } from "./useConversations.js";
|
|
8
|
+
import { useChatJira as se } from "../../../contexts/ChatJiraContext.js";
|
|
9
|
+
import { useChatPreferences as re } from "./useChatPreferences.js";
|
|
10
10
|
import { useChatSyncUserSettings as ne } from "./useChatSyncUserSettings.js";
|
|
11
|
-
import { useChatKeyboardsShortcuts as
|
|
12
|
-
const
|
|
11
|
+
import { useChatKeyboardsShortcuts as oe } from "./useChatKeyboardsShortcuts.js";
|
|
12
|
+
const ae = (e) => e == null ? void 0 : e.map((r) => ({
|
|
13
13
|
href: r.href || r.url || "#",
|
|
14
14
|
title: r.title || "Source"
|
|
15
|
-
})),
|
|
15
|
+
})), ie = (e) => {
|
|
16
16
|
if (e)
|
|
17
17
|
return typeof e == "string" ? { content: e, duration: 0 } : {
|
|
18
18
|
content: e.content ?? "",
|
|
@@ -31,41 +31,41 @@ const ie = (e) => e == null ? void 0 : e.map((r) => ({
|
|
|
31
31
|
return {
|
|
32
32
|
key: r,
|
|
33
33
|
version: p,
|
|
34
|
-
sources:
|
|
35
|
-
reasoning:
|
|
34
|
+
sources: ae(e.sources),
|
|
35
|
+
reasoning: ie(e.reasoning)
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
-
function
|
|
39
|
-
const { toast: e } =
|
|
40
|
-
user:
|
|
41
|
-
dbUserId:
|
|
42
|
-
} =
|
|
38
|
+
function ye() {
|
|
39
|
+
const { toast: e } = X(), r = Z(), { setJiraConfigured: p, setJiraAuthSettings: _ } = se(), {
|
|
40
|
+
user: K,
|
|
41
|
+
dbUserId: C
|
|
42
|
+
} = ee(), [A, T] = j(!1), [D, N] = j(!1), [R, v] = j(""), {
|
|
43
43
|
chatMessages: u,
|
|
44
44
|
setChatMessages: m,
|
|
45
45
|
currentConversationId: d,
|
|
46
46
|
sidebarRefreshTrigger: U,
|
|
47
|
-
isLoadingMessage:
|
|
48
|
-
setIsLoadingMessage:
|
|
49
|
-
loadConversation:
|
|
50
|
-
handleNewConversation:
|
|
47
|
+
isLoadingMessage: x,
|
|
48
|
+
setIsLoadingMessage: o,
|
|
49
|
+
loadConversation: P,
|
|
50
|
+
handleNewConversation: $,
|
|
51
51
|
saveConversation: g
|
|
52
|
-
} =
|
|
53
|
-
ne(),
|
|
52
|
+
} = te();
|
|
53
|
+
ne(), oe(), re();
|
|
54
54
|
const {
|
|
55
55
|
canvasType: E,
|
|
56
|
-
projectKey:
|
|
57
|
-
releaseNoteSettings:
|
|
56
|
+
projectKey: b,
|
|
57
|
+
releaseNoteSettings: n,
|
|
58
58
|
isFullscreen: H,
|
|
59
59
|
canvasWidth: O,
|
|
60
60
|
isResizing: z,
|
|
61
61
|
resizeWidth: F
|
|
62
|
-
} =
|
|
62
|
+
} = Y(), J = k(
|
|
63
63
|
async (l) => {
|
|
64
64
|
var y;
|
|
65
65
|
if (!((y = l.text) != null && y.trim()))
|
|
66
66
|
return;
|
|
67
|
-
const a = l.text.trim(), i =
|
|
68
|
-
if (
|
|
67
|
+
const a = l.text.trim(), i = V(a);
|
|
68
|
+
if (B(i)) {
|
|
69
69
|
if (i.command === "settings") {
|
|
70
70
|
T(!0);
|
|
71
71
|
return;
|
|
@@ -77,25 +77,25 @@ function Ce() {
|
|
|
77
77
|
versions: [
|
|
78
78
|
{
|
|
79
79
|
id: `assistant-${Date.now()}`,
|
|
80
|
-
content:
|
|
80
|
+
content: G(),
|
|
81
81
|
responseType: "message"
|
|
82
82
|
}
|
|
83
83
|
],
|
|
84
84
|
avatar: "https://github.com/openai.png",
|
|
85
85
|
name: "Assistant"
|
|
86
86
|
};
|
|
87
|
-
m((c) => [...c, t]),
|
|
87
|
+
m((c) => [...c, t]), v("");
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
if (i.command === "clear") {
|
|
91
91
|
m([]), e({
|
|
92
92
|
title: "Cleared",
|
|
93
93
|
description: "Conversation history cleared"
|
|
94
|
-
}),
|
|
94
|
+
}), v("");
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
const
|
|
98
|
+
const I = {
|
|
99
99
|
key: `user-${Date.now()}`,
|
|
100
100
|
from: "user",
|
|
101
101
|
versions: [
|
|
@@ -107,24 +107,24 @@ function Ce() {
|
|
|
107
107
|
avatar: "https://github.com/haydenbleasel.png",
|
|
108
108
|
name: "User"
|
|
109
109
|
};
|
|
110
|
-
m((t) => [...t,
|
|
110
|
+
m((t) => [...t, I]), v(""), setTimeout(() => {
|
|
111
111
|
g();
|
|
112
|
-
}, 200),
|
|
112
|
+
}, 200), o(!0);
|
|
113
113
|
try {
|
|
114
|
-
const t =
|
|
115
|
-
projectKey:
|
|
116
|
-
status:
|
|
117
|
-
boardId:
|
|
114
|
+
const t = n ? {
|
|
115
|
+
projectKey: n.projectKey,
|
|
116
|
+
status: n.status,
|
|
117
|
+
boardId: n.boardId
|
|
118
118
|
} : void 0, c = await r.chatCanvas({
|
|
119
119
|
message: a,
|
|
120
120
|
conversationHistory: u.flatMap(
|
|
121
|
-
(s) => s.versions.map((
|
|
121
|
+
(s) => s.versions.map((Q) => ({
|
|
122
122
|
role: s.from,
|
|
123
|
-
content:
|
|
123
|
+
content: Q.content
|
|
124
124
|
}))
|
|
125
125
|
),
|
|
126
|
-
projectKey:
|
|
127
|
-
userId:
|
|
126
|
+
projectKey: b ?? void 0,
|
|
127
|
+
userId: C ?? void 0,
|
|
128
128
|
conversationId: d ?? void 0,
|
|
129
129
|
releaseNoteSettings: t
|
|
130
130
|
});
|
|
@@ -132,23 +132,23 @@ function Ce() {
|
|
|
132
132
|
c.error === "jira_oauth_required" && p(!1), m((s) => s.slice(0, -1)), _({
|
|
133
133
|
authUrl: c.auth_url ?? "",
|
|
134
134
|
threadId: d || void 0
|
|
135
|
-
}),
|
|
135
|
+
}), o(!1);
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
|
-
const { key: f, version: w, sources:
|
|
138
|
+
const { key: f, version: w, sources: S, reasoning: M } = q(c), h = {
|
|
139
139
|
key: f,
|
|
140
140
|
from: "assistant",
|
|
141
141
|
versions: [w],
|
|
142
142
|
avatar: "https://github.com/openai.png",
|
|
143
143
|
name: "Assistant",
|
|
144
|
-
sources:
|
|
144
|
+
sources: S,
|
|
145
145
|
reasoning: M
|
|
146
146
|
};
|
|
147
|
-
m((s) => [...s,
|
|
147
|
+
m((s) => [...s, h]), o(!1), setTimeout(() => {
|
|
148
148
|
g();
|
|
149
149
|
}, 100);
|
|
150
150
|
} catch (t) {
|
|
151
|
-
console.error("Chat error:", t),
|
|
151
|
+
console.error("Chat error:", t), o(!1), e({
|
|
152
152
|
title: "Error",
|
|
153
153
|
description: "Failed to get response. Please try again.",
|
|
154
154
|
variant: "destructive"
|
|
@@ -159,21 +159,21 @@ function Ce() {
|
|
|
159
159
|
r,
|
|
160
160
|
u,
|
|
161
161
|
d,
|
|
162
|
+
C,
|
|
162
163
|
b,
|
|
163
|
-
|
|
164
|
-
o,
|
|
164
|
+
n,
|
|
165
165
|
g,
|
|
166
166
|
_,
|
|
167
167
|
p,
|
|
168
168
|
e
|
|
169
169
|
]
|
|
170
|
-
), L =
|
|
170
|
+
), L = k(
|
|
171
171
|
async (l) => {
|
|
172
172
|
var y;
|
|
173
173
|
const a = u.findIndex((t) => t.key === l);
|
|
174
174
|
if (a === -1) return;
|
|
175
|
-
const i = a > 0 ? u[a - 1] : null,
|
|
176
|
-
if (!
|
|
175
|
+
const i = a > 0 ? u[a - 1] : null, I = ((y = i == null ? void 0 : i.versions[0]) == null ? void 0 : y.content) || "";
|
|
176
|
+
if (!I) {
|
|
177
177
|
e({
|
|
178
178
|
title: "Erreur",
|
|
179
179
|
description: "Impossible de régénérer : aucun message précédent trouvé",
|
|
@@ -181,22 +181,22 @@ function Ce() {
|
|
|
181
181
|
});
|
|
182
182
|
return;
|
|
183
183
|
}
|
|
184
|
-
|
|
184
|
+
o(!0);
|
|
185
185
|
try {
|
|
186
|
-
const t =
|
|
187
|
-
projectKey:
|
|
188
|
-
status:
|
|
189
|
-
boardId:
|
|
186
|
+
const t = n ? {
|
|
187
|
+
projectKey: n.projectKey,
|
|
188
|
+
status: n.status,
|
|
189
|
+
boardId: n.boardId
|
|
190
190
|
} : void 0, c = u.slice(0, a).flatMap(
|
|
191
|
-
(
|
|
192
|
-
role:
|
|
191
|
+
(h) => h.versions.map((s) => ({
|
|
192
|
+
role: h.from,
|
|
193
193
|
content: s.content
|
|
194
194
|
}))
|
|
195
195
|
), f = await r.chatCanvas({
|
|
196
|
-
message:
|
|
196
|
+
message: I,
|
|
197
197
|
conversationHistory: c,
|
|
198
|
-
projectKey:
|
|
199
|
-
userId:
|
|
198
|
+
projectKey: b ?? void 0,
|
|
199
|
+
userId: C ?? void 0,
|
|
200
200
|
conversationId: d ?? void 0,
|
|
201
201
|
releaseNoteSettings: t
|
|
202
202
|
});
|
|
@@ -204,22 +204,22 @@ function Ce() {
|
|
|
204
204
|
f.error === "jira_oauth_required" && p(!1), _({
|
|
205
205
|
authUrl: f.auth_url ?? "",
|
|
206
206
|
threadId: d || void 0
|
|
207
|
-
}),
|
|
207
|
+
}), o(!1);
|
|
208
208
|
return;
|
|
209
209
|
}
|
|
210
|
-
const { version: w, sources:
|
|
210
|
+
const { version: w, sources: S, reasoning: M } = q(f);
|
|
211
211
|
m(
|
|
212
|
-
(
|
|
212
|
+
(h) => h.map((s) => s.key === l ? {
|
|
213
213
|
...s,
|
|
214
214
|
versions: [...s.versions, w],
|
|
215
|
-
sources:
|
|
215
|
+
sources: S,
|
|
216
216
|
reasoning: M
|
|
217
217
|
} : s)
|
|
218
|
-
),
|
|
218
|
+
), o(!1), setTimeout(() => {
|
|
219
219
|
g();
|
|
220
220
|
}, 100);
|
|
221
221
|
} catch (t) {
|
|
222
|
-
console.error("Regenerate error:", t),
|
|
222
|
+
console.error("Regenerate error:", t), o(!1), e({
|
|
223
223
|
title: "Erreur",
|
|
224
224
|
description: "Impossible de régénérer la réponse. Veuillez réessayer.",
|
|
225
225
|
variant: "destructive"
|
|
@@ -230,27 +230,28 @@ function Ce() {
|
|
|
230
230
|
r,
|
|
231
231
|
u,
|
|
232
232
|
d,
|
|
233
|
+
C,
|
|
233
234
|
b,
|
|
234
|
-
|
|
235
|
-
o,
|
|
235
|
+
n,
|
|
236
236
|
g,
|
|
237
237
|
p,
|
|
238
238
|
e
|
|
239
239
|
]
|
|
240
|
-
), W =
|
|
241
|
-
|
|
242
|
-
}, [])
|
|
240
|
+
), W = k((l) => {
|
|
241
|
+
v(l);
|
|
242
|
+
}, []);
|
|
243
243
|
return {
|
|
244
|
+
user: K,
|
|
244
245
|
chatMessages: u,
|
|
245
|
-
settingsOpen:
|
|
246
|
+
settingsOpen: A,
|
|
246
247
|
setSettingsOpen: T,
|
|
247
|
-
sidebarOpen:
|
|
248
|
-
setSidebarOpen:
|
|
248
|
+
sidebarOpen: D,
|
|
249
|
+
setSidebarOpen: N,
|
|
249
250
|
sidebarRefreshTrigger: U,
|
|
250
251
|
currentConversationId: d,
|
|
251
|
-
loadConversation:
|
|
252
|
-
handleNewConversation:
|
|
253
|
-
isLoadingMessage:
|
|
252
|
+
loadConversation: P,
|
|
253
|
+
handleNewConversation: $,
|
|
254
|
+
isLoadingMessage: x,
|
|
254
255
|
canvasType: E,
|
|
255
256
|
isFullscreen: H,
|
|
256
257
|
canvasWidth: O,
|
|
@@ -260,11 +261,10 @@ function Ce() {
|
|
|
260
261
|
handleSubmit: J,
|
|
261
262
|
handleRegenerate: L,
|
|
262
263
|
localInput: R,
|
|
263
|
-
setLocalInput:
|
|
264
|
-
emptyStateGreeting: B
|
|
264
|
+
setLocalInput: v
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
export {
|
|
268
|
-
|
|
268
|
+
ye as useChat
|
|
269
269
|
};
|
|
270
270
|
//# sourceMappingURL=useChat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChat.js","sources":["../../../../lib/organisms/chat/hooks/useChat.ts"],"sourcesContent":["\"use client\";\n\nimport {useCallback, useState} from \"react\";\nimport {getCommandHelp, parseChatCommand, shouldHandleCommand} from \"../../../utils/chat-commands\";\nimport {useToast} from \"../../../molecules/Notifications/useToast\";\nimport type {PromptInputMessage} from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport {useCanvasStore} from \"../../../utils/canvas-store\";\nimport type {ChatMessage} from \"../types\";\nimport type {ChatCanvasResponse} from \"@clubmed/usg-chat-ui/core/interfaces/ChatCanvas\";\nimport {useChatApiClient, useChatConfig} from \"../../../contexts/ChatContext\";\nimport {useConversations} from \"./useConversations\";\nimport {useChatJira} from \"@clubmed/usg-chat-ui/contexts/ChatJiraContext\";\nimport {useChatPreferences} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatPreferences\";\nimport {useChatSyncUserSettings} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatSyncUserSettings\";\nimport {useChatKeyboardsShortcuts} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatKeyboardsShortcuts\";\n\nconst mapCanvasSources = (sources: ChatCanvasResponse[\"sources\"]) =>\n sources?.map((source) => ({\n href: source.href || source.url || \"#\",\n title: source.title || \"Source\",\n }));\n\nconst mapCanvasReasoning = (reasoning: ChatCanvasResponse[\"reasoning\"]) => {\n if (!reasoning) {\n return undefined;\n }\n\n if (typeof reasoning === \"string\") {\n return {content: reasoning, duration: 0};\n }\n\n return {\n content: reasoning.content ?? \"\",\n duration: reasoning.duration ?? 0,\n };\n};\n\nconst buildAssistantResponseParts = (data: ChatCanvasResponse) => {\n if (data.response_type === \"auth_required\") {\n throw new Error(\"Cannot build assistant response for auth-required payload\");\n }\n\n const id = `assistant-${Date.now()}`;\n const version: ChatMessage[\"versions\"][number] = {\n id,\n content: data.content || \"Aucune réponse disponible\",\n responseType: data.response_type,\n canvasData: data.canvas_data,\n followupQuestions: data.followup_questions,\n };\n\n return {\n key: id,\n version,\n sources: mapCanvasSources(data.sources),\n reasoning: mapCanvasReasoning(data.reasoning),\n };\n};\n\nexport function useChat() {\n const {toast} = useToast();\n const apiClient = useChatApiClient();\n const {setJiraConfigured, setJiraAuthSettings} = useChatJira();\n\n const {\n user,\n dbUserId,\n } = useChatConfig();\n\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [localInput, setLocalInput] = useState(\"\");\n\n const {\n chatMessages,\n setChatMessages,\n currentConversationId,\n sidebarRefreshTrigger,\n isLoadingMessage,\n setIsLoadingMessage,\n loadConversation,\n handleNewConversation,\n saveConversation,\n } = useConversations();\n\n useChatSyncUserSettings();\n useChatKeyboardsShortcuts();\n useChatPreferences();\n\n const {\n canvasType,\n projectKey,\n releaseNoteSettings,\n isFullscreen,\n canvasWidth,\n isResizing,\n resizeWidth,\n } = useCanvasStore();\n\n const handleSubmit = useCallback(\n async (message: PromptInputMessage) => {\n\n if (!message.text?.trim()) {\n return;\n }\n\n const userMessage = message.text.trim();\n const parsed = parseChatCommand(userMessage);\n\n if (shouldHandleCommand(parsed)) {\n if (parsed.command === \"settings\") {\n setSettingsOpen(true);\n return;\n }\n\n if (parsed.command === \"help\") {\n const helpMessage: ChatMessage = {\n key: `assistant-${Date.now()}`,\n from: \"assistant\",\n versions: [\n {\n id: `assistant-${Date.now()}`,\n content: getCommandHelp(),\n responseType: \"message\",\n },\n ],\n avatar: \"https://github.com/openai.png\",\n name: \"Assistant\",\n };\n setChatMessages((prev) => [...prev, helpMessage]);\n setLocalInput(\"\");\n return;\n }\n\n if (parsed.command === \"clear\") {\n setChatMessages([]);\n toast({\n title: \"Cleared\",\n description: \"Conversation history cleared\",\n });\n setLocalInput(\"\");\n return;\n }\n }\n\n const newUserMessage: ChatMessage = {\n key: `user-${Date.now()}`,\n from: \"user\",\n versions: [\n {\n id: `user-${Date.now()}`,\n content: userMessage,\n },\n ],\n avatar: \"https://github.com/haydenbleasel.png\",\n name: \"User\",\n };\n setChatMessages((prev) => [...prev, newUserMessage]);\n setLocalInput(\"\");\n\n setTimeout(() => {\n saveConversation();\n }, 200);\n\n setIsLoadingMessage(true);\n\n try {\n const releaseNotePayload = releaseNoteSettings\n ? {\n projectKey: releaseNoteSettings.projectKey,\n status: releaseNoteSettings.status,\n boardId: releaseNoteSettings.boardId,\n }\n : undefined;\n\n const data = await apiClient.chatCanvas({\n message: userMessage,\n conversationHistory: chatMessages.flatMap((m) =>\n m.versions.map((v: ChatMessage[\"versions\"][number]) => ({\n role: m.from,\n content: v.content,\n }))\n ),\n projectKey: projectKey ?? undefined,\n userId: dbUserId ?? undefined,\n conversationId: currentConversationId ?? undefined,\n releaseNoteSettings: releaseNotePayload,\n });\n\n if (data.response_type === \"auth_required\") {\n if (data.error === \"jira_oauth_required\") {\n setJiraConfigured(false);\n }\n\n setChatMessages((prev) => prev.slice(0, -1));\n setJiraAuthSettings({\n authUrl: data.auth_url ?? \"\",\n threadId: currentConversationId || undefined,\n });\n\n setIsLoadingMessage(false);\n return;\n }\n\n const {key, version, sources, reasoning} = buildAssistantResponseParts(data);\n\n const assistantMessage: ChatMessage = {\n key,\n from: \"assistant\",\n versions: [version],\n avatar: \"https://github.com/openai.png\",\n name: \"Assistant\",\n sources,\n reasoning,\n };\n\n setChatMessages((prev) => [...prev, assistantMessage]);\n setIsLoadingMessage(false);\n\n setTimeout(() => {\n saveConversation();\n }, 100);\n } catch (error) {\n console.error(\"Chat error:\", error);\n setIsLoadingMessage(false);\n toast({\n title: \"Error\",\n description: \"Failed to get response. Please try again.\",\n variant: \"destructive\",\n });\n }\n },\n [\n apiClient,\n chatMessages,\n currentConversationId,\n dbUserId,\n projectKey,\n releaseNoteSettings,\n saveConversation,\n setJiraAuthSettings,\n setJiraConfigured,\n toast,\n ]\n );\n\n const handleRegenerate = useCallback(\n async (messageKey: string) => {\n const messageIndex = chatMessages.findIndex((msg) => msg.key === messageKey);\n if (messageIndex === -1) return;\n\n const previousMessage = messageIndex > 0 ? chatMessages[messageIndex - 1] : null;\n const userMessage = previousMessage?.versions[0]?.content || \"\";\n\n if (!userMessage) {\n toast({\n title: \"Erreur\",\n description: \"Impossible de régénérer : aucun message précédent trouvé\",\n variant: \"destructive\",\n });\n return;\n }\n\n setIsLoadingMessage(true);\n\n try {\n const releaseNotePayload = releaseNoteSettings\n ? {\n projectKey: releaseNoteSettings.projectKey,\n status: releaseNoteSettings.status,\n boardId: releaseNoteSettings.boardId,\n }\n : undefined;\n\n const history = chatMessages.slice(0, messageIndex).flatMap((m) =>\n m.versions.map((v: ChatMessage[\"versions\"][number]) => ({\n role: m.from,\n content: v.content,\n }))\n );\n\n const data = await apiClient.chatCanvas({\n message: userMessage,\n conversationHistory: history,\n projectKey: projectKey ?? undefined,\n userId: dbUserId ?? undefined,\n conversationId: currentConversationId ?? undefined,\n releaseNoteSettings: releaseNotePayload,\n });\n\n if (data.response_type === \"auth_required\") {\n if (data.error === \"jira_oauth_required\") {\n setJiraConfigured(false);\n }\n\n setJiraAuthSettings({\n authUrl: data.auth_url ?? \"\",\n threadId: currentConversationId || undefined,\n });\n\n setIsLoadingMessage(false);\n return;\n }\n\n const {version, sources, reasoning} = buildAssistantResponseParts(data);\n\n setChatMessages((prev) =>\n prev.map((msg) => {\n if (msg.key === messageKey) {\n return {\n ...msg,\n versions: [...msg.versions, version],\n sources,\n reasoning,\n };\n }\n return msg;\n })\n );\n\n setIsLoadingMessage(false);\n setTimeout(() => {\n saveConversation();\n }, 100);\n } catch (error) {\n console.error(\"Regenerate error:\", error);\n setIsLoadingMessage(false);\n toast({\n title: \"Erreur\",\n description: \"Impossible de régénérer la réponse. Veuillez réessayer.\",\n variant: \"destructive\",\n });\n }\n },\n [\n apiClient,\n chatMessages,\n currentConversationId,\n dbUserId,\n projectKey,\n releaseNoteSettings,\n saveConversation,\n setJiraConfigured,\n toast,\n ]\n );\n\n const handleFollowupClick = useCallback((question: string) => {\n setLocalInput(question);\n }, []);\n\n const emptyStateGreeting = user?.userName\n ? `Bonjour ${user.userName.split(\" \")[0]} 👋`\n : undefined;\n\n return {\n chatMessages,\n settingsOpen,\n setSettingsOpen,\n sidebarOpen,\n setSidebarOpen,\n sidebarRefreshTrigger,\n currentConversationId,\n loadConversation,\n handleNewConversation,\n isLoadingMessage,\n canvasType,\n isFullscreen,\n canvasWidth,\n isResizing,\n resizeWidth,\n handleFollowupClick,\n handleSubmit,\n handleRegenerate,\n localInput,\n setLocalInput,\n emptyStateGreeting\n };\n}\n"],"names":["mapCanvasSources","sources","source","mapCanvasReasoning","reasoning","buildAssistantResponseParts","data","id","version","useChat","toast","useToast","apiClient","useChatApiClient","setJiraConfigured","setJiraAuthSettings","useChatJira","user","dbUserId","useChatConfig","settingsOpen","setSettingsOpen","useState","sidebarOpen","setSidebarOpen","localInput","setLocalInput","chatMessages","setChatMessages","currentConversationId","sidebarRefreshTrigger","isLoadingMessage","setIsLoadingMessage","loadConversation","handleNewConversation","saveConversation","useConversations","useChatSyncUserSettings","useChatKeyboardsShortcuts","useChatPreferences","canvasType","projectKey","releaseNoteSettings","isFullscreen","canvasWidth","isResizing","resizeWidth","useCanvasStore","handleSubmit","useCallback","message","_a","userMessage","parsed","parseChatCommand","shouldHandleCommand","helpMessage","getCommandHelp","prev","newUserMessage","releaseNotePayload","m","v","key","assistantMessage","error","handleRegenerate","messageKey","messageIndex","msg","previousMessage","history","handleFollowupClick","question","emptyStateGreeting"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useChat.js","sources":["../../../../lib/organisms/chat/hooks/useChat.ts"],"sourcesContent":["\"use client\";\n\nimport {useCallback, useState} from \"react\";\nimport {getCommandHelp, parseChatCommand, shouldHandleCommand} from \"../../../utils/chat-commands\";\nimport {useToast} from \"../../../molecules/Notifications/useToast\";\nimport type {PromptInputMessage} from \"@clubmed/usg-chat-ui/molecules/AiElements/PromptInput\";\nimport {useCanvasStore} from \"../../../utils/canvas-store\";\nimport type {ChatMessage} from \"../types\";\nimport type {ChatCanvasResponse} from \"@clubmed/usg-chat-ui/core/interfaces/ChatCanvas\";\nimport {useChatApiClient, useChatConfig} from \"../../../contexts/ChatContext\";\nimport {useConversations} from \"./useConversations\";\nimport {useChatJira} from \"@clubmed/usg-chat-ui/contexts/ChatJiraContext\";\nimport {useChatPreferences} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatPreferences\";\nimport {useChatSyncUserSettings} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatSyncUserSettings\";\nimport {useChatKeyboardsShortcuts} from \"@clubmed/usg-chat-ui/organisms/chat/hooks/useChatKeyboardsShortcuts\";\n\nconst mapCanvasSources = (sources: ChatCanvasResponse[\"sources\"]) =>\n sources?.map((source) => ({\n href: source.href || source.url || \"#\",\n title: source.title || \"Source\",\n }));\n\nconst mapCanvasReasoning = (reasoning: ChatCanvasResponse[\"reasoning\"]) => {\n if (!reasoning) {\n return undefined;\n }\n\n if (typeof reasoning === \"string\") {\n return {content: reasoning, duration: 0};\n }\n\n return {\n content: reasoning.content ?? \"\",\n duration: reasoning.duration ?? 0,\n };\n};\n\nconst buildAssistantResponseParts = (data: ChatCanvasResponse) => {\n if (data.response_type === \"auth_required\") {\n throw new Error(\"Cannot build assistant response for auth-required payload\");\n }\n\n const id = `assistant-${Date.now()}`;\n const version: ChatMessage[\"versions\"][number] = {\n id,\n content: data.content || \"Aucune réponse disponible\",\n responseType: data.response_type,\n canvasData: data.canvas_data,\n followupQuestions: data.followup_questions,\n };\n\n return {\n key: id,\n version,\n sources: mapCanvasSources(data.sources),\n reasoning: mapCanvasReasoning(data.reasoning),\n };\n};\n\n\nexport function useChat() {\n const {toast} = useToast();\n const apiClient = useChatApiClient();\n const {setJiraConfigured, setJiraAuthSettings} = useChatJira();\n\n const {\n user,\n dbUserId,\n } = useChatConfig();\n\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [localInput, setLocalInput] = useState(\"\");\n\n const {\n chatMessages,\n setChatMessages,\n currentConversationId,\n sidebarRefreshTrigger,\n isLoadingMessage,\n setIsLoadingMessage,\n loadConversation,\n handleNewConversation,\n saveConversation,\n } = useConversations();\n\n useChatSyncUserSettings();\n useChatKeyboardsShortcuts();\n useChatPreferences();\n\n const {\n canvasType,\n projectKey,\n releaseNoteSettings,\n isFullscreen,\n canvasWidth,\n isResizing,\n resizeWidth,\n } = useCanvasStore();\n\n const handleSubmit = useCallback(\n async (message: PromptInputMessage) => {\n\n if (!message.text?.trim()) {\n return;\n }\n\n const userMessage = message.text.trim();\n const parsed = parseChatCommand(userMessage);\n\n if (shouldHandleCommand(parsed)) {\n if (parsed.command === \"settings\") {\n setSettingsOpen(true);\n return;\n }\n\n if (parsed.command === \"help\") {\n const helpMessage: ChatMessage = {\n key: `assistant-${Date.now()}`,\n from: \"assistant\",\n versions: [\n {\n id: `assistant-${Date.now()}`,\n content: getCommandHelp(),\n responseType: \"message\",\n },\n ],\n avatar: \"https://github.com/openai.png\",\n name: \"Assistant\",\n };\n setChatMessages((prev) => [...prev, helpMessage]);\n setLocalInput(\"\");\n return;\n }\n\n if (parsed.command === \"clear\") {\n setChatMessages([]);\n toast({\n title: \"Cleared\",\n description: \"Conversation history cleared\",\n });\n setLocalInput(\"\");\n return;\n }\n }\n\n const newUserMessage: ChatMessage = {\n key: `user-${Date.now()}`,\n from: \"user\",\n versions: [\n {\n id: `user-${Date.now()}`,\n content: userMessage,\n },\n ],\n avatar: \"https://github.com/haydenbleasel.png\",\n name: \"User\",\n };\n setChatMessages((prev) => [...prev, newUserMessage]);\n setLocalInput(\"\");\n\n setTimeout(() => {\n saveConversation();\n }, 200);\n\n setIsLoadingMessage(true);\n\n try {\n const releaseNotePayload = releaseNoteSettings\n ? {\n projectKey: releaseNoteSettings.projectKey,\n status: releaseNoteSettings.status,\n boardId: releaseNoteSettings.boardId,\n }\n : undefined;\n\n const data = await apiClient.chatCanvas({\n message: userMessage,\n conversationHistory: chatMessages.flatMap((m) =>\n m.versions.map((v: ChatMessage[\"versions\"][number]) => ({\n role: m.from,\n content: v.content,\n }))\n ),\n projectKey: projectKey ?? undefined,\n userId: dbUserId ?? undefined,\n conversationId: currentConversationId ?? undefined,\n releaseNoteSettings: releaseNotePayload,\n });\n\n if (data.response_type === \"auth_required\") {\n if (data.error === \"jira_oauth_required\") {\n setJiraConfigured(false);\n }\n\n setChatMessages((prev) => prev.slice(0, -1));\n setJiraAuthSettings({\n authUrl: data.auth_url ?? \"\",\n threadId: currentConversationId || undefined,\n });\n\n setIsLoadingMessage(false);\n return;\n }\n\n const {key, version, sources, reasoning} = buildAssistantResponseParts(data);\n\n const assistantMessage: ChatMessage = {\n key,\n from: \"assistant\",\n versions: [version],\n avatar: \"https://github.com/openai.png\",\n name: \"Assistant\",\n sources,\n reasoning,\n };\n\n setChatMessages((prev) => [...prev, assistantMessage]);\n setIsLoadingMessage(false);\n\n setTimeout(() => {\n saveConversation();\n }, 100);\n } catch (error) {\n console.error(\"Chat error:\", error);\n setIsLoadingMessage(false);\n toast({\n title: \"Error\",\n description: \"Failed to get response. Please try again.\",\n variant: \"destructive\",\n });\n }\n },\n [\n apiClient,\n chatMessages,\n currentConversationId,\n dbUserId,\n projectKey,\n releaseNoteSettings,\n saveConversation,\n setJiraAuthSettings,\n setJiraConfigured,\n toast,\n ]\n );\n\n const handleRegenerate = useCallback(\n async (messageKey: string) => {\n const messageIndex = chatMessages.findIndex((msg) => msg.key === messageKey);\n if (messageIndex === -1) return;\n\n const previousMessage = messageIndex > 0 ? chatMessages[messageIndex - 1] : null;\n const userMessage = previousMessage?.versions[0]?.content || \"\";\n\n if (!userMessage) {\n toast({\n title: \"Erreur\",\n description: \"Impossible de régénérer : aucun message précédent trouvé\",\n variant: \"destructive\",\n });\n return;\n }\n\n setIsLoadingMessage(true);\n\n try {\n const releaseNotePayload = releaseNoteSettings\n ? {\n projectKey: releaseNoteSettings.projectKey,\n status: releaseNoteSettings.status,\n boardId: releaseNoteSettings.boardId,\n }\n : undefined;\n\n const history = chatMessages.slice(0, messageIndex).flatMap((m) =>\n m.versions.map((v: ChatMessage[\"versions\"][number]) => ({\n role: m.from,\n content: v.content,\n }))\n );\n\n const data = await apiClient.chatCanvas({\n message: userMessage,\n conversationHistory: history,\n projectKey: projectKey ?? undefined,\n userId: dbUserId ?? undefined,\n conversationId: currentConversationId ?? undefined,\n releaseNoteSettings: releaseNotePayload,\n });\n\n if (data.response_type === \"auth_required\") {\n if (data.error === \"jira_oauth_required\") {\n setJiraConfigured(false);\n }\n\n setJiraAuthSettings({\n authUrl: data.auth_url ?? \"\",\n threadId: currentConversationId || undefined,\n });\n\n setIsLoadingMessage(false);\n return;\n }\n\n const {version, sources, reasoning} = buildAssistantResponseParts(data);\n\n setChatMessages((prev) =>\n prev.map((msg) => {\n if (msg.key === messageKey) {\n return {\n ...msg,\n versions: [...msg.versions, version],\n sources,\n reasoning,\n };\n }\n return msg;\n })\n );\n\n setIsLoadingMessage(false);\n setTimeout(() => {\n saveConversation();\n }, 100);\n } catch (error) {\n console.error(\"Regenerate error:\", error);\n setIsLoadingMessage(false);\n toast({\n title: \"Erreur\",\n description: \"Impossible de régénérer la réponse. Veuillez réessayer.\",\n variant: \"destructive\",\n });\n }\n },\n [\n apiClient,\n chatMessages,\n currentConversationId,\n dbUserId,\n projectKey,\n releaseNoteSettings,\n saveConversation,\n setJiraConfigured,\n toast,\n ]\n );\n\n const handleFollowupClick = useCallback((question: string) => {\n setLocalInput(question);\n }, []);\n\n return {\n user,\n chatMessages,\n settingsOpen,\n setSettingsOpen,\n sidebarOpen,\n setSidebarOpen,\n sidebarRefreshTrigger,\n currentConversationId,\n loadConversation,\n handleNewConversation,\n isLoadingMessage,\n canvasType,\n isFullscreen,\n canvasWidth,\n isResizing,\n resizeWidth,\n handleFollowupClick,\n handleSubmit,\n handleRegenerate,\n localInput,\n setLocalInput,\n };\n}\n"],"names":["mapCanvasSources","sources","source","mapCanvasReasoning","reasoning","buildAssistantResponseParts","data","id","version","useChat","toast","useToast","apiClient","useChatApiClient","setJiraConfigured","setJiraAuthSettings","useChatJira","user","dbUserId","useChatConfig","settingsOpen","setSettingsOpen","useState","sidebarOpen","setSidebarOpen","localInput","setLocalInput","chatMessages","setChatMessages","currentConversationId","sidebarRefreshTrigger","isLoadingMessage","setIsLoadingMessage","loadConversation","handleNewConversation","saveConversation","useConversations","useChatSyncUserSettings","useChatKeyboardsShortcuts","useChatPreferences","canvasType","projectKey","releaseNoteSettings","isFullscreen","canvasWidth","isResizing","resizeWidth","useCanvasStore","handleSubmit","useCallback","message","_a","userMessage","parsed","parseChatCommand","shouldHandleCommand","helpMessage","getCommandHelp","prev","newUserMessage","releaseNotePayload","m","v","key","assistantMessage","error","handleRegenerate","messageKey","messageIndex","msg","previousMessage","history","handleFollowupClick","question"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const c = /{{\s*([\w.-]+)\s*}}/g, i = (t) => t.replace(/\s{2,}/g, " ").trim(), a = (t, o = {}, { preserveWhitespace: n = !1 } = {}) => {
|
|
2
|
+
if (!t)
|
|
3
|
+
return;
|
|
4
|
+
const r = t.replace(c, (l, s) => {
|
|
5
|
+
const e = o[s];
|
|
6
|
+
return e == null ? "" : String(e);
|
|
7
|
+
});
|
|
8
|
+
return (n ? r.trim() : i(r)) || void 0;
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
a as interpolate
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=interpolate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolate.js","sources":["../../lib/utils/interpolate.ts"],"sourcesContent":["const PLACEHOLDER_PATTERN = /{{\\s*([\\w.-]+)\\s*}}/g;\n\ntype InterpolateValues = Record<string, string | number | null | undefined>;\n\nconst normalizeWhitespace = (value: string) => value.replace(/\\s{2,}/g, \" \").trim();\n\nexport const interpolate = (\n template: string,\n values: InterpolateValues = {},\n {preserveWhitespace = false}: {preserveWhitespace?: boolean} = {}\n) => {\n if (!template) {\n return undefined;\n }\n\n const replaced = template.replace(PLACEHOLDER_PATTERN, (_, key: string) => {\n const value = values[key];\n return value === null || value === undefined ? \"\" : String(value);\n });\n\n const output = preserveWhitespace ? replaced.trim() : normalizeWhitespace(replaced);\n\n return output || undefined;\n};\n"],"names":["PLACEHOLDER_PATTERN","normalizeWhitespace","value","interpolate","template","values","preserveWhitespace","replaced","_","key"],"mappings":"AAAA,MAAMA,IAAsB,wBAItBC,IAAsB,CAACC,MAAkBA,EAAM,QAAQ,WAAW,GAAG,EAAE,KAAA,GAEhEC,IAAc,CACzBC,GACAC,IAA4B,CAAA,GAC5B,EAAC,oBAAAC,IAAqB,GAAA,IAAyC,OAC5D;AACH,MAAI,CAACF;AACH;AAGF,QAAMG,IAAWH,EAAS,QAAQJ,GAAqB,CAACQ,GAAGC,MAAgB;AACzE,UAAMP,IAAQG,EAAOI,CAAG;AACxB,WAAOP,KAAU,OAA8B,KAAK,OAAOA,CAAK;AAAA,EAClE,CAAC;AAID,UAFeI,IAAqBC,EAAS,KAAA,IAASN,EAAoBM,CAAQ,MAEjE;AACnB;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { interpolate as e } from "./interpolate.js";
|
|
2
|
+
import { d as o, i as s, g as t } from "../chunks/vi.2VT5v0um.js";
|
|
3
|
+
o("interpolate", () => {
|
|
4
|
+
s("replaces tokens and collapses whitespace by default", () => {
|
|
5
|
+
const n = e(" Hello {{name}} {{emoji}} ", {
|
|
6
|
+
name: "Ava",
|
|
7
|
+
emoji: "👋"
|
|
8
|
+
});
|
|
9
|
+
t(n).toBe("Hello Ava 👋");
|
|
10
|
+
}), s("returns undefined when template is falsy or resolves to empty content", () => {
|
|
11
|
+
t(e("", { name: "Ava" })).toBeUndefined(), t(e("{{missing}}", { missing: "" })).toBeUndefined();
|
|
12
|
+
}), s("preserves intentional spacing when requested", () => {
|
|
13
|
+
const n = e(
|
|
14
|
+
"Hello {{name}} ",
|
|
15
|
+
{ name: "Ben" },
|
|
16
|
+
{ preserveWhitespace: !0 }
|
|
17
|
+
);
|
|
18
|
+
t(n).toBe("Hello Ben");
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=interpolate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolate.test.js","sources":["../../lib/utils/interpolate.test.ts"],"sourcesContent":["import {describe, expect, it} from \"vitest\";\nimport {interpolate} from \"./interpolate\";\n\ndescribe(\"interpolate\", () => {\n it(\"replaces tokens and collapses whitespace by default\", () => {\n const result = interpolate(\" Hello {{name}} {{emoji}} \", {\n name: \"Ava\",\n emoji: \"👋\",\n });\n expect(result).toBe(\"Hello Ava 👋\");\n });\n\n it(\"returns undefined when template is falsy or resolves to empty content\", () => {\n expect(interpolate(\"\", {name: \"Ava\"})).toBeUndefined();\n expect(interpolate(\"{{missing}}\", {missing: \"\"})).toBeUndefined();\n });\n\n it(\"preserves intentional spacing when requested\", () => {\n const result = interpolate(\n \"Hello {{name}} \",\n {name: \"Ben\"},\n {preserveWhitespace: true}\n );\n expect(result).toBe(\"Hello Ben\");\n });\n});\n"],"names":["describe","it","result","interpolate","expect"],"mappings":";;AAGAA,EAAS,eAAe,MAAM;AAC5B,EAAAC,EAAG,uDAAuD,MAAM;AAC9D,UAAMC,IAASC,EAAY,+BAA+B;AAAA,MACxD,MAAM;AAAA,MACN,OAAO;AAAA,IAAA,CACR;AACDC,IAAAA,EAAOF,CAAM,EAAE,KAAK,cAAc;AAAA,EACpC,CAAC,GAEDD,EAAG,yEAAyE,MAAM;AAChFG,IAAAA,EAAOD,EAAY,IAAI,EAAC,MAAM,OAAM,CAAC,EAAE,cAAA,GACvCC,EAAOD,EAAY,eAAe,EAAC,SAAS,IAAG,CAAC,EAAE,cAAA;AAAA,EACpD,CAAC,GAEDF,EAAG,gDAAgD,MAAM;AACvD,UAAMC,IAASC;AAAA,MACb;AAAA,MACA,EAAC,MAAM,MAAA;AAAA,MACP,EAAC,oBAAoB,GAAA;AAAA,IAAI;AAE3BC,IAAAA,EAAOF,CAAM,EAAE,KAAK,aAAa;AAAA,EACnC,CAAC;AACH,CAAC;"}
|