Compare commits

...

37 Commits

Author SHA1 Message Date
NFish 3c404d18b3 Merge branch 'fix/web-app-support-session-in-url' into deploy/enterprise 10 months ago
GareArc ff25bbca9f 1.7.0
-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCAAdFiEEFK5K98uJ0hmL9JLza6DRCN7QEf8FAmiAvFgACgkQa6DRCN7Q
 Ef816Qv+NYHzK0yCcwji6lvzcUgf7V1l8ZCbbJdbzztbQuoKlUsB2XQhyr2y30X5
 kYHafWGSXbEAVOII7ca39EuUGVnvLx/AR7AsPzxOL4bxmWNricCUaK/XFtlbFuo5
 Rp5PQSPXa0VOFfBzktH7R1B3ET5eGfKauA5exDesiAHG6EDWbchnsFSYxpXzHLLs
 wLX7IMhQjFqBLyOKfI88+IxN+Gyo2NOTUhjt5yEqm6pUJANi3pg6ZwLl3/ODW+fx
 fu9rcOWZj7SHMhS6J5tIqRi6YO2o/b1tgBhsgI5gsAKJOdV8BwC71Vfwe+sJv3oC
 aMn6l4z0GENKC+256ag13Ku4/EKXytOY4LGZZrMUHr4n7EEGI1ODsVjXXOr5Fh6S
 wPO4GziBHaSyVogvvR8Mq7w1E5D6neqe2H87zc3dLe+E/vkZsv1W/E+Qo3iTJmqU
 VN1Q6WyeF/MhPEafXVPhBTLqrwiHmtZHVARuTpFvJb1wVGV3Cb28a6YMnMLOTYf3
 KW8VxjGZ
 =EOwC
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg6SWWoDRBZt3I2ReXCRLrVSezuD
 ZkSRk8YmJa0R3Cde8AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
 AAAAQEZuS8+VT7OGNR+ITQUEyJM/KdyuP6rcLIaf48ccZ6dRLgGvRVV6UxtFjKiApRkPQZ
 uwVfos66Dd9sZxbEiFagE=
 -----END SSH SIGNATURE-----

Merge tag '1.7.0' into deploy/enterprise

1.7.0
10 months ago
NFish 24fdf10d1d fix: support authorization using session and user_id in URL. 10 months ago
-LAN- 51f26a83c6
test: add comprehensive unit tests for EmailI18nService
- Created comprehensive test suite with 19 test cases covering all EmailI18nService functionality
- Implemented mock classes (MockEmailRenderer, MockBrandingService, MockEmailSender) following protocol pattern
- Avoided using patch decorator, instead using constructor dependency injection for cleaner testing
- Tests cover:
  * Email sending with different languages (English, Chinese, fallback handling)
  * Branding enabled/disabled scenarios
  * Change email workflows (old/new phases)
  * Raw email sending (single and multiple recipients)
  * Error handling for invalid phases and missing templates
  * Subject templating with variables
  * Integration tests for default configuration and service creation
  * Flask-specific components (renderer and sender)

The tests follow DDD principles with proper separation of concerns and use
dependency injection rather than mocking frameworks for cleaner, more maintainable tests.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
10 months ago
-LAN- 1fe87c01c5
refactor: migrate direct mail.send usages to EmailI18nService
- Updated mail_enterprise_task.py to use EmailI18nService.send_raw_email()
- Updated queue_monitor_task.py to use EmailI18nService with new QUEUE_MONITOR_ALERT type
- Updated mail_clean_document_notify_task.py to use EmailI18nService with new DOCUMENT_CLEAN_NOTIFY type
- Added send_raw_email() method for backward compatibility with pre-rendered HTML emails
- Added new email types: ENTERPRISE_CUSTOM, QUEUE_MONITOR_ALERT, DOCUMENT_CLEAN_NOTIFY
- Added email template configurations for the new email types
- Removed unused imports (render_template, mail) from refactored files

This change centralizes email handling through EmailI18nService while maintaining
backward compatibility for legacy email sending patterns.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
10 months ago
-LAN- f05e7e7068
refactor: centralize email internationalization handling
- Create elegant email i18n module following DDD principles
- Eliminate repetitive language switching logic across email tasks
- Add comprehensive type hints and proper abstractions
- Support all existing email types with centralized configuration
- Reduce code duplication by 50% while maintaining backward compatibility
- Improve maintainability with single responsibility and dependency injection
10 months ago
NFish fc6017c46c fix: the text/icon shows wrong color in darkmode 10 months ago
crazywoola 7e0d865152 Chore/update gh template (#22480) 10 months ago
heyszt f4b92bb038 fix aliyun trace session_id (#22468) 10 months ago
Wu Tianwei 61de7a8654 fix: add background color for chat bubble in light and dark themes (#22472) 10 months ago
QuantumGhost 9269989924 feat(api): add UUIDv7 implementation in SQL and Python (#22058)
This PR introduces UUIDv7 implementations in both Python and SQL to establish the foundation for migrating from UUIDv4 to UUIDv7 as proposed in #19754.

ID generation algorithm of existing models are not changed, and new models should use UUIDv7 for ID generation.

Close #19754.
10 months ago
QuantumGhost 59c35a49b1 refactor(api): Separate SegmentType for Integer/Float to Enable Pydantic Serialization (#22025)
refactor(api): Separate SegmentType for Integer/Float to Enable Pydantic Serialization (#22025)

This PR addresses serialization issues in the VariablePool model by separating the `value_type` tags for `IntegerSegment`/`FloatSegment` and `IntegerVariable`/`FloatVariable`. Previously, both Integer and Float types shared the same `SegmentType.NUMBER` tag, causing conflicts during serialization.

Key changes:
- Introduce distinct `value_type` tags for Integer and Float segments/variables
- Add `VariableUnion` and `SegmentUnion` types for proper type discrimination
- Leverage Pydantic's discriminated union feature for seamless serialization/deserialization
- Enable accurate serialization of data structures containing these types

Closes #22024.
10 months ago
Kerwin Bryant 4a06e4d4d9 Improve Tooltip UX by enabling delay by default (#21383) 10 months ago
yolofit 5ba6983727 fix: When var value changed, PromptEditor should be reset (#22219) 10 months ago
NeatGuyCoding 8ef7f0fed2 minor fix: using Pydantic model_validate instead of deprecated parse_obj (#22239)
Signed-off-by: neatguycoding <15627489+NeatGuyCoding@users.noreply.github.com>
10 months ago
Jason Young b4779d4042 test: add comprehensive unit tests for console authentication and authorization decorators (#22439) 10 months ago
znn 23996a5605 adding tooltip for bindingCount (#22450)
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: crazywoola <427733928@qq.com>
10 months ago
NeatGuyCoding 780748460d fix(api): Fix potential thread leak in MCP `BaseSession` (#22169)
The `BaseSession` class in the `core/mcp/session` package uses `ThreadPoolExecutor` 
to run the receive loop but fails to properly clean up the executor and receiver 
future, leading to potential thread leaks.

This PR addresses this issue by:
- Initializing `_executor` and `_receiver_future` attributes to `None` for proper cleanup checks
- Adding graceful shutdown with a 5-second timeout in the `__exit__` method
- Ensuring the ThreadPoolExecutor is properly shut down to prevent resource leaks

This fix prevents memory leaks and hanging threads in long-running scenarios where 
multiple MCP sessions are created and destroyed.

Signed-off-by: neatguycoding <15627489+NeatGuyCoding@users.noreply.github.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
10 months ago
Jacky Wu e48483b52d chore: add SQLALCHEMY_POOL_USE_LIFO option and missing SQLALCHEMY_POOL_PRE_PING env default value. (#22371) 10 months ago
GuanMu db2b3650ca fix: Disable question editing in chat history (#22438) 10 months ago
GuanMu 6f35fa1e46 fix: Update condition items to support variable type acquisition (#22414) 10 months ago
zyssyz123 3484cee5cf
Feat/change user email (#22425)
Co-authored-by: JzoNg <jzongcode@gmail.com>
10 months ago
Garfield Dai 0fe9d4955c Merge remote-tracking branch 'origin/main' into deploy/enterprise 10 months ago
NFish 2a0a315187 Merge branch 'perf/web-app-authrozation' into deploy/enterprise 10 months ago
NFish 3e18dd41e7 fix: show App is UnAvailable when no app info found in explore page 10 months ago
NFish 128f8de382 Merge branch 'perf/web-app-authrozation' into deploy/enterprise 10 months ago
NFish 8ead8961ce fix: check user can access web app in background task 10 months ago
NFish 8a888e082d Merge branch 'perf/web-app-authrozation' into deploy/enterprise 10 months ago
NFish 513af98729 perf: use component to handle webapp info fetch, authorization 10 months ago
NFish 35d2a935a3 Merge branch 'fix/allow-update-plugin-settings' into deploy/enterprise 10 months ago
NFish 207d0f78f5 fix: allow update plugin install settings 10 months ago
NFish 56e8b9711d Merge branch 'perf/web-app-authrozation' into deploy/enterprise 11 months ago
NFish e4b6c33bdd wip: Adjust the authentication process to improve user experience 11 months ago
NFish c0e73c1659 Merge branch 'fix/install-preference-error' into deploy/enterprise 11 months ago
NFish 434c809866 don't add search params when opening detail links from marketplace. 11 months ago
NFish 6ab09397ef Merge branch 'perf/web-app-authrozation' into deploy/enterprise 11 months ago
NFish 3bead19f19 wip: enhance user experience by refining authorization verification process 11 months ago

@ -43,6 +43,18 @@ class OwnerTransferRateLimitExceededError(BaseHTTPException):
code = 429
class EmailChangeRateLimitExceededError(BaseHTTPException):
error_code = "email_change_rate_limit_exceeded"
description = "Too many email change emails have been sent. Please try again in 1 minutes."
code = 429
class OwnerTransferRateLimitExceededError(BaseHTTPException):
error_code = "owner_transfer_rate_limit_exceeded"
description = "Too many owner tansfer emails have been sent. Please try again in 1 minutes."
code = 429
class EmailCodeError(BaseHTTPException):
error_code = "email_code_error"
description = "Email code is invalid or expired."

@ -1,38 +1,26 @@
import pytz
from flask import request
from flask_login import current_user
from flask_restful import Resource, fields, marshal_with, reqparse
from sqlalchemy import select
from sqlalchemy.orm import Session
from configs import dify_config
from constants.languages import supported_language
from controllers.console import api
from controllers.console.auth.error import (
EmailAlreadyInUseError,
from controllers.console.auth.error import (EmailAlreadyInUseError,
EmailChangeLimitError,
EmailCodeError,
InvalidEmailError,
InvalidTokenError,
)
EmailCodeError, InvalidEmailError,
InvalidTokenError)
from controllers.console.error import AccountNotFound, EmailSendIpLimitError
from controllers.console.workspace.error import (
AccountAlreadyInitedError,
CurrentPasswordIncorrectError,
InvalidAccountDeletionCodeError,
InvalidInvitationCodeError,
RepeatPasswordNotMatchError,
)
from controllers.console.wraps import (
account_initialization_required,
AccountAlreadyInitedError, CurrentPasswordIncorrectError,
InvalidAccountDeletionCodeError, InvalidInvitationCodeError,
RepeatPasswordNotMatchError)
from controllers.console.wraps import (account_initialization_required,
cloud_edition_billing_enabled,
enable_change_email,
enterprise_license_required,
only_edition_cloud,
setup_required,
)
only_edition_cloud, setup_required)
from extensions.ext_database import db
from fields.member_fields import account_fields
from flask import request
from flask_login import current_user
from flask_restful import Resource, fields, marshal_with, reqparse
from libs.datetime_utils import naive_utc_now
from libs.helper import TimestampField, email, extract_remote_ip, timezone
from libs.login import login_required
@ -40,7 +28,10 @@ from models import AccountIntegrate, InvitationCode
from models.account import Account
from services.account_service import AccountService
from services.billing_service import BillingService
from services.errors.account import CurrentPasswordIncorrectError as ServiceCurrentPasswordIncorrectError
from services.errors.account import \
CurrentPasswordIncorrectError as ServiceCurrentPasswordIncorrectError
from sqlalchemy import select
from sqlalchemy.orm import Session
class AccountInitApi(Resource):

@ -1,34 +1,29 @@
from urllib import parse
from flask import request
from flask_login import current_user
from flask_restful import Resource, abort, marshal_with, reqparse
import services
from configs import dify_config
from controllers.console import api
from controllers.console.auth.error import (
CannotTransferOwnerToSelfError,
EmailCodeError,
InvalidEmailError,
from controllers.console.auth.error import (CannotTransferOwnerToSelfError,
EmailCodeError, InvalidEmailError,
InvalidTokenError,
MemberNotInTenantError,
NotOwnerError,
OwnerTransferLimitError,
)
from controllers.console.error import EmailSendIpLimitError, WorkspaceMembersLimitExceeded
from controllers.console.wraps import (
account_initialization_required,
OwnerTransferLimitError)
from controllers.console.error import (EmailSendIpLimitError,
WorkspaceMembersLimitExceeded)
from controllers.console.wraps import (account_initialization_required,
cloud_edition_billing_resource_check,
is_allow_transfer_owner,
setup_required,
)
is_allow_transfer_owner, setup_required)
from extensions.ext_database import db
from fields.member_fields import account_with_role_list_fields
from flask import request
from flask_login import current_user
from flask_restful import Resource, abort, marshal_with, reqparse
from libs.helper import extract_remote_ip
from libs.login import login_required
from models.account import Account, TenantAccountRole
from services.account_service import AccountService, RegisterService, TenantService
from services.account_service import (AccountService, RegisterService,
TenantService)
from services.errors.account import AccountAlreadyInTenantError
from services.feature_service import FeatureService

@ -2,24 +2,18 @@ import logging
from collections.abc import Mapping
from typing import Any, Optional, cast
from sqlalchemy import select
from sqlalchemy.orm import Session
from configs import dify_config
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfig
from core.app.apps.advanced_chat.app_config_manager import \
AdvancedChatAppConfig
from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.apps.workflow_app_runner import WorkflowBasedAppRunner
from core.app.entities.app_invoke_entities import (
AdvancedChatAppGenerateEntity,
AppGenerateEntity,
InvokeFrom,
)
from core.app.entities.queue_entities import (
QueueAnnotationReplyEvent,
AdvancedChatAppGenerateEntity, AppGenerateEntity, InvokeFrom)
from core.app.entities.queue_entities import (QueueAnnotationReplyEvent,
QueueStopEvent,
QueueTextChunkEvent,
)
from core.app.features.annotation_reply.annotation_reply import AnnotationReplyFeature
QueueTextChunkEvent)
from core.app.features.annotation_reply.annotation_reply import \
AnnotationReplyFeature
from core.moderation.base import ModerationError
from core.moderation.input_moderation import InputModeration
from core.variables.variables import VariableUnion
@ -33,6 +27,8 @@ from models import Workflow
from models.enums import UserFrom
from models.model import App, Conversation, Message, MessageAnnotation
from models.workflow import ConversationVariable, WorkflowType
from sqlalchemy import select
from sqlalchemy.orm import Session
logger = logging.getLogger(__name__)

@ -5,10 +5,8 @@ from configs import dify_config
from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.apps.workflow.app_config_manager import WorkflowAppConfig
from core.app.apps.workflow_app_runner import WorkflowBasedAppRunner
from core.app.entities.app_invoke_entities import (
InvokeFrom,
WorkflowAppGenerateEntity,
)
from core.app.entities.app_invoke_entities import (InvokeFrom,
WorkflowAppGenerateEntity)
from core.workflow.callbacks import WorkflowCallback, WorkflowLoggingCallback
from core.workflow.entities.variable_pool import VariablePool
from core.workflow.system_variable import SystemVariable

@ -4,46 +4,26 @@ from collections.abc import Callable, Generator
from contextlib import contextmanager
from typing import Any, Optional, Union
from sqlalchemy.orm import Session
from constants.tts_auto_play_timeout import TTS_AUTO_PLAY_TIMEOUT, TTS_AUTO_PLAY_YIELD_CPU_TIME
from constants.tts_auto_play_timeout import (TTS_AUTO_PLAY_TIMEOUT,
TTS_AUTO_PLAY_YIELD_CPU_TIME)
from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.apps.common.workflow_response_converter import WorkflowResponseConverter
from core.app.entities.app_invoke_entities import (
InvokeFrom,
WorkflowAppGenerateEntity,
)
from core.app.apps.common.workflow_response_converter import \
WorkflowResponseConverter
from core.app.entities.app_invoke_entities import (InvokeFrom,
WorkflowAppGenerateEntity)
from core.app.entities.queue_entities import (
MessageQueueMessage,
QueueAgentLogEvent,
QueueErrorEvent,
QueueIterationCompletedEvent,
QueueIterationNextEvent,
QueueIterationStartEvent,
QueueLoopCompletedEvent,
QueueLoopNextEvent,
QueueLoopStartEvent,
QueueNodeExceptionEvent,
QueueNodeFailedEvent,
QueueNodeInIterationFailedEvent,
QueueNodeInLoopFailedEvent,
QueueNodeRetryEvent,
QueueNodeStartedEvent,
QueueNodeSucceededEvent,
QueueParallelBranchRunFailedEvent,
QueueParallelBranchRunStartedEvent,
QueueParallelBranchRunSucceededEvent,
QueuePingEvent,
QueueStopEvent,
QueueTextChunkEvent,
QueueWorkflowFailedEvent,
QueueWorkflowPartialSuccessEvent,
QueueWorkflowStartedEvent,
QueueWorkflowSucceededEvent,
WorkflowQueueMessage,
)
from core.app.entities.task_entities import (
ErrorStreamResponse,
MessageQueueMessage, QueueAgentLogEvent, QueueErrorEvent,
QueueIterationCompletedEvent, QueueIterationNextEvent,
QueueIterationStartEvent, QueueLoopCompletedEvent, QueueLoopNextEvent,
QueueLoopStartEvent, QueueNodeExceptionEvent, QueueNodeFailedEvent,
QueueNodeInIterationFailedEvent, QueueNodeInLoopFailedEvent,
QueueNodeRetryEvent, QueueNodeStartedEvent, QueueNodeSucceededEvent,
QueueParallelBranchRunFailedEvent, QueueParallelBranchRunStartedEvent,
QueueParallelBranchRunSucceededEvent, QueuePingEvent, QueueStopEvent,
QueueTextChunkEvent, QueueWorkflowFailedEvent,
QueueWorkflowPartialSuccessEvent, QueueWorkflowStartedEvent,
QueueWorkflowSucceededEvent, WorkflowQueueMessage)
from core.app.entities.task_entities import (ErrorStreamResponse,
MessageAudioEndStreamResponse,
MessageAudioStreamResponse,
PingStreamResponse,
@ -52,27 +32,31 @@ from core.app.entities.task_entities import (
WorkflowAppBlockingResponse,
WorkflowAppStreamResponse,
WorkflowFinishStreamResponse,
WorkflowStartStreamResponse,
)
from core.app.task_pipeline.based_generate_task_pipeline import BasedGenerateTaskPipeline
WorkflowStartStreamResponse)
from core.app.task_pipeline.based_generate_task_pipeline import \
BasedGenerateTaskPipeline
from core.base.tts import AppGeneratorTTSPublisher, AudioTrunk
from core.ops.ops_trace_manager import TraceQueueManager
from core.workflow.entities.workflow_execution import WorkflowExecution, WorkflowExecutionStatus, WorkflowType
from core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeState
from core.workflow.repositories.draft_variable_repository import DraftVariableSaverFactory
from core.workflow.repositories.workflow_execution_repository import WorkflowExecutionRepository
from core.workflow.repositories.workflow_node_execution_repository import WorkflowNodeExecutionRepository
from core.workflow.entities.workflow_execution import (WorkflowExecution,
WorkflowExecutionStatus,
WorkflowType)
from core.workflow.graph_engine.entities.graph_runtime_state import \
GraphRuntimeState
from core.workflow.repositories.draft_variable_repository import \
DraftVariableSaverFactory
from core.workflow.repositories.workflow_execution_repository import \
WorkflowExecutionRepository
from core.workflow.repositories.workflow_node_execution_repository import \
WorkflowNodeExecutionRepository
from core.workflow.system_variable import SystemVariable
from core.workflow.workflow_cycle_manager import CycleManagerWorkflowInfo, WorkflowCycleManager
from core.workflow.workflow_cycle_manager import (CycleManagerWorkflowInfo,
WorkflowCycleManager)
from extensions.ext_database import db
from models.account import Account
from models.enums import CreatorUserRole
from models.model import EndUser
from models.workflow import (
Workflow,
WorkflowAppLog,
WorkflowAppLogCreatedFrom,
)
from models.workflow import Workflow, WorkflowAppLog, WorkflowAppLogCreatedFrom
from sqlalchemy.orm import Session
logger = logging.getLogger(__name__)

@ -3,16 +3,17 @@ from collections import defaultdict
from collections.abc import Mapping, Sequence
from typing import Annotated, Any, Union, cast
from pydantic import BaseModel, Field
from core.file import File, FileAttribute, file_manager
from core.variables import Segment, SegmentGroup, Variable
from core.variables.consts import MIN_SELECTORS_LENGTH
from core.variables.segments import FileSegment, NoneSegment
from core.variables.variables import VariableUnion
from core.workflow.constants import CONVERSATION_VARIABLE_NODE_ID, ENVIRONMENT_VARIABLE_NODE_ID, SYSTEM_VARIABLE_NODE_ID
from core.workflow.constants import (CONVERSATION_VARIABLE_NODE_ID,
ENVIRONMENT_VARIABLE_NODE_ID,
SYSTEM_VARIABLE_NODE_ID)
from core.workflow.system_variable import SystemVariable
from factories import variable_factory
from pydantic import BaseModel, Field
VariableValue = Union[str, int, float, dict, list, File]
@ -186,3 +187,4 @@ class VariablePool(BaseModel):
def empty(cls) -> "VariablePool":
"""Create an empty variable pool."""
return cls(system_variables=SystemVariable.empty())
return cls(system_variables=SystemVariable.empty())

@ -4,28 +4,29 @@ from datetime import datetime
from typing import Any, Optional, Union
from uuid import uuid4
from core.app.entities.app_invoke_entities import AdvancedChatAppGenerateEntity, WorkflowAppGenerateEntity
from core.app.entities.queue_entities import (
QueueNodeExceptionEvent,
from core.app.entities.app_invoke_entities import (
AdvancedChatAppGenerateEntity, WorkflowAppGenerateEntity)
from core.app.entities.queue_entities import (QueueNodeExceptionEvent,
QueueNodeFailedEvent,
QueueNodeInIterationFailedEvent,
QueueNodeInLoopFailedEvent,
QueueNodeRetryEvent,
QueueNodeStartedEvent,
QueueNodeSucceededEvent,
)
QueueNodeSucceededEvent)
from core.app.task_pipeline.exc import WorkflowRunNotFoundError
from core.ops.entities.trace_entity import TraceTaskName
from core.ops.ops_trace_manager import TraceQueueManager, TraceTask
from core.workflow.entities.workflow_execution import WorkflowExecution, WorkflowExecutionStatus, WorkflowType
from core.workflow.entities.workflow_execution import (WorkflowExecution,
WorkflowExecutionStatus,
WorkflowType)
from core.workflow.entities.workflow_node_execution import (
WorkflowNodeExecution,
WorkflowNodeExecutionMetadataKey,
WorkflowNodeExecutionStatus,
)
WorkflowNodeExecution, WorkflowNodeExecutionMetadataKey,
WorkflowNodeExecutionStatus)
from core.workflow.enums import SystemVariableKey
from core.workflow.repositories.workflow_execution_repository import WorkflowExecutionRepository
from core.workflow.repositories.workflow_node_execution_repository import WorkflowNodeExecutionRepository
from core.workflow.repositories.workflow_execution_repository import \
WorkflowExecutionRepository
from core.workflow.repositories.workflow_node_execution_repository import \
WorkflowNodeExecutionRepository
from core.workflow.system_variable import SystemVariable
from core.workflow.workflow_entry import WorkflowEntry
from libs.datetime_utils import naive_utc_now
@ -453,3 +454,4 @@ class WorkflowCycleManager:
execution_metadata_dict.update(event.execution_metadata)
return {**execution_metadata_dict, **origin_metadata} if execution_metadata_dict else origin_metadata
return {**execution_metadata_dict, **origin_metadata} if execution_metadata_dict else origin_metadata

@ -5,11 +5,9 @@ from collections.abc import Callable, Generator, Mapping, Sequence
from typing import Any, Optional, cast
from uuid import uuid4
from sqlalchemy import select
from sqlalchemy.orm import Session, sessionmaker
from core.app.app_config.entities import VariableEntityType
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
from core.app.apps.advanced_chat.app_config_manager import \
AdvancedChatAppConfigManager
from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager
from core.file import File
from core.repositories import DifyCoreRepositoryFactory
@ -17,7 +15,8 @@ from core.variables import Variable
from core.variables.variables import VariableUnion
from core.workflow.entities.node_entities import NodeRunResult
from core.workflow.entities.variable_pool import VariablePool
from core.workflow.entities.workflow_node_execution import WorkflowNodeExecution, WorkflowNodeExecutionStatus
from core.workflow.entities.workflow_node_execution import (
WorkflowNodeExecution, WorkflowNodeExecutionStatus)
from core.workflow.errors import WorkflowNodeRunFailedError
from core.workflow.graph_engine.entities.event import InNodeEvent
from core.workflow.nodes import NodeType
@ -25,33 +24,32 @@ from core.workflow.nodes.base.node import BaseNode
from core.workflow.nodes.enums import ErrorStrategy
from core.workflow.nodes.event import RunCompletedEvent
from core.workflow.nodes.event.types import NodeEvent
from core.workflow.nodes.node_mapping import LATEST_VERSION, NODE_TYPE_CLASSES_MAPPING
from core.workflow.nodes.node_mapping import (LATEST_VERSION,
NODE_TYPE_CLASSES_MAPPING)
from core.workflow.nodes.start.entities import StartNodeData
from core.workflow.system_variable import SystemVariable
from core.workflow.workflow_entry import WorkflowEntry
from events.app_event import app_draft_workflow_was_synced, app_published_workflow_was_updated
from events.app_event import (app_draft_workflow_was_synced,
app_published_workflow_was_updated)
from extensions.ext_database import db
from factories.file_factory import build_from_mapping, build_from_mappings
from libs.datetime_utils import naive_utc_now
from models.account import Account
from models.model import App, AppMode
from models.tools import WorkflowToolProvider
from models.workflow import (
Workflow,
WorkflowNodeExecutionModel,
WorkflowNodeExecutionTriggeredFrom,
WorkflowType,
)
from models.workflow import (Workflow, WorkflowNodeExecutionModel,
WorkflowNodeExecutionTriggeredFrom, WorkflowType)
from repositories.factory import DifyAPIRepositoryFactory
from services.errors.app import IsDraftWorkflowError, WorkflowHashNotEqualError
from services.workflow.workflow_converter import WorkflowConverter
from sqlalchemy import select
from sqlalchemy.orm import Session, sessionmaker
from .errors.workflow_service import DraftWorkflowDeletionError, WorkflowInUseError
from .workflow_draft_variable_service import (
DraftVariableSaver,
from .errors.workflow_service import (DraftWorkflowDeletionError,
WorkflowInUseError)
from .workflow_draft_variable_service import (DraftVariableSaver,
DraftVarLoader,
WorkflowDraftVariableService,
)
WorkflowDraftVariableService)
class WorkflowService:

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -122,4 +125,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -122,4 +125,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -122,4 +125,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -121,4 +124,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -89,4 +91,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -89,4 +91,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -97,7 +99,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -111,12 +114,14 @@
</div>
<p class="title">Workspace ownership has been transferred</p>
<div class="description">
<p class="content1">You have successfully transferred ownership of the workspace "{{WorkspaceName}}" to {{NewOwnerEmail}}.</p>
<p class="content2">You no longer have owner privileges for this workspace. Your access level has been changed to Admin.</p>
<p class="content3">If you did not initiate this transfer or have concerns about this change, please contact support@dify.ai immediately.</p>
<p class="content1">You have successfully transferred ownership of the workspace "{{WorkspaceName}}" to
{{NewOwnerEmail}}.</p>
<p class="content2">You no longer have owner privileges for this workspace. Your access level has been changed to
Admin.</p>
<p class="content3">If you did not initiate this transfer or have concerns about this change, please contact
support@dify.ai immediately.</p>
</div>
</div>
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -97,7 +99,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -119,4 +122,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -95,7 +97,8 @@
font-size: 14px;
font-style: normal;
font-weight: 600;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
}
.warningList {
@ -106,7 +109,8 @@
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -119,7 +123,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -150,4 +155,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -95,7 +97,8 @@
font-size: 14px;
font-style: normal;
font-weight: 600;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
}
.warningList {
@ -106,7 +109,8 @@
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -119,7 +123,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -150,4 +155,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -119,4 +122,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -119,4 +122,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -119,4 +122,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -96,7 +98,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -118,4 +121,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -86,4 +88,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -86,4 +88,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -97,7 +99,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -108,12 +111,14 @@
<div class="header"></div>
<p class="title">Workspace ownership has been transferred</p>
<div class="description">
<p class="content1">You have successfully transferred ownership of the workspace "{{WorkspaceName}}" to {{NewOwnerEmail}}.</p>
<p class="content2">You no longer have owner privileges for this workspace. Your access level has been changed to Admin.</p>
<p class="content3">If you did not initiate this transfer or have concerns about this change, please contact support@dify.ai immediately.</p>
<p class="content1">You have successfully transferred ownership of the workspace "{{WorkspaceName}}" to
{{NewOwnerEmail}}.</p>
<p class="content2">You no longer have owner privileges for this workspace. Your access level has been changed to
Admin.</p>
<p class="content3">If you did not initiate this transfer or have concerns about this change, please contact
support@dify.ai immediately.</p>
</div>
</div>
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -97,7 +99,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -116,4 +119,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -95,7 +97,8 @@
font-size: 14px;
font-style: normal;
font-weight: 600;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
}
.warningList {
@ -106,7 +109,8 @@
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -119,7 +123,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -147,4 +152,3 @@
</body>
</html>

@ -42,7 +42,8 @@
font-family: Inter;
font-style: normal;
font-weight: 600;
line-height: 120%; /* 28.8px */
line-height: 120%;
/* 28.8px */
}
.description {
@ -51,7 +52,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -95,7 +97,8 @@
font-size: 14px;
font-style: normal;
font-weight: 600;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
}
.warningList {
@ -106,7 +109,8 @@
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
@ -119,7 +123,8 @@
font-family: Inter;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
line-height: 20px;
/* 142.857% */
letter-spacing: -0.07px;
}
</style>
@ -147,4 +152,3 @@
</body>
</html>

@ -1,44 +1,24 @@
import dataclasses
from pydantic import BaseModel
from core.file import File, FileTransferMethod, FileType
from core.helper import encrypter
from core.variables.segments import (
ArrayAnySegment,
ArrayFileSegment,
ArrayNumberSegment,
ArrayObjectSegment,
ArrayStringSegment,
FileSegment,
FloatSegment,
IntegerSegment,
NoneSegment,
ObjectSegment,
Segment,
SegmentUnion,
StringSegment,
get_segment_discriminator,
)
from core.variables.segments import (ArrayAnySegment, ArrayFileSegment,
ArrayNumberSegment, ArrayObjectSegment,
ArrayStringSegment, FileSegment,
FloatSegment, IntegerSegment, NoneSegment,
ObjectSegment, Segment, SegmentUnion,
StringSegment, get_segment_discriminator)
from core.variables.types import SegmentType
from core.variables.variables import (
ArrayAnyVariable,
ArrayFileVariable,
ArrayNumberVariable,
ArrayObjectVariable,
ArrayStringVariable,
FileVariable,
FloatVariable,
IntegerVariable,
NoneVariable,
ObjectVariable,
SecretVariable,
StringVariable,
Variable,
VariableUnion,
)
from core.variables.variables import (ArrayAnyVariable, ArrayFileVariable,
ArrayNumberVariable, ArrayObjectVariable,
ArrayStringVariable, FileVariable,
FloatVariable, IntegerVariable,
NoneVariable, ObjectVariable,
SecretVariable, StringVariable, Variable,
VariableUnion)
from core.workflow.entities.variable_pool import VariablePool
from core.workflow.system_variable import SystemVariable
from pydantic import BaseModel
def test_segment_group_to_text():

@ -1,12 +1,7 @@
import React, { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import { useContext } from 'use-context-selector'
import { ToastContext } from '@/app/components/base/toast'
import { RiCloseLine } from '@remixicon/react'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import { ToastContext } from '@/app/components/base/toast'
import {
checkEmailExisted,
logout,
@ -14,7 +9,12 @@ import {
sendVerifyCode,
verifyEmail,
} from '@/service/common'
import { RiCloseLine } from '@remixicon/react'
import { noop } from 'lodash-es'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
type Props = {
show: boolean

@ -1,30 +1,28 @@
'use client'
import { useState } from 'react'
import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import PremiumBadge from '@/app/components/base/premium-badge'
import { ToastContext } from '@/app/components/base/toast'
import type { IItem } from '@/app/components/header/account-setting/collapse'
import Collapse from '@/app/components/header/account-setting/collapse'
import { IS_CE_EDITION, validPassword } from '@/config'
import { useAppContext } from '@/context/app-context'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useProviderContext } from '@/context/provider-context'
import { fetchAppList } from '@/service/apps'
import { updateUserProfile } from '@/service/common'
import {
RiGraduationCapFill,
} from '@remixicon/react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import useSWR from 'swr'
import { useContext } from 'use-context-selector'
import DeleteAccount from '../delete-account'
import AvatarWithEdit from './AvatarWithEdit'
import Collapse from '@/app/components/header/account-setting/collapse'
import type { IItem } from '@/app/components/header/account-setting/collapse'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import { updateUserProfile } from '@/service/common'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { ToastContext } from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon'
import { IS_CE_EDITION } from '@/config'
import Input from '@/app/components/base/input'
import PremiumBadge from '@/app/components/base/premium-badge'
import { useGlobalPublicStore } from '@/context/global-public-context'
import EmailChangeModal from './email-change-modal'
import { validPassword } from '@/config'
import { fetchAppList } from '@/service/apps'
import type { App } from '@/types/app'
const titleClassName = `
system-sm-semibold text-text-secondary
@ -207,7 +205,7 @@ export default function AccountPage() {
{!!apps.length && (
<Collapse
title={`${t('common.account.showAppLength', { length: apps.length })}`}
items={apps.map((app: App) => ({ ...app, key: app.id, name: app.name }))}
items={apps.map(app => ({ key: app.id, name: app.name }))}
renderItem={renderAppItem}
wrapperClassName='mt-2'
/>

@ -117,7 +117,7 @@ const Question: FC<QuestionProps> = ({
</div>
<div
ref={contentRef}
className='w-full rounded-2xl bg-background-gradient-bg-fill-chat-bubble-bg-3 px-4 py-3 text-sm text-text-primary'
className='bg-background-gradient-bg-fill-chat-bubble-bg-3 w-full rounded-2xl px-4 py-3 text-sm text-text-primary'
style={theme?.chatBubbleColorStyle ? CssTransform(theme.chatBubbleColorStyle) : {}}
>
{

@ -1,19 +1,19 @@
import React, { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { RiCloseLine } from '@remixicon/react'
import { useAppContext } from '@/context/app-context'
import { ToastContext } from '@/app/components/base/toast'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import MemberSelector from './member-selector'
import Modal from '@/app/components/base/modal'
import { ToastContext } from '@/app/components/base/toast'
import { useAppContext } from '@/context/app-context'
import {
ownershipTransfer,
sendOwnerEmail,
verifyOwnerEmail,
} from '@/service/common'
import { RiCloseLine } from '@remixicon/react'
import { noop } from 'lodash-es'
import { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import MemberSelector from './member-selector'
type Props = {
show: boolean

@ -2,6 +2,7 @@
import type { ChatConfig } from '@/app/components/base/chat/types'
import Loading from '@/app/components/base/loading'
import { checkOrSetAccessToken } from '@/app/components/share/utils'
import { AccessMode } from '@/models/access-control'
import type { AppData, AppMeta } from '@/models/share'
import { useGetWebAppAccessModeByCode } from '@/service/use-share'
@ -60,6 +61,8 @@ const WebAppStoreProvider: FC<PropsWithChildren> = ({ children }) => {
const pathname = usePathname()
const searchParams = useSearchParams()
const redirectUrlParam = searchParams.get('redirect_url')
const session = searchParams.get('session')
const sysUserId = searchParams.get('sys.user_id')
const [shareCode, setShareCode] = useState<string | null>(null)
useEffect(() => {
const shareCodeFromRedirect = getShareCodeFromRedirectUrl(redirectUrlParam)
@ -69,11 +72,22 @@ const WebAppStoreProvider: FC<PropsWithChildren> = ({ children }) => {
updateShareCode(newShareCode)
}, [pathname, redirectUrlParam, updateShareCode])
const { isFetching, data: accessModeResult } = useGetWebAppAccessModeByCode(shareCode)
const [isFetchingAccessToken, setIsFetchingAccessToken] = useState(true)
useEffect(() => {
if (accessModeResult?.accessMode)
if (accessModeResult?.accessMode) {
updateWebAppAccessMode(accessModeResult.accessMode)
}, [accessModeResult, updateWebAppAccessMode])
if (isFetching) {
if (accessModeResult?.accessMode === AccessMode.PUBLIC && session && sysUserId) {
setIsFetchingAccessToken(true)
checkOrSetAccessToken(shareCode).finally(() => {
setIsFetchingAccessToken(false)
})
}
else {
setIsFetchingAccessToken(false)
}
}
}, [accessModeResult, updateWebAppAccessMode, setIsFetchingAccessToken, shareCode, session, sysUserId])
if (isFetching || isFetchingAccessToken) {
return <div className='flex h-full w-full items-center justify-center'>
<Loading />
</div>

@ -1,5 +1,16 @@
import type { Fetcher } from 'swr'
import { del, get, patch, post, put } from './base'
import type {
DefaultModelResponse,
Model,
ModelItem,
ModelLoadBalancingConfig,
ModelParameterRule,
ModelProvider,
ModelTypeEnum,
} from '@/app/components/header/account-setting/model-provider-page/declarations'
import type {
UpdateOpenAIKeyResponse,
ValidateOpenAIKeyResponse,
} from '@/models/app'
import type {
AccountIntegrate,
ApiBasedExtension,
@ -22,21 +33,10 @@ import type {
SetupStatusResponse,
UserProfileOriginResponse,
} from '@/models/common'
import type {
UpdateOpenAIKeyResponse,
ValidateOpenAIKeyResponse,
} from '@/models/app'
import type {
DefaultModelResponse,
Model,
ModelItem,
ModelLoadBalancingConfig,
ModelParameterRule,
ModelProvider,
ModelTypeEnum,
} from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { RETRIEVE_METHOD } from '@/types/app'
import type { SystemFeatures } from '@/types/feature'
import type { Fetcher } from 'swr'
import { del, get, patch, post, put } from './base'
type LoginSuccess = {
result: 'success'

Loading…
Cancel
Save