Compare commits

...

10 Commits

Author SHA1 Message Date
denislov
c5e7030dd1 Merge branch 'main' of https://github.com/CherryHQ/cherry-studio
合并上游
2025-02-12 12:55:14 +08:00
牡丹凤凰
ceb97e80ff Update embedings.ts 2025-02-12 08:31:00 +08:00
牡丹凤凰
bf1fa5b767 Update zh-tw.json
更正繁体中文当中关于Temperature的描述
2025-02-12 08:30:34 +08:00
airwish
e99f34893e feat: expanded web search models 2025-02-12 08:30:00 +08:00
牡丹凤凰
a49dd6101e
Update zh-tw.json (#1433)
助手菜单名称显示不全
2025-02-12 08:25:14 +08:00
denislov
4317699602 add csv loader patch 2025-02-12 01:55:16 +08:00
denislov
8c54530d58 Merge branch 'main' of https://github.com/CherryHQ/cherry-studio
合并上游
2025-02-12 01:46:50 +08:00
denislov
66cba8d4e4 add csv loader 2025-02-12 01:44:58 +08:00
denislov
d958f8d31f format 2025-02-12 00:39:50 +08:00
kangfenmao
d03b852671 feat: Add image loader to embedjs configuration 2025-02-11 22:55:49 +08:00
17 changed files with 543 additions and 457 deletions

View File

@ -0,0 +1,17 @@
diff --git a/src/csv-loader.js b/src/csv-loader.js
index b53938d5e763b9f31e928492966bac5ef2c2e9a6..ddd469865d68bc420fd14e5097ed77f350c448a7 100644
--- a/src/csv-loader.js
+++ b/src/csv-loader.js
@@ -23,8 +23,11 @@ export class CsvLoader extends BaseLoader {
const parser = parse(buffer, this.csvParseOptions);
this.debug('CSV parsing started...');
for await (const record of parser) {
+ const stringified = Object.entries(record)
+ .map(([key, value]) => `${key}: ${value}`)
+ .join("\n");
yield {
- pageContent: cleanString(record.join(',')),
+ pageContent: cleanString(stringified),
metadata: {
type: 'CsvLoader',
source: this.filePathOrUrl,

View File

@ -117,7 +117,8 @@ For more detailed guidelines, please refer to our [Contributing Guide](./CONTRIB
Thank you for your support and contributions!
## Related Projects
* [one-api](https://github.com/songquanpeng/one-api):LLM API management and distribution system, supporting mainstream models like OpenAI, Azure, and Anthropic. Features unified API interface, suitable for key management and secondary distribution.
- [one-api](https://github.com/songquanpeng/one-api):LLM API management and distribution system, supporting mainstream models like OpenAI, Azure, and Anthropic. Features unified API interface, suitable for key management and secondary distribution.
# 🚀 Contributors

View File

@ -118,7 +118,8 @@ Cherry Studioへの貢献を歓迎します以下の方法で貢献できま
ご支援と貢献に感謝します!
## 関連頁版
* [one-api](https://github.com/songquanpeng/one-api):LLM APIの管理・配信システム。OpenAI、Azure、Anthropicなどの主要モデルに対応し、統一APIインターフェースを提供。APIキー管理と再配布に利用可能。
- [one-api](https://github.com/songquanpeng/one-api):LLM APIの管理・配信システム。OpenAI、Azure、Anthropicなどの主要モデルに対応し、統一APIインターフェースを提供。APIキー管理と再配布に利用可能。
# 🚀 コントリビューター

View File

@ -118,7 +118,8 @@ $ yarn build:linux
感谢您的支持和贡献!
## 相关项目
* [one-api](https://github.com/songquanpeng/one-api):LLM API管理及分发系统支持OpenAI、Azure、Anthropic等主流模型统一API接口可用于密钥管理与二次分发。
- [one-api](https://github.com/songquanpeng/one-api):LLM API管理及分发系统支持OpenAI、Azure、Anthropic等主流模型统一API接口可用于密钥管理与二次分发。
# 🚀 贡献者

View File

@ -20,7 +20,8 @@ export default defineConfig({
'@llm-tools/embedjs-loader-xml',
'@llm-tools/embedjs-loader-pdf',
'@llm-tools/embedjs-loader-sitemap',
'@llm-tools/embedjs-libsql'
'@llm-tools/embedjs-libsql',
'@llm-tools/embedjs-loader-image'
]
}),
...visualizerPlugin('main')

View File

@ -53,7 +53,8 @@
"@google/generative-ai": "^0.21.0",
"@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.28-8e4393fa2d.patch",
"@llm-tools/embedjs-libsql": "^0.1.28",
"@llm-tools/embedjs-loader-csv": "^0.1.28",
"@llm-tools/embedjs-loader-csv": "patch:@llm-tools/embedjs-loader-csv@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-csv-npm-0.1.28-a5dac8addd.patch",
"@llm-tools/embedjs-loader-image": "^0.1.28",
"@llm-tools/embedjs-loader-markdown": "patch:@llm-tools/embedjs-loader-markdown@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-markdown-npm-0.1.28-81647ffac6.patch",
"@llm-tools/embedjs-loader-msoffice": "^0.1.28",
"@llm-tools/embedjs-loader-pdf": "^0.1.28",

View File

@ -1,118 +1,111 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CherryStudio 许可协议-ZH/EN</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet" />
</head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CherryStudio 许可协议-ZH/EN</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet" />
</head>
<body class="bg-gray-100 p-8">
<div class="container mx-auto bg-white p-6 rounded shadow-lg">
<h1 class="text-3xl font-bold mb-6 text-center">Cherry Studio 许可协议</h1>
<div class="mb-8">
<h2 class="text-2xl font-semibold mb-4">许可协议</h2>
<p class="mb-4">
本软件采用 <strong>Apache License 2.0</strong> 许可。除 Apache License 2.0 规定的条款外,您在使用 Cherry
Studio 时还应遵守以下附加条款:
</p>
<h3 class="text-xl font-semibold mb-2">一. 商用许可</h3>
<ol class="list-decimal list-inside mb-4">
<li><strong>免费商用</strong>:用户在不修改代码的情况下,可以免费用于商业目的。</li>
<li>
<strong>商业授权</strong>:如果您满足以下任意条件之一,需取得商业授权:
<ol class="list-decimal list-inside ml-4">
<li>对本软件进行二次修改、开发包括但不限于修改应用名称、logo、代码以及功能</li>
<li>为企业客户提供多租户服务,且该服务支持 10 人或以上的使用。</li>
<li>预装或集成到硬件设备或产品中进行捆绑销售。</li>
<li>政府或教育机构的大规模采购项目,特别是涉及安全、数据隐私等敏感需求时。</li>
</ol>
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">二. 贡献者协议</h3>
<ol class="list-decimal list-inside mb-4">
<li><strong>许可调整</strong>:生产者有权根据需要对开源协议进行调整,使其更加严格或宽松。</li>
<li><strong>商业用途</strong>:您贡献的代码可能会被用于商业用途,包括但不限于云业务运营。</li>
</ol>
<h3 class="text-xl font-semibold mb-2">三. 其他条款</h3>
<ol class="list-decimal list-inside mb-4">
<li>本协议条款的解释权归 Cherry Studio 开发者所有。</li>
<li>本协议可能根据实际情况进行更新,更新时将通过本软件通知用户。</li>
</ol>
<p class="mb-4">如有任何问题或需申请商业授权,请联系 Cherry Studio 开发团队。</p>
<p>
除上述特定条件外,其他所有权利和限制均遵循 Apache License 2.0。有关 Apache License 2.0 的详细信息,请访问
<a href="http://www.apache.org/licenses/LICENSE-2.0"
class="text-blue-500 underline">http://www.apache.org/licenses/LICENSE-2.0</a>
</p>
<body class="bg-gray-100 p-8">
<div class="container mx-auto bg-white p-6 rounded shadow-lg">
<h1 class="text-3xl font-bold mb-6 text-center">Cherry Studio 许可协议</h1>
<div class="mb-8">
<h2 class="text-2xl font-semibold mb-4">许可协议</h2>
<p class="mb-4">
本软件采用 <strong>Apache License 2.0</strong> 许可。除 Apache License 2.0 规定的条款外,您在使用 Cherry
Studio 时还应遵守以下附加条款:
</p>
<h3 class="text-xl font-semibold mb-2">一. 商用许可</h3>
<ol class="list-decimal list-inside mb-4">
<li><strong>免费商用</strong>:用户在不修改代码的情况下,可以免费用于商业目的。</li>
<li>
<strong>商业授权</strong>:如果您满足以下任意条件之一,需取得商业授权:
<ol class="list-decimal list-inside ml-4">
<li>对本软件进行二次修改、开发包括但不限于修改应用名称、logo、代码以及功能</li>
<li>为企业客户提供多租户服务,且该服务支持 10 人或以上的使用。</li>
<li>预装或集成到硬件设备或产品中进行捆绑销售。</li>
<li>政府或教育机构的大规模采购项目,特别是涉及安全、数据隐私等敏感需求时。</li>
</ol>
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">二. 贡献者协议</h3>
<ol class="list-decimal list-inside mb-4">
<li><strong>许可调整</strong>:生产者有权根据需要对开源协议进行调整,使其更加严格或宽松。</li>
<li><strong>商业用途</strong>:您贡献的代码可能会被用于商业用途,包括但不限于云业务运营。</li>
</ol>
<h3 class="text-xl font-semibold mb-2">三. 其他条款</h3>
<ol class="list-decimal list-inside mb-4">
<li>本协议条款的解释权归 Cherry Studio 开发者所有。</li>
<li>本协议可能根据实际情况进行更新,更新时将通过本软件通知用户。</li>
</ol>
<p class="mb-4">如有任何问题或需申请商业授权,请联系 Cherry Studio 开发团队。</p>
<p>
除上述特定条件外,其他所有权利和限制均遵循 Apache License 2.0。有关 Apache License 2.0 的详细信息,请访问
<a href="http://www.apache.org/licenses/LICENSE-2.0" class="text-blue-500 underline"
>http://www.apache.org/licenses/LICENSE-2.0</a
>
</p>
</div>
<h1 class="text-3xl font-bold mb-6 text-center">Cherry Studio License</h1>
<div class="mb-8">
<h2 class="text-2xl font-semibold mb-4">License Agreement</h2>
<p class="mb-4">
This software is licensed under the <strong>Apache License 2.0</strong>. In addition to the terms of the
Apache License 2.0, the following additional terms apply to the use of Cherry Studio:
</p>
<h3 class="text-xl font-semibold mb-2">I. Commercial Use License</h3>
<ol class="list-decimal list-inside mb-4">
<li>
<strong>Free Commercial Use</strong>: Users can use the software for commercial purposes without modifying
the code.
</li>
<li>
<strong>Commercial License Required</strong>: A commercial license is required if any of the following
conditions are met:
<ol class="list-decimal list-inside ml-4">
<li>
You modify, develop, or alter the software, including but not limited to changes to the application
name, logo, code, or functionality.
</li>
<li>You provide multi-tenant services to enterprise customers with 10 or more users.</li>
<li>
You pre-install or integrate the software into hardware devices or products and bundle it for sale.
</li>
<li>
You are engaging in large-scale procurement for government or educational institutions, especially
involving security, data privacy, or other sensitive requirements.
</li>
</ol>
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">II. Contributor Agreement</h3>
<ol class="list-decimal list-inside mb-4">
<li>
<strong>License Adjustment</strong>: The producer reserves the right to adjust the open-source license as
needed, making it stricter or more lenient.
</li>
<li>
<strong>Commercial Use</strong>: Any code you contribute may be used for commercial purposes, including but
not limited to cloud business operations.
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">III. Other Terms</h3>
<ol class="list-decimal list-inside mb-4">
<li>The interpretation of these terms is subject to the discretion of Cherry Studio developers.</li>
<li>These terms may be updated, and users will be notified through the software when changes occur.</li>
</ol>
<p class="mb-4">
For any questions or to request a commercial license, please contact the Cherry Studio development team.
</p>
<p>
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache
License 2.0. Detailed information about the Apache License 2.0 can be found at
<a href="http://www.apache.org/licenses/LICENSE-2.0" class="text-blue-500 underline"
>http://www.apache.org/licenses/LICENSE-2.0</a
>
</p>
</div>
</div>
<h1 class="text-3xl font-bold mb-6 text-center">Cherry Studio License</h1>
<div class="mb-8">
<h2 class="text-2xl font-semibold mb-4">License Agreement</h2>
<p class="mb-4">
This software is licensed under the <strong>Apache License 2.0</strong>. In addition to the terms of the
Apache License 2.0, the following additional terms apply to the use of Cherry Studio:
</p>
<h3 class="text-xl font-semibold mb-2">I. Commercial Use License</h3>
<ol class="list-decimal list-inside mb-4">
<li>
<strong>Free Commercial Use</strong>: Users can use the software for commercial purposes without
modifying
the code.
</li>
<li>
<strong>Commercial License Required</strong>: A commercial license is required if any of the
following
conditions are met:
<ol class="list-decimal list-inside ml-4">
<li>
You modify, develop, or alter the software, including but not limited to changes to the
application
name, logo, code, or functionality.
</li>
<li>You provide multi-tenant services to enterprise customers with 10 or more users.</li>
<li>
You pre-install or integrate the software into hardware devices or products and bundle it
for sale.
</li>
<li>
You are engaging in large-scale procurement for government or educational institutions,
especially
involving security, data privacy, or other sensitive requirements.
</li>
</ol>
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">II. Contributor Agreement</h3>
<ol class="list-decimal list-inside mb-4">
<li>
<strong>License Adjustment</strong>: The producer reserves the right to adjust the open-source
license as
needed, making it stricter or more lenient.
</li>
<li>
<strong>Commercial Use</strong>: Any code you contribute may be used for commercial purposes,
including but
not limited to cloud business operations.
</li>
</ol>
<h3 class="text-xl font-semibold mb-2">III. Other Terms</h3>
<ol class="list-decimal list-inside mb-4">
<li>The interpretation of these terms is subject to the discretion of Cherry Studio developers.</li>
<li>These terms may be updated, and users will be notified through the software when changes occur.</li>
</ol>
<p class="mb-4">
For any questions or to request a commercial license, please contact the Cherry Studio development team.
</p>
<p>
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache
License 2.0. Detailed information about the Apache License 2.0 can be found at
<a href="http://www.apache.org/licenses/LICENSE-2.0"
class="text-blue-500 underline">http://www.apache.org/licenses/LICENSE-2.0</a>
</p>
</div>
</div>
</body>
</html>
</body>
</html>

View File

@ -1,7 +1,6 @@
<!doctype html>
<html lang="en">
<head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Github Releases Timeline</title>
@ -9,194 +8,201 @@
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@13.0.1/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/typography@0.5.10/dist/typography.min.css"></script>
</head>
</head>
<body id="app">
<body id="app">
<div :class="isDark ? 'dark-bg' : 'bg'" class="min-h-screen">
<div class="max-w-3xl mx-auto py-12 px-4">
<h1 class="text-3xl font-bold mb-8" :class="isDark ? 'text-white' : 'text-gray-900'">Release Timeline</h1>
<div class="max-w-3xl mx-auto py-12 px-4">
<h1 class="text-3xl font-bold mb-8" :class="isDark ? 'text-white' : 'text-gray-900'">Release Timeline</h1>
<!-- Loading状态 -->
<div v-if="loading" class="text-center py-8">
<div class="inline-block animate-spin rounded-full h-8 w-8 border-4"
:class="isDark ? 'border-gray-700 border-t-blue-500' : 'border-gray-300 border-t-blue-500'"></div>
</div>
<!-- Error 状态 -->
<div v-else-if="error" class="text-red-500 text-center py-8">{{ error }}</div>
<!-- Release 列表 -->
<div v-else class="space-y-8">
<div v-for="release in releases" :key="release.id" class="relative pl-8"
:class="isDark ? 'border-l-2 border-gray-700' : 'border-l-2 border-gray-200'">
<div class="absolute -left-2 top-0 w-4 h-4 rounded-full bg-green-500"></div>
<div class="rounded-lg shadow-sm p-6 transition-shadow"
:class="isDark ? 'bg-black hover:shadow-md hover:shadow-black' : 'bg-white hover:shadow-md'">
<div class="flex items-start justify-between mb-4">
<div>
<h2 class="text-xl font-semibold" :class="isDark ? 'text-white' : 'text-gray-900'">
{{ release.name || release.tag_name }}
</h2>
<p class="text-sm mt-1" :class="isDark ? 'text-gray-400' : 'text-gray-500'">
{{ formatDate(release.published_at) }}
</p>
</div>
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium"
:class="isDark ? 'bg-green-900 text-green-200' : 'bg-green-100 text-green-800'">
{{ release.tag_name }}
</span>
</div>
<div class="prose" :class="isDark ? 'text-gray-300 dark-prose' : 'text-gray-600'"
v-html="renderMarkdown(release.body)"></div>
</div>
</div>
</div>
<!-- Loading状态 -->
<div v-if="loading" class="text-center py-8">
<div
class="inline-block animate-spin rounded-full h-8 w-8 border-4"
:class="isDark ? 'border-gray-700 border-t-blue-500' : 'border-gray-300 border-t-blue-500'"></div>
</div>
<!-- Error 状态 -->
<div v-else-if="error" class="text-red-500 text-center py-8">{{ error }}</div>
<!-- Release 列表 -->
<div v-else class="space-y-8">
<div
v-for="release in releases"
:key="release.id"
class="relative pl-8"
:class="isDark ? 'border-l-2 border-gray-700' : 'border-l-2 border-gray-200'">
<div class="absolute -left-2 top-0 w-4 h-4 rounded-full bg-green-500"></div>
<div
class="rounded-lg shadow-sm p-6 transition-shadow"
:class="isDark ? 'bg-black hover:shadow-md hover:shadow-black' : 'bg-white hover:shadow-md'">
<div class="flex items-start justify-between mb-4">
<div>
<h2 class="text-xl font-semibold" :class="isDark ? 'text-white' : 'text-gray-900'">
{{ release.name || release.tag_name }}
</h2>
<p class="text-sm mt-1" :class="isDark ? 'text-gray-400' : 'text-gray-500'">
{{ formatDate(release.published_at) }}
</p>
</div>
<span
class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium"
:class="isDark ? 'bg-green-900 text-green-200' : 'bg-green-100 text-green-800'">
{{ release.tag_name }}
</span>
</div>
<div
class="prose"
:class="isDark ? 'text-gray-300 dark-prose' : 'text-gray-600'"
v-html="renderMarkdown(release.body)"></div>
</div>
</div>
</div>
</div>
</div>
<script>
const md = window.markdownit({
breaks: true,
linkify: true
})
const md = window.markdownit({
breaks: true,
linkify: true
})
const { createApp } = Vue
const { createApp } = Vue
createApp({
data() {
return {
releases: [],
loading: true,
error: null,
isDark: false
}
},
methods: {
async fetchReleases() {
try {
this.loading = true
this.error = null
const response = await fetch('https://api.github.com/repos/kangfenmao/cherry-studio/releases')
if (!response.ok) {
throw new Error('Failed to fetch releases')
}
this.releases = await response.json()
} catch (err) {
this.error = 'Error loading releases: ' + err.message
} finally {
this.loading = false
}
},
formatDate(dateString) {
return new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
},
renderMarkdown(content) {
if (!content) return ''
return md.render(content)
},
initTheme() {
// 从 URL 参数获取主题设置
const url = new URL(window.location.href)
const theme = url.searchParams.get('theme')
this.isDark = theme === 'dark'
}
},
mounted() {
this.initTheme()
this.fetchReleases()
createApp({
data() {
return {
releases: [],
loading: true,
error: null,
isDark: false
}
},
methods: {
async fetchReleases() {
try {
this.loading = true
this.error = null
const response = await fetch('https://api.github.com/repos/kangfenmao/cherry-studio/releases')
if (!response.ok) {
throw new Error('Failed to fetch releases')
}
this.releases = await response.json()
} catch (err) {
this.error = 'Error loading releases: ' + err.message
} finally {
this.loading = false
}
}).mount('#app')
},
formatDate(dateString) {
return new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
},
renderMarkdown(content) {
if (!content) return ''
return md.render(content)
},
initTheme() {
// 从 URL 参数获取主题设置
const url = new URL(window.location.href)
const theme = url.searchParams.get('theme')
this.isDark = theme === 'dark'
}
},
mounted() {
this.initTheme()
this.fetchReleases()
}
}).mount('#app')
</script>
<style>
/* 基础的 Markdown 样式 */
.prose {
line-height: 1.6;
}
/* 基础的 Markdown 样式 */
.prose {
line-height: 1.6;
}
.prose h1 {
font-size: 1.5em;
margin: 1em 0;
}
.prose h1 {
font-size: 1.5em;
margin: 1em 0;
}
.prose h2 {
font-size: 1.3em;
margin: 0.8em 0;
}
.prose h2 {
font-size: 1.3em;
margin: 0.8em 0;
}
.prose h3 {
font-size: 1.1em;
margin: 0.6em 0;
}
.prose h3 {
font-size: 1.1em;
margin: 0.6em 0;
}
.prose ul {
list-style-type: disc;
margin-left: 1.5em;
margin-bottom: 1em;
}
.prose ul {
list-style-type: disc;
margin-left: 1.5em;
margin-bottom: 1em;
}
.prose ol {
list-style-type: decimal;
margin-left: 1.5em;
margin-bottom: 1em;
}
.prose ol {
list-style-type: decimal;
margin-left: 1.5em;
margin-bottom: 1em;
}
.prose code {
padding: 0.2em 0.4em;
border-radius: 0.2em;
font-size: 0.9em;
}
.prose code {
padding: 0.2em 0.4em;
border-radius: 0.2em;
font-size: 0.9em;
}
.dark .prose code {
background-color: #1f2937;
}
.dark .prose code {
background-color: #1f2937;
}
.prose code {
background-color: #f3f4f6;
}
.prose code {
background-color: #f3f4f6;
}
.prose pre code {
display: block;
padding: 1em;
overflow-x: auto;
}
.prose pre code {
display: block;
padding: 1em;
overflow-x: auto;
}
.prose a {
color: #3b82f6;
text-decoration: underline;
}
.prose a {
color: #3b82f6;
text-decoration: underline;
}
.dark .prose a {
color: #60a5fa;
}
.dark .prose a {
color: #60a5fa;
}
.prose blockquote {
border-left: 4px solid #e5e7eb;
padding-left: 1em;
margin: 1em 0;
}
.prose blockquote {
border-left: 4px solid #e5e7eb;
padding-left: 1em;
margin: 1em 0;
}
.dark .prose blockquote {
border-left-color: #374151;
color: #9ca3af;
}
.dark .prose blockquote {
border-left-color: #374151;
color: #9ca3af;
}
.dark .prose {
color: #e5e7eb;
}
.dark .prose {
color: #e5e7eb;
}
.dark-bg {
background-color: #151515;
}
.dark-bg {
background-color: #151515;
}
.bg {
background-color: #f2f2f2;
}
.bg {
background-color: #f2f2f2;
}
</style>
</body>
</html>
</body>
</html>

View File

@ -120,6 +120,7 @@ class KnowledgeService {
if (item.type === 'file') {
const file = item.content as FileType
console.log(file)
if (file.ext === '.pdf') {
return await ragApplication.addLoader(
@ -165,6 +166,27 @@ class KnowledgeService {
)
}
if (file.ext === '.csv') {
try {
const module = await import('@llm-tools/embedjs-loader-csv/src/index.js')
// 使用module中的功能
console.log(module.CsvLoader) // 假设模块导出了一个默认值
return await ragApplication.addLoader(
new module.CsvLoader({
filePathOrUrl: file.path,
chunkSize: base.chunkSize,
chunkOverlap: base.chunkOverlap,
csvParseOptions: {
columns: true
}
}) as any,
forceReload
)
} catch (error) {
console.error('加载模块时出错:', error)
}
}
if (['.md'].includes(file.ext)) {
return await ragApplication.addLoader(
new MarkdownLoader({

View File

@ -1,42 +1,41 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1, width=device-width" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; connect-src blob: *; script-src 'self' 'unsafe-eval' *; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' *; font-src 'self' data: *; img-src 'self' data: file: * blob:; frame-src * file:" />
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1, width=device-width" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; connect-src blob: *; script-src 'self' 'unsafe-eval' *; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' *; font-src 'self' data: *; img-src 'self' data: file: * blob:; frame-src * file:" />
<style>
html,
body {
margin: 0;
}
<style>
html,
body {
margin: 0;
}
#spinner {
position: fixed;
width: 100vw;
height: 100vh;
flex-direction: row;
justify-content: center;
align-items: center;
display: none;
}
#spinner {
position: fixed;
width: 100vw;
height: 100vh;
flex-direction: row;
justify-content: center;
align-items: center;
display: none;
}
#spinner img {
width: 100px;
border-radius: 50px;
}
</style>
</head>
#spinner img {
width: 100px;
border-radius: 50px;
}
</style>
</head>
<body>
<div id="root"></div>
<div id="spinner">
<img src="/src/assets/images/logo.png" />
</div>
<script type="module" src="/src/init.ts"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
<body>
<div id="root"></div>
<div id="spinner">
<img src="/src/assets/images/logo.png" />
</div>
<script type="module" src="/src/init.ts"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@ -95,14 +95,14 @@ export const Box = styled.div<BoxProps>`
box-sizing: border-box;
border: ${(props) => props?.border || 'none'};
gap: ${(p) => (p.gap ? getElementValue(p.gap) : 0)};
margin: ${(props) => (props.m || props.margin ? props.m ?? props.margin : 'none')};
margin: ${(props) => (props.m || props.margin ? (props.m ?? props.margin) : 'none')};
margin-top: ${(props) => (props.mt || props.marginTop ? getElementValue(props.mt || props.marginTop) : 'default')};
margin-bottom: ${(props) =>
props.mb || props.marginBottom ? getElementValue(props.mb ?? props.marginBottom) : 'default'};
margin-left: ${(props) => (props.ml || props.marginLeft ? getElementValue(props.ml ?? props.marginLeft) : 'default')};
margin-right: ${(props) =>
props.mr || props.marginRight ? getElementValue(props.mr ?? props.marginRight) : 'default'};
padding: ${(props) => (props.p || props.padding ? props.p ?? props.padding : 'none')};
padding: ${(props) => (props.p || props.padding ? (props.p ?? props.padding) : 'none')};
padding-top: ${(props) => (props.pt || props.paddingTop ? getElementValue(props.pt ?? props.paddingTop) : 'auto')};
padding-bottom: ${(props) =>
props.pb || props.paddingBottom ? getElementValue(props.pb ?? props.paddingBottom) : 'auto'};

View File

@ -222,6 +222,10 @@ export const EMBEDDING_MODELS = [
{
id: 'embed-multilingual-v2.0',
max_context: 256
},
{
id: 'text-embedding-004',
max_context: 2048
}
]

View File

@ -1191,7 +1191,12 @@ export function isWebSearchModel(model: Model): boolean {
}
if (provider.id === 'aihubmix') {
return model?.id === 'gemini-2.0-flash-exp-search'
const models = [
'gemini-2.0-flash-search',
'gemini-2.0-flash-exp-search',
'gemini-2.0-pro-exp-02-05-search'
]
return models.includes(model?.id)
}
if (provider.id === 'zhipu') {

View File

@ -32,7 +32,7 @@
"title": "智能體"
},
"assistants": {
"abbr": "助",
"abbr": "助",
"clear.content": "清空話題會刪除助手下所有主題和文件,確定要繼續嗎?",
"clear.title": "清空話題",
"copy.title": "複製助手",
@ -107,7 +107,7 @@
"settings.set_as_default": "設為預設助手",
"settings.show_line_numbers": "代码顯示行號",
"settings.temperature": "溫度",
"settings.temperature.tip": "較低的值使模型更具創造性和不可預測性,較高的值則使其更具確定性和精確性。",
"settings.temperature.tip": "模型產生文字的隨機程度。數值越高,回應內容越具多樣性、創意性及隨機性;設定為 0 則會依據事實回答。一般聊天建議設定為 0.7",
"settings.top_p": "Top-P",
"settings.top_p.tip": "模型生成文本的隨機程度。值越小AI 生成的內容越單調也越容易理解值越大AI 回覆的詞彙範圍越大,越多樣化",
"suggestions.title": "建議的問題",

View File

@ -33,7 +33,7 @@ interface KnowledgeContentProps {
selectedBase: KnowledgeBase
}
const fileTypes = ['.pdf', '.docx', '.pptx', '.xlsx', '.txt', '.md', '.html']
const fileTypes = ['.pdf', '.docx', '.pptx', '.xlsx', '.txt', '.md', '.html', '.csv']
const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
const { t } = useTranslation()

View File

@ -1,146 +1,144 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Selection Menu</title>
<style>
:root {
--bg-color: rgba(255, 255, 255, 0.95);
--button-bg: #f5f5f5;
--button-hover: #e8e8e8;
--text-color: #333;
--border-color: rgba(0, 0, 0, 0.06);
}
@media (prefers-color-scheme: dark) {
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Selection Menu</title>
<style>
:root {
--bg-color: rgba(80, 80, 80, 0.95);
--button-bg: #2c2c2c;
--button-hover: #383838;
--text-color: #e0e0e0;
--border-color: rgba(255, 255, 255, 0.08);
--bg-color: rgba(255, 255, 255, 0.95);
--button-bg: #f5f5f5;
--button-hover: #e8e8e8;
--text-color: #333;
--border-color: rgba(0, 0, 0, 0.06);
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: rgba(80, 80, 80, 0.95);
--button-bg: #2c2c2c;
--button-hover: #383838;
--text-color: #e0e0e0;
--border-color: rgba(255, 255, 255, 0.08);
}
}
body {
width: 280px;
height: 40px;
background: var(--bg-color);
overflow: hidden;
display: flex;
align-items: center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
.drag-handle {
width: 20px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
-webkit-app-region: drag;
}
body {
width: 280px;
height: 40px;
background: var(--bg-color);
overflow: hidden;
display: flex;
align-items: center;
}
.drag-handle::before,
.drag-handle::after {
content: '';
width: 2px;
height: 16px;
background-color: var(--border-color);
border-radius: 1px;
}
.drag-handle {
width: 20px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
-webkit-app-region: drag;
}
menu {
display: flex;
align-items: center;
height: 40px;
flex: 1;
margin-right: 10px;
gap: 5px;
}
.drag-handle::before,
.drag-handle::after {
content: '';
width: 2px;
height: 16px;
background-color: var(--border-color);
border-radius: 1px;
}
button {
flex: 1;
min-width: 0;
height: 32px;
border: none;
background: transparent;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
color: var(--text-color);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
outline: none;
}
menu {
display: flex;
align-items: center;
height: 40px;
flex: 1;
margin-right: 10px;
gap: 5px;
}
button:hover {
background: var(--button-hover);
}
button {
flex: 1;
min-width: 0;
height: 32px;
border: none;
background: transparent;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
color: var(--text-color);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
outline: none;
}
button:active {
transform: scale(0.95);
}
button:hover {
background: var(--button-hover);
}
svg {
width: 16px;
height: 16px;
fill: currentColor;
}
</style>
</head>
button:active {
transform: scale(0.95);
}
<body>
<div class="drag-handle"></div>
<menu>
<button data-action="chat">
<svg viewBox="0 0 24 24">
<path d="M20,2H4C2.9,2,2,2.9,2,4v18l4-4h14c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2z M20,16H6l-2,2V4h16V16z" />
</svg>
提问
</button>
<button data-action="explanation">
<svg viewBox="0 0 24 24">
<path
d="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M13,17h-2v-6h2V17z M13,9h-2V7h2V9z" />
</svg>
释义
</button>
<button data-action="translate">
<svg viewBox="0 0 24 24">
<path d="M6 4h12v2H6zM6 10h12v2H6zM6 16h8v2H6z" />
</svg>
翻译
</button>
<button data-action="summary">
<svg viewBox="0 0 24 24">
<path d="M14,17H4v2h10V17z M20,9H4v2h16V9z M4,15h16v-2H4V15z M4,5v2h16V5H4z" />
</svg>
总结
</button>
</menu>
svg {
width: 16px;
height: 16px;
fill: currentColor;
}
</style>
</head>
<script>
document.querySelectorAll('button').forEach(button => {
button.addEventListener('click', () => {
const action = button.getAttribute('data-action')
window.api.selectionMenu.action(action)
<body>
<div class="drag-handle"></div>
<menu>
<button data-action="chat">
<svg viewBox="0 0 24 24">
<path d="M20,2H4C2.9,2,2,2.9,2,4v18l4-4h14c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2z M20,16H6l-2,2V4h16V16z" />
</svg>
提问
</button>
<button data-action="explanation">
<svg viewBox="0 0 24 24">
<path
d="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M13,17h-2v-6h2V17z M13,9h-2V7h2V9z" />
</svg>
释义
</button>
<button data-action="translate">
<svg viewBox="0 0 24 24">
<path d="M6 4h12v2H6zM6 10h12v2H6zM6 16h8v2H6z" />
</svg>
翻译
</button>
<button data-action="summary">
<svg viewBox="0 0 24 24">
<path d="M14,17H4v2h10V17z M20,9H4v2h16V9z M4,15h16v-2H4V15z M4,5v2h16V5H4z" />
</svg>
总结
</button>
</menu>
<script>
document.querySelectorAll('button').forEach((button) => {
button.addEventListener('click', () => {
const action = button.getAttribute('data-action')
window.api.selectionMenu.action(action)
})
})
})
</script>
</body>
</html>
</script>
</body>
</html>

View File

@ -1518,7 +1518,7 @@ __metadata:
languageName: node
linkType: hard
"@llm-tools/embedjs-loader-csv@npm:^0.1.28":
"@llm-tools/embedjs-loader-csv@npm:0.1.28":
version: 0.1.28
resolution: "@llm-tools/embedjs-loader-csv@npm:0.1.28"
dependencies:
@ -1531,6 +1531,35 @@ __metadata:
languageName: node
linkType: hard
"@llm-tools/embedjs-loader-csv@patch:@llm-tools/embedjs-loader-csv@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-csv-npm-0.1.28-a5dac8addd.patch":
version: 0.1.28
resolution: "@llm-tools/embedjs-loader-csv@patch:@llm-tools/embedjs-loader-csv@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-csv-npm-0.1.28-a5dac8addd.patch::version=0.1.28&hash=c89b03"
dependencies:
"@llm-tools/embedjs-interfaces": "npm:0.1.28"
"@llm-tools/embedjs-utils": "npm:0.1.28"
csv-parse: "npm:^5.6.0"
debug: "npm:^4.4.0"
md5: "npm:^2.3.0"
checksum: 10c0/ed1e6f498293bfaa33e9fa7d1ad9cf916c39fc84e2cf29597be4e134913968e4a75017b081baaea6c550cf5910ea57ff5db3dccde5afe2b1c05b3bba741d384e
languageName: node
linkType: hard
"@llm-tools/embedjs-loader-image@npm:^0.1.28":
version: 0.1.28
resolution: "@llm-tools/embedjs-loader-image@npm:0.1.28"
dependencies:
"@langchain/core": "npm:^0.3.26"
"@llm-tools/embedjs-interfaces": "npm:0.1.28"
"@llm-tools/embedjs-utils": "npm:0.1.28"
debug: "npm:^4.4.0"
exifremove: "npm:^1.0.1"
md5: "npm:^2.3.0"
mime: "npm:^4.0.6"
stream-mime-type: "npm:^2.0.0"
checksum: 10c0/e9414dde0d10afe1541bfe464b80f5cb61ec523f28dce62ab931a3f4ffde93c5589fde8e7a7f5751e7dc20d68fe2d28883925ba65e2542ee9d43002591568af1
languageName: node
linkType: hard
"@llm-tools/embedjs-loader-markdown@npm:0.1.28":
version: 0.1.28
resolution: "@llm-tools/embedjs-loader-markdown@npm:0.1.28"
@ -2971,7 +3000,8 @@ __metadata:
"@kangfenmao/keyv-storage": "npm:^0.1.0"
"@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.28-8e4393fa2d.patch"
"@llm-tools/embedjs-libsql": "npm:^0.1.28"
"@llm-tools/embedjs-loader-csv": "npm:^0.1.28"
"@llm-tools/embedjs-loader-csv": "patch:@llm-tools/embedjs-loader-csv@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-csv-npm-0.1.28-a5dac8addd.patch"
"@llm-tools/embedjs-loader-image": "npm:^0.1.28"
"@llm-tools/embedjs-loader-markdown": "patch:@llm-tools/embedjs-loader-markdown@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-loader-markdown-npm-0.1.28-81647ffac6.patch"
"@llm-tools/embedjs-loader-msoffice": "npm:^0.1.28"
"@llm-tools/embedjs-loader-pdf": "npm:^0.1.28"
@ -5945,6 +5975,13 @@ __metadata:
languageName: node
linkType: hard
"exifremove@npm:^1.0.1":
version: 1.0.1
resolution: "exifremove@npm:1.0.1"
checksum: 10c0/df5a30087b262a35f2932e4d8b567206ec5f39518740c1552361e9a6eee0a38819359bd8ab2bd5df391647c4dea8d572995852f355cf8fc504df6b1685d82921
languageName: node
linkType: hard
"expand-template@npm:^2.0.3":
version: 2.0.3
resolution: "expand-template@npm:2.0.3"