mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-01 09:49:03 +08:00
Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2
This commit is contained in:
commit
7c0b03dbdc
2
.github/ISSUE_TEMPLATE/0_bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/0_bug_report.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: 🐛 Bug Report (English)
|
||||
name: 🐛 Bug Report
|
||||
description: Create a report to help us improve
|
||||
title: '[Bug]: '
|
||||
labels: ['BUG']
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/1_feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/1_feature_request.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: 💡 Feature Request (English)
|
||||
name: 💡 Feature Request
|
||||
description: Suggest an idea for this project
|
||||
title: '[Feature]: '
|
||||
labels: ['feature']
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/3_others.yml
vendored
2
.github/ISSUE_TEMPLATE/3_others.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: 🤔 Other Questions (English)
|
||||
name: 🤔 Other Questions
|
||||
description: Submit questions that don't fit into bug reports or feature requests
|
||||
title: '[Other]: '
|
||||
body:
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
diff --git a/dist/utils/tiktoken.cjs b/dist/utils/tiktoken.cjs
|
||||
index 973b0d0e75aeaf8de579419af31b879b32975413..f23c7caa8b9dc8bd404132725346a4786f6b278b 100644
|
||||
--- a/dist/utils/tiktoken.cjs
|
||||
+++ b/dist/utils/tiktoken.cjs
|
||||
@@ -1,25 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.encodingForModel = exports.getEncoding = void 0;
|
||||
-const lite_1 = require("js-tiktoken/lite");
|
||||
const async_caller_js_1 = require("./async_caller.cjs");
|
||||
const cache = {};
|
||||
const caller = /* #__PURE__ */ new async_caller_js_1.AsyncCaller({});
|
||||
async function getEncoding(encoding) {
|
||||
- if (!(encoding in cache)) {
|
||||
- cache[encoding] = caller
|
||||
- .fetch(`https://tiktoken.pages.dev/js/${encoding}.json`)
|
||||
- .then((res) => res.json())
|
||||
- .then((data) => new lite_1.Tiktoken(data))
|
||||
- .catch((e) => {
|
||||
- delete cache[encoding];
|
||||
- throw e;
|
||||
- });
|
||||
- }
|
||||
- return await cache[encoding];
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
exports.getEncoding = getEncoding;
|
||||
async function encodingForModel(model) {
|
||||
- return getEncoding((0, lite_1.getEncodingNameForModel)(model));
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
exports.encodingForModel = encodingForModel;
|
||||
diff --git a/dist/utils/tiktoken.js b/dist/utils/tiktoken.js
|
||||
index 8e41ee6f00f2f9c7fa2c59fa2b2f4297634b97aa..aa5f314a6349ad0d1c5aea8631a56aad099176e0 100644
|
||||
--- a/dist/utils/tiktoken.js
|
||||
+++ b/dist/utils/tiktoken.js
|
||||
@@ -1,20 +1,9 @@
|
||||
-import { Tiktoken, getEncodingNameForModel, } from "js-tiktoken/lite";
|
||||
import { AsyncCaller } from "./async_caller.js";
|
||||
const cache = {};
|
||||
const caller = /* #__PURE__ */ new AsyncCaller({});
|
||||
export async function getEncoding(encoding) {
|
||||
- if (!(encoding in cache)) {
|
||||
- cache[encoding] = caller
|
||||
- .fetch(`https://tiktoken.pages.dev/js/${encoding}.json`)
|
||||
- .then((res) => res.json())
|
||||
- .then((data) => new Tiktoken(data))
|
||||
- .catch((e) => {
|
||||
- delete cache[encoding];
|
||||
- throw e;
|
||||
- });
|
||||
- }
|
||||
- return await cache[encoding];
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
export async function encodingForModel(model) {
|
||||
- return getEncoding(getEncodingNameForModel(model));
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
diff --git a/package.json b/package.json
|
||||
index 36072aecf700fca1bc49832a19be832eca726103..90b8922fba1c3d1b26f78477c891b07816d6238a 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -37,7 +37,6 @@
|
||||
"ansi-styles": "^5.0.0",
|
||||
"camelcase": "6",
|
||||
"decamelize": "1.2.0",
|
||||
- "js-tiktoken": "^1.0.12",
|
||||
"langsmith": ">=0.2.8 <0.4.0",
|
||||
"mustache": "^4.2.0",
|
||||
"p-queue": "^6.6.2",
|
||||
68
.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch
vendored
Normal file
68
.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
diff --git a/dist/utils/tiktoken.cjs b/dist/utils/tiktoken.cjs
|
||||
index c5b41f121d2e3d24c3a4969e31fa1acffdcad3b9..ec724489dcae79ee6c61acf2d4d84bd19daef036 100644
|
||||
--- a/dist/utils/tiktoken.cjs
|
||||
+++ b/dist/utils/tiktoken.cjs
|
||||
@@ -1,6 +1,5 @@
|
||||
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
||||
const require_utils_async_caller = require('./async_caller.cjs');
|
||||
-const js_tiktoken_lite = require_rolldown_runtime.__toESM(require("js-tiktoken/lite"));
|
||||
|
||||
//#region src/utils/tiktoken.ts
|
||||
var tiktoken_exports = {};
|
||||
@@ -11,14 +10,10 @@ require_rolldown_runtime.__export(tiktoken_exports, {
|
||||
const cache = {};
|
||||
const caller = /* @__PURE__ */ new require_utils_async_caller.AsyncCaller({});
|
||||
async function getEncoding(encoding) {
|
||||
- if (!(encoding in cache)) cache[encoding] = caller.fetch(`https://tiktoken.pages.dev/js/${encoding}.json`).then((res) => res.json()).then((data) => new js_tiktoken_lite.Tiktoken(data)).catch((e) => {
|
||||
- delete cache[encoding];
|
||||
- throw e;
|
||||
- });
|
||||
- return await cache[encoding];
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
async function encodingForModel(model) {
|
||||
- return getEncoding((0, js_tiktoken_lite.getEncodingNameForModel)(model));
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
diff --git a/dist/utils/tiktoken.js b/dist/utils/tiktoken.js
|
||||
index 641acca03cb92f04a6fa5c9c31f1880ce635572e..707389970ad957aa0ff20ef37fa8dd2875be737c 100644
|
||||
--- a/dist/utils/tiktoken.js
|
||||
+++ b/dist/utils/tiktoken.js
|
||||
@@ -1,6 +1,5 @@
|
||||
import { __export } from "../_virtual/rolldown_runtime.js";
|
||||
import { AsyncCaller } from "./async_caller.js";
|
||||
-import { Tiktoken, getEncodingNameForModel } from "js-tiktoken/lite";
|
||||
|
||||
//#region src/utils/tiktoken.ts
|
||||
var tiktoken_exports = {};
|
||||
@@ -11,14 +10,10 @@ __export(tiktoken_exports, {
|
||||
const cache = {};
|
||||
const caller = /* @__PURE__ */ new AsyncCaller({});
|
||||
async function getEncoding(encoding) {
|
||||
- if (!(encoding in cache)) cache[encoding] = caller.fetch(`https://tiktoken.pages.dev/js/${encoding}.json`).then((res) => res.json()).then((data) => new Tiktoken(data)).catch((e) => {
|
||||
- delete cache[encoding];
|
||||
- throw e;
|
||||
- });
|
||||
- return await cache[encoding];
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
async function encodingForModel(model) {
|
||||
- return getEncoding(getEncodingNameForModel(model));
|
||||
+ throw new Error("TikToken Not implemented");
|
||||
}
|
||||
|
||||
//#endregion
|
||||
diff --git a/package.json b/package.json
|
||||
index a24f8fc61de58526051999260f2ebee5f136354b..e885359e8966e7730c51772533ce37e01edb3046 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -20,7 +20,6 @@
|
||||
"ansi-styles": "^5.0.0",
|
||||
"camelcase": "6",
|
||||
"decamelize": "1.2.0",
|
||||
- "js-tiktoken": "^1.0.12",
|
||||
"langsmith": "^0.3.64",
|
||||
"mustache": "^4.2.0",
|
||||
"p-queue": "^6.6.2",
|
||||
@ -1,19 +0,0 @@
|
||||
diff --git a/dist/embeddings.js b/dist/embeddings.js
|
||||
index 1f8154be3e9c22442a915eb4b85fa6d2a21b0d0c..dc13ef4a30e6c282824a5357bcee9bd0ae222aab 100644
|
||||
--- a/dist/embeddings.js
|
||||
+++ b/dist/embeddings.js
|
||||
@@ -214,10 +214,12 @@ export class OpenAIEmbeddings extends Embeddings {
|
||||
* @returns Promise that resolves to an embedding for the document.
|
||||
*/
|
||||
async embedQuery(text) {
|
||||
+ const isBaiduCloud = this.clientConfig.baseURL.includes('baidubce.com')
|
||||
+ const input = this.stripNewLines ? text.replace(/\n/g, ' ') : text
|
||||
const params = {
|
||||
model: this.model,
|
||||
- input: this.stripNewLines ? text.replace(/\n/g, " ") : text,
|
||||
- };
|
||||
+ input: isBaiduCloud ? [input] : input
|
||||
+ }
|
||||
if (this.dimensions) {
|
||||
params.dimensions = this.dimensions;
|
||||
}
|
||||
17
.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch
vendored
Normal file
17
.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
diff --git a/dist/embeddings.js b/dist/embeddings.js
|
||||
index 6f4b928d3e4717309382e1b5c2e31ab5bc6c5af0..bc79429c88a6d27d4997a2740c4d8ae0707f5991 100644
|
||||
--- a/dist/embeddings.js
|
||||
+++ b/dist/embeddings.js
|
||||
@@ -94,9 +94,11 @@ var OpenAIEmbeddings = class extends Embeddings {
|
||||
* @returns Promise that resolves to an embedding for the document.
|
||||
*/
|
||||
async embedQuery(text) {
|
||||
+ const isBaiduCloud = this.clientConfig.baseURL.includes('baidubce.com');
|
||||
+ const input = this.stripNewLines ? text.replace(/\n/g, " ") : text
|
||||
const params = {
|
||||
model: this.model,
|
||||
- input: this.stripNewLines ? text.replace(/\n/g, " ") : text
|
||||
+ input: isBaiduCloud ? [input] : input
|
||||
};
|
||||
if (this.dimensions) params.dimensions = this.dimensions;
|
||||
if (this.encodingFormat) params.encoding_format = this.encodingFormat;
|
||||
@ -23,7 +23,7 @@
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": false,
|
||||
"includes": ["**"],
|
||||
"includes": ["**", "!**/.claude/**"],
|
||||
"maxSize": 2097152
|
||||
},
|
||||
"formatter": {
|
||||
|
||||
13
package.json
13
package.json
@ -151,7 +151,9 @@
|
||||
"@google/genai": "patch:@google/genai@npm%3A1.0.1#~/.yarn/patches/@google-genai-npm-1.0.1-e26f0f9af7.patch",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"@heroui/react": "^2.8.3",
|
||||
"@langchain/community": "^0.3.50",
|
||||
"@langchain/community": "^1.0.0",
|
||||
"@langchain/core": "patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch",
|
||||
"@langchain/openai": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
|
||||
"@mistralai/mistralai": "^1.7.5",
|
||||
"@modelcontextprotocol/sdk": "^1.17.5",
|
||||
"@mozilla/readability": "^0.6.0",
|
||||
@ -377,9 +379,7 @@
|
||||
"@codemirror/language": "6.11.3",
|
||||
"@codemirror/lint": "6.8.5",
|
||||
"@codemirror/view": "6.38.1",
|
||||
"@langchain/core@npm:^0.3.26": "patch:@langchain/core@npm%3A0.3.44#~/.yarn/patches/@langchain-core-npm-0.3.44-41d5c3cb0a.patch",
|
||||
"@langchain/openai@npm:^0.3.16": "patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch",
|
||||
"@langchain/openai@npm:>=0.1.0 <0.4.0": "patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch",
|
||||
"@langchain/core@npm:^0.3.26": "patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch",
|
||||
"app-builder-lib@npm:26.0.13": "patch:app-builder-lib@npm%3A26.0.13#~/.yarn/patches/app-builder-lib-npm-26.0.13-a064c9e1d0.patch",
|
||||
"app-builder-lib@npm:26.0.15": "patch:app-builder-lib@npm%3A26.0.15#~/.yarn/patches/app-builder-lib-npm-26.0.15-360e5b0476.patch",
|
||||
"atomically@npm:^1.7.0": "patch:atomically@npm%3A1.7.0#~/.yarn/patches/atomically-npm-1.7.0-e742e5293b.patch",
|
||||
@ -403,7 +403,10 @@
|
||||
"@img/sharp-linux-arm64": "0.34.3",
|
||||
"@img/sharp-linux-x64": "0.34.3",
|
||||
"@img/sharp-win32-x64": "0.34.3",
|
||||
"openai@npm:5.12.2": "npm:@cherrystudio/openai@6.5.0"
|
||||
"openai@npm:5.12.2": "npm:@cherrystudio/openai@6.5.0",
|
||||
"@langchain/openai@npm:>=0.1.0 <0.6.0": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
|
||||
"@langchain/openai@npm:^0.3.16": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
|
||||
"@langchain/openai@npm:>=0.2.0 <0.7.0": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch"
|
||||
},
|
||||
"packageManager": "yarn@4.9.1",
|
||||
"lint-staged": {
|
||||
|
||||
@ -2,6 +2,7 @@ import type { BaseEmbeddings } from '@cherrystudio/embedjs-interfaces'
|
||||
import { OllamaEmbeddings } from '@cherrystudio/embedjs-ollama'
|
||||
import { OpenAiEmbeddings } from '@cherrystudio/embedjs-openai'
|
||||
import type { ApiClient } from '@types'
|
||||
import { net } from 'electron'
|
||||
|
||||
import { VoyageEmbeddings } from './VoyageEmbeddings'
|
||||
|
||||
@ -43,7 +44,7 @@ export default class EmbeddingsFactory {
|
||||
apiKey,
|
||||
dimensions,
|
||||
batchSize,
|
||||
configuration: { baseURL }
|
||||
configuration: { baseURL, fetch: net.fetch as typeof fetch }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
119
src/renderer/src/components/Popups/AddAssistantOrAgentPopup.tsx
Normal file
119
src/renderer/src/components/Popups/AddAssistantOrAgentPopup.tsx
Normal file
@ -0,0 +1,119 @@
|
||||
import { cn } from '@heroui/react'
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { Modal } from 'antd'
|
||||
import { Bot, MessageSquare } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type OptionType = 'assistant' | 'agent'
|
||||
|
||||
interface ShowParams {
|
||||
onSelect: (type: OptionType) => void
|
||||
}
|
||||
|
||||
interface Props extends ShowParams {
|
||||
resolve: (data: { type?: OptionType }) => void
|
||||
}
|
||||
|
||||
const PopupContainer: React.FC<Props> = ({ onSelect, resolve }) => {
|
||||
const { t } = useTranslation()
|
||||
const [open, setOpen] = useState(true)
|
||||
const [hoveredOption, setHoveredOption] = useState<OptionType | null>(null)
|
||||
|
||||
const onCancel = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
resolve({})
|
||||
}
|
||||
|
||||
const handleSelect = (type: OptionType) => {
|
||||
setOpen(false)
|
||||
onSelect(type)
|
||||
resolve({ type })
|
||||
}
|
||||
|
||||
AddAssistantOrAgentPopup.hide = onCancel
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('chat.add.option.title')}
|
||||
open={open}
|
||||
onCancel={onCancel}
|
||||
afterClose={onClose}
|
||||
transitionName="animation-move-down"
|
||||
centered
|
||||
footer={null}
|
||||
width={560}>
|
||||
<div className="grid grid-cols-2 gap-4 py-4">
|
||||
{/* Assistant Option */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSelect('assistant')}
|
||||
className="group flex flex-col items-center gap-3 rounded-lg bg-[var(--color-background-soft)] p-6 transition-all hover:bg-[var(--color-hover)]"
|
||||
onMouseEnter={() => setHoveredOption('assistant')}
|
||||
onMouseLeave={() => setHoveredOption(null)}>
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-[var(--color-list-item)] transition-colors">
|
||||
<MessageSquare
|
||||
size={24}
|
||||
className={cn(
|
||||
'transition-colors',
|
||||
hoveredOption === 'assistant' ? 'text-[var(--color-primary)]' : 'text-[var(--color-icon-white)]'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h3 className="mb-1 font-semibold text-[var(--color-text-1)] text-base">{t('chat.add.assistant.title')}</h3>
|
||||
<p className="text-[var(--color-text-2)] text-sm">{t('chat.add.assistant.description')}</p>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* Agent Option */}
|
||||
<button
|
||||
onClick={() => handleSelect('agent')}
|
||||
type="button"
|
||||
className="group flex flex-col items-center gap-3 rounded-lg bg-[var(--color-background-soft)] p-6 transition-all hover:bg-[var(--color-hover)]"
|
||||
onMouseEnter={() => setHoveredOption('agent')}
|
||||
onMouseLeave={() => setHoveredOption(null)}>
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-[var(--color-list-item)] transition-colors">
|
||||
<Bot
|
||||
size={24}
|
||||
className={cn(
|
||||
'transition-colors',
|
||||
hoveredOption === 'agent' ? 'text-[var(--color-primary)]' : 'text-[var(--color-icon-white)]'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h3 className="mb-1 font-semibold text-[var(--color-text-1)] text-base">{t('agent.add.title')}</h3>
|
||||
<p className="text-[var(--color-text-2)] text-sm">{t('agent.add.description')}</p>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const TopViewKey = 'AddAssistantOrAgentPopup'
|
||||
|
||||
export default class AddAssistantOrAgentPopup {
|
||||
static topviewId = 0
|
||||
static hide() {
|
||||
TopView.hide(TopViewKey)
|
||||
}
|
||||
static show(props: ShowParams) {
|
||||
return new Promise<{ type?: OptionType }>((resolve) => {
|
||||
TopView.show(
|
||||
<PopupContainer
|
||||
{...props}
|
||||
resolve={(v) => {
|
||||
resolve(v)
|
||||
TopView.hide(TopViewKey)
|
||||
}}
|
||||
/>,
|
||||
TopViewKey
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,10 @@ export const useAgent = (id: string | null) => {
|
||||
const client = useAgentClient()
|
||||
const key = id ? client.agentPaths.withId(id) : null
|
||||
const { apiServerConfig, apiServerRunning } = useApiServer()
|
||||
|
||||
// Disable SWR fetching when server is not running by setting key to null
|
||||
const swrKey = apiServerRunning && id ? key : null
|
||||
|
||||
const fetcher = useCallback(async () => {
|
||||
if (!id) {
|
||||
throw new Error(t('agent.get.error.null_id'))
|
||||
@ -17,13 +21,10 @@ export const useAgent = (id: string | null) => {
|
||||
if (!apiServerConfig.enabled) {
|
||||
throw new Error(t('apiServer.messages.notEnabled'))
|
||||
}
|
||||
if (!apiServerRunning) {
|
||||
throw new Error(t('agent.server.error.not_running'))
|
||||
}
|
||||
const result = await client.getAgent(id)
|
||||
return result
|
||||
}, [apiServerConfig.enabled, apiServerRunning, client, id, t])
|
||||
const { data, error, isLoading } = useSWR(key, id ? fetcher : null)
|
||||
}, [apiServerConfig.enabled, client, id, t])
|
||||
const { data, error, isLoading } = useSWR(swrKey, fetcher)
|
||||
|
||||
return {
|
||||
agent: data,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"agent": {
|
||||
"add": {
|
||||
"description": "Handle complex tasks with various tools",
|
||||
"error": {
|
||||
"failed": "Failed to add a agent",
|
||||
"invalid_agent": "Invalid Agent"
|
||||
@ -547,8 +548,12 @@
|
||||
"chat": {
|
||||
"add": {
|
||||
"assistant": {
|
||||
"description": "Daily conversations and quick Q&A",
|
||||
"title": "Add Assistant"
|
||||
},
|
||||
"option": {
|
||||
"title": "Select Type"
|
||||
},
|
||||
"topic": {
|
||||
"title": "New Topic"
|
||||
}
|
||||
@ -2923,15 +2928,14 @@
|
||||
},
|
||||
"description": "A powerful AI assistant for producer",
|
||||
"downloading": "Downloading...",
|
||||
"enterprise": {
|
||||
"title": "Enterprise"
|
||||
},
|
||||
"feedback": {
|
||||
"button": "Feedback",
|
||||
"title": "Feedback"
|
||||
},
|
||||
"label": "About & Feedback",
|
||||
"license": {
|
||||
"button": "License",
|
||||
"title": "License"
|
||||
},
|
||||
"releases": {
|
||||
"button": "Releases",
|
||||
"title": "Release Notes"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"agent": {
|
||||
"add": {
|
||||
"description": "调用各种工具处理复杂任务",
|
||||
"error": {
|
||||
"failed": "添加 Agent 失败",
|
||||
"invalid_agent": "无效的 Agent"
|
||||
@ -547,8 +548,12 @@
|
||||
"chat": {
|
||||
"add": {
|
||||
"assistant": {
|
||||
"description": "日常对话和快速问答",
|
||||
"title": "添加助手"
|
||||
},
|
||||
"option": {
|
||||
"title": "选择添加类型"
|
||||
},
|
||||
"topic": {
|
||||
"title": "新建话题"
|
||||
}
|
||||
@ -2923,15 +2928,14 @@
|
||||
},
|
||||
"description": "一款为创造者而生的 AI 助手",
|
||||
"downloading": "正在下载更新...",
|
||||
"enterprise": {
|
||||
"title": "企业版"
|
||||
},
|
||||
"feedback": {
|
||||
"button": "反馈",
|
||||
"title": "意见反馈"
|
||||
},
|
||||
"label": "关于我们",
|
||||
"license": {
|
||||
"button": "查看",
|
||||
"title": "许可证"
|
||||
},
|
||||
"releases": {
|
||||
"button": "查看",
|
||||
"title": "更新日志"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"agent": {
|
||||
"add": {
|
||||
"description": "調用各種工具處理複雜任務",
|
||||
"error": {
|
||||
"failed": "無法新增代理人",
|
||||
"invalid_agent": "無效的 Agent"
|
||||
@ -547,8 +548,12 @@
|
||||
"chat": {
|
||||
"add": {
|
||||
"assistant": {
|
||||
"description": "日常對話和快速問答",
|
||||
"title": "新增助手"
|
||||
},
|
||||
"option": {
|
||||
"title": "選擇新增類型"
|
||||
},
|
||||
"topic": {
|
||||
"title": "新增話題"
|
||||
}
|
||||
@ -1047,7 +1052,7 @@
|
||||
"clear": "清除",
|
||||
"close": "關閉",
|
||||
"collapse": "折疊",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "已完成",
|
||||
"confirm": "確認",
|
||||
"copied": "已複製",
|
||||
"copy": "複製",
|
||||
@ -2923,15 +2928,14 @@
|
||||
},
|
||||
"description": "一款為創作者而生的強大 AI 助手",
|
||||
"downloading": "正在下載...",
|
||||
"enterprise": {
|
||||
"title": "企業版"
|
||||
},
|
||||
"feedback": {
|
||||
"button": "回饋",
|
||||
"title": "回饋"
|
||||
},
|
||||
"label": "關於與回饋",
|
||||
"license": {
|
||||
"button": "檢視",
|
||||
"title": "授權"
|
||||
},
|
||||
"releases": {
|
||||
"button": "檢視",
|
||||
"title": "更新日誌"
|
||||
@ -3045,37 +3049,37 @@
|
||||
},
|
||||
"content": "匯出部分數據,包括聊天記錄、設定。請注意,備份過程可能需要一些時間,感謝您的耐心等候。",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"auto_close_tip": "將於 {{seconds}} 秒後自動關閉...",
|
||||
"confirm_close_message": "檔案傳輸正在進行中。關閉將會中斷傳輸。您確定要強制關閉嗎?",
|
||||
"confirm_close_title": "確認關閉",
|
||||
"connected": "已連線",
|
||||
"connection_failed": "連線失敗",
|
||||
"content": "請確保電腦和手機處於同一網路以使用區域網路傳輸。請打開 Cherry Studio App 掃描此 QR 碼。",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "初始化失敗",
|
||||
"no_file": "未選擇檔案",
|
||||
"no_ip": "無法取得 IP 位址",
|
||||
"send_failed": "無法傳送檔案"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"force_close": "強制關閉",
|
||||
"generating_qr": "正在生成 QR 碼...",
|
||||
"noZipSelected": "未選取壓縮檔案",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"scan_qr": "請使用手機掃描QR碼",
|
||||
"selectZip": "選擇壓縮檔案",
|
||||
"sendZip": "開始恢復資料",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "轉帳完成",
|
||||
"connected": "已連線",
|
||||
"connecting": "連線中...",
|
||||
"disconnected": "已斷線",
|
||||
"error": "連線錯誤",
|
||||
"initializing": "正在初始化連線...",
|
||||
"preparing": "正在準備傳輸...",
|
||||
"sending": "傳輸中 {{progress}}%",
|
||||
"waiting_qr_scan": "請掃描QR碼以連接"
|
||||
},
|
||||
"title": "區域網路傳輸",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"transfer_progress": "傳輸進度"
|
||||
},
|
||||
"title": "匯出手機"
|
||||
},
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Löschen",
|
||||
"close": "Schließen",
|
||||
"collapse": "Einklappen",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Abgeschlossen",
|
||||
"confirm": "Bestätigen",
|
||||
"copied": "Kopiert",
|
||||
"copy": "Kopieren",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:Select backup file"
|
||||
"button": "Sicherungsdatei auswählen"
|
||||
},
|
||||
"content": "[to be translated]:Export some data, including chat logs and settings. Please note that the backup process may take some time. Thank you for your patience.",
|
||||
"content": "Exportieren Sie einige Daten, einschließlich Chat-Protokollen und Einstellungen. Bitte beachten Sie, dass der Sicherungsvorgang einige Zeit in Anspruch nehmen kann. Vielen Dank für Ihre Geduld.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:Please ensure your computer and phone are on the same network for LAN transfer. Open the Cherry Studio App to scan this QR code.",
|
||||
"auto_close_tip": "Automatisches Schließen in {{seconds}} Sekunden...",
|
||||
"confirm_close_message": "Dateiübertragung läuft. Beim Schließen wird die Übertragung unterbrochen. Möchten Sie wirklich das Schließen erzwingen?",
|
||||
"confirm_close_title": "Schließen bestätigen",
|
||||
"connected": "Verbunden",
|
||||
"connection_failed": "Verbindung fehlgeschlagen",
|
||||
"content": "Bitte stelle sicher, dass sich dein Computer und dein Telefon im selben Netzwerk befinden, um eine LAN-Übertragung durchzuführen. Öffne die Cherry Studio App, um diesen QR-Code zu scannen.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Initialisierung fehlgeschlagen",
|
||||
"no_file": "Keine Datei ausgewählt",
|
||||
"no_ip": "IP-Adresse kann nicht abgerufen werden",
|
||||
"send_failed": "Fehler beim Senden der Datei"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:No compressed file selected",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:Select a compressed file",
|
||||
"sendZip": "[to be translated]:Begin data recovery",
|
||||
"force_close": "Erzwungenes Schließen",
|
||||
"generating_qr": "QR-Code wird generiert...",
|
||||
"noZipSelected": "Keine komprimierte Datei ausgewählt",
|
||||
"scan_qr": "Bitte scannen Sie den QR-Code mit Ihrem Telefon.",
|
||||
"selectZip": "Wählen Sie eine komprimierte Datei",
|
||||
"sendZip": "Datenwiederherstellung beginnen",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Übertragung abgeschlossen",
|
||||
"connected": "Verbunden",
|
||||
"connecting": "Verbindung wird hergestellt...",
|
||||
"disconnected": "Getrennt",
|
||||
"error": "Verbindungsfehler",
|
||||
"initializing": "Verbindung wird initialisiert...",
|
||||
"preparing": "Übertragung wird vorbereitet...",
|
||||
"sending": "Übertrage {{progress}}%",
|
||||
"waiting_qr_scan": "Bitte QR-Code scannen, um zu verbinden"
|
||||
},
|
||||
"title": "[to be translated]:LAN transmission",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "LAN-Übertragung",
|
||||
"transfer_progress": "Übertragungsfortschritt"
|
||||
},
|
||||
"title": "[to be translated]:Export to phone"
|
||||
"title": "Auf Telefon exportieren"
|
||||
},
|
||||
"hour_interval_one": "{{count}} Stunde",
|
||||
"hour_interval_other": "{{count}} Stunden",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Καθαρισμός",
|
||||
"close": "Κλείσιμο",
|
||||
"collapse": "Σύμπτυξη",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Ολοκληρώθηκε",
|
||||
"confirm": "Επιβεβαίωση",
|
||||
"copied": "Αντιγράφηκε",
|
||||
"copy": "Αντιγραφή",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "Επιλέξτε αρχείο αντιγράφων ασφαλείας"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "Εξαγωγή μέρους των δεδομένων, συμπεριλαμβανομένων των ιστορικών συνομιλιών και των ρυθμίσεων. Σημειώστε ότι η διαδικασία δημιουργίας αντιγράφων ασφαλείας ενδέχεται να διαρκέσει κάποιο χρονικό διάστημα, ευχαριστούμε για την υπομονή σας.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "Αυτόματο κλείσιμο σε {{seconds}} δευτερόλεπτα...",
|
||||
"confirm_close_message": "Η μεταφορά αρχείων είναι σε εξέλιξη. Το κλείσιμο θα διακόψει τη μεταφορά. Είστε σίγουροι ότι θέλετε να κλείσετε βίαια;",
|
||||
"confirm_close_title": "Επιβεβαίωση Κλεισίματος",
|
||||
"connected": "Συνδεδεμένος",
|
||||
"connection_failed": "Η σύνδεση απέτυχε",
|
||||
"content": "Βεβαιωθείτε ότι ο υπολογιστής και το κινητό βρίσκονται στο ίδιο δίκτυο για να χρησιμοποιήσετε τη μεταφορά LAN. Ανοίξτε την εφαρμογή Cherry Studio και σαρώστε αυτόν τον κωδικό QR.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Η αρχικοποίηση απέτυχε",
|
||||
"no_file": "Κανένα αρχείο δεν επιλέχθηκε",
|
||||
"no_ip": "Αδυναμία λήψης διεύθυνσης IP",
|
||||
"send_failed": "Αποτυχία αποστολής αρχείου"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "Κλείσιμο με βία",
|
||||
"generating_qr": "Δημιουργία κώδικα QR...",
|
||||
"noZipSelected": "Δεν επιλέχθηκε συμπιεσμένο αρχείο",
|
||||
"scan_qr": "Παρακαλώ σαρώστε τον κωδικό QR με το τηλέφωνό σας",
|
||||
"selectZip": "Επιλέξτε συμπιεσμένο αρχείο",
|
||||
"sendZip": "Έναρξη ανάκτησης δεδομένων",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Η μεταφορά ολοκληρώθηκε",
|
||||
"connected": "Συνδεδεμένος",
|
||||
"connecting": "Σύνδεση...",
|
||||
"disconnected": "Αποσυνδέθηκε",
|
||||
"error": "Σφάλμα σύνδεσης",
|
||||
"initializing": "Αρχικοποίηση σύνδεσης...",
|
||||
"preparing": "Προετοιμασία μεταφοράς...",
|
||||
"sending": "Μεταφορά {{progress}}%",
|
||||
"waiting_qr_scan": "Παρακαλώ σαρώστε τον κωδικό QR για σύνδεση"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "Μεταφορά τοπικού δικτύου",
|
||||
"transfer_progress": "Πρόοδος μεταφοράς"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "Εξαγωγή στο κινητό"
|
||||
},
|
||||
"hour_interval_one": "{{count}} ώρα",
|
||||
"hour_interval_other": "{{count}} ώρες",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Limpiar",
|
||||
"close": "Cerrar",
|
||||
"collapse": "Colapsar",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Completado",
|
||||
"confirm": "Confirmar",
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "Seleccionar archivo de copia de seguridad"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "Exportar parte de los datos, incluidos los registros de chat y la configuración. Tenga en cuenta que el proceso de copia de seguridad puede tardar un tiempo; gracias por su paciencia.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "Cierre automático en {{seconds}} segundos...",
|
||||
"confirm_close_message": "La transferencia de archivos está en progreso. Cerrar interrumpirá la transferencia. ¿Estás seguro de que quieres forzar el cierre?",
|
||||
"confirm_close_title": "Confirmar Cierre",
|
||||
"connected": "Conectado",
|
||||
"connection_failed": "Conexión fallida",
|
||||
"content": "Asegúrate de que el ordenador y el móvil estén en la misma red para usar la transferencia por LAN. Abre la aplicación Cherry Studio y escanea este código QR.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Falló la inicialización",
|
||||
"no_file": "Ningún archivo seleccionado",
|
||||
"no_ip": "No se puede obtener la dirección IP",
|
||||
"send_failed": "Error al enviar el archivo"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "Cerrar forzosamente",
|
||||
"generating_qr": "Generando código QR...",
|
||||
"noZipSelected": "No se ha seleccionado ningún archivo comprimido",
|
||||
"scan_qr": "Por favor, escanea el código QR con tu teléfono",
|
||||
"selectZip": "Seleccionar archivo comprimido",
|
||||
"sendZip": "Comenzar la recuperación de datos",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Transferencia completada",
|
||||
"connected": "Conectado",
|
||||
"connecting": "Conectando...",
|
||||
"disconnected": "Desconectado",
|
||||
"error": "Error de conexión",
|
||||
"initializing": "Inicializando conexión...",
|
||||
"preparing": "Preparando transferencia...",
|
||||
"sending": "Transfiriendo {{progress}}%",
|
||||
"waiting_qr_scan": "Por favor, escanea el código QR para conectarte"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "Transferencia de red local",
|
||||
"transfer_progress": "Progreso de transferencia"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "Exportar al teléfono"
|
||||
},
|
||||
"hour_interval_one": "{{count}} hora",
|
||||
"hour_interval_other": "{{count}} horas",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Effacer",
|
||||
"close": "Fermer",
|
||||
"collapse": "Réduire",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Terminé",
|
||||
"confirm": "Confirmer",
|
||||
"copied": "Copié",
|
||||
"copy": "Copier",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "Sélectionner le fichier de sauvegarde"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "Exporter une partie des données, incluant les historiques de discussion et les paramètres. Veuillez noter que le processus de sauvegarde peut prendre un certain temps ; merci pour votre patience.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "Fermeture automatique dans {{seconds}} secondes...",
|
||||
"confirm_close_message": "Le transfert de fichier est en cours. Fermer interrompra le transfert. Êtes-vous sûr de vouloir forcer la fermeture ?",
|
||||
"confirm_close_title": "Confirmer la fermeture",
|
||||
"connected": "Connecté",
|
||||
"connection_failed": "Échec de la connexion",
|
||||
"content": "Assurez-vous que l'ordinateur et le téléphone sont connectés au même réseau pour utiliser le transfert en réseau local. Ouvrez l'application Cherry Studio et scannez ce code QR.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Échec de l'initialisation",
|
||||
"no_file": "Aucun fichier sélectionné",
|
||||
"no_ip": "Impossible d'obtenir l'adresse IP",
|
||||
"send_failed": "Échec de l'envoi du fichier"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "Fermer de force",
|
||||
"generating_qr": "Génération du code QR...",
|
||||
"noZipSelected": "Aucun fichier compressé sélectionné",
|
||||
"scan_qr": "Veuillez scanner le code QR avec votre téléphone",
|
||||
"selectZip": "Sélectionner le fichier compressé",
|
||||
"sendZip": "Commencer la restauration des données",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Transfert terminé",
|
||||
"connected": "Connecté",
|
||||
"connecting": "Connexion...",
|
||||
"disconnected": "Déconnecté",
|
||||
"error": "Erreur de connexion",
|
||||
"initializing": "Initialisation de la connexion...",
|
||||
"preparing": "Préparation du transfert...",
|
||||
"sending": "Transfert {{progress}} %",
|
||||
"waiting_qr_scan": "Veuillez scanner le code QR pour vous connecter"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "Transmission en réseau local",
|
||||
"transfer_progress": "Progression du transfert"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "Exporter vers le téléphone"
|
||||
},
|
||||
"hour_interval_one": "{{count}} heure",
|
||||
"hour_interval_other": "{{count}} heures",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "クリア",
|
||||
"close": "閉じる",
|
||||
"collapse": "折りたたむ",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "完了",
|
||||
"confirm": "確認",
|
||||
"copied": "コピーされました",
|
||||
"copy": "コピー",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "バックアップファイルを選択"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "一部のデータ、チャット履歴や設定をエクスポートします。バックアップには時間がかかる場合がありますので、しばらくお待ちください。",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "{{seconds}}秒後に自動的に閉じます...",
|
||||
"confirm_close_message": "ファイル転送が進行中です。閉じると転送が中断されます。強制終了してもよろしいですか?",
|
||||
"confirm_close_title": "閉じることを確認",
|
||||
"connected": "接続済み",
|
||||
"connection_failed": "接続に失敗しました",
|
||||
"content": "コンピューターとスマートフォンが同じネットワークに接続されていることを確認し、ローカルエリアネットワーク転送を使用してください。Cherry Studioアプリを開き、このQRコードをスキャンしてください。",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "初期化に失敗しました",
|
||||
"no_file": "ファイルが選択されていません",
|
||||
"no_ip": "IPアドレスを取得できません",
|
||||
"send_failed": "ファイルの送信に失敗しました"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "強制終了",
|
||||
"generating_qr": "QRコードを生成中...",
|
||||
"noZipSelected": "圧縮ファイルが選択されていません",
|
||||
"scan_qr": "携帯電話でQRコードをスキャンしてください",
|
||||
"selectZip": "圧縮ファイルを選択",
|
||||
"sendZip": "データの復元を開始します",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "転送完了",
|
||||
"connected": "接続済み",
|
||||
"connecting": "接続中...",
|
||||
"disconnected": "切断されました",
|
||||
"error": "接続エラー",
|
||||
"initializing": "接続を初期化中...",
|
||||
"preparing": "転送準備中...",
|
||||
"sending": "転送中 {{progress}}%",
|
||||
"waiting_qr_scan": "QRコードをスキャンして接続してください"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "LAN転送",
|
||||
"transfer_progress": "転送進行"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "スマートフォンにエクスポート"
|
||||
},
|
||||
"hour_interval_one": "{{count}} 時間",
|
||||
"hour_interval_other": "{{count}} 時間",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Limpar",
|
||||
"close": "Fechar",
|
||||
"collapse": "Recolher",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Concluído",
|
||||
"confirm": "Confirmar",
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "Selecionar arquivo de backup"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "Exportar parte dos dados, incluindo registros de conversas e configurações. Observe que o processo de backup pode demorar um pouco; agradecemos sua paciência.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "Fechando automaticamente em {{seconds}} segundos...",
|
||||
"confirm_close_message": "Transferência de arquivo em andamento. Fechar irá interromper a transferência. Tem certeza de que deseja forçar o fechamento?",
|
||||
"confirm_close_title": "Confirmar Fechamento",
|
||||
"connected": "Conectado",
|
||||
"connection_failed": "Falha na conexão",
|
||||
"content": "Certifique-se de que o computador e o telefone estejam na mesma rede para usar a transferência via LAN. Abra o aplicativo Cherry Studio e escaneie este código QR.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Falha na inicialização",
|
||||
"no_file": "Nenhum arquivo selecionado",
|
||||
"no_ip": "Incapaz de obter endereço IP",
|
||||
"send_failed": "Falha ao enviar arquivo"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "Forçar Fechamento",
|
||||
"generating_qr": "Gerando código QR...",
|
||||
"noZipSelected": "Nenhum arquivo de compressão selecionado",
|
||||
"scan_qr": "Por favor, escaneie o código QR com o seu telefone",
|
||||
"selectZip": "Selecionar arquivo compactado",
|
||||
"sendZip": "Iniciar recuperação de dados",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Transferência concluída",
|
||||
"connected": "Conectado",
|
||||
"connecting": "Conectando...",
|
||||
"disconnected": "Desconectado",
|
||||
"error": "Erro de conexão",
|
||||
"initializing": "Inicializando conexão...",
|
||||
"preparing": "Preparando transferência...",
|
||||
"sending": "Transferindo {{progress}}%",
|
||||
"waiting_qr_scan": "Por favor, escaneie o código QR para conectar"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "transmissão de rede local",
|
||||
"transfer_progress": "Progresso da transferência"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "Exportar para o telemóvel"
|
||||
},
|
||||
"hour_interval_one": "{{count}} hora",
|
||||
"hour_interval_other": "{{count}} horas",
|
||||
|
||||
@ -1047,7 +1047,7 @@
|
||||
"clear": "Очистить",
|
||||
"close": "Закрыть",
|
||||
"collapse": "Свернуть",
|
||||
"completed": "[to be translated]:Completed",
|
||||
"completed": "Завершено",
|
||||
"confirm": "Подтверждение",
|
||||
"copied": "Скопировано",
|
||||
"copy": "Копировать",
|
||||
@ -3041,43 +3041,43 @@
|
||||
},
|
||||
"export_to_phone": {
|
||||
"confirm": {
|
||||
"button": "[to be translated]:选择备份文件"
|
||||
"button": "Выберите файл резервной копии"
|
||||
},
|
||||
"content": "[to be translated]:导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"content": "Экспорт части данных, включая чат и настройки. Пожалуйста, обратите внимание, что процесс резервного копирования может занять некоторое время. Благодарим за ваше терпение.",
|
||||
"lan": {
|
||||
"auto_close_tip": "[to be translated]:Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "[to be translated]:File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "[to be translated]:Confirm Close",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connection_failed": "[to be translated]:Connection failed",
|
||||
"content": "[to be translated]:请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"auto_close_tip": "Автоматическое закрытие через {{seconds}} секунд...",
|
||||
"confirm_close_message": "Передача файла в процессе. Закрытие прервет передачу. Вы уверены, что хотите принудительно закрыть?",
|
||||
"confirm_close_title": "Подтвердить закрытие",
|
||||
"connected": "Подключено",
|
||||
"connection_failed": "Соединение не удалось",
|
||||
"content": "Убедитесь, что компьютер и телефон подключены к одной сети, чтобы использовать локальную передачу. Откройте приложение Cherry Studio и отсканируйте этот QR-код.",
|
||||
"error": {
|
||||
"init_failed": "[to be translated]:Initialization failed",
|
||||
"no_file": "[to be translated]:No file selected",
|
||||
"no_ip": "[to be translated]:Unable to get IP address",
|
||||
"send_failed": "[to be translated]:Failed to send file"
|
||||
"init_failed": "Инициализация не удалась",
|
||||
"no_file": "Файл не выбран",
|
||||
"no_ip": "Не удалось получить IP-адрес",
|
||||
"send_failed": "Не удалось отправить файл"
|
||||
},
|
||||
"force_close": "[to be translated]:Force Close",
|
||||
"generating_qr": "[to be translated]:Generating QR code...",
|
||||
"noZipSelected": "[to be translated]:未选择压缩文件",
|
||||
"scan_qr": "[to be translated]:Please scan QR code with your phone",
|
||||
"selectZip": "[to be translated]:选择压缩文件",
|
||||
"sendZip": "[to be translated]:开始恢复数据",
|
||||
"force_close": "Принудительное закрытие",
|
||||
"generating_qr": "Генерация QR-кода...",
|
||||
"noZipSelected": "Архив не выбран",
|
||||
"scan_qr": "Пожалуйста, отсканируйте QR-код с помощью вашего телефона",
|
||||
"selectZip": "Выберите архив",
|
||||
"sendZip": "Начать восстановление данных",
|
||||
"status": {
|
||||
"completed": "[to be translated]:Transfer completed",
|
||||
"connected": "[to be translated]:Connected",
|
||||
"connecting": "[to be translated]:Connecting...",
|
||||
"disconnected": "[to be translated]:Disconnected",
|
||||
"error": "[to be translated]:Connection error",
|
||||
"initializing": "[to be translated]:Initializing connection...",
|
||||
"preparing": "[to be translated]:Preparing transfer...",
|
||||
"sending": "[to be translated]:Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "[to be translated]:Please scan QR code to connect"
|
||||
"completed": "Перевод завершён",
|
||||
"connected": "Подключено",
|
||||
"connecting": "Подключение...",
|
||||
"disconnected": "Отключено",
|
||||
"error": "Ошибка подключения",
|
||||
"initializing": "Инициализация соединения...",
|
||||
"preparing": "Подготовка передачи...",
|
||||
"sending": "Передача {{progress}}%",
|
||||
"waiting_qr_scan": "Пожалуйста, отсканируйте QR-код для подключения"
|
||||
},
|
||||
"title": "[to be translated]:局域网传输",
|
||||
"transfer_progress": "[to be translated]:Transfer progress"
|
||||
"title": "Передача по локальной сети",
|
||||
"transfer_progress": "Прогресс передачи"
|
||||
},
|
||||
"title": "[to be translated]:导出至手机"
|
||||
"title": "Экспорт на телефон"
|
||||
},
|
||||
"hour_interval_one": "{{count}} час",
|
||||
"hour_interval_other": "{{count}} часов",
|
||||
|
||||
@ -172,7 +172,7 @@ const AssistantsTab: FC<AssistantsTabProps> = (props) => {
|
||||
onAssistantSwitch={setActiveAssistant}
|
||||
onAssistantDelete={onDeleteAssistant}
|
||||
onAgentDelete={deleteAgent}
|
||||
onAgentPress={setActiveAgentId}
|
||||
onAgentPress={handleAgentPress}
|
||||
addPreset={addAssistantPreset}
|
||||
copyAssistant={copyAssistant}
|
||||
onCreateDefaultAssistant={onCreateDefaultAssistant}
|
||||
|
||||
@ -85,7 +85,8 @@ export const Container: React.FC<{ isActive?: boolean } & React.HTMLAttributes<H
|
||||
}) => (
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex h-[37px] w-[calc(var(--assistants-width)-20px)] cursor-pointer flex-row justify-between rounded-[var(--list-item-border-radius)] border border-transparent px-2 hover:bg-[var(--color-list-item-hover)]',
|
||||
'relative flex h-[37px] w-[calc(var(--assistants-width)-20px)] cursor-pointer flex-row justify-between rounded-[var(--list-item-border-radius)] border border-transparent px-2',
|
||||
!isActive && 'hover:bg-[var(--color-list-item-hover)]',
|
||||
isActive && 'bg-[var(--color-list-item)] shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]',
|
||||
className
|
||||
)}
|
||||
|
||||
@ -404,7 +404,8 @@ const Container = ({
|
||||
<div
|
||||
{...props}
|
||||
className={cn(
|
||||
'relative flex h-[37px] w-[calc(var(--assistants-width)-20px)] cursor-pointer flex-row justify-between rounded-[var(--list-item-border-radius)] border-[0.5px] border-transparent px-2 hover:bg-[var(--color-list-item-hover)]',
|
||||
'relative flex h-[37px] w-[calc(var(--assistants-width)-20px)] cursor-pointer flex-row justify-between rounded-[var(--list-item-border-radius)] border-[0.5px] border-transparent px-2',
|
||||
!isActive && 'hover:bg-[var(--color-list-item-hover)]',
|
||||
isActive && 'bg-[var(--color-list-item)] shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]',
|
||||
className
|
||||
)}>
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Button, Popover, PopoverContent, PopoverTrigger, useDisclosure } from '@heroui/react'
|
||||
import { useDisclosure } from '@heroui/react'
|
||||
import AddAssistantOrAgentPopup from '@renderer/components/Popups/AddAssistantOrAgentPopup'
|
||||
import { AgentModal } from '@renderer/components/Popups/agent/AgentModal'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import { setActiveTopicOrSessionAction } from '@renderer/store/runtime'
|
||||
import type { AgentEntity, Assistant, Topic } from '@renderer/types'
|
||||
import { Bot, MessageSquare } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import AddButton from './AddButton'
|
||||
@ -18,18 +18,19 @@ interface UnifiedAddButtonProps {
|
||||
|
||||
const UnifiedAddButton: FC<UnifiedAddButtonProps> = ({ onCreateAssistant, setActiveAssistant, setActiveAgentId }) => {
|
||||
const { t } = useTranslation()
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false)
|
||||
const { isOpen: isAgentModalOpen, onOpen: onAgentModalOpen, onClose: onAgentModalClose } = useDisclosure()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
const handleAddAssistant = () => {
|
||||
setIsPopoverOpen(false)
|
||||
onCreateAssistant()
|
||||
}
|
||||
|
||||
const handleAddAgent = () => {
|
||||
setIsPopoverOpen(false)
|
||||
onAgentModalOpen()
|
||||
const handleAddButtonClick = () => {
|
||||
AddAssistantOrAgentPopup.show({
|
||||
onSelect: (type) => {
|
||||
if (type === 'assistant') {
|
||||
onCreateAssistant()
|
||||
} else if (type === 'agent') {
|
||||
onAgentModalOpen()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const afterCreate = useCallback(
|
||||
@ -59,32 +60,9 @@ const UnifiedAddButton: FC<UnifiedAddButtonProps> = ({ onCreateAssistant, setAct
|
||||
|
||||
return (
|
||||
<div className="mb-1">
|
||||
<Popover
|
||||
isOpen={isPopoverOpen}
|
||||
onOpenChange={setIsPopoverOpen}
|
||||
placement="bottom"
|
||||
classNames={{ content: 'p-0 min-w-[200px]' }}>
|
||||
<PopoverTrigger>
|
||||
<AddButton>{t('chat.add.assistant.title')}</AddButton>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<div className="flex w-full flex-col gap-1 p-1">
|
||||
<Button
|
||||
onClick={handleAddAssistant}
|
||||
className="w-full justify-start bg-transparent hover:bg-[var(--color-list-item)]"
|
||||
startContent={<MessageSquare size={16} className="shrink-0" />}>
|
||||
{t('chat.add.assistant.title')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleAddAgent}
|
||||
className="w-full justify-start bg-transparent hover:bg-[var(--color-list-item)]"
|
||||
startContent={<Bot size={16} className="shrink-0" />}>
|
||||
{t('agent.add.title')}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
<AddButton onClick={handleAddButtonClick} className="-mt-[1px] mb-[2px]">
|
||||
{t('chat.add.assistant.title')}
|
||||
</AddButton>
|
||||
<AgentModal isOpen={isAgentModalOpen} onClose={onAgentModalClose} afterSubmit={afterCreate} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -717,10 +717,17 @@ const NotesPage: FC = () => {
|
||||
const normalizedActivePath = activeFilePath ? normalizePathValue(activeFilePath) : undefined
|
||||
if (normalizedActivePath) {
|
||||
if (normalizedActivePath === sourceNode.externalPath) {
|
||||
// Cancel debounced save to prevent saving to old path
|
||||
debouncedSaveRef.current?.cancel()
|
||||
lastFilePathRef.current = destinationPath
|
||||
dispatch(setActiveFilePath(destinationPath))
|
||||
} else if (sourceNode.type === 'folder' && normalizedActivePath.startsWith(`${sourceNode.externalPath}/`)) {
|
||||
const suffix = normalizedActivePath.slice(sourceNode.externalPath.length)
|
||||
dispatch(setActiveFilePath(`${destinationPath}${suffix}`))
|
||||
const newActivePath = `${destinationPath}${suffix}`
|
||||
// Cancel debounced save to prevent saving to old path
|
||||
debouncedSaveRef.current?.cancel()
|
||||
lastFilePathRef.current = newActivePath
|
||||
dispatch(setActiveFilePath(newActivePath))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ import { ThemeMode } from '@shared/data/preference/preferenceTypes'
|
||||
import { Progress, Row, Tag } from 'antd'
|
||||
import type { UpdateInfo } from 'builder-util-runtime'
|
||||
import { debounce } from 'lodash'
|
||||
import { Bug, FileCheck, Globe, Mail, Rss } from 'lucide-react'
|
||||
import { Bug, Building2, Github, Globe, Mail, Rss } from 'lucide-react'
|
||||
import { BadgeQuestionMark } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
@ -90,14 +90,8 @@ const AboutSettings: FC = () => {
|
||||
await window.api.devTools.toggle()
|
||||
}
|
||||
|
||||
const showLicense = async () => {
|
||||
const { appPath } = await window.api.getAppInfo()
|
||||
openSmartMinapp({
|
||||
id: 'cherrystudio-license',
|
||||
name: t('settings.about.license.title'),
|
||||
url: `file://${appPath}/resources/cherry-studio/license.html`,
|
||||
logo: AppLogo
|
||||
})
|
||||
const showEnterprise = async () => {
|
||||
onOpenWebsite('https://cherry-ai.com/enterprise')
|
||||
}
|
||||
|
||||
const showReleases = async () => {
|
||||
@ -315,7 +309,7 @@ const AboutSettings: FC = () => {
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>
|
||||
<GithubOutlined size={18} />
|
||||
<Github size={18} />
|
||||
{t('settings.about.feedback.title')}
|
||||
</SettingRowTitle>
|
||||
<Button onClick={() => onOpenWebsite('https://github.com/CherryHQ/cherry-studio/issues/new/choose')}>
|
||||
@ -325,10 +319,10 @@ const AboutSettings: FC = () => {
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitle>
|
||||
<FileCheck size={18} />
|
||||
{t('settings.about.license.title')}
|
||||
<Building2 size={18} />
|
||||
{t('settings.about.enterprise.title')}
|
||||
</SettingRowTitle>
|
||||
<Button onClick={showLicense}>{t('settings.about.license.button')}</Button>
|
||||
<Button onClick={showEnterprise}>{t('settings.about.website.button')}</Button>
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
|
||||
@ -55,7 +55,7 @@ const PluginSettings: FC<PluginSettingsProps> = ({ agentBase }) => {
|
||||
)
|
||||
|
||||
return (
|
||||
<SettingsContainer>
|
||||
<SettingsContainer className="pr-0">
|
||||
<Tabs
|
||||
aria-label="Plugin settings tabs"
|
||||
classNames={{
|
||||
@ -64,7 +64,7 @@ const PluginSettings: FC<PluginSettingsProps> = ({ agentBase }) => {
|
||||
panel: 'w-full flex-1 overflow-hidden'
|
||||
}}>
|
||||
<Tab key="available" title={t('agent.settings.plugins.available.title')}>
|
||||
<div className="flex h-full flex-col overflow-y-auto pt-4">
|
||||
<div className="flex h-full flex-col overflow-y-auto pt-1 pr-2">
|
||||
{errorAvailable ? (
|
||||
<Card className="bg-danger-50 dark:bg-danger-900/20">
|
||||
<CardBody>
|
||||
@ -89,7 +89,7 @@ const PluginSettings: FC<PluginSettingsProps> = ({ agentBase }) => {
|
||||
</Tab>
|
||||
|
||||
<Tab key="installed" title={t('agent.settings.plugins.installed.title')}>
|
||||
<div className="flex h-full flex-col overflow-y-auto pt-4">
|
||||
<div className="flex h-full flex-col overflow-y-auto pt-4 pr-2">
|
||||
{errorInstalled ? (
|
||||
<Card className="bg-danger-50 dark:bg-danger-900/20">
|
||||
<CardBody>
|
||||
|
||||
@ -169,6 +169,7 @@ export const ToolingSettings: FC<AgentToolingSettingsProps> = ({ agentBase, upda
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
centered: true,
|
||||
okText: t('common.confirm'),
|
||||
cancelText: t('common.cancel'),
|
||||
onOk: applyChange,
|
||||
@ -275,9 +276,10 @@ export const ToolingSettings: FC<AgentToolingSettingsProps> = ({ agentBase, upda
|
||||
key={card.mode}
|
||||
isPressable={!disabled}
|
||||
isDisabled={disabled || isUpdatingMode}
|
||||
shadow="none"
|
||||
onPress={() => handleSelectPermissionMode(card.mode)}
|
||||
className={`border ${
|
||||
isSelected ? 'border-primary shadow-lg' : 'border-default-200'
|
||||
isSelected ? 'border-primary' : 'border-default-200'
|
||||
} ${disabled ? 'opacity-60' : ''}`}>
|
||||
<CardHeader className="flex items-start justify-between gap-2">
|
||||
<div className="flex flex-col">
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
import { Chip } from '@heroui/react'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export interface CategoryFilterProps {
|
||||
categories: string[]
|
||||
selectedCategories: string[]
|
||||
onChange: (categories: string[]) => void
|
||||
}
|
||||
|
||||
export const CategoryFilter: FC<CategoryFilterProps> = ({ categories, selectedCategories, onChange }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const isAllSelected = selectedCategories.length === 0
|
||||
|
||||
const handleCategoryClick = (category: string) => {
|
||||
if (selectedCategories.includes(category)) {
|
||||
onChange(selectedCategories.filter((c) => c !== category))
|
||||
} else {
|
||||
onChange([...selectedCategories, category])
|
||||
}
|
||||
}
|
||||
|
||||
const handleAllClick = () => {
|
||||
onChange([])
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex max-h-24 flex-wrap gap-2 overflow-y-auto">
|
||||
<Chip
|
||||
variant={isAllSelected ? 'solid' : 'bordered'}
|
||||
color={isAllSelected ? 'primary' : 'default'}
|
||||
onClick={handleAllClick}
|
||||
className="cursor-pointer">
|
||||
{t('plugins.all_categories')}
|
||||
</Chip>
|
||||
|
||||
{categories.map((category) => {
|
||||
const isSelected = selectedCategories.includes(category)
|
||||
return (
|
||||
<Chip
|
||||
key={category}
|
||||
variant={isSelected ? 'solid' : 'bordered'}
|
||||
color={isSelected ? 'primary' : 'default'}
|
||||
onClick={() => handleCategoryClick(category)}
|
||||
className="cursor-pointer">
|
||||
{category}
|
||||
</Chip>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -56,7 +56,7 @@ export const InstalledPluginsList: FC<InstalledPluginsListProps> = ({ plugins, o
|
||||
<TableColumn>{t('plugins.name')}</TableColumn>
|
||||
<TableColumn>{t('plugins.type')}</TableColumn>
|
||||
<TableColumn>{t('plugins.category')}</TableColumn>
|
||||
<TableColumn width={100}>{t('plugins.actions')}</TableColumn>
|
||||
<TableColumn align="end">{t('plugins.actions')}</TableColumn>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{plugins.map((plugin) => (
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { Input, Pagination, Tab, Tabs } from '@heroui/react'
|
||||
import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Input, Tab, Tabs } from '@heroui/react'
|
||||
import type { InstalledPlugin, PluginMetadata } from '@renderer/types/plugin'
|
||||
import { Search } from 'lucide-react'
|
||||
import { Filter, Search } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { CategoryFilter } from './CategoryFilter'
|
||||
import { PluginCard } from './PluginCard'
|
||||
import { PluginDetailModal } from './PluginDetailModal'
|
||||
|
||||
@ -38,10 +37,11 @@ export const PluginBrowser: FC<PluginBrowserProps> = ({
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [selectedCategories, setSelectedCategories] = useState<string[]>([])
|
||||
const [activeType, setActiveType] = useState<PluginType>('all')
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [displayCount, setDisplayCount] = useState(ITEMS_PER_PAGE)
|
||||
const [actioningPlugin, setActioningPlugin] = useState<string | null>(null)
|
||||
const [selectedPlugin, setSelectedPlugin] = useState<PluginMetadata | null>(null)
|
||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
||||
const observerTarget = useRef<HTMLDivElement>(null)
|
||||
|
||||
// Combine all plugins based on active type
|
||||
const allPlugins = useMemo(() => {
|
||||
@ -87,14 +87,35 @@ export const PluginBrowser: FC<PluginBrowserProps> = ({
|
||||
})
|
||||
}, [allPlugins, searchQuery, selectedCategories])
|
||||
|
||||
// Paginate filtered plugins
|
||||
const paginatedPlugins = useMemo(() => {
|
||||
const startIndex = (currentPage - 1) * ITEMS_PER_PAGE
|
||||
const endIndex = startIndex + ITEMS_PER_PAGE
|
||||
return filteredPlugins.slice(startIndex, endIndex)
|
||||
}, [filteredPlugins, currentPage])
|
||||
// Display plugins based on displayCount
|
||||
const displayedPlugins = useMemo(() => {
|
||||
return filteredPlugins.slice(0, displayCount)
|
||||
}, [filteredPlugins, displayCount])
|
||||
|
||||
const totalPages = Math.ceil(filteredPlugins.length / ITEMS_PER_PAGE)
|
||||
const hasMore = displayCount < filteredPlugins.length
|
||||
|
||||
// Reset display count when filters change
|
||||
useEffect(() => {
|
||||
setDisplayCount(ITEMS_PER_PAGE)
|
||||
}, [filteredPlugins])
|
||||
|
||||
// Infinite scroll observer
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting && hasMore) {
|
||||
setDisplayCount((prev) => prev + ITEMS_PER_PAGE)
|
||||
}
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
)
|
||||
|
||||
if (observerTarget.current) {
|
||||
observer.observe(observerTarget.current)
|
||||
}
|
||||
|
||||
return () => observer.disconnect()
|
||||
}, [hasMore])
|
||||
|
||||
// Check if a plugin is installed
|
||||
const isPluginInstalled = (plugin: PluginMetadata): boolean => {
|
||||
@ -117,20 +138,22 @@ export const PluginBrowser: FC<PluginBrowserProps> = ({
|
||||
setActioningPlugin(null)
|
||||
}
|
||||
|
||||
// Reset to first page when filters change
|
||||
// Reset display count when filters change
|
||||
const handleSearchChange = (value: string) => {
|
||||
setSearchQuery(value)
|
||||
setCurrentPage(1)
|
||||
}
|
||||
|
||||
const handleCategoryChange = (categories: string[]) => {
|
||||
setSelectedCategories(categories)
|
||||
setCurrentPage(1)
|
||||
const handleCategoryChange = (keys: Set<string>) => {
|
||||
// Reset if "all" selected, otherwise filter categories
|
||||
if (keys.has('all') || keys.size === 0) {
|
||||
setSelectedCategories([])
|
||||
} else {
|
||||
setSelectedCategories(Array.from(keys).filter((key) => key !== 'all'))
|
||||
}
|
||||
}
|
||||
|
||||
const handleTypeChange = (type: string | number) => {
|
||||
setActiveType(type as PluginType)
|
||||
setCurrentPage(1)
|
||||
}
|
||||
|
||||
const handlePluginClick = (plugin: PluginMetadata) => {
|
||||
@ -145,33 +168,76 @@ export const PluginBrowser: FC<PluginBrowserProps> = ({
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Search Input */}
|
||||
<Input
|
||||
placeholder={t('plugins.search_placeholder')}
|
||||
value={searchQuery}
|
||||
onValueChange={handleSearchChange}
|
||||
startContent={<Search className="h-4 w-4 text-default-400" />}
|
||||
isClearable
|
||||
classNames={{
|
||||
input: 'text-small',
|
||||
inputWrapper: 'h-10'
|
||||
}}
|
||||
/>
|
||||
{/* Search and Filter */}
|
||||
<div className="relative flex gap-0">
|
||||
<Input
|
||||
placeholder={t('plugins.search_placeholder')}
|
||||
value={searchQuery}
|
||||
onValueChange={handleSearchChange}
|
||||
startContent={<Search className="h-4 w-4 text-default-400" />}
|
||||
isClearable
|
||||
size="md"
|
||||
className="flex-1"
|
||||
classNames={{
|
||||
inputWrapper: 'pr-12'
|
||||
}}
|
||||
/>
|
||||
<Dropdown placement="bottom-end" classNames={{ content: 'max-h-60 overflow-y-auto p-0' }}>
|
||||
<DropdownTrigger>
|
||||
<Button
|
||||
isIconOnly
|
||||
variant={selectedCategories.length > 0 ? 'flat' : 'light'}
|
||||
color={selectedCategories.length > 0 ? 'primary' : 'default'}
|
||||
size="sm"
|
||||
className="-translate-y-1/2 absolute top-1/2 right-2 z-10">
|
||||
<Filter className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu
|
||||
aria-label="Category filter"
|
||||
closeOnSelect={false}
|
||||
className="max-h-60 overflow-y-auto"
|
||||
items={[
|
||||
{ key: 'all', label: t('plugins.all_categories') },
|
||||
...allCategories.map((category) => ({ key: category, label: category }))
|
||||
]}>
|
||||
{(item) => {
|
||||
const isSelected =
|
||||
item.key === 'all' ? selectedCategories.length === 0 : selectedCategories.includes(item.key)
|
||||
|
||||
{/* Category Filter */}
|
||||
<CategoryFilter
|
||||
categories={allCategories}
|
||||
selectedCategories={selectedCategories}
|
||||
onChange={handleCategoryChange}
|
||||
/>
|
||||
return (
|
||||
<DropdownItem
|
||||
key={item.key}
|
||||
textValue={item.label}
|
||||
onPress={() => {
|
||||
if (item.key === 'all') {
|
||||
handleCategoryChange(new Set(['all']))
|
||||
} else {
|
||||
const newKeys = selectedCategories.includes(item.key)
|
||||
? new Set(selectedCategories.filter((c) => c !== item.key))
|
||||
: new Set([...selectedCategories, item.key])
|
||||
handleCategoryChange(newKeys)
|
||||
}
|
||||
}}
|
||||
className={isSelected ? 'bg-primary-50' : ''}>
|
||||
{item.label}
|
||||
{isSelected && <span className="ml-2 text-primary text-sm">✓</span>}
|
||||
</DropdownItem>
|
||||
)
|
||||
}}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
{/* Type Tabs */}
|
||||
<Tabs selectedKey={activeType} onSelectionChange={handleTypeChange} variant="underlined">
|
||||
<Tab key="all" title={t('plugins.all_types')} />
|
||||
<Tab key="agent" title={t('plugins.agents')} />
|
||||
<Tab key="command" title={t('plugins.commands')} />
|
||||
<Tab key="skill" title={t('plugins.skills')} />
|
||||
</Tabs>
|
||||
<div className="-mt-3 flex justify-center">
|
||||
<Tabs selectedKey={activeType} onSelectionChange={handleTypeChange} variant="underlined">
|
||||
<Tab key="all" title={t('plugins.all_types')} />
|
||||
<Tab key="agent" title={t('plugins.agents')} />
|
||||
<Tab key="command" title={t('plugins.commands')} />
|
||||
<Tab key="skill" title={t('plugins.skills')} />
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
{/* Result Count */}
|
||||
<div className="flex items-center justify-between">
|
||||
@ -179,37 +245,35 @@ export const PluginBrowser: FC<PluginBrowserProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Plugin Grid */}
|
||||
{paginatedPlugins.length === 0 ? (
|
||||
{displayedPlugins.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center py-12 text-center">
|
||||
<p className="text-default-400">{t('plugins.no_results')}</p>
|
||||
<p className="text-default-300 text-small">{t('plugins.try_different_search')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{paginatedPlugins.map((plugin) => {
|
||||
const installed = isPluginInstalled(plugin)
|
||||
const isActioning = actioningPlugin === plugin.sourcePath
|
||||
<>
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
{displayedPlugins.map((plugin) => {
|
||||
const installed = isPluginInstalled(plugin)
|
||||
const isActioning = actioningPlugin === plugin.sourcePath
|
||||
|
||||
return (
|
||||
<PluginCard
|
||||
key={`${plugin.type}-${plugin.sourcePath}`}
|
||||
plugin={plugin}
|
||||
installed={installed}
|
||||
onInstall={() => handleInstall(plugin)}
|
||||
onUninstall={() => handleUninstall(plugin)}
|
||||
loading={loading || isActioning}
|
||||
onClick={() => handlePluginClick(plugin)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Pagination */}
|
||||
{totalPages > 1 && (
|
||||
<div className="flex justify-center">
|
||||
<Pagination total={totalPages} page={currentPage} onChange={setCurrentPage} showControls />
|
||||
</div>
|
||||
return (
|
||||
<div key={`${plugin.type}-${plugin.sourcePath}`} className="h-full">
|
||||
<PluginCard
|
||||
plugin={plugin}
|
||||
installed={installed}
|
||||
onInstall={() => handleInstall(plugin)}
|
||||
onUninstall={() => handleUninstall(plugin)}
|
||||
loading={loading || isActioning}
|
||||
onClick={() => handlePluginClick(plugin)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{/* Infinite scroll trigger */}
|
||||
{hasMore && <div ref={observerTarget} className="h-10" />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Plugin Detail Modal */}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Button, Card, CardBody, CardFooter, CardHeader, Chip, Spinner } from '@heroui/react'
|
||||
import type { PluginMetadata } from '@renderer/types/plugin'
|
||||
import { upperFirst } from 'lodash'
|
||||
import { Download, Trash2 } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -17,15 +18,20 @@ export const PluginCard: FC<PluginCardProps> = ({ plugin, installed, onInstall,
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Card className="w-full cursor-pointer transition-shadow hover:shadow-md" isPressable onPress={onClick}>
|
||||
<Card
|
||||
className="flex h-full w-full cursor-pointer flex-col border-[0.5px] border-default-200"
|
||||
isPressable
|
||||
shadow="none"
|
||||
onPress={onClick}>
|
||||
<CardHeader className="flex flex-col items-start gap-2 pb-2">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<h3 className="font-semibold text-medium">{plugin.name}</h3>
|
||||
<div className="flex w-full items-center justify-between gap-2">
|
||||
<h3 className="truncate font-medium text-small">{plugin.name}</h3>
|
||||
<Chip
|
||||
size="sm"
|
||||
variant="solid"
|
||||
color={plugin.type === 'agent' ? 'primary' : plugin.type === 'skill' ? 'success' : 'secondary'}>
|
||||
{plugin.type}
|
||||
color={plugin.type === 'agent' ? 'primary' : plugin.type === 'skill' ? 'success' : 'secondary'}
|
||||
className="h-4 min-w-0 flex-shrink-0 px-0.5 text-xs">
|
||||
{upperFirst(plugin.type)}
|
||||
</Chip>
|
||||
</div>
|
||||
<Chip size="sm" variant="dot" color="default">
|
||||
@ -33,7 +39,7 @@ export const PluginCard: FC<PluginCardProps> = ({ plugin, installed, onInstall,
|
||||
</Chip>
|
||||
</CardHeader>
|
||||
|
||||
<CardBody className="py-2">
|
||||
<CardBody className="flex-1 py-2">
|
||||
<p className="line-clamp-3 text-default-500 text-small">{plugin.description || t('plugins.no_description')}</p>
|
||||
|
||||
{plugin.tags && plugin.tags.length > 0 && (
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
export type { CategoryFilterProps } from './CategoryFilter'
|
||||
export { CategoryFilter } from './CategoryFilter'
|
||||
export type { InstalledPluginsListProps } from './InstalledPluginsList'
|
||||
export { InstalledPluginsList } from './InstalledPluginsList'
|
||||
export type { PluginBrowserProps } from './PluginBrowser'
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { loggerService } from '@logger'
|
||||
import type { Span } from '@opentelemetry/api'
|
||||
import AiProvider from '@renderer/aiCore'
|
||||
import { ModernAiProvider } from '@renderer/aiCore'
|
||||
import AiProvider from '@renderer/aiCore/legacy'
|
||||
import { DEFAULT_KNOWLEDGE_DOCUMENT_COUNT, DEFAULT_KNOWLEDGE_THRESHOLD } from '@renderer/config/constant'
|
||||
import { getEmbeddingMaxContext } from '@renderer/config/embedings'
|
||||
import { isGeminiProvider } from '@renderer/config/providers'
|
||||
import { isAzureOpenAIProvider, isGeminiProvider } from '@renderer/config/providers'
|
||||
import { addSpan, endSpan } from '@renderer/services/SpanManagerService'
|
||||
import store from '@renderer/store'
|
||||
import type {
|
||||
@ -15,6 +16,7 @@ import type {
|
||||
} from '@renderer/types'
|
||||
import type { Chunk } from '@renderer/types/chunk'
|
||||
import { ChunkType } from '@renderer/types/chunk'
|
||||
import { routeToEndpoint } from '@renderer/utils'
|
||||
import type { ExtractResults } from '@renderer/utils/extract'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
@ -24,9 +26,8 @@ import FileManager from './FileManager'
|
||||
const logger = loggerService.withContext('RendererKnowledgeService')
|
||||
|
||||
export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams => {
|
||||
const provider = getProviderByModel(base.model)
|
||||
const rerankProvider = getProviderByModel(base.rerankModel)
|
||||
const aiProvider = new AiProvider(provider)
|
||||
const aiProvider = new ModernAiProvider(base.model)
|
||||
const rerankAiProvider = new AiProvider(rerankProvider)
|
||||
|
||||
// get preprocess provider from store instead of base.preprocessProvider
|
||||
@ -40,12 +41,19 @@ export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams
|
||||
}
|
||||
: base.preprocessProvider
|
||||
|
||||
let host = aiProvider.getBaseURL()
|
||||
const actualProvider = aiProvider.getActualProvider()
|
||||
|
||||
let { baseURL } = routeToEndpoint(actualProvider.apiHost)
|
||||
|
||||
const rerankHost = rerankAiProvider.getBaseURL()
|
||||
if (isGeminiProvider(provider)) {
|
||||
host = host + '/v1beta/openai/'
|
||||
if (isGeminiProvider(actualProvider)) {
|
||||
baseURL = baseURL + '/openai'
|
||||
} else if (isAzureOpenAIProvider(actualProvider)) {
|
||||
baseURL = baseURL + '/v1'
|
||||
}
|
||||
|
||||
logger.info(`Knowledge base ${base.name} using baseURL: ${baseURL}`)
|
||||
|
||||
let chunkSize = base.chunkSize
|
||||
const maxChunkSize = getEmbeddingMaxContext(base.model.id)
|
||||
|
||||
@ -65,8 +73,7 @@ export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams
|
||||
model: base.model.id,
|
||||
provider: base.model.provider,
|
||||
apiKey: aiProvider.getApiKey() || 'secret',
|
||||
apiVersion: provider.apiVersion,
|
||||
baseURL: host
|
||||
baseURL
|
||||
},
|
||||
chunkSize,
|
||||
chunkOverlap: base.chunkOverlap,
|
||||
|
||||
429
yarn.lock
429
yarn.lock
@ -2801,7 +2801,7 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@cherrystudio/openai@npm:^6.5.0, openai@npm:@cherrystudio/openai@6.5.0":
|
||||
"@cherrystudio/openai@npm:^6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@cherrystudio/openai@npm:6.5.0"
|
||||
peerDependencies:
|
||||
@ -4286,39 +4286,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@graphql-typed-document-node/core@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "@graphql-typed-document-node/core@npm:3.2.0"
|
||||
peerDependencies:
|
||||
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
|
||||
checksum: 10c0/94e9d75c1f178bbae8d874f5a9361708a3350c8def7eaeb6920f2c820e82403b7d4f55b3735856d68e145e86c85cbfe2adc444fdc25519cd51f108697e99346c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@grpc/grpc-js@npm:^1.13.1":
|
||||
version: 1.13.4
|
||||
resolution: "@grpc/grpc-js@npm:1.13.4"
|
||||
dependencies:
|
||||
"@grpc/proto-loader": "npm:^0.7.13"
|
||||
"@js-sdsl/ordered-map": "npm:^4.4.2"
|
||||
checksum: 10c0/ecdb99efbe540d8b261ca53e4be224fb4683fb22c6ab1b575d2f4ca34471fc7f221b58f718001a6d157c54237cc482514766233968f5de50e358f061600a885b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@grpc/proto-loader@npm:^0.7.13":
|
||||
version: 0.7.15
|
||||
resolution: "@grpc/proto-loader@npm:0.7.15"
|
||||
dependencies:
|
||||
lodash.camelcase: "npm:^4.3.0"
|
||||
long: "npm:^5.0.0"
|
||||
protobufjs: "npm:^7.2.5"
|
||||
yargs: "npm:^17.7.2"
|
||||
bin:
|
||||
proto-loader-gen-types: build/bin/proto-loader-gen-types.js
|
||||
checksum: 10c0/514a134a724b56d73d0a202b7e02c84479da21e364547bacb2f4995ebc0d52412a1a21653add9f004ebd146c1e6eb4bcb0b8846fdfe1bfa8a98ed8f3d203da4a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@hello-pangea/dnd@npm:^18.0.1":
|
||||
version: 18.0.1
|
||||
resolution: "@hello-pangea/dnd@npm:18.0.1"
|
||||
@ -7497,13 +7464,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@js-sdsl/ordered-map@npm:^4.4.2":
|
||||
version: 4.4.2
|
||||
resolution: "@js-sdsl/ordered-map@npm:4.4.2"
|
||||
checksum: 10c0/cc7e15dc4acf6d9ef663757279600bab70533d847dcc1ab01332e9e680bd30b77cdf9ad885cc774276f51d98b05a013571c940e5b360985af5eb798dc1a2ee2b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@jsdevtools/ono@npm:^7.1.3":
|
||||
version: 7.1.3
|
||||
resolution: "@jsdevtools/ono@npm:7.1.3"
|
||||
@ -7511,27 +7471,56 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/community@npm:^0.3.50":
|
||||
version: 0.3.54
|
||||
resolution: "@langchain/community@npm:0.3.54"
|
||||
"@langchain/classic@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@langchain/classic@npm:1.0.0"
|
||||
dependencies:
|
||||
"@langchain/openai": "npm:>=0.2.0 <0.7.0"
|
||||
"@langchain/weaviate": "npm:^0.2.0"
|
||||
"@langchain/openai": "npm:1.0.0-alpha.3"
|
||||
"@langchain/textsplitters": "npm:1.0.0"
|
||||
handlebars: "npm:^4.7.8"
|
||||
js-yaml: "npm:^4.1.0"
|
||||
jsonpointer: "npm:^5.0.1"
|
||||
langsmith: "npm:^0.3.64"
|
||||
openapi-types: "npm:^12.1.3"
|
||||
p-retry: "npm:4"
|
||||
uuid: "npm:^10.0.0"
|
||||
yaml: "npm:^2.2.1"
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
peerDependencies:
|
||||
"@langchain/core": ^1.0.0
|
||||
cheerio: "*"
|
||||
peggy: ^3.0.2
|
||||
typeorm: "*"
|
||||
dependenciesMeta:
|
||||
langsmith:
|
||||
optional: true
|
||||
peerDependenciesMeta:
|
||||
cheerio:
|
||||
optional: true
|
||||
peggy:
|
||||
optional: true
|
||||
typeorm:
|
||||
optional: true
|
||||
checksum: 10c0/5d222a0dcd5faa9c0c520a79e8852403f6d4c8ecc34d48a3aaeec6965e68be3b02aae97c91a3ffea0c99114884bd1cbf48551bbb8c5cd71811685778a8ac30d8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/community@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@langchain/community@npm:1.0.0"
|
||||
dependencies:
|
||||
"@langchain/classic": "npm:1.0.0"
|
||||
"@langchain/openai": "npm:1.0.0"
|
||||
binary-extensions: "npm:^2.2.0"
|
||||
expr-eval: "npm:^2.0.2"
|
||||
flat: "npm:^5.0.2"
|
||||
js-yaml: "npm:^4.1.0"
|
||||
langchain: "npm:>=0.2.3 <0.3.0 || >=0.3.4 <0.4.0"
|
||||
langsmith: "npm:^0.3.46"
|
||||
uuid: "npm:^10.0.0"
|
||||
zod: "npm:^3.25.32"
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
peerDependencies:
|
||||
"@arcjet/redact": ^v1.0.0-alpha.23
|
||||
"@aws-crypto/sha256-js": ^5.0.0
|
||||
"@aws-sdk/client-bedrock-agent-runtime": ^3.749.0
|
||||
"@aws-sdk/client-bedrock-runtime": ^3.749.0
|
||||
"@aws-sdk/client-dynamodb": ^3.749.0
|
||||
"@aws-sdk/client-kendra": ^3.749.0
|
||||
"@aws-sdk/client-lambda": ^3.749.0
|
||||
"@aws-sdk/client-s3": ^3.749.0
|
||||
"@aws-sdk/client-sagemaker-runtime": ^3.749.0
|
||||
@ -7542,22 +7531,19 @@ __metadata:
|
||||
"@browserbasehq/sdk": "*"
|
||||
"@browserbasehq/stagehand": ^1.0.0
|
||||
"@clickhouse/client": ^0.2.5
|
||||
"@cloudflare/ai": "*"
|
||||
"@datastax/astra-db-ts": ^1.0.0
|
||||
"@elastic/elasticsearch": ^8.4.0
|
||||
"@getmetal/metal-sdk": "*"
|
||||
"@getzep/zep-cloud": ^1.0.6
|
||||
"@getzep/zep-js": ^0.9.0
|
||||
"@gomomento/sdk": ^1.51.1
|
||||
"@gomomento/sdk-core": ^1.51.1
|
||||
"@google-ai/generativelanguage": "*"
|
||||
"@google-cloud/storage": ^6.10.1 || ^7.7.0
|
||||
"@gradientai/nodejs-sdk": ^1.2.0
|
||||
"@huggingface/inference": ^4.0.5
|
||||
"@huggingface/transformers": ^3.5.2
|
||||
"@ibm-cloud/watsonx-ai": "*"
|
||||
"@lancedb/lancedb": ^0.12.0
|
||||
"@langchain/core": ">=0.3.58 <0.4.0"
|
||||
"@lancedb/lancedb": ^0.19.1
|
||||
"@langchain/core": ^1.0.0
|
||||
"@layerup/layerup-security": ^1.5.12
|
||||
"@libsql/client": ^0.14.0
|
||||
"@mendable/firecrawl-js": ^1.4.3
|
||||
@ -7566,10 +7552,8 @@ __metadata:
|
||||
"@neondatabase/serverless": "*"
|
||||
"@notionhq/client": ^2.2.10
|
||||
"@opensearch-project/opensearch": "*"
|
||||
"@pinecone-database/pinecone": "*"
|
||||
"@planetscale/database": ^1.8.0
|
||||
"@premai/prem-sdk": ^0.3.25
|
||||
"@qdrant/js-client-rest": ^1.15.0
|
||||
"@raycast/api": ^1.55.2
|
||||
"@rockset/client": ^0.9.1
|
||||
"@smithy/eventstream-codec": ^2.0.5
|
||||
@ -7579,7 +7563,6 @@ __metadata:
|
||||
"@spider-cloud/spider-client": ^0.0.21
|
||||
"@supabase/supabase-js": ^2.45.0
|
||||
"@tensorflow-models/universal-sentence-encoder": "*"
|
||||
"@tensorflow/tfjs-converter": "*"
|
||||
"@tensorflow/tfjs-core": "*"
|
||||
"@upstash/ratelimit": ^1.1.3 || ^2.0.3
|
||||
"@upstash/redis": ^1.20.6
|
||||
@ -7600,16 +7583,15 @@ __metadata:
|
||||
closevector-common: 0.1.3
|
||||
closevector-node: 0.1.6
|
||||
closevector-web: 0.1.6
|
||||
cohere-ai: "*"
|
||||
convex: ^1.3.1
|
||||
crypto-js: ^4.2.0
|
||||
d3-dsv: ^2.0.0
|
||||
discord.js: ^14.14.1
|
||||
dria: ^0.0.3
|
||||
duck-duck-scrape: ^2.2.5
|
||||
epub2: ^3.0.1
|
||||
faiss-node: "*"
|
||||
fast-xml-parser: "*"
|
||||
firebase-admin: ^11.9.0 || ^12.0.0
|
||||
firebase-admin: ^11.9.0 || ^12.0.0 || ^13.0.0
|
||||
google-auth-library: "*"
|
||||
googleapis: "*"
|
||||
hnswlib-node: ^3.0.0
|
||||
@ -7621,15 +7603,14 @@ __metadata:
|
||||
it-all: ^3.0.4
|
||||
jsdom: "*"
|
||||
jsonwebtoken: ^9.0.2
|
||||
llmonitor: ^0.5.9
|
||||
lodash: ^4.17.21
|
||||
lunary: ^0.7.10
|
||||
mammoth: ^1.6.0
|
||||
mariadb: ^3.4.0
|
||||
mem0ai: ^2.1.8
|
||||
mongodb: ^6.17.0
|
||||
mysql2: ^3.9.8
|
||||
neo4j-driver: "*"
|
||||
node-llama-cpp: ">=3.0.0"
|
||||
notion-to-md: ^3.1.0
|
||||
officeparser: ^4.0.4
|
||||
openai: "*"
|
||||
@ -7641,7 +7622,6 @@ __metadata:
|
||||
portkey-ai: ^0.1.11
|
||||
puppeteer: "*"
|
||||
pyodide: ">=0.24.1 <0.27.0"
|
||||
redis: "*"
|
||||
replicate: "*"
|
||||
sonix-speech-recognition: ^2.1.1
|
||||
srt-parser-2: ^1.2.3
|
||||
@ -7649,8 +7629,6 @@ __metadata:
|
||||
typesense: ^1.5.3
|
||||
usearch: ^1.1.1
|
||||
voy-search: 0.6.2
|
||||
weaviate-client: ^3.5.2
|
||||
web-auth-library: ^1.0.3
|
||||
word-extractor: "*"
|
||||
ws: ^8.14.2
|
||||
youtubei.js: "*"
|
||||
@ -7659,14 +7637,8 @@ __metadata:
|
||||
optional: true
|
||||
"@aws-crypto/sha256-js":
|
||||
optional: true
|
||||
"@aws-sdk/client-bedrock-agent-runtime":
|
||||
optional: true
|
||||
"@aws-sdk/client-bedrock-runtime":
|
||||
optional: true
|
||||
"@aws-sdk/client-dynamodb":
|
||||
optional: true
|
||||
"@aws-sdk/client-kendra":
|
||||
optional: true
|
||||
"@aws-sdk/client-lambda":
|
||||
optional: true
|
||||
"@aws-sdk/client-s3":
|
||||
@ -7687,8 +7659,6 @@ __metadata:
|
||||
optional: true
|
||||
"@clickhouse/client":
|
||||
optional: true
|
||||
"@cloudflare/ai":
|
||||
optional: true
|
||||
"@datastax/astra-db-ts":
|
||||
optional: true
|
||||
"@elastic/elasticsearch":
|
||||
@ -7699,12 +7669,8 @@ __metadata:
|
||||
optional: true
|
||||
"@getzep/zep-js":
|
||||
optional: true
|
||||
"@gomomento/sdk":
|
||||
optional: true
|
||||
"@gomomento/sdk-core":
|
||||
optional: true
|
||||
"@google-ai/generativelanguage":
|
||||
optional: true
|
||||
"@google-cloud/storage":
|
||||
optional: true
|
||||
"@gradientai/nodejs-sdk":
|
||||
@ -7757,8 +7723,6 @@ __metadata:
|
||||
optional: true
|
||||
"@tensorflow-models/universal-sentence-encoder":
|
||||
optional: true
|
||||
"@tensorflow/tfjs-converter":
|
||||
optional: true
|
||||
"@tensorflow/tfjs-core":
|
||||
optional: true
|
||||
"@upstash/ratelimit":
|
||||
@ -7775,6 +7739,8 @@ __metadata:
|
||||
optional: true
|
||||
"@xata.io/client":
|
||||
optional: true
|
||||
"@xenova/transformers":
|
||||
optional: true
|
||||
"@zilliz/milvus2-sdk-node":
|
||||
optional: true
|
||||
apify-client:
|
||||
@ -7809,12 +7775,12 @@ __metadata:
|
||||
optional: true
|
||||
discord.js:
|
||||
optional: true
|
||||
dria:
|
||||
optional: true
|
||||
duck-duck-scrape:
|
||||
optional: true
|
||||
epub2:
|
||||
optional: true
|
||||
faiss-node:
|
||||
optional: true
|
||||
fast-xml-parser:
|
||||
optional: true
|
||||
firebase-admin:
|
||||
@ -7839,8 +7805,6 @@ __metadata:
|
||||
optional: true
|
||||
jsonwebtoken:
|
||||
optional: true
|
||||
llmonitor:
|
||||
optional: true
|
||||
lodash:
|
||||
optional: true
|
||||
lunary:
|
||||
@ -7857,6 +7821,8 @@ __metadata:
|
||||
optional: true
|
||||
neo4j-driver:
|
||||
optional: true
|
||||
node-llama-cpp:
|
||||
optional: true
|
||||
notion-to-md:
|
||||
optional: true
|
||||
officeparser:
|
||||
@ -7895,55 +7861,51 @@ __metadata:
|
||||
optional: true
|
||||
weaviate-client:
|
||||
optional: true
|
||||
web-auth-library:
|
||||
optional: true
|
||||
word-extractor:
|
||||
optional: true
|
||||
ws:
|
||||
optional: true
|
||||
youtubei.js:
|
||||
optional: true
|
||||
checksum: 10c0/17ba91662e644cde0b8ffa9d11d2c2de47e32b3567cee08628d316251f860f0ac874ec3b4f44012e0d93009b1779fbd514c6882fadac8c2368213b6578f59d88
|
||||
checksum: 10c0/b933e0afeb54267b41579e7b8590e9279a11bb1f7434a0357f437348a79ad74e24d7c0287e1e4db85e049ee72eb97150a3a1e2134c93cf74f82b783e36be4970
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/core@npm:0.3.44":
|
||||
version: 0.3.44
|
||||
resolution: "@langchain/core@npm:0.3.44"
|
||||
"@langchain/core@npm:1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "@langchain/core@npm:1.0.2"
|
||||
dependencies:
|
||||
"@cfworker/json-schema": "npm:^4.0.2"
|
||||
ansi-styles: "npm:^5.0.0"
|
||||
camelcase: "npm:6"
|
||||
decamelize: "npm:1.2.0"
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
langsmith: "npm:>=0.2.8 <0.4.0"
|
||||
langsmith: "npm:^0.3.64"
|
||||
mustache: "npm:^4.2.0"
|
||||
p-queue: "npm:^6.6.2"
|
||||
p-retry: "npm:4"
|
||||
uuid: "npm:^10.0.0"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
checksum: 10c0/fb8d7c5760419cc9d0a3ed4f04473e103c8a27031566ba0c89438879bbd66e3d8869349f943045e86ddb33c4e8db4ae59311a3aad45e832d273b0e7d7db3f939
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
checksum: 10c0/2ffa73615f6e2b98b9204e73b678f10b6d18c100d78481c8dbd4f628f5b934dd3f1b1f4de793d51d2e290aa65c07d7f903d6396ac8dc24d9ed219672157a6a09
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/core@patch:@langchain/core@npm%3A0.3.44#~/.yarn/patches/@langchain-core-npm-0.3.44-41d5c3cb0a.patch":
|
||||
version: 0.3.44
|
||||
resolution: "@langchain/core@patch:@langchain/core@npm%3A0.3.44#~/.yarn/patches/@langchain-core-npm-0.3.44-41d5c3cb0a.patch::version=0.3.44&hash=41dd7b"
|
||||
"@langchain/core@patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch":
|
||||
version: 1.0.2
|
||||
resolution: "@langchain/core@patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch::version=1.0.2&hash=95b174"
|
||||
dependencies:
|
||||
"@cfworker/json-schema": "npm:^4.0.2"
|
||||
ansi-styles: "npm:^5.0.0"
|
||||
camelcase: "npm:6"
|
||||
decamelize: "npm:1.2.0"
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
langsmith: "npm:>=0.2.8 <0.4.0"
|
||||
langsmith: "npm:^0.3.64"
|
||||
mustache: "npm:^4.2.0"
|
||||
p-queue: "npm:^6.6.2"
|
||||
p-retry: "npm:4"
|
||||
uuid: "npm:^10.0.0"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
checksum: 10c0/7002581999230bc6fbdb6c2fad0eda2c1ca93a7629e28eadf1501dd0a7f785010d6b3e7841148ced186fc0fb4a84ec5f3b75850985579610e222943cc57e1649
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
checksum: 10c0/c83e49ef2293c49821264ee81cc7bfaac3321289dae1b1553c929bd67ee361df2a0f3c950ac24a361916349c4d66f2db2ee5a6a509c6b8be288acebb06c17a89
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -7961,58 +7923,53 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/openai@npm:0.3.16":
|
||||
version: 0.3.16
|
||||
resolution: "@langchain/openai@npm:0.3.16"
|
||||
"@langchain/openai@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@langchain/openai@npm:1.0.0"
|
||||
dependencies:
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
openai: "npm:^4.77.0"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
openai: "npm:^6.3.0"
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.2.26 <0.4.0"
|
||||
checksum: 10c0/5955a02c09227d8d1d7feef26d3487cf151e2c3d36ec7550c4fe111179eb78de76befd1bd2df6a80ae4fc88676f5ebaa35d5d8788faab62972d82989ca18ec87
|
||||
"@langchain/core": ^1.0.0
|
||||
checksum: 10c0/788b6c996c19b7ff4a87b4005898f737d54998ce07aeab99225bd251cdfbb49a1b7a2f6340ce55f16ffb7566b3a050bb997866603a2b0acd5b22fff7910af2d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/openai@npm:>=0.1.0 <0.6.0":
|
||||
version: 0.5.5
|
||||
resolution: "@langchain/openai@npm:0.5.5"
|
||||
"@langchain/openai@npm:1.0.0-alpha.3":
|
||||
version: 1.0.0-alpha.3
|
||||
resolution: "@langchain/openai@npm:1.0.0-alpha.3"
|
||||
dependencies:
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
openai: "npm:^4.87.3"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
openai: "npm:^6.3.0"
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.3.39 <0.4.0"
|
||||
checksum: 10c0/475c040f473f9c9270e8130c86d480f68834af5723e7e9b761c60152cafe5bc162e87856a4c654b12d6fe8f0cf99b27247b3869e4c0c79797847263523e045d4
|
||||
"@langchain/core": ^1.0.0-alpha.6
|
||||
checksum: 10c0/e33abd68b3f22314dcf9256e500eb166d64476dd8f000314c237e94efef47e9889b29934f0dac816ec5834bb9848fe22ea715cd49efccc5363f224a9dc2965c4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/openai@npm:>=0.2.0 <0.7.0":
|
||||
version: 0.6.11
|
||||
resolution: "@langchain/openai@npm:0.6.11"
|
||||
"@langchain/openai@patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch":
|
||||
version: 1.0.0
|
||||
resolution: "@langchain/openai@patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch::version=1.0.0&hash=682dd3"
|
||||
dependencies:
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
openai: "npm:5.12.2"
|
||||
zod: "npm:^3.25.32"
|
||||
openai: "npm:^6.3.0"
|
||||
zod: "npm:^3.25.76 || ^4"
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.3.68 <0.4.0"
|
||||
checksum: 10c0/d95bc7f4f4a66c82f031800d1196d1e13a536b3f647480209d8432bb4d2ebfbc53dddb43d86e6d2de0f4d94050ca4b8002e50ab1813552faba24d4045c00feda
|
||||
"@langchain/core": ^1.0.0
|
||||
checksum: 10c0/93503a3322af417f2209923ecb01fb8f94946d0806007eacb94fd8b44fa4f2976e2ef84094b4e462b320886bcef8d59f12fa109c8bf654e2dd98dd9c8cd073be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/openai@patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch":
|
||||
version: 0.3.16
|
||||
resolution: "@langchain/openai@patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch::version=0.3.16&hash=642f39"
|
||||
"@langchain/textsplitters@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@langchain/textsplitters@npm:1.0.0"
|
||||
dependencies:
|
||||
js-tiktoken: "npm:^1.0.12"
|
||||
openai: "npm:^4.77.0"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.2.26 <0.4.0"
|
||||
checksum: 10c0/2106626e01e1865ad08b647d155bee86caf83620040a00d3406ec0a7d34650e393a7bbf7cfbbc3b45958ddeaf29055f6e1fe5b61d85da07a87e89ccbc5b6c4b6
|
||||
"@langchain/core": ^1.0.0
|
||||
checksum: 10c0/733039261456099f71c282c64a0f36c8283547d3db1c16218f0a67bd80837c73a70bf0c60072c5b496257c6b2d4eff84d88a1a9a4daa8f798f5f573686eb0dbb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -8027,18 +7984,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/weaviate@npm:^0.2.0":
|
||||
version: 0.2.2
|
||||
resolution: "@langchain/weaviate@npm:0.2.2"
|
||||
dependencies:
|
||||
uuid: "npm:^10.0.0"
|
||||
weaviate-client: "npm:^3.5.2"
|
||||
peerDependencies:
|
||||
"@langchain/core": ">=0.2.21 <0.4.0"
|
||||
checksum: 10c0/f1ec809e5b6ba6c14efeea93d6c7a8e015c2f9eaaa732884ba25d32cb6517117e38cddb6ec662358a40246523309f07e5f3114d3067e03eb43af168a43cc6405
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.0.3, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0, @lezer/common@npm:^1.2.1":
|
||||
version: 1.2.3
|
||||
resolution: "@lezer/common@npm:1.2.3"
|
||||
@ -17235,7 +17180,9 @@ __metadata:
|
||||
"@google/genai": "patch:@google/genai@npm%3A1.0.1#~/.yarn/patches/@google-genai-npm-1.0.1-e26f0f9af7.patch"
|
||||
"@hello-pangea/dnd": "npm:^18.0.1"
|
||||
"@heroui/react": "npm:^2.8.3"
|
||||
"@langchain/community": "npm:^0.3.50"
|
||||
"@langchain/community": "npm:^1.0.0"
|
||||
"@langchain/core": "patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch"
|
||||
"@langchain/openai": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch"
|
||||
"@libsql/client": "npm:0.14.0"
|
||||
"@libsql/win32-x64-msvc": "npm:^0.4.7"
|
||||
"@mistralai/mistralai": "npm:^1.7.5"
|
||||
@ -17494,13 +17441,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"abort-controller-x@npm:^0.4.0, abort-controller-x@npm:^0.4.3":
|
||||
version: 0.4.3
|
||||
resolution: "abort-controller-x@npm:0.4.3"
|
||||
checksum: 10c0/8091b5c9279c304890e4e9cc90601947790846b7b2c149bb322a25e873eb3db060ef3da74a93b6fe40ccea41c3962fc4b175468a0ecdf4c4bb6421023ad9d71e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"abort-controller@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "abort-controller@npm:3.0.0"
|
||||
@ -23244,25 +23184,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"graphql-request@npm:^6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "graphql-request@npm:6.1.0"
|
||||
dependencies:
|
||||
"@graphql-typed-document-node/core": "npm:^3.2.0"
|
||||
cross-fetch: "npm:^3.1.5"
|
||||
peerDependencies:
|
||||
graphql: 14 - 16
|
||||
checksum: 10c0/f8167925a110e8e1de93d56c14245e7e64391dc8dce5002dd01bf24a3059f345d4ca1bb6ce2040e2ec78264211b0704e75da3e63984f0f74d2042f697a4e8cc6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"graphql@npm:^16.11.0":
|
||||
version: 16.11.0
|
||||
resolution: "graphql@npm:16.11.0"
|
||||
checksum: 10c0/124da7860a2292e9acf2fed0c71fc0f6a9b9ca865d390d112bdd563c1f474357141501c12891f4164fe984315764736ad67f705219c62f7580681d431a85db88
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"gray-matter@npm:^4.0.3":
|
||||
version: 4.0.3
|
||||
resolution: "gray-matter@npm:4.0.3"
|
||||
@ -23292,6 +23213,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"handlebars@npm:^4.7.8":
|
||||
version: 4.7.8
|
||||
resolution: "handlebars@npm:4.7.8"
|
||||
dependencies:
|
||||
minimist: "npm:^1.2.5"
|
||||
neo-async: "npm:^2.6.2"
|
||||
source-map: "npm:^0.6.1"
|
||||
uglify-js: "npm:^3.1.4"
|
||||
wordwrap: "npm:^1.0.0"
|
||||
dependenciesMeta:
|
||||
uglify-js:
|
||||
optional: true
|
||||
bin:
|
||||
handlebars: bin/handlebars
|
||||
checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"has-flag@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "has-flag@npm:4.0.0"
|
||||
@ -24762,7 +24701,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"langchain@npm:>=0.2.3 <0.3.0 || >=0.3.4 <0.4.0, langchain@npm:^0.3.8":
|
||||
"langchain@npm:^0.3.8":
|
||||
version: 0.3.21
|
||||
resolution: "langchain@npm:0.3.21"
|
||||
dependencies:
|
||||
@ -24869,9 +24808,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"langsmith@npm:^0.3.46":
|
||||
version: 0.3.67
|
||||
resolution: "langsmith@npm:0.3.67"
|
||||
"langsmith@npm:^0.3.64":
|
||||
version: 0.3.76
|
||||
resolution: "langsmith@npm:0.3.76"
|
||||
dependencies:
|
||||
"@types/uuid": "npm:^10.0.0"
|
||||
chalk: "npm:^4.1.2"
|
||||
@ -24894,7 +24833,7 @@ __metadata:
|
||||
optional: true
|
||||
openai:
|
||||
optional: true
|
||||
checksum: 10c0/e22ec270764632a110dc77cb7fd018cd59e905fda529fba4c056e5c1ceda5a2746dc5e07e81b5ef2c949c0a712ffe5dd99721b465ba08d699e9a56e42b041bf4
|
||||
checksum: 10c0/3e76e69add862e6031a385edd2cf2e963b0db9e606d582a46fd77f05e49d8b9746eacdb5bc6b1fba2be2744f94e9d4e2d055c3ba0f394d6bc6e0f85f9cf4df77
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -25295,13 +25234,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.camelcase@npm:^4.3.0":
|
||||
version: 4.3.0
|
||||
resolution: "lodash.camelcase@npm:4.3.0"
|
||||
checksum: 10c0/fcba15d21a458076dd309fce6b1b4bf611d84a0ec252cb92447c948c533ac250b95d2e00955801ebc367e5af5ed288b996d75d37d2035260a937008e14eaf432
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.curry@npm:^4.0.1":
|
||||
version: 4.1.1
|
||||
resolution: "lodash.curry@npm:4.1.1"
|
||||
@ -25395,7 +25327,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"long@npm:^5.0.0, long@npm:^5.3.2":
|
||||
"long@npm:^5.0.0":
|
||||
version: 5.3.2
|
||||
resolution: "long@npm:5.3.2"
|
||||
checksum: 10c0/7130fe1cbce2dca06734b35b70d380ca3f70271c7f8852c922a7c62c86c4e35f0c39290565eca7133c625908d40e126ac57c02b1b1a4636b9457d77e1e60b981
|
||||
@ -27178,6 +27110,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"neo-async@npm:^2.6.2":
|
||||
version: 2.6.2
|
||||
resolution: "neo-async@npm:2.6.2"
|
||||
checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nested-property@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "nested-property@npm:4.0.0"
|
||||
@ -27192,36 +27131,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nice-grpc-client-middleware-retry@npm:^3.1.11":
|
||||
version: 3.1.11
|
||||
resolution: "nice-grpc-client-middleware-retry@npm:3.1.11"
|
||||
dependencies:
|
||||
abort-controller-x: "npm:^0.4.0"
|
||||
nice-grpc-common: "npm:^2.0.2"
|
||||
checksum: 10c0/0d9c704a1a5c399f8243753c75a7db86c9eb414ca5bae1920cd66f60ea235190c5ea667daa1c161345ae4bf86817085f3add4438ca67f9144c5e57b9542ef5c5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nice-grpc-common@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "nice-grpc-common@npm:2.0.2"
|
||||
dependencies:
|
||||
ts-error: "npm:^1.0.6"
|
||||
checksum: 10c0/9eb8a44e1a5c7051cf0e4a06dc7fda2c7abb6cfbcbb746806418c2c58f3f0075212c61bbce54239a204e6a552065f0fa92dfedcf3402dc16220b2ffaee4ab857
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nice-grpc@npm:^2.1.12":
|
||||
version: 2.1.12
|
||||
resolution: "nice-grpc@npm:2.1.12"
|
||||
dependencies:
|
||||
"@grpc/grpc-js": "npm:^1.13.1"
|
||||
abort-controller-x: "npm:^0.4.0"
|
||||
nice-grpc-common: "npm:^2.0.2"
|
||||
checksum: 10c0/7a8e720a42a0297315bfafa0c93297e36d341927eaddae9e5a06c8ea2863b16d701a642dc9610e3e768d19cc9569afe5b99de2dfaeb1648042d32a139a7ba773
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-abi@npm:4.12.0":
|
||||
version: 4.12.0
|
||||
resolution: "node-abi@npm:4.12.0"
|
||||
@ -27625,6 +27534,23 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"openai@npm:^6.3.0":
|
||||
version: 6.7.0
|
||||
resolution: "openai@npm:6.7.0"
|
||||
peerDependencies:
|
||||
ws: ^8.18.0
|
||||
zod: ^3.25 || ^4.0
|
||||
peerDependenciesMeta:
|
||||
ws:
|
||||
optional: true
|
||||
zod:
|
||||
optional: true
|
||||
bin:
|
||||
openai: bin/cli
|
||||
checksum: 10c0/dbee766f28308235fdc370a325f50ab4de2d869a832f78fbb7cb81ede0518b55c6e6ab70cd0fe9cdc7a3fd948ef56a8d8f23d0a86fef21ac7ed97e35ef547c92
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"openapi-types@npm:^12.1.3":
|
||||
version: 12.1.3
|
||||
resolution: "openapi-types@npm:12.1.3"
|
||||
@ -28783,26 +28709,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"protobufjs@npm:^7.2.5":
|
||||
version: 7.5.4
|
||||
resolution: "protobufjs@npm:7.5.4"
|
||||
dependencies:
|
||||
"@protobufjs/aspromise": "npm:^1.1.2"
|
||||
"@protobufjs/base64": "npm:^1.1.2"
|
||||
"@protobufjs/codegen": "npm:^2.0.4"
|
||||
"@protobufjs/eventemitter": "npm:^1.1.0"
|
||||
"@protobufjs/fetch": "npm:^1.1.0"
|
||||
"@protobufjs/float": "npm:^1.0.2"
|
||||
"@protobufjs/inquire": "npm:^1.1.0"
|
||||
"@protobufjs/path": "npm:^1.1.2"
|
||||
"@protobufjs/pool": "npm:^1.1.0"
|
||||
"@protobufjs/utf8": "npm:^1.1.0"
|
||||
"@types/node": "npm:>=13.7.0"
|
||||
long: "npm:^5.0.0"
|
||||
checksum: 10c0/913b676109ffb3c05d3d31e03a684e569be91f3bba8613da4a683d69d9dba948daa2afd7d2e7944d1aa6c417890c35d9d9a8883c1160affafb0f9670d59ef722
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"protobufjs@npm:^7.3.0":
|
||||
version: 7.5.2
|
||||
resolution: "protobufjs@npm:7.5.2"
|
||||
@ -31460,7 +31366,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"source-map@npm:^0.6.0, source-map@npm:~0.6.1":
|
||||
"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1":
|
||||
version: 0.6.1
|
||||
resolution: "source-map@npm:0.6.1"
|
||||
checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011
|
||||
@ -32620,13 +32526,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-error@npm:^1.0.6":
|
||||
version: 1.0.6
|
||||
resolution: "ts-error@npm:1.0.6"
|
||||
checksum: 10c0/c46994b0b88eae75d676ab18edcdb3e6c309abb39d8169c2d15286d10f4fc7bfc58c537a81f3efe24701e840247b5e79ac8e21a7335327811a07cfc33f69a72f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-pattern@npm:^5.7.0":
|
||||
version: 5.7.0
|
||||
resolution: "ts-pattern@npm:5.7.0"
|
||||
@ -33006,6 +32905,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uglify-js@npm:^3.1.4":
|
||||
version: 3.19.3
|
||||
resolution: "uglify-js@npm:3.19.3"
|
||||
bin:
|
||||
uglifyjs: bin/uglifyjs
|
||||
checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unbzip2-stream@npm:^1.0.9":
|
||||
version: 1.4.3
|
||||
resolution: "unbzip2-stream@npm:1.4.3"
|
||||
@ -33790,22 +33698,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"weaviate-client@npm:^3.5.2":
|
||||
version: 3.8.1
|
||||
resolution: "weaviate-client@npm:3.8.1"
|
||||
dependencies:
|
||||
abort-controller-x: "npm:^0.4.3"
|
||||
graphql: "npm:^16.11.0"
|
||||
graphql-request: "npm:^6.1.0"
|
||||
long: "npm:^5.3.2"
|
||||
nice-grpc: "npm:^2.1.12"
|
||||
nice-grpc-client-middleware-retry: "npm:^3.1.11"
|
||||
nice-grpc-common: "npm:^2.0.2"
|
||||
uuid: "npm:^9.0.1"
|
||||
checksum: 10c0/a001a1b0eaf9b1344f1d7963520fe43b83bfc1a34efbe1d1b8748ae7b042f95d502cc6d31f681969865d7df90cf54a902233c3dea379aac6df40cb4ed704f665
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"web-namespaces@npm:^2.0.0":
|
||||
version: 2.0.1
|
||||
resolution: "web-namespaces@npm:2.0.1"
|
||||
@ -34058,6 +33950,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"wordwrap@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "wordwrap@npm:1.0.0"
|
||||
checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "wrap-ansi@npm:7.0.0"
|
||||
@ -34310,7 +34209,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
|
||||
"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2":
|
||||
version: 17.7.2
|
||||
resolution: "yargs@npm:17.7.2"
|
||||
dependencies:
|
||||
@ -34443,10 +34342,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:^3.25.32":
|
||||
version: 3.25.76
|
||||
resolution: "zod@npm:3.25.76"
|
||||
checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c
|
||||
"zod@npm:^3.25.76 || ^4":
|
||||
version: 4.1.12
|
||||
resolution: "zod@npm:4.1.12"
|
||||
checksum: 10c0/b64c1feb19e99d77075261eaf613e0b2be4dfcd3551eff65ad8b4f2a079b61e379854d066f7d447491fcf193f45babd8095551a9d47973d30b46b6d8e2c46774
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user