mirror of
https://github.com/langgenius/dify.git
synced 2026-04-27 02:36:29 +08:00
Merge branch 'feat/r2' into deploy/rag-dev
This commit is contained in:
commit
fa9f0ebfb1
@ -163,7 +163,7 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
)
|
)
|
||||||
db.session.add(end_user)
|
db.session.add(end_user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
exp_dt = datetime.now(UTC) + timedelta(hours=dify_config.ACCESS_TOKEN_EXPIRE_MINUTES * 24)
|
exp_dt = datetime.now(UTC) + timedelta(minutes=dify_config.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||||
exp = int(exp_dt.timestamp())
|
exp = int(exp_dt.timestamp())
|
||||||
payload = {
|
payload = {
|
||||||
"iss": site.id,
|
"iss": site.id,
|
||||||
|
|||||||
@ -32,6 +32,7 @@ from core.repositories.sqlalchemy_workflow_execution_repository import SQLAlchem
|
|||||||
from core.workflow.repositories.workflow_execution_repository import WorkflowExecutionRepository
|
from core.workflow.repositories.workflow_execution_repository import WorkflowExecutionRepository
|
||||||
from core.workflow.repositories.workflow_node_execution_repository import WorkflowNodeExecutionRepository
|
from core.workflow.repositories.workflow_node_execution_repository import WorkflowNodeExecutionRepository
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
|
from libs.flask_utils import preserve_flask_contexts
|
||||||
from models import Account, EndUser, Workflow, WorkflowNodeExecutionTriggeredFrom
|
from models import Account, EndUser, Workflow, WorkflowNodeExecutionTriggeredFrom
|
||||||
from models.dataset import Document, DocumentPipelineExecutionLog, Pipeline
|
from models.dataset import Document, DocumentPipelineExecutionLog, Pipeline
|
||||||
from models.enums import WorkflowRunTriggeredFrom
|
from models.enums import WorkflowRunTriggeredFrom
|
||||||
@ -209,25 +210,22 @@ class PipelineGenerator(BaseAppGenerator):
|
|||||||
# run in child thread
|
# run in child thread
|
||||||
context = contextvars.copy_context()
|
context = contextvars.copy_context()
|
||||||
|
|
||||||
@copy_current_request_context
|
worker_thread = threading.Thread(
|
||||||
def worker_with_context():
|
target=self._generate,
|
||||||
# Run the worker within the copied context
|
kwargs={
|
||||||
return context.run(
|
"flask_app": current_app._get_current_object(), # type: ignore
|
||||||
self._generate,
|
"context": context,
|
||||||
flask_app=current_app._get_current_object(), # type: ignore
|
"pipeline": pipeline,
|
||||||
context=context,
|
"workflow_id": workflow.id,
|
||||||
pipeline=pipeline,
|
"user": user,
|
||||||
workflow_id=workflow.id,
|
"application_generate_entity": application_generate_entity,
|
||||||
user=user,
|
"invoke_from": invoke_from,
|
||||||
application_generate_entity=application_generate_entity,
|
"workflow_execution_repository": workflow_execution_repository,
|
||||||
invoke_from=invoke_from,
|
"workflow_node_execution_repository": workflow_node_execution_repository,
|
||||||
workflow_execution_repository=workflow_execution_repository,
|
"streaming": streaming,
|
||||||
workflow_node_execution_repository=workflow_node_execution_repository,
|
"workflow_thread_pool_id": workflow_thread_pool_id,
|
||||||
streaming=streaming,
|
},
|
||||||
workflow_thread_pool_id=workflow_thread_pool_id,
|
)
|
||||||
)
|
|
||||||
|
|
||||||
worker_thread = threading.Thread(target=worker_with_context)
|
|
||||||
|
|
||||||
worker_thread.start()
|
worker_thread.start()
|
||||||
# return batch, dataset, documents
|
# return batch, dataset, documents
|
||||||
@ -282,23 +280,7 @@ class PipelineGenerator(BaseAppGenerator):
|
|||||||
:param streaming: is stream
|
:param streaming: is stream
|
||||||
:param workflow_thread_pool_id: workflow thread pool id
|
:param workflow_thread_pool_id: workflow thread pool id
|
||||||
"""
|
"""
|
||||||
print("jin ru la 1")
|
with preserve_flask_contexts(flask_app, context_vars=context):
|
||||||
for var, val in context.items():
|
|
||||||
var.set(val)
|
|
||||||
|
|
||||||
# FIXME(-LAN-): Save current user before entering new app context
|
|
||||||
from flask import g
|
|
||||||
|
|
||||||
saved_user = None
|
|
||||||
if has_request_context() and hasattr(g, "_login_user"):
|
|
||||||
saved_user = g._login_user
|
|
||||||
with flask_app.app_context():
|
|
||||||
# Restore user in new app context
|
|
||||||
print("jin ru la 2")
|
|
||||||
if saved_user is not None:
|
|
||||||
from flask import g
|
|
||||||
|
|
||||||
g._login_user = saved_user
|
|
||||||
# init queue manager
|
# init queue manager
|
||||||
workflow = db.session.query(Workflow).filter(Workflow.id == workflow_id).first()
|
workflow = db.session.query(Workflow).filter(Workflow.id == workflow_id).first()
|
||||||
if not workflow:
|
if not workflow:
|
||||||
@ -311,20 +293,17 @@ class PipelineGenerator(BaseAppGenerator):
|
|||||||
)
|
)
|
||||||
context = contextvars.copy_context()
|
context = contextvars.copy_context()
|
||||||
|
|
||||||
@copy_current_request_context
|
|
||||||
def worker_with_context():
|
|
||||||
# Run the worker within the copied context
|
|
||||||
return context.run(
|
|
||||||
self._generate_worker,
|
|
||||||
flask_app=current_app._get_current_object(), # type: ignore
|
|
||||||
context=context,
|
|
||||||
queue_manager=queue_manager,
|
|
||||||
application_generate_entity=application_generate_entity,
|
|
||||||
workflow_thread_pool_id=workflow_thread_pool_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
# new thread
|
# new thread
|
||||||
worker_thread = threading.Thread(target=worker_with_context)
|
worker_thread = threading.Thread(
|
||||||
|
target=self._generate_worker,
|
||||||
|
kwargs={
|
||||||
|
"flask_app": current_app._get_current_object(), # type: ignore
|
||||||
|
"context": context,
|
||||||
|
"queue_manager": queue_manager,
|
||||||
|
"application_generate_entity": application_generate_entity,
|
||||||
|
"workflow_thread_pool_id": workflow_thread_pool_id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
worker_thread.start()
|
worker_thread.start()
|
||||||
|
|
||||||
@ -521,20 +500,9 @@ class PipelineGenerator(BaseAppGenerator):
|
|||||||
:param workflow_thread_pool_id: workflow thread pool id
|
:param workflow_thread_pool_id: workflow thread pool id
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
print("jin ru la 3")
|
|
||||||
for var, val in context.items():
|
|
||||||
var.set(val)
|
|
||||||
from flask import g
|
|
||||||
|
|
||||||
saved_user = None
|
with preserve_flask_contexts(flask_app, context_vars=context):
|
||||||
if has_request_context() and hasattr(g, "_login_user"):
|
|
||||||
saved_user = g._login_user
|
|
||||||
with flask_app.app_context():
|
|
||||||
try:
|
try:
|
||||||
if saved_user is not None:
|
|
||||||
from flask import g
|
|
||||||
|
|
||||||
g._login_user = saved_user
|
|
||||||
# workflow app
|
# workflow app
|
||||||
runner = PipelineRunner(
|
runner = PipelineRunner(
|
||||||
application_generate_entity=application_generate_entity,
|
application_generate_entity=application_generate_entity,
|
||||||
|
|||||||
@ -41,6 +41,12 @@ class WeaviateVector(BaseVector):
|
|||||||
|
|
||||||
weaviate.connect.connection.has_grpc = False
|
weaviate.connect.connection.has_grpc = False
|
||||||
|
|
||||||
|
# Fix to minimize the performance impact of the deprecation check in weaviate-client 3.24.0,
|
||||||
|
# by changing the connection timeout to pypi.org from 1 second to 0.001 seconds.
|
||||||
|
# TODO: This can be removed once weaviate-client is updated to 3.26.7 or higher,
|
||||||
|
# which does not contain the deprecation check.
|
||||||
|
weaviate.connect.connection.PYPI_TIMEOUT = 0.001
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = weaviate.Client(
|
client = weaviate.Client(
|
||||||
url=config.endpoint, auth_client_secret=auth_config, timeout_config=(5, 60), startup_period=None
|
url=config.endpoint, auth_client_secret=auth_config, timeout_config=(5, 60), startup_period=None
|
||||||
|
|||||||
@ -214,7 +214,7 @@ class AgentNode(ToolNode):
|
|||||||
)
|
)
|
||||||
if tool_runtime.entity.description:
|
if tool_runtime.entity.description:
|
||||||
tool_runtime.entity.description.llm = (
|
tool_runtime.entity.description.llm = (
|
||||||
extra.get("descrption", "") or tool_runtime.entity.description.llm
|
extra.get("description", "") or tool_runtime.entity.description.llm
|
||||||
)
|
)
|
||||||
for tool_runtime_params in tool_runtime.entity.parameters:
|
for tool_runtime_params in tool_runtime.entity.parameters:
|
||||||
tool_runtime_params.form = (
|
tool_runtime_params.form = (
|
||||||
|
|||||||
@ -31,10 +31,13 @@ const TestApi: FC<Props> = ({
|
|||||||
const language = getLanguage(locale)
|
const language = getLanguage(locale)
|
||||||
const [credentialsModalShow, setCredentialsModalShow] = useState(false)
|
const [credentialsModalShow, setCredentialsModalShow] = useState(false)
|
||||||
const [tempCredential, setTempCredential] = React.useState<Credential>(customCollection.credentials)
|
const [tempCredential, setTempCredential] = React.useState<Credential>(customCollection.credentials)
|
||||||
|
const [testing, setTesting] = useState(false)
|
||||||
const [result, setResult] = useState<string>('')
|
const [result, setResult] = useState<string>('')
|
||||||
const { operation_id: toolName, parameters } = tool
|
const { operation_id: toolName, parameters } = tool
|
||||||
const [parametersValue, setParametersValue] = useState<Record<string, string>>({})
|
const [parametersValue, setParametersValue] = useState<Record<string, string>>({})
|
||||||
const handleTest = async () => {
|
const handleTest = async () => {
|
||||||
|
if (testing) return
|
||||||
|
setTesting(true)
|
||||||
// clone test schema
|
// clone test schema
|
||||||
const credentials = JSON.parse(JSON.stringify(tempCredential)) as Credential
|
const credentials = JSON.parse(JSON.stringify(tempCredential)) as Credential
|
||||||
if (credentials.auth_type === AuthType.none) {
|
if (credentials.auth_type === AuthType.none) {
|
||||||
@ -52,6 +55,7 @@ const TestApi: FC<Props> = ({
|
|||||||
}
|
}
|
||||||
const res = await testAPIAvailable(data) as any
|
const res = await testAPIAvailable(data) as any
|
||||||
setResult(res.error || res.result)
|
setResult(res.error || res.result)
|
||||||
|
setTesting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -107,7 +111,7 @@ const TestApi: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<Button variant='primary' className=' mt-4 h-10 w-full' onClick={handleTest}>{t('tools.test.title')}</Button>
|
<Button variant='primary' className=' mt-4 h-10 w-full' loading={testing} disabled={testing} onClick={handleTest}>{t('tools.test.title')}</Button>
|
||||||
<div className='mt-6'>
|
<div className='mt-6'>
|
||||||
<div className='flex items-center space-x-3'>
|
<div className='flex items-center space-x-3'>
|
||||||
<div className='system-xs-semibold text-text-tertiary'>{t('tools.test.testResult')}</div>
|
<div className='system-xs-semibold text-text-tertiary'>{t('tools.test.testResult')}</div>
|
||||||
|
|||||||
@ -118,6 +118,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
|||||||
title={<>
|
title={<>
|
||||||
{renderI18nObject(def.label)} {def.required && <span className='text-red-500'>*</span>}
|
{renderI18nObject(def.label)} {def.required && <span className='text-red-500'>*</span>}
|
||||||
</>}
|
</>}
|
||||||
|
key={def.variable}
|
||||||
tooltip={def.tooltip && renderI18nObject(def.tooltip)}
|
tooltip={def.tooltip && renderI18nObject(def.tooltip)}
|
||||||
inline
|
inline
|
||||||
>
|
>
|
||||||
|
|||||||
@ -140,6 +140,7 @@ const CodeEditor: FC<Props> = ({
|
|||||||
language={languageMap[language] || 'javascript'}
|
language={languageMap[language] || 'javascript'}
|
||||||
theme={isMounted ? theme : 'default-theme'} // sometimes not load the default theme
|
theme={isMounted ? theme : 'default-theme'} // sometimes not load the default theme
|
||||||
value={outPutValue}
|
value={outPutValue}
|
||||||
|
loading={<span className='text-text-primary'>Loading...</span>}
|
||||||
onChange={handleEditorChange}
|
onChange={handleEditorChange}
|
||||||
// https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOptions.html
|
// https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOptions.html
|
||||||
options={{
|
options={{
|
||||||
|
|||||||
@ -54,9 +54,9 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
|||||||
const field = param.name
|
const field = param.name
|
||||||
const value = inputs.agent_parameters?.[field]?.value
|
const value = inputs.agent_parameters?.[field]?.value
|
||||||
if (value) {
|
if (value) {
|
||||||
(value as unknown as any[]).forEach((item) => {
|
(value as unknown as any[]).forEach((item, idx) => {
|
||||||
tools.push({
|
tools.push({
|
||||||
id: `${param.name}-${i}`,
|
id: `${param.name}-${idx}`,
|
||||||
providerName: item.provider_name,
|
providerName: item.provider_name,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -207,6 +207,7 @@ const translation = {
|
|||||||
modelNotSupportedTip: 'El modelo actual no admite esta función y se degrada automáticamente a inyección de comandos.',
|
modelNotSupportedTip: 'El modelo actual no admite esta función y se degrada automáticamente a inyección de comandos.',
|
||||||
structuredTip: 'Las Salidas Estructuradas son una función que garantiza que el modelo siempre generará respuestas que se ajusten a su esquema JSON proporcionado.',
|
structuredTip: 'Las Salidas Estructuradas son una función que garantiza que el modelo siempre generará respuestas que se ajusten a su esquema JSON proporcionado.',
|
||||||
modelNotSupported: 'Modelo no soportado',
|
modelNotSupported: 'Modelo no soportado',
|
||||||
|
structured: 'sistemático',
|
||||||
},
|
},
|
||||||
accessItemsDescription: {
|
accessItemsDescription: {
|
||||||
anyone: 'Cualquiera puede acceder a la aplicación web.',
|
anyone: 'Cualquiera puede acceder a la aplicación web.',
|
||||||
|
|||||||
@ -202,6 +202,7 @@ const translation = {
|
|||||||
builtInDescription: 'Los metadatos integrados se extraen y generan automáticamente. Deben estar habilitados antes de su uso y no se pueden editar.',
|
builtInDescription: 'Los metadatos integrados se extraen y generan automáticamente. Deben estar habilitados antes de su uso y no se pueden editar.',
|
||||||
name: 'Nombre',
|
name: 'Nombre',
|
||||||
description: 'Puedes gestionar todos los metadatos en este conocimiento aquí. Las modificaciones se sincronizarán en todos los documentos.',
|
description: 'Puedes gestionar todos los metadatos en este conocimiento aquí. Las modificaciones se sincronizarán en todos los documentos.',
|
||||||
|
disabled: 'desactivar',
|
||||||
},
|
},
|
||||||
documentMetadata: {
|
documentMetadata: {
|
||||||
technicalParameters: 'Parámetros técnicos',
|
technicalParameters: 'Parámetros técnicos',
|
||||||
|
|||||||
@ -188,6 +188,7 @@ const translation = {
|
|||||||
nodeResize: '노드 크기 조정됨',
|
nodeResize: '노드 크기 조정됨',
|
||||||
nodeDragStop: '노드가 이동했습니다.',
|
nodeDragStop: '노드가 이동했습니다.',
|
||||||
edgeDelete: '노드가 연결이 끊어졌습니다.',
|
edgeDelete: '노드가 연결이 끊어졌습니다.',
|
||||||
|
nodeTitleChange: '노드 제목이 변경됨',
|
||||||
},
|
},
|
||||||
errorMsg: {
|
errorMsg: {
|
||||||
fieldRequired: '{{field}}가 필요합니다',
|
fieldRequired: '{{field}}가 필요합니다',
|
||||||
|
|||||||
@ -188,6 +188,7 @@ const translation = {
|
|||||||
nodeDescriptionChange: 'Descrierea nodului a fost modificată',
|
nodeDescriptionChange: 'Descrierea nodului a fost modificată',
|
||||||
edgeDelete: 'Nod deconectat',
|
edgeDelete: 'Nod deconectat',
|
||||||
nodeAdd: 'Nod adăugat',
|
nodeAdd: 'Nod adăugat',
|
||||||
|
nodeDragStop: 'Nod mutat',
|
||||||
},
|
},
|
||||||
errorMsg: {
|
errorMsg: {
|
||||||
fieldRequired: '{{field}} este obligatoriu',
|
fieldRequired: '{{field}} este obligatoriu',
|
||||||
|
|||||||
@ -112,6 +112,7 @@ const translation = {
|
|||||||
pointerMode: 'Način s kazalcem',
|
pointerMode: 'Način s kazalcem',
|
||||||
autoSaved: 'Samodejno shranjeno',
|
autoSaved: 'Samodejno shranjeno',
|
||||||
configure: 'Konfiguriraj',
|
configure: 'Konfiguriraj',
|
||||||
|
inRunMode: 'V načinu izvajanja',
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
modal: {
|
modal: {
|
||||||
@ -185,6 +186,7 @@ const translation = {
|
|||||||
clearHistory: 'Počisti zgodovino',
|
clearHistory: 'Počisti zgodovino',
|
||||||
hintText: 'Vaša dejanja urejanja so sledena v zgodovini sprememb, ki se hrani na vaši napravi za čas trajanja te seje. Ta zgodovina bo izbrisana, ko zapustite urejevalnik.',
|
hintText: 'Vaša dejanja urejanja so sledena v zgodovini sprememb, ki se hrani na vaši napravi za čas trajanja te seje. Ta zgodovina bo izbrisana, ko zapustite urejevalnik.',
|
||||||
placeholder: 'Še niste spremenili ničesar.',
|
placeholder: 'Še niste spremenili ničesar.',
|
||||||
|
stepForward_one: '{{count}} korak naprej',
|
||||||
},
|
},
|
||||||
errorMsg: {
|
errorMsg: {
|
||||||
fields: {
|
fields: {
|
||||||
@ -836,6 +838,7 @@ const translation = {
|
|||||||
upload_file_id: 'Naložite ID datoteke',
|
upload_file_id: 'Naložite ID datoteke',
|
||||||
title: 'datoteke, ki jih je ustvaril agent',
|
title: 'datoteke, ki jih je ustvaril agent',
|
||||||
url: 'URL slike',
|
url: 'URL slike',
|
||||||
|
transfer_method: 'Metoda prenosa. Vrednost je remote_url ali local_file.',
|
||||||
},
|
},
|
||||||
json: 'agent generiran json',
|
json: 'agent generiran json',
|
||||||
text: 'vsebina, ki jo je ustvaril agent',
|
text: 'vsebina, ki jo je ustvaril agent',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user