Merge branch 'feat/r2' into deploy/rag-dev

This commit is contained in:
jyong 2025-06-18 11:06:37 +08:00
commit fa9f0ebfb1
13 changed files with 53 additions and 66 deletions

View File

@ -163,7 +163,7 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
)
db.session.add(end_user)
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())
payload = {
"iss": site.id,

View File

@ -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_node_execution_repository import WorkflowNodeExecutionRepository
from extensions.ext_database import db
from libs.flask_utils import preserve_flask_contexts
from models import Account, EndUser, Workflow, WorkflowNodeExecutionTriggeredFrom
from models.dataset import Document, DocumentPipelineExecutionLog, Pipeline
from models.enums import WorkflowRunTriggeredFrom
@ -209,25 +210,22 @@ class PipelineGenerator(BaseAppGenerator):
# run in child thread
context = contextvars.copy_context()
@copy_current_request_context
def worker_with_context():
# Run the worker within the copied context
return context.run(
self._generate,
flask_app=current_app._get_current_object(), # type: ignore
context=context,
pipeline=pipeline,
workflow_id=workflow.id,
user=user,
application_generate_entity=application_generate_entity,
invoke_from=invoke_from,
workflow_execution_repository=workflow_execution_repository,
workflow_node_execution_repository=workflow_node_execution_repository,
streaming=streaming,
workflow_thread_pool_id=workflow_thread_pool_id,
)
worker_thread = threading.Thread(target=worker_with_context)
worker_thread = threading.Thread(
target=self._generate,
kwargs={
"flask_app": current_app._get_current_object(), # type: ignore
"context": context,
"pipeline": pipeline,
"workflow_id": workflow.id,
"user": user,
"application_generate_entity": application_generate_entity,
"invoke_from": invoke_from,
"workflow_execution_repository": workflow_execution_repository,
"workflow_node_execution_repository": workflow_node_execution_repository,
"streaming": streaming,
"workflow_thread_pool_id": workflow_thread_pool_id,
},
)
worker_thread.start()
# return batch, dataset, documents
@ -282,23 +280,7 @@ class PipelineGenerator(BaseAppGenerator):
:param streaming: is stream
:param workflow_thread_pool_id: workflow thread pool id
"""
print("jin ru la 1")
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
with preserve_flask_contexts(flask_app, context_vars=context):
# init queue manager
workflow = db.session.query(Workflow).filter(Workflow.id == workflow_id).first()
if not workflow:
@ -311,20 +293,17 @@ class PipelineGenerator(BaseAppGenerator):
)
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
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()
@ -521,20 +500,9 @@ class PipelineGenerator(BaseAppGenerator):
:param workflow_thread_pool_id: workflow thread pool id
:return:
"""
print("jin ru la 3")
for var, val in context.items():
var.set(val)
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():
with preserve_flask_contexts(flask_app, context_vars=context):
try:
if saved_user is not None:
from flask import g
g._login_user = saved_user
# workflow app
runner = PipelineRunner(
application_generate_entity=application_generate_entity,

View File

@ -41,6 +41,12 @@ class WeaviateVector(BaseVector):
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:
client = weaviate.Client(
url=config.endpoint, auth_client_secret=auth_config, timeout_config=(5, 60), startup_period=None

View File

@ -214,7 +214,7 @@ class AgentNode(ToolNode):
)
if tool_runtime.entity.description:
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:
tool_runtime_params.form = (

View File

@ -31,10 +31,13 @@ const TestApi: FC<Props> = ({
const language = getLanguage(locale)
const [credentialsModalShow, setCredentialsModalShow] = useState(false)
const [tempCredential, setTempCredential] = React.useState<Credential>(customCollection.credentials)
const [testing, setTesting] = useState(false)
const [result, setResult] = useState<string>('')
const { operation_id: toolName, parameters } = tool
const [parametersValue, setParametersValue] = useState<Record<string, string>>({})
const handleTest = async () => {
if (testing) return
setTesting(true)
// clone test schema
const credentials = JSON.parse(JSON.stringify(tempCredential)) as Credential
if (credentials.auth_type === AuthType.none) {
@ -52,6 +55,7 @@ const TestApi: FC<Props> = ({
}
const res = await testAPIAvailable(data) as any
setResult(res.error || res.result)
setTesting(false)
}
return (
@ -107,7 +111,7 @@ const TestApi: FC<Props> = ({
</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='flex items-center space-x-3'>
<div className='system-xs-semibold text-text-tertiary'>{t('tools.test.testResult')}</div>

View File

@ -118,6 +118,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
title={<>
{renderI18nObject(def.label)} {def.required && <span className='text-red-500'>*</span>}
</>}
key={def.variable}
tooltip={def.tooltip && renderI18nObject(def.tooltip)}
inline
>

View File

@ -140,6 +140,7 @@ const CodeEditor: FC<Props> = ({
language={languageMap[language] || 'javascript'}
theme={isMounted ? theme : 'default-theme'} // sometimes not load the default theme
value={outPutValue}
loading={<span className='text-text-primary'>Loading...</span>}
onChange={handleEditorChange}
// https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOptions.html
options={{

View File

@ -54,9 +54,9 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
const field = param.name
const value = inputs.agent_parameters?.[field]?.value
if (value) {
(value as unknown as any[]).forEach((item) => {
(value as unknown as any[]).forEach((item, idx) => {
tools.push({
id: `${param.name}-${i}`,
id: `${param.name}-${idx}`,
providerName: item.provider_name,
})
})

View File

@ -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.',
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',
structured: 'sistemático',
},
accessItemsDescription: {
anyone: 'Cualquiera puede acceder a la aplicación web.',

View File

@ -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.',
name: 'Nombre',
description: 'Puedes gestionar todos los metadatos en este conocimiento aquí. Las modificaciones se sincronizarán en todos los documentos.',
disabled: 'desactivar',
},
documentMetadata: {
technicalParameters: 'Parámetros técnicos',

View File

@ -188,6 +188,7 @@ const translation = {
nodeResize: '노드 크기 조정됨',
nodeDragStop: '노드가 이동했습니다.',
edgeDelete: '노드가 연결이 끊어졌습니다.',
nodeTitleChange: '노드 제목이 변경됨',
},
errorMsg: {
fieldRequired: '{{field}}가 필요합니다',

View File

@ -188,6 +188,7 @@ const translation = {
nodeDescriptionChange: 'Descrierea nodului a fost modificată',
edgeDelete: 'Nod deconectat',
nodeAdd: 'Nod adăugat',
nodeDragStop: 'Nod mutat',
},
errorMsg: {
fieldRequired: '{{field}} este obligatoriu',

View File

@ -112,6 +112,7 @@ const translation = {
pointerMode: 'Način s kazalcem',
autoSaved: 'Samodejno shranjeno',
configure: 'Konfiguriraj',
inRunMode: 'V načinu izvajanja',
},
env: {
modal: {
@ -185,6 +186,7 @@ const translation = {
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.',
placeholder: 'Še niste spremenili ničesar.',
stepForward_one: '{{count}} korak naprej',
},
errorMsg: {
fields: {
@ -836,6 +838,7 @@ const translation = {
upload_file_id: 'Naložite ID datoteke',
title: 'datoteke, ki jih je ustvaril agent',
url: 'URL slike',
transfer_method: 'Metoda prenosa. Vrednost je remote_url ali local_file.',
},
json: 'agent generiran json',
text: 'vsebina, ki jo je ustvaril agent',