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 = (
)
-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"