diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2daaed3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,85 @@ +{ + "name": "tero", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "moment": "^2.30.1" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.5", + "@types/json-schema": "^7.0.15", + "@types/moment": "^2.11.29", + "@types/node": "^25.0.1", + "@vue/tsconfig": "^0.8.1" + } + }, + "node_modules/@tsconfig/node22": { + "version": "22.0.5", + "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.5.tgz", + "integrity": "sha512-hLf2ld+sYN/BtOJjHUWOk568dvjFQkHnLNa6zce25GIH+vxKfvTgm3qpaH6ToF5tu/NN0IH66s+Bb5wElHrLcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/moment": { + "version": "2.11.29", + "resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.11.29.tgz", + "integrity": "sha512-D5WIgbLYQzvgfsDnBhZFSTnt/BjGPOE+Jsh3k1BYYijJAkrn7ceeLvU4jtjKKXXuXN42O3ARlU4D/P9ezbQYFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.1.tgz", + "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@vue/tsconfig": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.8.1.tgz", + "integrity": "sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": "5.x", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..cdc527b --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "dependencies": { + "moment": "^2.30.1" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.5", + "@types/json-schema": "^7.0.15", + "@types/moment": "^2.11.29", + "@types/node": "^25.0.1", + "@vue/tsconfig": "^0.8.1" + } +} diff --git a/src/frontend/src/components/chat/ChatHeaderMenu.vue b/src/frontend/src/components/chat/ChatHeaderMenu.vue index d2252c5..1162016 100644 --- a/src/frontend/src/components/chat/ChatHeaderMenu.vue +++ b/src/frontend/src/components/chat/ChatHeaderMenu.vue @@ -3,16 +3,19 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { Agent, Thread } from '@/services/api'; import { useAgentStore } from '@/composables/useAgentStore'; -import { IconMessage2Plus, IconEditCircle, IconHistory, IconTrash, IconInfoCircle, IconCopyPlus } from '@tabler/icons-vue'; +import { useChatExport } from '@/composables/useChatExport'; +import { IconMessage2Plus, IconEditCircle, IconHistory, IconTrash, IconInfoCircle, IconCopyPlus, IconDownload } from '@tabler/icons-vue'; import { useErrorHandler } from '@/composables/useErrorHandler'; const { configureAgent, cloneAgent } = useAgentStore(); const { handleError } = useErrorHandler(); +const { exportChatAsJson, exportChatAsMarkdown } = useChatExport(); const props = defineProps<{ agent: Agent, chat: Thread, - editingAgent?: boolean + editingAgent?: boolean, + messages?: any[] }>() const emit = defineEmits<{ (e: 'showPastChats'): void @@ -61,6 +64,17 @@ const handleCloneAgent = async () => { } } + +const handleExportAsJson = () => { + exportChatAsJson(props.chat, props.chat.name, agentName.value, props.messages ?? []); + closeMenu(); +} + +const handleExportAsMarkdown = () => { + exportChatAsMarkdown(props.chat, props.chat.name, agentName.value, props.messages ?? []); + closeMenu(); +} +