diff --git a/.github/ISSUE_TEMPLATE/help_wanted.yml b/.github/ISSUE_TEMPLATE/help_wanted.yml new file mode 100644 index 00000000000000..63c3dea4c18b12 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/help_wanted.yml @@ -0,0 +1,11 @@ +name: "🤝 Help Wanted" +description: "Request help from the community" +labels: +- help-wanted +body: +- type: textarea + attributes: + label: Provide a description of the help you need + placeholder: Briefly describe what you need help with. + validations: + required: true \ No newline at end of file diff --git a/api/config.py b/api/config.py index 694179c074b317..2e06012e86f831 100644 --- a/api/config.py +++ b/api/config.py @@ -102,7 +102,7 @@ def __init__(self): self.CONSOLE_URL = get_env('CONSOLE_URL') self.API_URL = get_env('API_URL') self.APP_URL = get_env('APP_URL') - self.CURRENT_VERSION = "0.3.22" + self.CURRENT_VERSION = "0.3.23" self.COMMIT_SHA = get_env('COMMIT_SHA') self.EDITION = "SELF_HOSTED" self.DEPLOY_ENV = get_env('DEPLOY_ENV') diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index ba12030efa76f8..ba209ab75949aa 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -2,7 +2,7 @@ version: '3.1' services: # API service api: - image: langgenius/dify-api:0.3.22 + image: langgenius/dify-api:0.3.23 restart: always environment: # Startup mode, 'api' starts the API server. @@ -124,7 +124,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.3.22 + image: langgenius/dify-api:0.3.23 restart: always environment: # Startup mode, 'worker' starts the Celery worker for processing the queue. @@ -176,7 +176,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.3.22 + image: langgenius/dify-web:0.3.23 restart: always environment: EDITION: SELF_HOSTED diff --git a/web/app/components/app/chat/copy-btn/index.tsx b/web/app/components/app/chat/copy-btn/index.tsx index 5e2a9bdaaff091..a03b99105740e7 100644 --- a/web/app/components/app/chat/copy-btn/index.tsx +++ b/web/app/components/app/chat/copy-btn/index.tsx @@ -1,9 +1,10 @@ 'use client' -import React from 'react' +import { useRef, useState } from 'react' import { t } from 'i18next' import copy from 'copy-to-clipboard' import s from './style.module.css' import Tooltip from '@/app/components/base/tooltip' +import { randomString } from '@/utils' type ICopyBtnProps = { value: string @@ -16,12 +17,13 @@ const CopyBtn = ({ className, isPlain, }: ICopyBtnProps) => { - const [isCopied, setIsCopied] = React.useState(false) + const [isCopied, setIsCopied] = useState(false) + const selector = useRef(`copy-tooltip-${randomString(4)}`) return (
diff --git a/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx b/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx index 1928dd8f90085f..32c39102957c0b 100644 --- a/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx +++ b/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx @@ -14,6 +14,8 @@ import OpeningStatement from '@/app/components/app/configuration/features/chat-g import GroupName from '@/app/components/app/configuration/base/group-name' import Loading from '@/app/components/base/loading' import Confirm from '@/app/components/base/confirm' +// type +import type { AutomaticRes } from '@/service/debug' const noDataIcon = ( @@ -21,12 +23,6 @@ const noDataIcon = ( ) -export type AutomaticRes = { - prompt: string - variables: string[] - opening_statement: string -} - export type IGetAutomaticResProps = { mode: AppType isShow: boolean @@ -98,7 +94,7 @@ const GetAutomaticRes: FC = ({ audiences, hoping_to_solve: hopingToSolve, }) - setRes(res as AutomaticRes) + setRes(res) } finally { setLoadingFalse() @@ -193,7 +189,7 @@ const GetAutomaticRes: FC = ({ onClose={() => setShowConfirmOverwrite(false)} onConfirm={() => { setShowConfirmOverwrite(false) - onFinished(res as AutomaticRes) + onFinished(res!) }} onCancel={() => setShowConfirmOverwrite(false)} /> diff --git a/web/app/components/header/account-setting/model-page/model-item/FreeQuota.tsx b/web/app/components/header/account-setting/model-page/model-item/FreeQuota.tsx index c4493327c84a77..90e4b5cd297512 100644 --- a/web/app/components/header/account-setting/model-page/model-item/FreeQuota.tsx +++ b/web/app/components/header/account-setting/model-page/model-item/FreeQuota.tsx @@ -16,8 +16,8 @@ const TIP_MAP: { [k: string]: TypeWithI18N } = { 'zh-Hans': '免费获取 100 万个 token', }, [ProviderEnumValue.spark]: { - 'en': 'Earn 3 million tokens for free', - 'zh-Hans': '免费获取 300 万个 token', + 'en': 'Earn 6 million tokens for free', + 'zh-Hans': '免费获取 600 万个 token', }, [ProviderEnumValue.zhipuai]: { 'en': 'Earn 10 million tokens for free', diff --git a/web/package.json b/web/package.json index e614f4efe24e88..0b28091b250826 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "dify-web", - "version": "0.3.22", + "version": "0.3.23", "private": true, "scripts": { "dev": "next dev", diff --git a/web/service/base.ts b/web/service/base.ts index 00ce140d6920a9..16bbc70f130496 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -77,18 +77,18 @@ export function format(text: string) { return res.replaceAll('\n', '
').replaceAll('```', '') } -const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted, onThought?: IOnThought, onMessageEnd?: IOnMessageEnd) => { +const handleStream = (response: Response, onData: IOnData, onCompleted?: IOnCompleted, onThought?: IOnThought, onMessageEnd?: IOnMessageEnd) => { if (!response.ok) throw new Error('Network response was not ok') - const reader = response.body.getReader() + const reader = response.body?.getReader() const decoder = new TextDecoder('utf-8') let buffer = '' - let bufferObj: any + let bufferObj: Record let isFirstMessage = true function read() { let hasError = false - reader.read().then((result: any) => { + reader?.read().then((result: any) => { if (result.done) { onCompleted && onCompleted() return @@ -99,7 +99,7 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted lines.forEach((message) => { if (message.startsWith('data: ')) { // check if it starts with data: try { - bufferObj = JSON.parse(message.substring(6)) // remove data: and parse as json + bufferObj = JSON.parse(message.substring(6)) as Record// remove data: and parse as json } catch (e) { // mute handle message cut off @@ -113,11 +113,11 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted onData('', false, { conversationId: undefined, messageId: '', - errorMessage: bufferObj.message, - errorCode: bufferObj.code, + errorMessage: bufferObj?.message, + errorCode: bufferObj?.code, }) hasError = true - onCompleted && onCompleted(true) + onCompleted?.(true) return } if (bufferObj.event === 'message') { @@ -130,10 +130,10 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted isFirstMessage = false } else if (bufferObj.event === 'agent_thought') { - onThought?.(bufferObj as any) + onThought?.(bufferObj as ThoughtItem) } else if (bufferObj.event === 'message_end') { - onMessageEnd?.(bufferObj as any) + onMessageEnd?.(bufferObj as MessageEnd) } } }) @@ -146,7 +146,7 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted errorMessage: `${e}`, }) hasError = true - onCompleted && onCompleted(true) + onCompleted?.(true) return } if (!hasError) diff --git a/web/service/debug.ts b/web/service/debug.ts index a9e3ec55052233..03fa9d877ac0ac 100644 --- a/web/service/debug.ts +++ b/web/service/debug.ts @@ -1,6 +1,12 @@ import type { IOnCompleted, IOnData, IOnError, IOnMessageEnd } from './base' import { get, post, ssePost } from './base' +export type AutomaticRes = { + prompt: string + variables: string[] + opening_statement: string +} + export const sendChatMessage = async (appId: string, body: Record, { onData, onCompleted, onError, getAbortController, onMessageEnd }: { onData: IOnData onCompleted: IOnCompleted @@ -46,7 +52,7 @@ export const fetchConvesationMessages = (appId: string, conversation_id: string) } export const generateRule = (body: Record) => { - return post('/rule-generate', { + return post('/rule-generate', { body, }) } diff --git a/web/yarn.lock b/web/yarn.lock index 8447fd74ab2581..7a45bbddfb1754 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -3752,7 +3752,11 @@ mdast-util-from-markdown@^0.8.5: parse-entities "^2.0.0" unist-util-stringify-position "^2.0.0" +<<<<<<< Updated upstream mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0, mdast-util-from-markdown@^1.3.0: +======= +mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0: +>>>>>>> Stashed changes version "1.3.1" resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz" integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== @@ -5368,11 +5372,14 @@ safe-regex@^2.1.1: dependencies: regexp-tree "~0.1.1" +<<<<<<< Updated upstream "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +======= +>>>>>>> Stashed changes sass@^1.61.0: version "1.62.1" resolved "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz" @@ -6120,11 +6127,14 @@ web-namespaces@^2.0.0: resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== +<<<<<<< Updated upstream web-worker@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== +======= +>>>>>>> Stashed changes which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"