@meistrari/chat-nuxt 4.13.0-rc.4 → 4.13.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/conversations/components/chat-export-code-block.d.vue.ts +9 -0
- package/dist/runtime/conversations/components/chat-export-code-block.vue +12 -0
- package/dist/runtime/conversations/components/chat-export-code-block.vue.d.ts +9 -0
- package/dist/runtime/conversations/components/chat-export-openui.vue +3 -1
- package/dist/runtime/conversations/components/chat-export-steps.d.vue.ts +15 -0
- package/dist/runtime/conversations/components/chat-export-steps.vue +18 -0
- package/dist/runtime/conversations/components/chat-export-steps.vue.d.ts +15 -0
- package/dist/runtime/conversations/components/chat-new-conversation-modal.d.vue.ts +1 -1
- package/dist/runtime/conversations/components/chat-new-conversation-modal.vue.d.ts +1 -1
- package/dist/runtime/conversations/export.js +15 -2
- package/dist/runtime/embed/components/mobile/chat-mobile-header.d.vue.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-header.vue.d.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +13 -13
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +13 -13
- package/dist/runtime/messages/components/chat-debug-widget-gallery.d.vue.ts +7 -0
- package/dist/runtime/messages/components/chat-debug-widget-gallery.vue +218 -0
- package/dist/runtime/messages/components/chat-debug-widget-gallery.vue.d.ts +7 -0
- package/dist/runtime/rendering/debug/widget-gallery.d.ts +24 -0
- package/dist/runtime/rendering/debug/widget-gallery.js +25 -0
- package/package.json +2 -2
package/dist/module.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
props: {
|
|
3
|
+
code: string;
|
|
4
|
+
language?: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
props: { type: Object, required: true }
|
|
4
|
+
});
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div data-openui="code-block" border rounded-8px p-12px flex="~ col" gap-4px>
|
|
9
|
+
<span v-if="props.language" body-12-regular>{{ props.language }}</span>
|
|
10
|
+
<pre m-0 whitespace-pre-wrap font-mono text-13px><code>{{ props.code }}</code></pre>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
props: {
|
|
3
|
+
code: string;
|
|
4
|
+
language?: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -4,13 +4,15 @@ import OpenuiImage from "../../rendering/components/openui/image.vue";
|
|
|
4
4
|
import OpenuiCitation from "../../rendering/components/openui/citation.vue";
|
|
5
5
|
import ChatExportQuestions from "./chat-export-questions.vue";
|
|
6
6
|
import ChatExportFile from "./chat-export-file.vue";
|
|
7
|
+
import ChatExportCodeBlock from "./chat-export-code-block.vue";
|
|
8
|
+
import ChatExportSteps from "./chat-export-steps.vue";
|
|
7
9
|
const props = defineProps({
|
|
8
10
|
node: { type: Object, required: true }
|
|
9
11
|
});
|
|
10
12
|
const code = computed(() => props.node.code ?? props.node.content ?? "");
|
|
11
13
|
const host = {
|
|
12
14
|
prose: OpenuiMarkdownProse,
|
|
13
|
-
components: { Questions: ChatExportQuestions, FileCard: ChatExportFile, Image: OpenuiImage, Citation: OpenuiCitation }
|
|
15
|
+
components: { Questions: ChatExportQuestions, FileCard: ChatExportFile, Image: OpenuiImage, Citation: OpenuiCitation, CodeBlock: ChatExportCodeBlock, Steps: ChatExportSteps }
|
|
14
16
|
};
|
|
15
17
|
</script>
|
|
16
18
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Step = {
|
|
2
|
+
props?: {
|
|
3
|
+
title?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
props: {
|
|
10
|
+
steps?: Step[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
props: { type: Object, required: true }
|
|
4
|
+
});
|
|
5
|
+
const STATUS_LABELS = { done: "conclu\xEDda", current: "em andamento", pending: "pendente" };
|
|
6
|
+
function line(step) {
|
|
7
|
+
const status = STATUS_LABELS[step.props?.status ?? ""];
|
|
8
|
+
return `${step.props?.title ?? ""}${status ? ` (${status})` : ""}${step.props?.description ? ` \u2014 ${step.props.description}` : ""}`;
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<ol data-openui="steps" pl-20px>
|
|
14
|
+
<li v-for="(step, index) in props.steps ?? []" :key="index" body-14-regular>
|
|
15
|
+
{{ line(step) }}
|
|
16
|
+
</li>
|
|
17
|
+
</ol>
|
|
18
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Step = {
|
|
2
|
+
props?: {
|
|
3
|
+
title?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
props: {
|
|
10
|
+
steps?: Step[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
9
|
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
9
|
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -38,13 +38,14 @@ export function conversationExportFilename(title, format) {
|
|
|
38
38
|
return `${title.trim().replace(/[<>:"/\\|?*\p{Cc}]/gu, "_").slice(0, 150) || "Conversa"}.${format}`;
|
|
39
39
|
}
|
|
40
40
|
export function renderedConversationToText(html) {
|
|
41
|
-
const blocks = /* @__PURE__ */ new Set(["h1", "h2", "h3", "h4", "h5", "h6", "p", "div", "section", "article", "header", "footer", "table", "ul", "ol", "pre", "blockquote", "figure"]);
|
|
41
|
+
const blocks = /* @__PURE__ */ new Set(["h1", "h2", "h3", "h4", "h5", "h6", "p", "div", "section", "article", "header", "footer", "table", "ul", "ol", "dl", "pre", "blockquote", "figure"]);
|
|
42
42
|
const ignored = /* @__PURE__ */ new Set(["script", "style", "svg"]);
|
|
43
43
|
const links = [];
|
|
44
44
|
let text = "";
|
|
45
45
|
let ignoredDepth = 0;
|
|
46
46
|
const whitespace = [];
|
|
47
47
|
let cells = 0;
|
|
48
|
+
let trimNextText = false;
|
|
48
49
|
const parser = new Parser({
|
|
49
50
|
onopentag(name, attributes) {
|
|
50
51
|
if (ignoredDepth || ignored.has(name)) {
|
|
@@ -65,6 +66,14 @@ export function renderedConversationToText(html) {
|
|
|
65
66
|
}
|
|
66
67
|
if (name === "li")
|
|
67
68
|
text += "\n- ";
|
|
69
|
+
if (name === "dt") {
|
|
70
|
+
text += "\n";
|
|
71
|
+
trimNextText = true;
|
|
72
|
+
}
|
|
73
|
+
if (name === "dd") {
|
|
74
|
+
text = `${text.replace(/[ \t]+$/, "")}: `;
|
|
75
|
+
trimNextText = true;
|
|
76
|
+
}
|
|
68
77
|
if (name === "br" || name === "hr")
|
|
69
78
|
text += "\n";
|
|
70
79
|
if (name === "img" && attributes.alt)
|
|
@@ -75,7 +84,11 @@ export function renderedConversationToText(html) {
|
|
|
75
84
|
ontext(value) {
|
|
76
85
|
if (!ignoredDepth) {
|
|
77
86
|
const mode = whitespace.at(-1);
|
|
78
|
-
|
|
87
|
+
const written = mode === "pre" || mode === "pre-wrap" || mode === "break-spaces" ? value : mode === "pre-line" ? value.replace(/[^\S\r\n]+/g, " ") : value.replace(/\s+/g, " ");
|
|
88
|
+
const shown = trimNextText ? written.trimStart() : written;
|
|
89
|
+
if (shown)
|
|
90
|
+
trimNextText = false;
|
|
91
|
+
text += shown;
|
|
79
92
|
}
|
|
80
93
|
},
|
|
81
94
|
onclosetag(name) {
|
|
@@ -15,23 +15,23 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
+
openDrawer: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
20
|
+
openOutdatedSettings: () => any;
|
|
18
21
|
rename: () => any;
|
|
19
22
|
duplicate: () => any;
|
|
20
23
|
export: () => any;
|
|
21
|
-
copyLink: () => any;
|
|
22
24
|
debug: () => any;
|
|
23
|
-
openDrawer: () => any;
|
|
24
|
-
openOutdatedSettings: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
+
onCopyLink?: (() => any) | undefined;
|
|
30
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
28
31
|
onRename?: (() => any) | undefined;
|
|
29
32
|
onDuplicate?: (() => any) | undefined;
|
|
30
33
|
onExport?: (() => any) | undefined;
|
|
31
|
-
onCopyLink?: (() => any) | undefined;
|
|
32
34
|
onDebug?: (() => any) | undefined;
|
|
33
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
34
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
37
37
|
showDrawerButton: boolean;
|
|
@@ -15,23 +15,23 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
+
openDrawer: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
20
|
+
openOutdatedSettings: () => any;
|
|
18
21
|
rename: () => any;
|
|
19
22
|
duplicate: () => any;
|
|
20
23
|
export: () => any;
|
|
21
|
-
copyLink: () => any;
|
|
22
24
|
debug: () => any;
|
|
23
|
-
openDrawer: () => any;
|
|
24
|
-
openOutdatedSettings: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
+
onCopyLink?: (() => any) | undefined;
|
|
30
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
28
31
|
onRename?: (() => any) | undefined;
|
|
29
32
|
onDuplicate?: (() => any) | undefined;
|
|
30
33
|
onExport?: (() => any) | undefined;
|
|
31
|
-
onCopyLink?: (() => any) | undefined;
|
|
32
34
|
onDebug?: (() => any) | undefined;
|
|
33
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
34
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
37
37
|
showDrawerButton: boolean;
|
|
@@ -66,46 +66,46 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
66
66
|
} & {
|
|
67
67
|
delete: () => any;
|
|
68
68
|
cancel: () => any;
|
|
69
|
+
settings: () => any;
|
|
70
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
|
+
newConversation: (groupId?: string | null | undefined) => any;
|
|
72
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
73
|
+
copyLink: () => any;
|
|
69
74
|
rename: () => any;
|
|
70
75
|
duplicate: () => any;
|
|
71
76
|
export: () => any;
|
|
72
|
-
copyLink: () => any;
|
|
73
77
|
debug: () => any;
|
|
74
|
-
selectConversation: (id: string) => any;
|
|
75
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
76
|
-
settings: () => any;
|
|
77
|
-
newConversation: (groupId?: string | null | undefined) => any;
|
|
78
|
-
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
79
78
|
tabChange: (tab: TopbarTab) => any;
|
|
80
79
|
switchWorkspace: () => any;
|
|
81
80
|
signout: () => any;
|
|
82
81
|
cancelEditing: () => any;
|
|
83
82
|
dismissOutdatedBanner: () => any;
|
|
84
83
|
saveTitle: () => any;
|
|
84
|
+
selectConversation: (id: string) => any;
|
|
85
85
|
"update:drawerOpen": (value: boolean) => any;
|
|
86
86
|
"update:editTitle": (value: string) => any;
|
|
87
87
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
88
88
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
89
89
|
onDelete?: (() => any) | undefined;
|
|
90
90
|
onCancel?: (() => any) | undefined;
|
|
91
|
-
onRename?: (() => any) | undefined;
|
|
92
|
-
onDuplicate?: (() => any) | undefined;
|
|
93
|
-
onExport?: (() => any) | undefined;
|
|
94
|
-
onCopyLink?: (() => any) | undefined;
|
|
95
|
-
onDebug?: (() => any) | undefined;
|
|
96
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
97
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
98
91
|
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
99
93
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
100
94
|
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
101
95
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
102
96
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
97
|
+
onCopyLink?: (() => any) | undefined;
|
|
98
|
+
onRename?: (() => any) | undefined;
|
|
99
|
+
onDuplicate?: (() => any) | undefined;
|
|
100
|
+
onExport?: (() => any) | undefined;
|
|
101
|
+
onDebug?: (() => any) | undefined;
|
|
103
102
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
104
103
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
105
104
|
onSignout?: (() => any) | undefined;
|
|
106
105
|
onCancelEditing?: (() => any) | undefined;
|
|
107
106
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
108
107
|
onSaveTitle?: (() => any) | undefined;
|
|
108
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
109
109
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
110
110
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
111
111
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -66,46 +66,46 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
66
66
|
} & {
|
|
67
67
|
delete: () => any;
|
|
68
68
|
cancel: () => any;
|
|
69
|
+
settings: () => any;
|
|
70
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
|
+
newConversation: (groupId?: string | null | undefined) => any;
|
|
72
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
73
|
+
copyLink: () => any;
|
|
69
74
|
rename: () => any;
|
|
70
75
|
duplicate: () => any;
|
|
71
76
|
export: () => any;
|
|
72
|
-
copyLink: () => any;
|
|
73
77
|
debug: () => any;
|
|
74
|
-
selectConversation: (id: string) => any;
|
|
75
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
76
|
-
settings: () => any;
|
|
77
|
-
newConversation: (groupId?: string | null | undefined) => any;
|
|
78
|
-
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
79
78
|
tabChange: (tab: TopbarTab) => any;
|
|
80
79
|
switchWorkspace: () => any;
|
|
81
80
|
signout: () => any;
|
|
82
81
|
cancelEditing: () => any;
|
|
83
82
|
dismissOutdatedBanner: () => any;
|
|
84
83
|
saveTitle: () => any;
|
|
84
|
+
selectConversation: (id: string) => any;
|
|
85
85
|
"update:drawerOpen": (value: boolean) => any;
|
|
86
86
|
"update:editTitle": (value: string) => any;
|
|
87
87
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
88
88
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
89
89
|
onDelete?: (() => any) | undefined;
|
|
90
90
|
onCancel?: (() => any) | undefined;
|
|
91
|
-
onRename?: (() => any) | undefined;
|
|
92
|
-
onDuplicate?: (() => any) | undefined;
|
|
93
|
-
onExport?: (() => any) | undefined;
|
|
94
|
-
onCopyLink?: (() => any) | undefined;
|
|
95
|
-
onDebug?: (() => any) | undefined;
|
|
96
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
97
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
98
91
|
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
99
93
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
100
94
|
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
101
95
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
102
96
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
97
|
+
onCopyLink?: (() => any) | undefined;
|
|
98
|
+
onRename?: (() => any) | undefined;
|
|
99
|
+
onDuplicate?: (() => any) | undefined;
|
|
100
|
+
onExport?: (() => any) | undefined;
|
|
101
|
+
onDebug?: (() => any) | undefined;
|
|
103
102
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
104
103
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
105
104
|
onSignout?: (() => any) | undefined;
|
|
106
105
|
onCancelEditing?: (() => any) | undefined;
|
|
107
106
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
108
107
|
onSaveTitle?: (() => any) | undefined;
|
|
108
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
109
109
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
110
110
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
111
111
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WidgetGalleryStory } from '../../rendering/debug/widget-gallery.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
stories: readonly WidgetGalleryStory[];
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { provideEmbedConfig } from "../../embed/composables/embed-config";
|
|
3
|
+
import ChatVaultLink from "../../files/components/chat-vault-link.vue";
|
|
4
|
+
import OpenuiBlock from "../../rendering/components/openui-block.vue";
|
|
5
|
+
import { buildSlackPreview, groupWidgetStories } from "../../rendering/debug/widget-gallery";
|
|
6
|
+
import { OPENUI_ERROR_REPORTER_KEY, OPENUI_MARKDOWN_COMPONENTS_KEY } from "../../rendering/openui/context";
|
|
7
|
+
import { CHAT_MESSAGE_CONTEXT_KEY, CHAT_MESSAGE_SEND_KEY } from "../../types/messages";
|
|
8
|
+
import { createChatDebugCitationsConfig } from "../debug/chat-debug-citations";
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
stories: { type: Array, required: true }
|
|
11
|
+
});
|
|
12
|
+
const STREAM_TICK_MS = 40;
|
|
13
|
+
const STREAM_CHARACTERS_PER_TICK = 6;
|
|
14
|
+
const groups = computed(() => groupWidgetStories(props.stories));
|
|
15
|
+
const selectedId = ref(props.stories[0]?.id ?? "");
|
|
16
|
+
const selectedStory = computed(() => props.stories.find((story) => story.id === selectedId.value) ?? props.stories[0]);
|
|
17
|
+
const code = ref(selectedStory.value?.code ?? "");
|
|
18
|
+
const viewportWidth = ref("default");
|
|
19
|
+
const viewportOptions = [
|
|
20
|
+
{ id: "narrow", label: "Narrow" },
|
|
21
|
+
{ id: "default", label: "Default" },
|
|
22
|
+
{ id: "wide", label: "Wide" }
|
|
23
|
+
];
|
|
24
|
+
const streamedCharacters = ref(null);
|
|
25
|
+
const streaming = computed(() => streamedCharacters.value !== null);
|
|
26
|
+
const visibleCode = computed(() => streamedCharacters.value === null ? code.value : code.value.slice(0, streamedCharacters.value));
|
|
27
|
+
let streamTimer = null;
|
|
28
|
+
const mountRevision = ref(0);
|
|
29
|
+
const sentMessages = ref([]);
|
|
30
|
+
const widgetErrors = ref([]);
|
|
31
|
+
const slack = computed(() => buildSlackPreview(code.value));
|
|
32
|
+
const slackJson = computed(() => JSON.stringify(slack.value.blocks, null, 2));
|
|
33
|
+
provideEmbedConfig({
|
|
34
|
+
workspaceId: "chat-debug-widget-gallery",
|
|
35
|
+
hideSidebar: true,
|
|
36
|
+
citations: createChatDebugCitationsConfig()
|
|
37
|
+
}, { syncGlobal: false });
|
|
38
|
+
provide(CHAT_MESSAGE_CONTEXT_KEY, {
|
|
39
|
+
messageId: "chat-debug-widget-gallery",
|
|
40
|
+
role: "assistant",
|
|
41
|
+
isLatestMessage: ref(true),
|
|
42
|
+
streaming
|
|
43
|
+
});
|
|
44
|
+
provide(CHAT_MESSAGE_SEND_KEY, async (content) => {
|
|
45
|
+
sentMessages.value = [...sentMessages.value, content];
|
|
46
|
+
return true;
|
|
47
|
+
});
|
|
48
|
+
provide(OPENUI_ERROR_REPORTER_KEY, (errors) => {
|
|
49
|
+
widgetErrors.value = errors.map((error) => `${error.code}: ${error.message}`);
|
|
50
|
+
});
|
|
51
|
+
provide(OPENUI_MARKDOWN_COMPONENTS_KEY, ref({ link: ChatVaultLink }));
|
|
52
|
+
function stopStream() {
|
|
53
|
+
if (streamTimer)
|
|
54
|
+
clearInterval(streamTimer);
|
|
55
|
+
streamTimer = null;
|
|
56
|
+
streamedCharacters.value = null;
|
|
57
|
+
}
|
|
58
|
+
function remount() {
|
|
59
|
+
stopStream();
|
|
60
|
+
sentMessages.value = [];
|
|
61
|
+
widgetErrors.value = [];
|
|
62
|
+
mountRevision.value += 1;
|
|
63
|
+
}
|
|
64
|
+
function selectStory(story) {
|
|
65
|
+
selectedId.value = story.id;
|
|
66
|
+
code.value = story.code;
|
|
67
|
+
remount();
|
|
68
|
+
}
|
|
69
|
+
function playStream() {
|
|
70
|
+
remount();
|
|
71
|
+
streamedCharacters.value = 0;
|
|
72
|
+
streamTimer = setInterval(() => {
|
|
73
|
+
const next = (streamedCharacters.value ?? 0) + STREAM_CHARACTERS_PER_TICK;
|
|
74
|
+
if (next >= code.value.length)
|
|
75
|
+
stopStream();
|
|
76
|
+
else
|
|
77
|
+
streamedCharacters.value = next;
|
|
78
|
+
}, STREAM_TICK_MS);
|
|
79
|
+
}
|
|
80
|
+
async function copySlackJson() {
|
|
81
|
+
await navigator.clipboard.writeText(slackJson.value);
|
|
82
|
+
}
|
|
83
|
+
watch(code, () => {
|
|
84
|
+
widgetErrors.value = [];
|
|
85
|
+
});
|
|
86
|
+
onBeforeUnmount(stopStream);
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<template>
|
|
90
|
+
<section class="chat-debug-widget-gallery" w-full h-full bg text-primary>
|
|
91
|
+
<aside px-20px py-22px overflow-y-auto>
|
|
92
|
+
<div v-for="group in groups" :key="group.name" mb-20px>
|
|
93
|
+
<div body-caption-9-medium text-tertiary mb-10px>
|
|
94
|
+
{{ group.name }}
|
|
95
|
+
</div>
|
|
96
|
+
<div flex="~ col" gap-4px>
|
|
97
|
+
<button
|
|
98
|
+
v-for="story in group.stories"
|
|
99
|
+
:key="story.id"
|
|
100
|
+
type="button"
|
|
101
|
+
py-5px
|
|
102
|
+
text-left
|
|
103
|
+
group
|
|
104
|
+
:data-story="story.id"
|
|
105
|
+
@click="selectStory(story)"
|
|
106
|
+
>
|
|
107
|
+
<div flex items-center gap-7px>
|
|
108
|
+
<span
|
|
109
|
+
w-4px h-4px rounded-full shrink-0
|
|
110
|
+
:class="story.id === selectedId ? 'bg-gray-900' : 'bg-gray-300 group-hover:bg-gray-500'"
|
|
111
|
+
transition-colors
|
|
112
|
+
/>
|
|
113
|
+
<span
|
|
114
|
+
body-12-medium
|
|
115
|
+
truncate
|
|
116
|
+
:class="story.id === selectedId ? 'text-primary' : 'text-secondary group-hover:text-primary'"
|
|
117
|
+
transition-colors
|
|
118
|
+
>
|
|
119
|
+
{{ story.title }}
|
|
120
|
+
</span>
|
|
121
|
+
</div>
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</aside>
|
|
126
|
+
|
|
127
|
+
<main min-w-0 min-h-0 flex="~ col">
|
|
128
|
+
<div h-48px px-24px flex items-center justify-between shrink-0>
|
|
129
|
+
<div flex items-center gap-8px body-11-regular text-tertiary>
|
|
130
|
+
<span>{{ selectedStory?.title }}</span>
|
|
131
|
+
<TelaDotSeparator />
|
|
132
|
+
<span>{{ streaming ? "streaming" : "complete" }}</span>
|
|
133
|
+
</div>
|
|
134
|
+
<div flex items-center gap-12px>
|
|
135
|
+
<div flex items-center gap-10px>
|
|
136
|
+
<button
|
|
137
|
+
v-for="option in viewportOptions"
|
|
138
|
+
:key="option.id"
|
|
139
|
+
type="button"
|
|
140
|
+
body-11-regular
|
|
141
|
+
:class="viewportWidth === option.id ? 'text-primary' : 'text-tertiary hover:text-secondary'"
|
|
142
|
+
transition-colors
|
|
143
|
+
@click="viewportWidth = option.id"
|
|
144
|
+
>
|
|
145
|
+
{{ option.label }}
|
|
146
|
+
</button>
|
|
147
|
+
</div>
|
|
148
|
+
<button type="button" body-11-regular text-tertiary hover:text-secondary transition-colors data-action="stream" @click="playStream">
|
|
149
|
+
Stream
|
|
150
|
+
</button>
|
|
151
|
+
<button type="button" body-11-regular text-tertiary hover:text-secondary transition-colors data-action="reset" @click="remount">
|
|
152
|
+
Reset
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div min-h-0 grow overflow-y-auto px-24px pb-24px>
|
|
158
|
+
<div class="widget-under-test" :class="`widget-under-test--${viewportWidth}`" data-gallery="web">
|
|
159
|
+
<OpenuiBlock :key="mountRevision" :node="{ type: 'code_block', raw: visibleCode, code: visibleCode }" :loading="streaming" />
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<div class="widget-under-test" :class="`widget-under-test--${viewportWidth}`" mt-24px>
|
|
163
|
+
<div body-caption-9-medium text-tertiary mb-8px>
|
|
164
|
+
Sent messages
|
|
165
|
+
</div>
|
|
166
|
+
<p v-if="!sentMessages.length" body-11-regular text-tertiary>
|
|
167
|
+
Buttons, forms and questions list here the user message they send.
|
|
168
|
+
</p>
|
|
169
|
+
<pre v-for="(message, index) in sentMessages" :key="index" class="gallery-code" body-12-regular mb-8px data-gallery="sent">{{ message }}</pre>
|
|
170
|
+
|
|
171
|
+
<template v-if="widgetErrors.length">
|
|
172
|
+
<div body-caption-9-medium text-tertiary mt-16px mb-8px>
|
|
173
|
+
Widget errors
|
|
174
|
+
</div>
|
|
175
|
+
<pre class="gallery-code" body-12-regular text-red-600 data-gallery="errors">{{ widgetErrors.join("\n") }}</pre>
|
|
176
|
+
</template>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</main>
|
|
180
|
+
|
|
181
|
+
<aside min-h-0 px-24px py-22px flex="~ col" gap-20px overflow-y-auto>
|
|
182
|
+
<div>
|
|
183
|
+
<div body-caption-9-medium text-tertiary mb-8px>
|
|
184
|
+
OpenUI Lang
|
|
185
|
+
</div>
|
|
186
|
+
<textarea
|
|
187
|
+
v-model="code"
|
|
188
|
+
class="gallery-code gallery-editor"
|
|
189
|
+
body-12-regular
|
|
190
|
+
spellcheck="false"
|
|
191
|
+
data-gallery="code"
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div min-h-0>
|
|
196
|
+
<div flex items-center justify-between mb-8px>
|
|
197
|
+
<span body-caption-9-medium text-tertiary>Slack Block Kit · {{ slack.blocks.length }} blocks</span>
|
|
198
|
+
<span flex items-center gap-10px body-11-regular>
|
|
199
|
+
<button type="button" text-tertiary hover:text-secondary transition-colors @click="copySlackJson">
|
|
200
|
+
Copy
|
|
201
|
+
</button>
|
|
202
|
+
<a :href="slack.builderUrl" target="_blank" rel="noopener" text-tertiary hover:text-secondary transition-colors data-gallery="builder-link">
|
|
203
|
+
Block Kit Builder
|
|
204
|
+
</a>
|
|
205
|
+
</span>
|
|
206
|
+
</div>
|
|
207
|
+
<p body-11-regular text-tertiary mb-8px data-gallery="slack-note">
|
|
208
|
+
Renderer output, before the connector applies its own limits: it sends a long answer as a file instead of blocks.
|
|
209
|
+
</p>
|
|
210
|
+
<pre class="gallery-code" body-12-regular data-gallery="slack">{{ slackJson }}</pre>
|
|
211
|
+
</div>
|
|
212
|
+
</aside>
|
|
213
|
+
</section>
|
|
214
|
+
</template>
|
|
215
|
+
|
|
216
|
+
<style scoped>
|
|
217
|
+
.chat-debug-widget-gallery{display:grid;grid-template-columns:220px minmax(420px,1fr) minmax(360px,480px);overflow:hidden}.widget-under-test{margin-inline:auto;width:100%}.widget-under-test--narrow{max-width:520px}.widget-under-test--default{max-width:760px}.widget-under-test--wide{max-width:1040px}.gallery-code{background:#f9fafb;border:1px solid #e5e7eb;border-radius:8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin:0;overflow-x:auto;padding:12px;white-space:pre-wrap;word-break:break-word}.gallery-editor{display:block;min-height:220px;outline:none;resize:vertical;width:100%}
|
|
218
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WidgetGalleryStory } from '../../rendering/debug/widget-gallery.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
stories: readonly WidgetGalleryStory[];
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SlackBlock } from '@meistrari/chat-ui-lang';
|
|
2
|
+
export type WidgetGalleryStory = {
|
|
3
|
+
id: string;
|
|
4
|
+
group: string;
|
|
5
|
+
title: string;
|
|
6
|
+
/** One OpenUI Lang program, without its fence. */
|
|
7
|
+
code: string;
|
|
8
|
+
};
|
|
9
|
+
export type WidgetGalleryGroup = {
|
|
10
|
+
name: string;
|
|
11
|
+
stories: WidgetGalleryStory[];
|
|
12
|
+
};
|
|
13
|
+
export declare function groupWidgetStories(stories: readonly WidgetGalleryStory[]): WidgetGalleryGroup[];
|
|
14
|
+
export type SlackPreview = {
|
|
15
|
+
blocks: SlackBlock[];
|
|
16
|
+
/** The answer written out, which Slack uses for notifications. */
|
|
17
|
+
text: string;
|
|
18
|
+
builderUrl: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* What the Slack renderer produces for one program, published in a thread so send buttons stay clickable. The connector
|
|
22
|
+
* applies its own limits after it, such as sending a long answer as a file.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildSlackPreview(code: string): SlackPreview;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { renderSlackAnswer, UI_LANG_FENCE } from "@meistrari/chat-ui-lang";
|
|
2
|
+
export function groupWidgetStories(stories) {
|
|
3
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const story of stories)
|
|
5
|
+
groups.set(story.group, [...groups.get(story.group) ?? [], story]);
|
|
6
|
+
return [...groups].map(([name, grouped]) => ({ name, stories: grouped }));
|
|
7
|
+
}
|
|
8
|
+
const BLOCK_KIT_BUILDER_URL = "https://app.slack.com/block-kit-builder/";
|
|
9
|
+
const PREVIEW_THREAD_TS = "1700000000.000100";
|
|
10
|
+
const PREVIEW_MAX_BLOCKS = 40;
|
|
11
|
+
export function buildSlackPreview(code) {
|
|
12
|
+
const answer = code.trim() ? renderSlackAnswer(`\`\`\`${UI_LANG_FENCE}
|
|
13
|
+
${code}
|
|
14
|
+
\`\`\``, {
|
|
15
|
+
prose: (text) => [{ type: "markdown", text }],
|
|
16
|
+
threadTs: PREVIEW_THREAD_TS,
|
|
17
|
+
maxBlocks: PREVIEW_MAX_BLOCKS
|
|
18
|
+
}) : null;
|
|
19
|
+
const blocks = answer?.blocks ?? [];
|
|
20
|
+
return {
|
|
21
|
+
blocks,
|
|
22
|
+
text: answer?.text ?? "",
|
|
23
|
+
builderUrl: `${BLOCK_KIT_BUILDER_URL}#${encodeURIComponent(JSON.stringify({ blocks }))}`
|
|
24
|
+
};
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/chat-nuxt",
|
|
3
|
-
"version": "4.13.0-rc.
|
|
3
|
+
"version": "4.13.0-rc.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@iconify-json/ph": "^1.2.2",
|
|
53
53
|
"@iconify/vue": "^5.0.0",
|
|
54
54
|
"@meistrari/auth-nuxt": "3.31.0",
|
|
55
|
-
"@meistrari/chat-ui-lang": "0.
|
|
55
|
+
"@meistrari/chat-ui-lang": "0.8.0-rc.1",
|
|
56
56
|
"@meistrari/logger": "^2.1.3",
|
|
57
57
|
"@meistrari/tela-build": "^1.79.0",
|
|
58
58
|
"@openuidev/lang-core": "1.0.0",
|