Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
dbfc79d7
Unverified
Commit
dbfc79d7
authored
Jul 16, 2023
by
John Wang
Committed by
GitHub
Jul 16, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'main' into feat/claude-api-support
parents
50615341
51038990
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
99 additions
and
8 deletions
+99
-8
app.py
api/app.py
+6
-1
config.py
api/config.py
+3
-0
dataset_service.py
api/services/dataset_service.py
+23
-0
index.tsx
web/app/components/app/chat/index.tsx
+6
-2
index.tsx
web/app/components/app/text-generate/item/index.tsx
+5
-1
index.tsx
...components/header/account-setting/provider-page/index.tsx
+1
-1
dify-header.svg
web/app/components/share/chatbot/icons/dify-header.svg
+22
-0
dify.svg
web/app/components/share/chatbot/icons/dify.svg
+11
-0
index.tsx
web/app/components/share/chatbot/index.tsx
+7
-1
style.module.css
web/app/components/share/chatbot/style.module.css
+11
-0
index.tsx
web/app/components/share/chatbot/welcome/index.tsx
+1
-1
header.tsx
web/app/components/share/header.tsx
+3
-1
No files found.
api/app.py
View file @
dbfc79d7
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
import
os
import
os
from
datetime
import
datetime
from
datetime
import
datetime
from
werkzeug.exceptions
import
Forbidden
if
not
os
.
environ
.
get
(
"DEBUG"
)
or
os
.
environ
.
get
(
"DEBUG"
)
.
lower
()
!=
'true'
:
if
not
os
.
environ
.
get
(
"DEBUG"
)
or
os
.
environ
.
get
(
"DEBUG"
)
.
lower
()
!=
'true'
:
from
gevent
import
monkey
from
gevent
import
monkey
monkey
.
patch_all
()
monkey
.
patch_all
()
...
@@ -27,7 +29,7 @@ from events import event_handlers
...
@@ -27,7 +29,7 @@ from events import event_handlers
import
core
import
core
from
config
import
Config
,
CloudEditionConfig
from
config
import
Config
,
CloudEditionConfig
from
commands
import
register_commands
from
commands
import
register_commands
from
models.account
import
TenantAccountJoin
from
models.account
import
TenantAccountJoin
,
AccountStatus
from
models.model
import
Account
,
EndUser
,
App
from
models.model
import
Account
,
EndUser
,
App
import
warnings
import
warnings
...
@@ -101,6 +103,9 @@ def load_user(user_id):
...
@@ -101,6 +103,9 @@ def load_user(user_id):
account
=
db
.
session
.
query
(
Account
)
.
filter
(
Account
.
id
==
account_id
)
.
first
()
account
=
db
.
session
.
query
(
Account
)
.
filter
(
Account
.
id
==
account_id
)
.
first
()
if
account
:
if
account
:
if
account
.
status
==
AccountStatus
.
BANNED
.
value
or
account
.
status
==
AccountStatus
.
CLOSED
.
value
:
raise
Forbidden
(
'Account is banned or closed.'
)
workspace_id
=
session
.
get
(
'workspace_id'
)
workspace_id
=
session
.
get
(
'workspace_id'
)
if
workspace_id
:
if
workspace_id
:
tenant_account_join
=
db
.
session
.
query
(
TenantAccountJoin
)
.
filter
(
tenant_account_join
=
db
.
session
.
query
(
TenantAccountJoin
)
.
filter
(
...
...
api/config.py
View file @
dbfc79d7
...
@@ -53,6 +53,7 @@ DEFAULTS = {
...
@@ -53,6 +53,7 @@ DEFAULTS = {
'DEFAULT_LLM_PROVIDER'
:
'openai'
,
'DEFAULT_LLM_PROVIDER'
:
'openai'
,
'OPENAI_HOSTED_QUOTA_LIMIT'
:
200
,
'OPENAI_HOSTED_QUOTA_LIMIT'
:
200
,
'ANTHROPIC_HOSTED_QUOTA_LIMIT'
:
1000
,
'ANTHROPIC_HOSTED_QUOTA_LIMIT'
:
1000
,
'TENANT_DOCUMENT_COUNT'
:
100
}
}
...
@@ -213,6 +214,8 @@ class Config:
...
@@ -213,6 +214,8 @@ class Config:
self
.
NOTION_INTERNAL_SECRET
=
get_env
(
'NOTION_INTERNAL_SECRET'
)
self
.
NOTION_INTERNAL_SECRET
=
get_env
(
'NOTION_INTERNAL_SECRET'
)
self
.
NOTION_INTEGRATION_TOKEN
=
get_env
(
'NOTION_INTEGRATION_TOKEN'
)
self
.
NOTION_INTEGRATION_TOKEN
=
get_env
(
'NOTION_INTEGRATION_TOKEN'
)
self
.
TENANT_DOCUMENT_COUNT
=
get_env
(
'TENANT_DOCUMENT_COUNT'
)
class
CloudEditionConfig
(
Config
):
class
CloudEditionConfig
(
Config
):
...
...
api/services/dataset_service.py
View file @
dbfc79d7
...
@@ -4,6 +4,9 @@ import datetime
...
@@ -4,6 +4,9 @@ import datetime
import
time
import
time
import
random
import
random
from
typing
import
Optional
,
List
from
typing
import
Optional
,
List
from
flask
import
current_app
from
extensions.ext_redis
import
redis_client
from
extensions.ext_redis
import
redis_client
from
flask_login
import
current_user
from
flask_login
import
current_user
...
@@ -374,6 +377,12 @@ class DocumentService:
...
@@ -374,6 +377,12 @@ class DocumentService:
def
save_document_with_dataset_id
(
dataset
:
Dataset
,
document_data
:
dict
,
def
save_document_with_dataset_id
(
dataset
:
Dataset
,
document_data
:
dict
,
account
:
Account
,
dataset_process_rule
:
Optional
[
DatasetProcessRule
]
=
None
,
account
:
Account
,
dataset_process_rule
:
Optional
[
DatasetProcessRule
]
=
None
,
created_from
:
str
=
'web'
):
created_from
:
str
=
'web'
):
# check document limit
if
current_app
.
config
[
'EDITION'
]
==
'CLOUD'
:
documents_count
=
DocumentService
.
get_tenant_documents_count
()
tenant_document_count
=
int
(
current_app
.
config
[
'TENANT_DOCUMENT_COUNT'
])
if
documents_count
>
tenant_document_count
:
raise
ValueError
(
f
"over document limit {tenant_document_count}."
)
# if dataset is empty, update dataset data_source_type
# if dataset is empty, update dataset data_source_type
if
not
dataset
.
data_source_type
:
if
not
dataset
.
data_source_type
:
dataset
.
data_source_type
=
document_data
[
"data_source"
][
"type"
]
dataset
.
data_source_type
=
document_data
[
"data_source"
][
"type"
]
...
@@ -521,6 +530,14 @@ class DocumentService:
...
@@ -521,6 +530,14 @@ class DocumentService:
)
)
return
document
return
document
@
staticmethod
def
get_tenant_documents_count
():
documents_count
=
Document
.
query
.
filter
(
Document
.
completed_at
.
isnot
(
None
),
Document
.
enabled
==
True
,
Document
.
archived
==
False
,
Document
.
tenant_id
==
current_user
.
current_tenant_id
)
.
count
()
return
documents_count
@
staticmethod
@
staticmethod
def
update_document_with_dataset_id
(
dataset
:
Dataset
,
document_data
:
dict
,
def
update_document_with_dataset_id
(
dataset
:
Dataset
,
document_data
:
dict
,
account
:
Account
,
dataset_process_rule
:
Optional
[
DatasetProcessRule
]
=
None
,
account
:
Account
,
dataset_process_rule
:
Optional
[
DatasetProcessRule
]
=
None
,
...
@@ -616,6 +633,12 @@ class DocumentService:
...
@@ -616,6 +633,12 @@ class DocumentService:
@
staticmethod
@
staticmethod
def
save_document_without_dataset_id
(
tenant_id
:
str
,
document_data
:
dict
,
account
:
Account
):
def
save_document_without_dataset_id
(
tenant_id
:
str
,
document_data
:
dict
,
account
:
Account
):
# check document limit
if
current_app
.
config
[
'EDITION'
]
==
'CLOUD'
:
documents_count
=
DocumentService
.
get_tenant_documents_count
()
tenant_document_count
=
int
(
current_app
.
config
[
'TENANT_DOCUMENT_COUNT'
])
if
documents_count
>
tenant_document_count
:
raise
ValueError
(
f
"over document limit {tenant_document_count}."
)
# save dataset
# save dataset
dataset
=
Dataset
(
dataset
=
Dataset
(
tenant_id
=
tenant_id
,
tenant_id
=
tenant_id
,
...
...
web/app/components/app/chat/index.tsx
View file @
dbfc79d7
...
@@ -65,6 +65,7 @@ export type IChatProps = {
...
@@ -65,6 +65,7 @@ export type IChatProps = {
isShowSuggestion
?:
boolean
isShowSuggestion
?:
boolean
suggestionList
?:
string
[]
suggestionList
?:
string
[]
isShowSpeechToText
?:
boolean
isShowSpeechToText
?:
boolean
answerIconClassName
?:
string
}
}
export
type
MessageMore
=
{
export
type
MessageMore
=
{
...
@@ -174,10 +175,11 @@ type IAnswerProps = {
...
@@ -174,10 +175,11 @@ type IAnswerProps = {
onSubmitAnnotation
?:
SubmitAnnotationFunc
onSubmitAnnotation
?:
SubmitAnnotationFunc
displayScene
:
DisplayScene
displayScene
:
DisplayScene
isResponsing
?:
boolean
isResponsing
?:
boolean
answerIconClassName
?:
string
}
}
// The component needs to maintain its own state to control whether to display input component
// The component needs to maintain its own state to control whether to display input component
const
Answer
:
FC
<
IAnswerProps
>
=
({
item
,
feedbackDisabled
=
false
,
isHideFeedbackEdit
=
false
,
onFeedback
,
onSubmitAnnotation
,
displayScene
=
'web'
,
isResponsing
})
=>
{
const
Answer
:
FC
<
IAnswerProps
>
=
({
item
,
feedbackDisabled
=
false
,
isHideFeedbackEdit
=
false
,
onFeedback
,
onSubmitAnnotation
,
displayScene
=
'web'
,
isResponsing
,
answerIconClassName
})
=>
{
const
{
id
,
content
,
more
,
feedback
,
adminFeedback
,
annotation
:
initAnnotation
}
=
item
const
{
id
,
content
,
more
,
feedback
,
adminFeedback
,
annotation
:
initAnnotation
}
=
item
const
[
showEdit
,
setShowEdit
]
=
useState
(
false
)
const
[
showEdit
,
setShowEdit
]
=
useState
(
false
)
const
[
loading
,
setLoading
]
=
useState
(
false
)
const
[
loading
,
setLoading
]
=
useState
(
false
)
...
@@ -292,7 +294,7 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
...
@@ -292,7 +294,7 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
return
(
return
(
<
div
key=
{
id
}
>
<
div
key=
{
id
}
>
<
div
className=
'flex items-start'
>
<
div
className=
'flex items-start'
>
<
div
className=
{
`${s.answerIcon} w-10 h-10 shrink-0`
}
>
<
div
className=
{
`${s.answerIcon}
${answerIconClassName}
w-10 h-10 shrink-0`
}
>
{
isResponsing
{
isResponsing
&&
<
div
className=
{
s
.
typeingIcon
}
>
&&
<
div
className=
{
s
.
typeingIcon
}
>
<
LoadingAnim
type=
'avatar'
/>
<
LoadingAnim
type=
'avatar'
/>
...
@@ -428,6 +430,7 @@ const Chat: FC<IChatProps> = ({
...
@@ -428,6 +430,7 @@ const Chat: FC<IChatProps> = ({
isShowSuggestion
,
isShowSuggestion
,
suggestionList
,
suggestionList
,
isShowSpeechToText
,
isShowSpeechToText
,
answerIconClassName
,
})
=>
{
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
const
{
notify
}
=
useContext
(
ToastContext
)
const
{
notify
}
=
useContext
(
ToastContext
)
...
@@ -520,6 +523,7 @@ const Chat: FC<IChatProps> = ({
...
@@ -520,6 +523,7 @@ const Chat: FC<IChatProps> = ({
onSubmitAnnotation=
{
onSubmitAnnotation
}
onSubmitAnnotation=
{
onSubmitAnnotation
}
displayScene=
{
displayScene
??
'web'
}
displayScene=
{
displayScene
??
'web'
}
isResponsing=
{
isResponsing
&&
isLast
}
isResponsing=
{
isResponsing
&&
isLast
}
answerIconClassName=
{
answerIconClassName
}
/>
/>
}
}
return
<
Question
key=
{
item
.
id
}
id=
{
item
.
id
}
content=
{
item
.
content
}
more=
{
item
.
more
}
useCurrentUserAvatar=
{
useCurrentUserAvatar
}
/>
return
<
Question
key=
{
item
.
id
}
id=
{
item
.
id
}
content=
{
item
.
content
}
more=
{
item
.
more
}
useCurrentUserAvatar=
{
useCurrentUserAvatar
}
/>
...
...
web/app/components/app/text-generate/item/index.tsx
View file @
dbfc79d7
...
@@ -184,7 +184,11 @@ const GenerationItem: FC<IGenerationItemProps> = ({
...
@@ -184,7 +184,11 @@ const GenerationItem: FC<IGenerationItemProps> = ({
{
taskId
}
{
taskId
}
</
div
>)
</
div
>)
}
}
<
Markdown
content=
{
content
}
/>
<
div
className=
'flex'
>
<
div
className=
'grow w-0'
>
<
Markdown
content=
{
content
}
/>
</
div
>
</
div
>
{
messageId
&&
(
{
messageId
&&
(
<
div
className=
'flex items-center justify-between mt-3'
>
<
div
className=
'flex items-center justify-between mt-3'
>
<
div
className=
'flex items-center'
>
<
div
className=
'flex items-center'
>
...
...
web/app/components/header/account-setting/provider-page/index.tsx
View file @
dbfc79d7
...
@@ -93,7 +93,7 @@ const ProviderPage = () => {
...
@@ -93,7 +93,7 @@ const ProviderPage = () => {
))
))
}
}
</
div
>
</
div
>
<
div
className=
'
absolute bottom-0 w-full
h-[42px] flex items-center bg-white text-xs text-gray-500'
>
<
div
className=
'
fixed bottom-0 w-[472px]
h-[42px] flex items-center bg-white text-xs text-gray-500'
>
<
LockClosedIcon
className=
'w-3 h-3 mr-1'
/>
<
LockClosedIcon
className=
'w-3 h-3 mr-1'
/>
{
t
(
'common.provider.encrypted.front'
)
}
{
t
(
'common.provider.encrypted.front'
)
}
<
Link
<
Link
...
...
web/app/components/share/chatbot/icons/dify-header.svg
0 → 100644
View file @
dbfc79d7
This diff is collapsed.
Click to expand it.
web/app/components/share/chatbot/icons/dify.svg
0 → 100644
View file @
dbfc79d7
This diff is collapsed.
Click to expand it.
web/app/components/share/chatbot/index.tsx
View file @
dbfc79d7
...
@@ -552,6 +552,10 @@ const Main: FC<IMainProps> = ({
...
@@ -552,6 +552,10 @@ const Main: FC<IMainProps> = ({
)
)
}
}
const
difyIcon
=
(
<
div
className=
{
s
.
difyHeader
}
></
div
>
)
if
(
appUnavailable
)
if
(
appUnavailable
)
return
<
AppUnavailable
isUnknwonReason=
{
isUnknwonReason
}
/>
return
<
AppUnavailable
isUnknwonReason=
{
isUnknwonReason
}
/>
...
@@ -562,7 +566,8 @@ const Main: FC<IMainProps> = ({
...
@@ -562,7 +566,8 @@ const Main: FC<IMainProps> = ({
<
div
>
<
div
>
<
Header
<
Header
title=
{
siteInfo
.
title
}
title=
{
siteInfo
.
title
}
icon=
{
siteInfo
.
icon
||
''
}
icon=
''
customerIcon=
{
difyIcon
}
icon_background=
{
siteInfo
.
icon_background
}
icon_background=
{
siteInfo
.
icon_background
}
isEmbedScene=
{
true
}
isEmbedScene=
{
true
}
isMobile=
{
isMobile
}
isMobile=
{
isMobile
}
...
@@ -624,6 +629,7 @@ const Main: FC<IMainProps> = ({
...
@@ -624,6 +629,7 @@ const Main: FC<IMainProps> = ({
suggestionList=
{
suggestQuestions
}
suggestionList=
{
suggestQuestions
}
displayScene=
'web'
displayScene=
'web'
isShowSpeechToText=
{
speechToTextConfig
?.
enabled
}
isShowSpeechToText=
{
speechToTextConfig
?.
enabled
}
answerIconClassName=
{
s
.
difyIcon
}
/>
/>
</
div
>
</
div
>
</
div
>)
</
div
>)
...
...
web/app/components/share/chatbot/style.module.css
View file @
dbfc79d7
.installedApp
{
.installedApp
{
height
:
calc
(
100vh
-
74px
);
height
:
calc
(
100vh
-
74px
);
}
.difyIcon
{
background-image
:
url(./icons/dify.svg)
;
}
.difyHeader
{
width
:
24px
;
height
:
24px
;
background
:
url(./icons/dify-header.svg)
center
center
no-repeat
;
background-size
:
contain
;
}
}
\ No newline at end of file
web/app/components/share/chatbot/welcome/index.tsx
View file @
dbfc79d7
...
@@ -307,7 +307,7 @@ const Welcome: FC<IWelcomeProps> = ({
...
@@ -307,7 +307,7 @@ const Welcome: FC<IWelcomeProps> = ({
}
}
return (
return (
<
div
className=
'relative
mobile:min-h-[48px]
tablet:min-h-[64px]'
>
<
div
className=
'relative tablet:min-h-[64px]'
>
{
/* {hasSetInputs && renderHeader()} */
}
{
/* {hasSetInputs && renderHeader()} */
}
<
div
className=
'mx-auto pc:w-[794px] max-w-full mobile:w-full px-3.5'
>
<
div
className=
'mx-auto pc:w-[794px] max-w-full mobile:w-full px-3.5'
>
{
/* Has't set inputs */
}
{
/* Has't set inputs */
}
...
...
web/app/components/share/header.tsx
View file @
dbfc79d7
...
@@ -3,6 +3,7 @@ import React from 'react'
...
@@ -3,6 +3,7 @@ import React from 'react'
import
AppIcon
from
'@/app/components/base/app-icon'
import
AppIcon
from
'@/app/components/base/app-icon'
export
type
IHeaderProps
=
{
export
type
IHeaderProps
=
{
title
:
string
title
:
string
customerIcon
?:
React
.
ReactNode
icon
:
string
icon
:
string
icon_background
:
string
icon_background
:
string
isMobile
?:
boolean
isMobile
?:
boolean
...
@@ -11,6 +12,7 @@ export type IHeaderProps = {
...
@@ -11,6 +12,7 @@ export type IHeaderProps = {
const
Header
:
FC
<
IHeaderProps
>
=
({
const
Header
:
FC
<
IHeaderProps
>
=
({
title
,
title
,
isMobile
,
isMobile
,
customerIcon
,
icon
,
icon
,
icon_background
,
icon_background
,
isEmbedScene
=
false
,
isEmbedScene
=
false
,
...
@@ -25,7 +27,7 @@ const Header: FC<IHeaderProps> = ({
...
@@ -25,7 +27,7 @@ const Header: FC<IHeaderProps> = ({
>
>
<
div
></
div
>
<
div
></
div
>
<
div
className=
"flex items-center space-x-2"
>
<
div
className=
"flex items-center space-x-2"
>
<
AppIcon
size=
"small"
icon=
{
icon
}
background=
{
icon_background
}
/>
{
customerIcon
||
<
AppIcon
size=
"small"
icon=
{
icon
}
background=
{
icon_background
}
/>
}
<
div
<
div
className=
{
`text-sm text-gray-800 font-bold ${
className=
{
`text-sm text-gray-800 font-bold ${
isEmbedScene ? 'text-white' : ''
isEmbedScene ? 'text-white' : ''
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment