Compare commits

..

24 Commits

Author SHA1 Message Date
208d6d6d94 chore: bump to 0.12.1 (#11122) 2024-11-26 15:46:17 +08:00
aa135a3780 Add TTS to OpenAI_API_Compatible (#11071) 2024-11-26 15:14:02 +08:00
044e7b63c2 fix(llm_node): Ignore file if not supported. (#11114) 2024-11-26 14:14:14 +08:00
5b7b328193 feat: Allow to contains files in the system prompt even model not support. (#11111) 2024-11-26 13:45:49 +08:00
8d5a1be227 fix: Cannot use files in the user inputs. (#11112) 2024-11-26 13:43:38 +08:00
90d5765fb6 fix: app copy raise error (#11108) 2024-11-26 13:42:13 +08:00
1db14793fa fix(anthropic_llm): Ignore non-text parts in the system prompt. (#11107) 2024-11-26 13:31:40 +08:00
cbb4e95928 fix(llm_node): Ignore user query when memory is disabled. (#11106) 2024-11-26 13:07:32 +08:00
20c091a5e7 fix: user query be ignored if query_prompt_template is an empty string (#11103) 2024-11-26 12:47:59 +08:00
e9c098d024 Fix regenerate themes (#11101) 2024-11-26 11:33:04 +08:00
9f75970347 fix: ops_trace_manager from_end_user_id (#11077) 2024-11-26 10:29:00 +08:00
f1366e8e19 fix #11091 raise redirect issue (#11092) 2024-11-26 10:25:42 +08:00
0f85e3557b fix: site icon not showing (#11094) 2024-11-26 10:23:03 +08:00
17ee731546 SearchApi - Return error message instead of raising a ValueError (#11083) 2024-11-26 09:34:51 +08:00
af2461cccc Add query_prefix + Return TED Transcript URL for Downstream Scraping Tasks (#11090) 2024-11-26 09:32:37 +08:00
60c1549771 fix: import Explore Apps raise error (#11091) 2024-11-26 09:32:08 +08:00
ab6dcf7032 fix: update the max tokens configuration for Azure GPT-4o (2024-08-06) to 16384 (#11074) 2024-11-25 21:13:02 +08:00
8aae235a71 fix: int None will cause error for context size (#11055)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
2024-11-25 21:04:16 +08:00
c032574491 fix: timezone not imported in conversation service. (#11076) 2024-11-25 20:53:55 +08:00
1065917872 Add grok-vision-beta to xAI + Update grok-beta Features (#11004) 2024-11-25 20:53:03 +08:00
56e361ac44 fix: chart tool chinese font display and raise error (#11058) 2024-11-25 19:50:33 +08:00
2e00829b1e fix: drop useless and wrong code for zhipu embedding (#11069)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
2024-11-25 19:50:23 +08:00
625aaceb00 chore: bump version to 0.12.0 (#11056) 2024-11-25 19:17:59 +08:00
98d85e6b74 fix: WorkflowNodeExecution.created_at may be earlier than WorkflowRun.created_at (#11070) 2024-11-25 18:16:55 +08:00
62 changed files with 876 additions and 182 deletions

View File

@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings):
CURRENT_VERSION: str = Field(
description="Dify version",
default="0.11.2",
default="0.12.1",
)
COMMIT_SHA: str = Field(

View File

@ -190,7 +190,7 @@ class AppCopyApi(Resource):
)
session.commit()
stmt = select(App).where(App.id == result.app.id)
stmt = select(App).where(App.id == result.app_id)
app = session.scalar(stmt)
return app, 201

View File

@ -127,7 +127,9 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
conversation_id=conversation.id if conversation else None,
inputs=conversation.inputs
if conversation
else self._prepare_user_inputs(user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.id),
else self._prepare_user_inputs(
user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.tenant_id
),
query=query,
files=file_objs,
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,

View File

@ -134,7 +134,9 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
conversation_id=conversation.id if conversation else None,
inputs=conversation.inputs
if conversation
else self._prepare_user_inputs(user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.id),
else self._prepare_user_inputs(
user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.tenant_id
),
query=query,
files=file_objs,
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,

View File

@ -132,7 +132,9 @@ class ChatAppGenerator(MessageBasedAppGenerator):
conversation_id=conversation.id if conversation else None,
inputs=conversation.inputs
if conversation
else self._prepare_user_inputs(user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.id),
else self._prepare_user_inputs(
user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.tenant_id
),
query=query,
files=file_objs,
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,

View File

@ -114,7 +114,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
model_conf=ModelConfigConverter.convert(app_config),
file_upload_config=file_extra_config,
inputs=self._prepare_user_inputs(
user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.id
user_inputs=inputs, variables=app_config.variables, tenant_id=app_model.tenant_id
),
query=query,
files=file_objs,

View File

@ -3,6 +3,7 @@ import time
from collections.abc import Mapping, Sequence
from datetime import UTC, datetime
from typing import Any, Optional, Union, cast
from uuid import uuid4
from sqlalchemy.orm import Session
@ -80,38 +81,38 @@ class WorkflowCycleManage:
inputs[f"sys.{key.value}"] = value
inputs = WorkflowEntry.handle_special_values(inputs)
triggered_from = (
WorkflowRunTriggeredFrom.DEBUGGING
if self._application_generate_entity.invoke_from == InvokeFrom.DEBUGGER
else WorkflowRunTriggeredFrom.APP_RUN
)
# init workflow run
workflow_run = WorkflowRun()
workflow_run_id = self._workflow_system_variables[SystemVariableKey.WORKFLOW_RUN_ID]
if workflow_run_id:
workflow_run.id = workflow_run_id
workflow_run.tenant_id = self._workflow.tenant_id
workflow_run.app_id = self._workflow.app_id
workflow_run.sequence_number = new_sequence_number
workflow_run.workflow_id = self._workflow.id
workflow_run.type = self._workflow.type
workflow_run.triggered_from = triggered_from.value
workflow_run.version = self._workflow.version
workflow_run.graph = self._workflow.graph
workflow_run.inputs = json.dumps(inputs)
workflow_run.status = WorkflowRunStatus.RUNNING.value
workflow_run.created_by_role = (
CreatedByRole.ACCOUNT.value if isinstance(self._user, Account) else CreatedByRole.END_USER.value
)
workflow_run.created_by = self._user.id
# handle special values
inputs = WorkflowEntry.handle_special_values(inputs)
db.session.add(workflow_run)
db.session.commit()
db.session.refresh(workflow_run)
db.session.close()
# init workflow run
with Session(db.engine, expire_on_commit=False) as session:
workflow_run = WorkflowRun()
system_id = self._workflow_system_variables[SystemVariableKey.WORKFLOW_RUN_ID]
workflow_run.id = system_id or str(uuid4())
workflow_run.tenant_id = self._workflow.tenant_id
workflow_run.app_id = self._workflow.app_id
workflow_run.sequence_number = new_sequence_number
workflow_run.workflow_id = self._workflow.id
workflow_run.type = self._workflow.type
workflow_run.triggered_from = triggered_from.value
workflow_run.version = self._workflow.version
workflow_run.graph = self._workflow.graph
workflow_run.inputs = json.dumps(inputs)
workflow_run.status = WorkflowRunStatus.RUNNING
workflow_run.created_by_role = (
CreatedByRole.ACCOUNT if isinstance(self._user, Account) else CreatedByRole.END_USER
)
workflow_run.created_by = self._user.id
workflow_run.created_at = datetime.now(UTC).replace(tzinfo=None)
session.add(workflow_run)
session.commit()
return workflow_run

View File

@ -720,8 +720,10 @@ class IndexingRunner:
tokens = 0
if embedding_model_instance:
page_content_list = [document.page_content for document in chunk_documents]
tokens += sum(embedding_model_instance.get_text_embedding_num_tokens(page_content_list))
tokens += sum(
embedding_model_instance.get_text_embedding_num_tokens([document.page_content])
for document in chunk_documents
)
# load index
index_processor.load(dataset, chunk_documents, with_keywords=False)

View File

@ -183,7 +183,7 @@ class ModelInstance:
input_type=input_type,
)
def get_text_embedding_num_tokens(self, texts: list[str]) -> list[int]:
def get_text_embedding_num_tokens(self, texts: list[str]) -> int:
"""
Get number of tokens for text embedding

View File

@ -453,7 +453,7 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
return credentials_kwargs
def _convert_prompt_messages(self, prompt_messages: list[PromptMessage]) -> tuple[str, list[dict]]:
def _convert_prompt_messages(self, prompt_messages: Sequence[PromptMessage]) -> tuple[str, list[dict]]:
"""
Convert prompt messages to dict list and system
"""
@ -461,7 +461,15 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
first_loop = True
for message in prompt_messages:
if isinstance(message, SystemPromptMessage):
message.content = message.content.strip()
if isinstance(message.content, str):
message.content = message.content.strip()
elif isinstance(message.content, list):
# System prompt only support text
message.content = "".join(
c.data.strip() for c in message.content if isinstance(c, TextPromptMessageContent)
)
else:
raise ValueError(f"Unknown system prompt message content type {type(message.content)}")
if first_loop:
system = message.content
first_loop = False

View File

@ -779,7 +779,7 @@ LLM_BASE_MODELS = [
name="frequency_penalty",
**PARAMETER_RULE_TEMPLATE[DefaultParameterName.FREQUENCY_PENALTY],
),
_get_max_tokens(default=512, min_val=1, max_val=4096),
_get_max_tokens(default=512, min_val=1, max_val=16384),
ParameterRule(
name="seed",
label=I18nObject(zh_Hans="种子", en_US="Seed"),

View File

@ -14,7 +14,7 @@ from core.model_runtime.model_providers.azure_openai._constant import TTS_BASE_M
class AzureOpenAIText2SpeechModel(_CommonAzureOpenAI, TTSModel):
"""
Model class for OpenAI Speech to text model.
Model class for OpenAI text2speech model.
"""
def _invoke(

View File

@ -122,7 +122,7 @@ class GiteeAIRerankModel(RerankModel):
label=I18nObject(en_US=model),
model_type=ModelType.RERANK,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))},
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512))},
)
return entity

View File

@ -10,7 +10,7 @@ from core.model_runtime.model_providers.gitee_ai._common import _CommonGiteeAI
class GiteeAIText2SpeechModel(_CommonGiteeAI, TTSModel):
"""
Model class for OpenAI Speech to text model.
Model class for OpenAI text2speech model.
"""
def _invoke(

View File

@ -140,7 +140,7 @@ class GPUStackRerankModel(RerankModel):
label=I18nObject(en_US=model),
model_type=ModelType.RERANK,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))},
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512))},
)
return entity

View File

@ -128,7 +128,7 @@ class JinaRerankModel(RerankModel):
label=I18nObject(en_US=model),
model_type=ModelType.RERANK,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))},
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 8000))},
)
return entity

View File

@ -193,7 +193,7 @@ class JinaTextEmbeddingModel(TextEmbeddingModel):
label=I18nObject(en_US=model),
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))},
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 8000))},
)
return entity

View File

@ -139,7 +139,7 @@ class OllamaEmbeddingModel(TextEmbeddingModel):
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size")),
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512)),
ModelPropertyKey.MAX_CHUNKS: 1,
},
parameter_rules=[],

View File

@ -943,6 +943,9 @@ class OpenAILargeLanguageModel(_CommonOpenAI, LargeLanguageModel):
}
elif isinstance(message, SystemPromptMessage):
message = cast(SystemPromptMessage, message)
if isinstance(message.content, list):
text_contents = filter(lambda c: isinstance(c, TextPromptMessageContent), message.content)
message.content = "".join(c.data for c in text_contents)
message_dict = {"role": "system", "content": message.content}
elif isinstance(message, ToolPromptMessage):
message = cast(ToolPromptMessage, message)

View File

@ -11,7 +11,7 @@ from core.model_runtime.model_providers.openai._common import _CommonOpenAI
class OpenAIText2SpeechModel(_CommonOpenAI, TTSModel):
"""
Model class for OpenAI Speech to text model.
Model class for OpenAI text2speech model.
"""
def _invoke(

View File

@ -9,6 +9,7 @@ supported_model_types:
- text-embedding
- speech2text
- rerank
- tts
configurate_methods:
- customizable-model
model_credential_schema:
@ -67,7 +68,7 @@ model_credential_schema:
- variable: __model_type
value: llm
type: text-input
default: '4096'
default: "4096"
placeholder:
zh_Hans: 在此输入您的模型上下文长度
en_US: Enter your Model context size
@ -80,7 +81,7 @@ model_credential_schema:
- variable: __model_type
value: text-embedding
type: text-input
default: '4096'
default: "4096"
placeholder:
zh_Hans: 在此输入您的模型上下文长度
en_US: Enter your Model context size
@ -93,7 +94,7 @@ model_credential_schema:
- variable: __model_type
value: rerank
type: text-input
default: '4096'
default: "4096"
placeholder:
zh_Hans: 在此输入您的模型上下文长度
en_US: Enter your Model context size
@ -104,7 +105,7 @@ model_credential_schema:
show_on:
- variable: __model_type
value: llm
default: '4096'
default: "4096"
type: text-input
- variable: function_calling_type
show_on:
@ -174,3 +175,19 @@ model_credential_schema:
value: llm
default: '\n\n'
type: text-input
- variable: voices
show_on:
- variable: __model_type
value: tts
label:
en_US: Available Voices (comma-separated)
zh_Hans: 可用声音(用英文逗号分隔)
type: text-input
required: false
default: "alloy"
placeholder:
en_US: "alloy,echo,fable,onyx,nova,shimmer"
zh_Hans: "alloy,echo,fable,onyx,nova,shimmer"
help:
en_US: "List voice names separated by commas. First voice will be used as default."
zh_Hans: "用英文逗号分隔的声音列表。第一个声音将作为默认值。"

View File

@ -176,7 +176,7 @@ class OAICompatEmbeddingModel(_CommonOaiApiCompat, TextEmbeddingModel):
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size")),
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512)),
ModelPropertyKey.MAX_CHUNKS: 1,
},
parameter_rules=[],

View File

@ -0,0 +1,145 @@
from collections.abc import Iterable
from typing import Optional
from urllib.parse import urljoin
import requests
from core.model_runtime.entities.common_entities import I18nObject
from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelPropertyKey, ModelType
from core.model_runtime.errors.invoke import InvokeBadRequestError
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.__base.tts_model import TTSModel
from core.model_runtime.model_providers.openai_api_compatible._common import _CommonOaiApiCompat
class OAICompatText2SpeechModel(_CommonOaiApiCompat, TTSModel):
"""
Model class for OpenAI-compatible text2speech model.
"""
def _invoke(
self,
model: str,
tenant_id: str,
credentials: dict,
content_text: str,
voice: str,
user: Optional[str] = None,
) -> Iterable[bytes]:
"""
Invoke TTS model
:param model: model name
:param tenant_id: user tenant id
:param credentials: model credentials
:param content_text: text content to be translated
:param voice: model voice/speaker
:param user: unique user id
:return: audio data as bytes iterator
"""
# Set up headers with authentication if provided
headers = {}
if api_key := credentials.get("api_key"):
headers["Authorization"] = f"Bearer {api_key}"
# Construct endpoint URL
endpoint_url = credentials.get("endpoint_url")
if not endpoint_url.endswith("/"):
endpoint_url += "/"
endpoint_url = urljoin(endpoint_url, "audio/speech")
# Get audio format from model properties
audio_format = self._get_model_audio_type(model, credentials)
# Split text into chunks if needed based on word limit
word_limit = self._get_model_word_limit(model, credentials)
sentences = self._split_text_into_sentences(content_text, word_limit)
for sentence in sentences:
# Prepare request payload
payload = {"model": model, "input": sentence, "voice": voice, "response_format": audio_format}
# Make POST request
response = requests.post(endpoint_url, headers=headers, json=payload, stream=True)
if response.status_code != 200:
raise InvokeBadRequestError(response.text)
# Stream the audio data
for chunk in response.iter_content(chunk_size=4096):
if chunk:
yield chunk
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
Validate model credentials
:param model: model name
:param credentials: model credentials
:return:
"""
try:
# Get default voice for validation
voice = self._get_model_default_voice(model, credentials)
# Test with a simple text
next(
self._invoke(
model=model, tenant_id="validate", credentials=credentials, content_text="Test.", voice=voice
)
)
except Exception as ex:
raise CredentialsValidateFailedError(str(ex))
def get_customizable_model_schema(self, model: str, credentials: dict) -> Optional[AIModelEntity]:
"""
Get customizable model schema
"""
# Parse voices from comma-separated string
voice_names = credentials.get("voices", "alloy").strip().split(",")
voices = []
for voice in voice_names:
voice = voice.strip()
if not voice:
continue
# Use en-US for all voices
voices.append(
{
"name": voice,
"mode": voice,
"language": "en-US",
}
)
# If no voices provided or all voices were empty strings, use 'alloy' as default
if not voices:
voices = [{"name": "Alloy", "mode": "alloy", "language": "en-US"}]
return AIModelEntity(
model=model,
label=I18nObject(en_US=model),
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_type=ModelType.TTS,
model_properties={
ModelPropertyKey.AUDIO_TYPE: credentials.get("audio_type", "mp3"),
ModelPropertyKey.WORD_LIMIT: int(credentials.get("word_limit", 4096)),
ModelPropertyKey.DEFAULT_VOICE: voices[0]["mode"],
ModelPropertyKey.VOICES: voices,
},
)
def get_tts_model_voices(self, model: str, credentials: dict, language: Optional[str] = None) -> list:
"""
Override base get_tts_model_voices to handle customizable voices
"""
model_schema = self.get_customizable_model_schema(model, credentials)
if not model_schema or ModelPropertyKey.VOICES not in model_schema.model_properties:
raise ValueError("this model does not support voice")
voices = model_schema.model_properties[ModelPropertyKey.VOICES]
# Always return all voices regardless of language
return [{"name": d["name"], "value": d["mode"]} for d in voices]

View File

@ -182,7 +182,7 @@ class OAICompatEmbeddingModel(_CommonOaiApiCompat, TextEmbeddingModel):
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size")),
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512)),
ModelPropertyKey.MAX_CHUNKS: 1,
},
parameter_rules=[],

View File

@ -173,7 +173,7 @@ class VertexAiTextEmbeddingModel(_CommonVertexAi, TextEmbeddingModel):
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size")),
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512)),
ModelPropertyKey.MAX_CHUNKS: 1,
},
parameter_rules=[],

View File

@ -166,7 +166,7 @@ class VoyageTextEmbeddingModel(TextEmbeddingModel):
label=I18nObject(en_US=model),
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))},
model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size", 512))},
)
return entity

View File

@ -1,9 +1,12 @@
model: grok-beta
label:
en_US: Grok beta
en_US: Grok Beta
model_type: llm
features:
- agent-thought
- tool-call
- multi-tool-call
- stream-tool-call
model_properties:
mode: chat
context_size: 131072

View File

@ -0,0 +1,64 @@
model: grok-vision-beta
label:
en_US: Grok Vision Beta
model_type: llm
features:
- agent-thought
- vision
model_properties:
mode: chat
context_size: 8192
parameter_rules:
- name: temperature
label:
en_US: "Temperature"
zh_Hans: "采样温度"
type: float
default: 0.7
min: 0.0
max: 2.0
precision: 1
required: true
help:
en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time."
zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。"
- name: top_p
label:
en_US: "Top P"
zh_Hans: "Top P"
type: float
default: 0.7
min: 0.0
max: 1.0
precision: 1
required: true
help:
en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time."
zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。"
- name: frequency_penalty
use_template: frequency_penalty
label:
en_US: "Frequency Penalty"
zh_Hans: "频率惩罚"
type: float
default: 0
min: 0
max: 2.0
precision: 1
required: false
help:
en_US: "Number between 0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim."
zh_Hans: "介于0和2.0之间的数字。正值会根据新标记在文本中迄今为止的现有频率来惩罚它们,从而降低模型一字不差地重复同一句话的可能性。"
- name: user
use_template: text
label:
en_US: "User"
zh_Hans: "用户"
type: string
required: false
help:
en_US: "Used to track and differentiate conversation requests from different users."
zh_Hans: "用于追踪和区分不同用户的对话请求。"

View File

@ -35,3 +35,5 @@ class XAILargeLanguageModel(OAIAPICompatLargeLanguageModel):
credentials["endpoint_url"] = str(URL(credentials["endpoint_url"])) or "https://api.x.ai/v1"
credentials["mode"] = LLMMode.CHAT.value
credentials["function_calling_type"] = "tool_call"
credentials["stream_function_calling"] = "support"
credentials["vision_support"] = "support"

View File

@ -105,17 +105,6 @@ class ZhipuAITextEmbeddingModel(_CommonZhipuaiAI, TextEmbeddingModel):
return [list(map(float, e)) for e in embeddings], embedding_used_tokens
def embed_query(self, text: str) -> list[float]:
"""Call out to ZhipuAI's embedding endpoint.
Args:
text: The text to embed.
Returns:
Embeddings for the text.
"""
return self.embed_documents([text])[0]
def _calc_response_usage(self, model: str, credentials: dict, tokens: int) -> EmbeddingUsage:
"""
Calculate response usage

View File

@ -445,7 +445,7 @@ class TraceTask:
"ls_provider": message_data.model_provider,
"ls_model_name": message_data.model_id,
"status": message_data.status,
"from_end_user_id": message_data.from_account_id,
"from_end_user_id": message_data.from_end_user_id,
"from_account_id": message_data.from_account_id,
"agent_based": message_data.agent_based,
"workflow_run_id": message_data.workflow_run_id,
@ -521,7 +521,7 @@ class TraceTask:
"ls_provider": message_data.model_provider,
"ls_model_name": message_data.model_id,
"status": message_data.status,
"from_end_user_id": message_data.from_account_id,
"from_end_user_id": message_data.from_end_user_id,
"from_account_id": message_data.from_account_id,
"agent_based": message_data.agent_based,
"workflow_run_id": message_data.workflow_run_id,
@ -570,7 +570,7 @@ class TraceTask:
"ls_provider": message_data.model_provider,
"ls_model_name": message_data.model_id,
"status": message_data.status,
"from_end_user_id": message_data.from_account_id,
"from_end_user_id": message_data.from_end_user_id,
"from_account_id": message_data.from_account_id,
"agent_based": message_data.agent_based,
"workflow_run_id": message_data.workflow_run_id,

View File

@ -78,13 +78,8 @@ class DatasetDocumentStore:
model_type=ModelType.TEXT_EMBEDDING,
model=self._dataset.embedding_model,
)
if embedding_model:
page_content_list = [doc.page_content for doc in docs]
tokens_list = embedding_model.get_text_embedding_num_tokens(page_content_list)
else:
tokens_list = [0] * len(docs)
for doc, tokens in zip(docs, tokens_list):
for doc in docs:
if not isinstance(doc, Document):
raise ValueError("doc must be a Document")
@ -96,6 +91,12 @@ class DatasetDocumentStore:
f"doc_id {doc.metadata['doc_id']} already exists. Set allow_update to True to overwrite."
)
# calc embedding use tokens
if embedding_model:
tokens = embedding_model.get_text_embedding_num_tokens(texts=[doc.page_content])
else:
tokens = 0
if not segment_document:
max_position += 1

View File

@ -65,9 +65,8 @@ class FixedRecursiveCharacterTextSplitter(EnhanceRecursiveCharacterTextSplitter)
chunks = [text]
final_chunks = []
chunks_lengths = self._length_function(chunks)
for chunk, chunk_length in zip(chunks, chunks_lengths):
if chunk_length > self._chunk_size:
for chunk in chunks:
if self._length_function(chunk) > self._chunk_size:
final_chunks.extend(self.recursive_split_text(chunk))
else:
final_chunks.append(chunk)
@ -94,8 +93,8 @@ class FixedRecursiveCharacterTextSplitter(EnhanceRecursiveCharacterTextSplitter)
# Now go merging things, recursively splitting longer texts.
_good_splits = []
_good_splits_lengths = [] # cache the lengths of the splits
s_lens = self._length_function(splits)
for s, s_len in zip(splits, s_lens):
for s in splits:
s_len = self._length_function(s)
if s_len < self._chunk_size:
_good_splits.append(s)
_good_splits_lengths.append(s_len)

View File

@ -45,7 +45,7 @@ class TextSplitter(BaseDocumentTransformer, ABC):
self,
chunk_size: int = 4000,
chunk_overlap: int = 200,
length_function: Callable[[str], [int]] = len,
length_function: Callable[[str], int] = len,
keep_separator: bool = False,
add_start_index: bool = False,
) -> None:
@ -224,8 +224,8 @@ class CharacterTextSplitter(TextSplitter):
splits = _split_text_with_regex(text, self._separator, self._keep_separator)
_separator = "" if self._keep_separator else self._separator
_good_splits_lengths = [] # cache the lengths of the splits
if splits:
_good_splits_lengths.extend(self._length_function(splits))
for split in splits:
_good_splits_lengths.append(self._length_function(split))
return self._merge_splits(splits, _separator, _good_splits_lengths)
@ -478,8 +478,9 @@ class RecursiveCharacterTextSplitter(TextSplitter):
_good_splits = []
_good_splits_lengths = [] # cache the lengths of the splits
_separator = "" if self._keep_separator else separator
s_lens = self._length_function(splits)
for s, s_len in zip(splits, s_lens):
for s in splits:
s_len = self._length_function(s)
if s_len < self._chunk_size:
_good_splits.append(s)
_good_splits_lengths.append(s_len)

View File

@ -1,3 +1,4 @@
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties, fontManager
@ -5,7 +6,7 @@ from core.tools.provider.builtin_tool_provider import BuiltinToolProviderControl
def set_chinese_font():
font_list = [
to_find_fonts = [
"PingFang SC",
"SimHei",
"Microsoft YaHei",
@ -15,16 +16,16 @@ def set_chinese_font():
"Noto Sans CJK SC",
"Noto Sans CJK JP",
]
for font in font_list:
if font in fontManager.ttflist:
chinese_font = FontProperties(font)
if chinese_font.get_name() == font:
return chinese_font
installed_fonts = frozenset(fontInfo.name for fontInfo in fontManager.ttflist)
for font in to_find_fonts:
if font in installed_fonts:
return FontProperties(font)
return FontProperties()
# use non-interactive backend to prevent `RuntimeError: main thread is not in main loop`
matplotlib.use("Agg")
# use a business theme
plt.style.use("seaborn-v0_8-darkgrid")
plt.rcParams["axes.unicode_minus"] = False

View File

@ -18,6 +18,12 @@ class DuckDuckGoImageSearchTool(BuiltinTool):
"size": tool_parameters.get("size"),
"max_results": tool_parameters.get("max_results"),
}
# Add query_prefix handling
query_prefix = tool_parameters.get("query_prefix", "").strip()
final_query = f"{query_prefix} {query_dict['keywords']}".strip()
query_dict["keywords"] = final_query
response = DDGS().images(**query_dict)
markdown_result = "\n\n"
json_result = []

View File

@ -86,3 +86,14 @@ parameters:
en_US: The size of the image to be searched.
zh_Hans: 要搜索的图片的大小
form: form
- name: query_prefix
label:
en_US: Query Prefix
zh_Hans: 查询前缀
type: string
required: false
default: ""
form: form
human_description:
en_US: Specific Search e.g. "site:unsplash.com"
zh_Hans: 定向搜索 e.g. "site:unsplash.com"

View File

@ -7,7 +7,7 @@ from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
SUMMARY_PROMPT = """
User's query:
User's query:
{query}
Here are the news results:
@ -30,6 +30,12 @@ class DuckDuckGoNewsSearchTool(BuiltinTool):
"safesearch": "moderate",
"region": "wt-wt",
}
# Add query_prefix handling
query_prefix = tool_parameters.get("query_prefix", "").strip()
final_query = f"{query_prefix} {query_dict['keywords']}".strip()
query_dict["keywords"] = final_query
try:
response = list(DDGS().news(**query_dict))
if not response:

View File

@ -69,3 +69,14 @@ parameters:
en_US: Whether to pass the news results to llm for summarization.
zh_Hans: 是否需要将新闻结果传给大模型总结
form: form
- name: query_prefix
label:
en_US: Query Prefix
zh_Hans: 查询前缀
type: string
required: false
default: ""
form: form
human_description:
en_US: Specific Search e.g. "site:msn.com"
zh_Hans: 定向搜索 e.g. "site:msn.com"

View File

@ -7,7 +7,7 @@ from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
SUMMARY_PROMPT = """
User's query:
User's query:
{query}
Here is the search engine result:
@ -26,7 +26,12 @@ class DuckDuckGoSearchTool(BuiltinTool):
query = tool_parameters.get("query")
max_results = tool_parameters.get("max_results", 5)
require_summary = tool_parameters.get("require_summary", False)
response = DDGS().text(query, max_results=max_results)
# Add query_prefix handling
query_prefix = tool_parameters.get("query_prefix", "").strip()
final_query = f"{query_prefix} {query}".strip()
response = DDGS().text(final_query, max_results=max_results)
if require_summary:
results = "\n".join([res.get("body") for res in response])
results = self.summary_results(user_id=user_id, content=results, query=query)

View File

@ -39,3 +39,14 @@ parameters:
en_US: Whether to pass the search results to llm for summarization.
zh_Hans: 是否需要将搜索结果传给大模型总结
form: form
- name: query_prefix
label:
en_US: Query Prefix
zh_Hans: 查询前缀
type: string
required: false
default: ""
form: form
human_description:
en_US: Specific Search e.g. "site:wikipedia.org"
zh_Hans: 定向搜索 e.g. "site:wikipedia.org"

View File

@ -24,7 +24,7 @@ max-width: 100%; border-radius: 8px;">
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> list[ToolInvokeMessage]:
query_dict = {
"keywords": tool_parameters.get("query"),
"keywords": tool_parameters.get("query"), # LLM's query
"region": tool_parameters.get("region", "wt-wt"),
"safesearch": tool_parameters.get("safesearch", "moderate"),
"timelimit": tool_parameters.get("timelimit"),
@ -40,6 +40,12 @@ max-width: 100%; border-radius: 8px;">
# Get proxy URL from parameters
proxy_url = tool_parameters.get("proxy_url", "").strip()
query_prefix = tool_parameters.get("query_prefix", "").strip()
final_query = f"{query_prefix} {query_dict['keywords']}".strip()
# Update the keywords in query_dict with the final_query
query_dict["keywords"] = final_query
response = DDGS().videos(**query_dict)
# Create HTML result with embedded iframes
@ -51,9 +57,13 @@ max-width: 100%; border-radius: 8px;">
embed_html = res.get("embed_html", "")
description = res.get("description", "")
content_url = res.get("content", "")
transcript_url = None
# Handle TED.com videos
if not embed_html and "ted.com/talks" in content_url:
if "ted.com/talks" in content_url:
# Create transcript URL
transcript_url = f"{content_url}/transcript"
# Create embed URL
embed_url = content_url.replace("www.ted.com", "embed.ted.com")
if proxy_url:
embed_url = f"{proxy_url}{embed_url}"
@ -68,8 +78,14 @@ max-width: 100%; border-radius: 8px;">
markdown_result += f"{title}\n\n"
markdown_result += f"{embed_html}\n\n"
if description:
markdown_result += f"{description}\n\n"
markdown_result += "---\n\n"
json_result.append(self.create_json_message(res))
# Add transcript_url to the JSON result if available
result_dict = res.copy()
if transcript_url:
result_dict["transcript_url"] = transcript_url
json_result.append(self.create_json_message(result_dict))
return [self.create_text_message(markdown_result)] + json_result

View File

@ -95,3 +95,14 @@ parameters:
en_US: Proxy URL
zh_Hans: 视频代理地址
form: form
- name: query_prefix
label:
en_US: Query Prefix
zh_Hans: 查询前缀
type: string
required: false
default: ""
form: form
human_description:
en_US: Specific Search e.g. "site:www.ted.com"
zh_Hans: 定向搜索 e.g. "site:www.ted.com"

View File

@ -45,7 +45,7 @@ class SearchAPI:
def _process_response(res: dict, type: str) -> str:
"""Process response from SearchAPI."""
if "error" in res:
raise ValueError(f"Got error from SearchApi: {res['error']}")
return res["error"]
toret = ""
if type == "text":

View File

@ -45,7 +45,7 @@ class SearchAPI:
def _process_response(res: dict, type: str) -> str:
"""Process response from SearchAPI."""
if "error" in res:
raise ValueError(f"Got error from SearchApi: {res['error']}")
return res["error"]
toret = ""
if type == "text":

View File

@ -45,7 +45,7 @@ class SearchAPI:
def _process_response(res: dict, type: str) -> str:
"""Process response from SearchAPI."""
if "error" in res:
raise ValueError(f"Got error from SearchApi: {res['error']}")
return res["error"]
toret = ""
if type == "text":

View File

@ -45,7 +45,7 @@ class SearchAPI:
def _process_response(res: dict) -> str:
"""Process response from SearchAPI."""
if "error" in res:
raise ValueError(f"Got error from SearchApi: {res['error']}")
return res["error"]
toret = ""
if "transcripts" in res and "text" in res["transcripts"][0]:

View File

@ -20,6 +20,7 @@ from core.model_runtime.entities import (
from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
PromptMessageContent,
PromptMessageRole,
SystemPromptMessage,
UserPromptMessage,
@ -66,7 +67,6 @@ from .entities import (
ModelConfig,
)
from .exc import (
FileTypeNotSupportError,
InvalidContextStructureError,
InvalidVariableTypeError,
LLMModeRequiredError,
@ -137,12 +137,12 @@ class LLMNode(BaseNode[LLMNodeData]):
query = None
if self.node_data.memory:
query = self.node_data.memory.query_prompt_template
if query is None and (
query_variable := self.graph_runtime_state.variable_pool.get(
(SYSTEM_VARIABLE_NODE_ID, SystemVariableKey.QUERY)
)
):
query = query_variable.text
if not query and (
query_variable := self.graph_runtime_state.variable_pool.get(
(SYSTEM_VARIABLE_NODE_ID, SystemVariableKey.QUERY)
)
):
query = query_variable.text
prompt_messages, stop = self._fetch_prompt_messages(
user_query=query,
@ -675,7 +675,7 @@ class LLMNode(BaseNode[LLMNodeData]):
and ModelFeature.AUDIO not in model_config.model_schema.features
)
):
raise FileTypeNotSupportError(type_name=content_item.type)
continue
prompt_message_content.append(content_item)
if len(prompt_message_content) == 1 and prompt_message_content[0].type == PromptMessageContentType.TEXT:
prompt_message.content = prompt_message_content[0].data
@ -828,14 +828,14 @@ class LLMNode(BaseNode[LLMNodeData]):
}
def _combine_text_message_with_role(*, text: str, role: PromptMessageRole):
def _combine_message_content_with_role(*, contents: Sequence[PromptMessageContent], role: PromptMessageRole):
match role:
case PromptMessageRole.USER:
return UserPromptMessage(content=[TextPromptMessageContent(data=text)])
return UserPromptMessage(content=contents)
case PromptMessageRole.ASSISTANT:
return AssistantPromptMessage(content=[TextPromptMessageContent(data=text)])
return AssistantPromptMessage(content=contents)
case PromptMessageRole.SYSTEM:
return SystemPromptMessage(content=[TextPromptMessageContent(data=text)])
return SystemPromptMessage(content=contents)
raise NotImplementedError(f"Role {role} is not supported")
@ -877,7 +877,9 @@ def _handle_list_messages(
jinjia2_variables=jinja2_variables,
variable_pool=variable_pool,
)
prompt_message = _combine_text_message_with_role(text=result_text, role=message.role)
prompt_message = _combine_message_content_with_role(
contents=[TextPromptMessageContent(data=result_text)], role=message.role
)
prompt_messages.append(prompt_message)
else:
# Get segment group from basic message
@ -908,12 +910,14 @@ def _handle_list_messages(
# Create message with text from all segments
plain_text = segment_group.text
if plain_text:
prompt_message = _combine_text_message_with_role(text=plain_text, role=message.role)
prompt_message = _combine_message_content_with_role(
contents=[TextPromptMessageContent(data=plain_text)], role=message.role
)
prompt_messages.append(prompt_message)
if file_contents:
# Create message with image contents
prompt_message = UserPromptMessage(content=file_contents)
prompt_message = _combine_message_content_with_role(contents=file_contents, role=message.role)
prompt_messages.append(prompt_message)
return prompt_messages
@ -1018,6 +1022,8 @@ def _handle_completion_template(
else:
template_text = template.text
result_text = variable_pool.convert_template(template_text).text
prompt_message = _combine_text_message_with_role(text=result_text, role=PromptMessageRole.USER)
prompt_message = _combine_message_content_with_role(
contents=[TextPromptMessageContent(data=result_text)], role=PromptMessageRole.USER
)
prompt_messages.append(prompt_message)
return prompt_messages

View File

@ -31,12 +31,12 @@ class AppIconUrlField(fields.Raw):
if obj is None:
return None
from models.model import App, IconType
from models.model import App, IconType, Site
if isinstance(obj, dict) and "app" in obj:
obj = obj["app"]
if isinstance(obj, App) and obj.icon_type == IconType.IMAGE.value:
if isinstance(obj, App | Site) and obj.icon_type == IconType.IMAGE.value:
return file_helpers.get_signed_file_url(obj.icon)
return None

View File

@ -56,8 +56,8 @@ class Account(UserMixin, db.Model):
self._current_tenant = tenant
@property
def current_tenant_id(self):
return self._current_tenant.id
def current_tenant_id(self) -> str | None:
return self._current_tenant.id if self._current_tenant else None
@current_tenant_id.setter
def current_tenant_id(self, value: str):

View File

@ -1,7 +1,7 @@
import json
from collections.abc import Mapping, Sequence
from datetime import UTC, datetime
from enum import Enum
from enum import Enum, StrEnum
from typing import Any, Optional, Union
import sqlalchemy as sa
@ -314,7 +314,7 @@ class Workflow(db.Model):
)
class WorkflowRunStatus(Enum):
class WorkflowRunStatus(StrEnum):
"""
Workflow Run Status Enum
"""
@ -393,13 +393,13 @@ class WorkflowRun(db.Model):
version = db.Column(db.String(255), nullable=False)
graph = db.Column(db.Text)
inputs = db.Column(db.Text)
status = db.Column(db.String(255), nullable=False)
outputs: Mapped[str] = db.Column(db.Text)
status = db.Column(db.String(255), nullable=False) # running, succeeded, failed, stopped
outputs: Mapped[str] = mapped_column(sa.Text, default="{}")
error = db.Column(db.Text)
elapsed_time = db.Column(db.Float, nullable=False, server_default=db.text("0"))
total_tokens = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
total_steps = db.Column(db.Integer, server_default=db.text("0"))
created_by_role = db.Column(db.String(255), nullable=False)
created_by_role = db.Column(db.String(255), nullable=False) # account, end_user
created_by = db.Column(StringUUID, nullable=False)
created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)"))
finished_at = db.Column(db.DateTime)

View File

@ -1,3 +1,4 @@
from collections.abc import Callable
from datetime import UTC, datetime
from typing import Optional, Union
@ -74,14 +75,14 @@ class ConversationService:
return InfiniteScrollPagination(data=conversations, limit=limit, has_more=has_more)
@classmethod
def _get_sort_params(cls, sort_by: str) -> tuple[str, callable]:
def _get_sort_params(cls, sort_by: str):
if sort_by.startswith("-"):
return sort_by[1:], desc
return sort_by, asc
@classmethod
def _build_filter_condition(
cls, sort_field: str, sort_direction: callable, reference_conversation: Conversation, is_next_page: bool = False
cls, sort_field: str, sort_direction: Callable, reference_conversation: Conversation, is_next_page: bool = False
):
field_value = getattr(reference_conversation, sort_field)
if (sort_direction == desc and not is_next_page) or (sort_direction == asc and is_next_page):
@ -160,5 +161,5 @@ class ConversationService:
conversation = cls.get_conversation(app_model, conversation_id, user)
conversation.is_deleted = True
conversation.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
conversation.updated_at = datetime.now(UTC).replace(tzinfo=None)
db.session.commit()

View File

@ -1390,7 +1390,7 @@ class SegmentService:
model=dataset.embedding_model,
)
# calc embedding use tokens
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])[0]
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
lock_name = "add_segment_lock_document_id_{}".format(document.id)
with redis_client.lock(lock_name, timeout=600):
max_position = (
@ -1467,11 +1467,9 @@ class SegmentService:
if dataset.indexing_technique == "high_quality" and embedding_model:
# calc embedding use tokens
if document.doc_form == "qa_model":
tokens = embedding_model.get_text_embedding_num_tokens(
texts=[content + segment_item["answer"]]
)[0]
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content + segment_item["answer"]])
else:
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])[0]
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
segment_document = DocumentSegment(
tenant_id=current_user.current_tenant_id,
dataset_id=document.dataset_id,
@ -1579,9 +1577,9 @@ class SegmentService:
# calc embedding use tokens
if document.doc_form == "qa_model":
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content + segment.answer])[0]
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content + segment.answer])
else:
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])[0]
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
segment.content = content
segment.index_node_hash = segment_hash
segment.word_count = len(content)

View File

@ -58,16 +58,12 @@ def batch_create_segment_to_index_task(
model=dataset.embedding_model,
)
word_count_change = 0
if embedding_model:
tokens_list = embedding_model.get_text_embedding_num_tokens(
texts=[segment["content"] for segment in content]
)
else:
tokens_list = [0] * len(content)
for segment, tokens in zip(content, tokens_list):
for segment in content:
content = segment["content"]
doc_id = str(uuid.uuid4())
segment_hash = helper.generate_text_hash(content)
# calc embedding use tokens
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content]) if embedding_model else 0
max_position = (
db.session.query(func.max(DocumentSegment.position))
.filter(DocumentSegment.document_id == dataset_document.id)

View File

@ -2,7 +2,7 @@ version: '3'
services:
# API service
api:
image: langgenius/dify-api:0.11.2
image: langgenius/dify-api:0.12.1
restart: always
environment:
# Startup mode, 'api' starts the API server.
@ -227,7 +227,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
image: langgenius/dify-api:0.11.2
image: langgenius/dify-api:0.12.1
restart: always
environment:
CONSOLE_WEB_URL: ''
@ -397,7 +397,7 @@ services:
# Frontend web application.
web:
image: langgenius/dify-web:0.11.2
image: langgenius/dify-web:0.12.1
restart: always
environment:
# The base URL of console application api server, refers to the Console base URL of WEB service if console domain is

View File

@ -291,7 +291,7 @@ x-shared-env: &shared-api-worker-env
services:
# API service
api:
image: langgenius/dify-api:0.11.2
image: langgenius/dify-api:0.12.1
restart: always
environment:
# Use the shared environment variables.
@ -311,7 +311,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
image: langgenius/dify-api:0.11.2
image: langgenius/dify-api:0.12.1
restart: always
environment:
# Use the shared environment variables.
@ -330,7 +330,7 @@ services:
# Frontend web application.
web:
image: langgenius/dify-web:0.11.2
image: langgenius/dify-web:0.12.1
restart: always
environment:
CONSOLE_API_URL: ${CONSOLE_API_URL:-}

View File

@ -14,7 +14,7 @@ import type { App } from '@/models/explore'
import Category from '@/app/components/explore/category'
import AppCard from '@/app/components/explore/app-card'
import { fetchAppDetail, fetchAppList } from '@/service/explore'
import { importApp } from '@/service/apps'
import { importDSL } from '@/service/apps'
import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
import CreateAppModal from '@/app/components/explore/create-app-modal'
import AppTypeSelector from '@/app/components/app/type-selector'
@ -24,6 +24,7 @@ import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { useAppContext } from '@/context/app-context'
import { getRedirection } from '@/utils/app-redirection'
import Input from '@/app/components/base/input'
import { DSLImportMode } from '@/models/app'
type AppsProps = {
pageType?: PageType
@ -127,8 +128,9 @@ const Apps = ({
currApp?.app.id as string,
)
try {
const app = await importApp({
data: export_data,
const app = await importDSL({
mode: DSLImportMode.YAML_CONTENT,
yaml_content: export_data,
name,
icon_type,
icon,
@ -143,7 +145,7 @@ const Apps = ({
if (onSuccess)
onSuccess()
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
getRedirection(isCurrentWorkspaceEditor, app, push)
getRedirection(isCurrentWorkspaceEditor, { id: app.app_id }, push)
}
catch (e) {
Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') })

View File

@ -1,6 +1,6 @@
{
"name": "dify-web",
"version": "0.11.2",
"version": "0.12.1",
"private": true,
"engines": {
"node": ">=18.17.0"

View File

@ -85,6 +85,10 @@ html[data-theme="dark"] {
--color-components-button-secondary-accent-border-hover: #FFFFFF1F;
--color-components-button-secondary-accent-border-disabled: #FFFFFF0D;
--color-components-button-indigo-bg: #444CE7;
--color-components-button-indigo-bg-hover: #6172F3;
--color-components-button-indigo-bg-disabled: #FFFFFF08;
--color-components-checkbox-icon: #FFFFFFF2;
--color-components-checkbox-icon-disabled: #FFFFFF33;
--color-components-checkbox-bg: #296DFF;
@ -95,10 +99,11 @@ html[data-theme="dark"] {
--color-components-checkbox-border-disabled: #FFFFFF03;
--color-components-checkbox-bg-unchecked: #FFFFFF08;
--color-components-checkbox-bg-unchecked-hover: #FFFFFF0D;
--color-components-checkbox-bg-disabled-checked: #155AEF33;
--color-components-radio-border-checked: #296DFF;
--color-components-radio-border-checked-hover: #5289FF;
--color-components-radio-border-checked-disabled: #FFFFFF14;
--color-components-radio-border-checked-disabled: #155AEF33;
--color-components-radio-bg-disabled: #FFFFFF08;
--color-components-radio-border: #FFFFFF66;
--color-components-radio-border-hover: #FFFFFF99;
@ -135,6 +140,9 @@ html[data-theme="dark"] {
--color-components-panel-on-panel-item-bg: #27272B;
--color-components-panel-on-panel-item-bg-hover: #3A3A40;
--color-components-panel-on-panel-item-bg-alt: #3A3A40;
--color-components-panel-on-panel-item-bg-transparent: #2C2C30F2;
--color-components-panel-on-panel-item-bg-hover-transparent: #3A3A4000;
--color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FFFBFA00;
--color-components-panel-bg-transparent: #22222500;
@ -208,10 +216,12 @@ html[data-theme="dark"] {
--color-components-actionbar-bg: #222225;
--color-components-actionbar-border: #C8CEDA14;
--color-components-actionbar-bg-accent: #27272B;
--color-components-actionbar-border-accent: #5289FF;
--color-components-dropzone-bg-alt: #18181BCC;
--color-components-dropzone-bg: #18181B66;
--color-components-dropzone-bg-accent: #155AEF24;
--color-components-dropzone-bg-accent: #155AEF33;
--color-components-dropzone-border: #C8CEDA24;
--color-components-dropzone-border-alt: #C8CEDA33;
--color-components-dropzone-border-accent: #84ABFF;
@ -228,6 +238,14 @@ html[data-theme="dark"] {
--color-components-progress-gray-border: #98A2B2;
--color-components-progress-gray-bg: #C8CEDA05;
--color-components-progress-warning-progress: #FDB022;
--color-components-progress-warning-border: #FDB022;
--color-components-progress-warning-bg: #F790090A;
--color-components-progress-error-progress: #F97066;
--color-components-progress-error-border: #F97066;
--color-components-progress-error-bg: #F044380A;
--color-components-chat-input-audio-bg: #155AEF33;
--color-components-chat-input-audio-wave-default: #C8CEDA24;
--color-components-chat-input-bg-mask-1: #18181B0A;
@ -236,13 +254,103 @@ html[data-theme="dark"] {
--color-components-chat-input-audio-wave-active: #84ABFF;
--color-components-chat-input-audio-bg-alt: #18181BE5;
--color-components-Avatar-shape-fill-stop-0: #FFFFFFF2;
--color-components-Avatar-shape-fill-stop-100: #FFFFFFCC;
--color-components-avatar-shape-fill-stop-0: #FFFFFFF2;
--color-components-avatar-shape-fill-stop-100: #FFFFFFCC;
--color-components-Avatar-bg-mask-stop-0: #FFFFFF33;
--color-components-Avatar-bg-mask-stop-100: #FFFFFF08;
--color-components-avatar-bg-mask-stop-0: #FFFFFF33;
--color-components-avatar-bg-mask-stop-100: #FFFFFF08;
--color-components-Avatar-default-avatar-bg: #222225;
--color-components-avatar-default-avatar-bg: #222225;
--color-components-avatar-mask-darkmode-dimmed: #0000001F;
--color-components-label-gray: #C8CEDA24;
--color-components-premium-badge-blue-bg-stop-0: #5289FF;
--color-components-premium-badge-blue-bg-stop-100: #296DFF;
--color-components-premium-badge-blue-stroke-stop-0: #FFFFFF33;
--color-components-premium-badge-blue-stroke-stop-100: #296DFF;
--color-components-premium-badge-blue-text-stop-0: #EFF4FF;
--color-components-premium-badge-blue-text-stop-100: #B2CAFF;
--color-components-premium-badge-blue-glow: #004AEB;
--color-components-premium-badge-blue-bg-stop-0-hover: #84ABFF;
--color-components-premium-badge-blue-bg-stop-100-hover: #004AEB;
--color-components-premium-badge-blue-glow-hover: #D1E0FF;
--color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFF80;
--color-components-premium-badge-blue-stroke-stop-100-hover: #296DFF;
--color-components-premium-badge-highlight-stop-0: #FFFFFF1F;
--color-components-premium-badge-highlight-stop-100: #FFFFFF33;
--color-components-premium-badge-indigo-bg-stop-0: #6172F3;
--color-components-premium-badge-indigo-bg-stop-100: #3538CD;
--color-components-premium-badge-indigo-stroke-stop-0: #FFFFFF33;
--color-components-premium-badge-indigo-stroke-stop-100: #444CE7;
--color-components-premium-badge-indigo-text-stop-0: #EEF4FF;
--color-components-premium-badge-indigo-text-stop-100: #C7D7FE;
--color-components-premium-badge-indigo-glow: #3538CD;
--color-components-premium-badge-indigo-glow-hover: #E0EAFF;
--color-components-premium-badge-indigo-bg-stop-0-hover: #A4BCFD;
--color-components-premium-badge-indigo-bg-stop-100-hover: #3538CD;
--color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFF80;
--color-components-premium-badge-indigo-stroke-stop-100-hover: #444CE7;
--color-components-premium-badge-grey-bg-stop-0: #676F83;
--color-components-premium-badge-grey-bg-stop-100: #495464;
--color-components-premium-badge-grey-stroke-stop-0: #FFFFFF1F;
--color-components-premium-badge-grey-stroke-stop-100: #495464;
--color-components-premium-badge-grey-text-stop-0: #F9FAFB;
--color-components-premium-badge-grey-text-stop-100: #E9EBF0;
--color-components-premium-badge-grey-glow: #354052;
--color-components-premium-badge-grey-glow-hover: #F2F4F7;
--color-components-premium-badge-grey-bg-stop-0-hover: #98A2B2;
--color-components-premium-badge-grey-bg-stop-100-hover: #354052;
--color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFF80;
--color-components-premium-badge-grey-stroke-stop-100-hover: #676F83;
--color-components-premium-badge-orange-bg-stop-0: #FF692E;
--color-components-premium-badge-orange-bg-stop-100: #E04F16;
--color-components-premium-badge-orange-stroke-stop-0: #FFFFFF33;
--color-components-premium-badge-orange-stroke-stop-100: #FF4405;
--color-components-premium-badge-orange-text-stop-0: #FEF6EE;
--color-components-premium-badge-orange-text-stop-100: #F9DBAF;
--color-components-premium-badge-orange-glow: #B93815;
--color-components-premium-badge-orange-glow-hover: #FDEAD7;
--color-components-premium-badge-orange-bg-stop-0-hover: #FF692E;
--color-components-premium-badge-orange-bg-stop-100-hover: #B93815;
--color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFF80;
--color-components-premium-badge-orange-stroke-stop-100-hover: #FF4405;
--color-components-progress-bar-bg: #C8CEDA14;
--color-components-progress-bar-progress: #C8CEDA24;
--color-components-progress-bar-border: #FFFFFF08;
--color-components-progress-bar-progress-solid: #FFFFFFF2;
--color-components-progress-bar-progress-highlight: #C8CEDA33;
--color-components-icon-bg-red-solid: #D92D20;
--color-components-icon-bg-rose-solid: #E31B54;
--color-components-icon-bg-pink-solid: #DD2590;
--color-components-icon-bg-orange-dark-solid: #FF4405;
--color-components-icon-bg-yellow-solid: #EAAA08;
--color-components-icon-bg-green-solid: #4CA30D;
--color-components-icon-bg-teal-solid: #0E9384;
--color-components-icon-bg-blue-light-solid: #0BA5EC;
--color-components-icon-bg-blue-solid: #155AEF;
--color-components-icon-bg-indigo-solid: #444CE7;
--color-components-icon-bg-violet-solid: #7839EE;
--color-components-icon-bg-midnight-solid: #5D698D;
--color-components-icon-bg-rose-soft: #F63D6833;
--color-components-icon-bg-pink-soft: #EE46BC33;
--color-components-icon-bg-orange-dark-soft: #FF440533;
--color-components-icon-bg-yellow-soft: #EAAA0833;
--color-components-icon-bg-green-soft: #66C61C33;
--color-components-icon-bg-teal-soft: #15B79E33;
--color-components-icon-bg-blue-light-soft: #0BA5EC33;
--color-components-icon-bg-blue-soft: #155AEF33;
--color-components-icon-bg-indigo-soft: #6172F333;
--color-components-icon-bg-violet-soft: #875BF733;
--color-components-icon-bg-midnight-soft: #828DAD33;
--color-components-icon-bg-red-soft: #F0443833;
--color-components-icon-bg-orange-solid: #F79009;
--color-components-icon-bg-orange-soft: #F7900933;
--color-text-primary: #FBFBFC;
--color-text-secondary: #D9D9DE;
@ -302,6 +410,7 @@ html[data-theme="dark"] {
--color-background-overlay-alt: #18181B66;
--color-background-surface-white: #FFFFFFE5;
--color-background-overlay-destructive: #F044384D;
--color-background-overlay-backdrop: #18181BF2;
--color-shadow-shadow-1: #0000000D;
--color-shadow-shadow-3: #0000001A;
@ -317,14 +426,20 @@ html[data-theme="dark"] {
--color-workflow-block-border: #FFFFFF14;
--color-workflow-block-parma-bg: #FFFFFF0D;
--color-workflow-block-bg: #27272B;
--color-workflow-block-bg-transparent: #27272BF5;
--color-workflow-block-border-highlight: #C8CEDA33;
--color-workflow-canvas-workflow-dot-color: #8585AD26;
--color-workflow-canvas-workflow-bg: #1D1D20;
--color-workflow-link-line-active: #296DFF;
--color-workflow-link-line-active: #5289FF;
--color-workflow-link-line-normal: #676F83;
--color-workflow-link-line-handle: #296DFF;
--color-workflow-link-line-handle: #5289FF;
--color-workflow-link-line-normal-transparent: #676F8333;
--color-workflow-link-line-failure-active: #FDB022;
--color-workflow-link-line-failure-handle: #FDB022;
--color-workflow-link-line-failure-button-bg: #F79009;
--color-workflow-link-line-failure-button-hover: #DC6803;
--color-workflow-link-line-success-active: #47CD89;
--color-workflow-link-line-success-handle: #47CD89;
@ -341,8 +456,8 @@ html[data-theme="dark"] {
--color-workflow-display-success-vignette-color: #17B26A40;
--color-workflow-display-success-bg-line-pattern: #18181BCC;
--color-workflow-display-glass-1: #FFFFFF03;
--color-workflow-display-glass-2: #FFFFFF08;
--color-workflow-display-glass-1: #FFFFFF08;
--color-workflow-display-glass-2: #FFFFFF0D;
--color-workflow-display-vignette-dark: #00000066;
--color-workflow-display-highlight: #FFFFFF1F;
--color-workflow-display-outline: #18181BF2;
@ -431,6 +546,7 @@ html[data-theme="dark"] {
--color-util-colors-orange-orange-500: #EF6820;
--color-util-colors-orange-orange-600: #F38744;
--color-util-colors-orange-orange-700: #F7B27A;
--color-util-colors-orange-orange-100-transparent: #77291700;
--color-util-colors-pink-pink-50: #4E0D30;
--color-util-colors-pink-pink-100: #851651;
@ -606,4 +722,16 @@ html[data-theme="dark"] {
--color-third-party-LangChain: #FFFFFF;
--color-third-party-Langfuse: #FFFFFF;
--color-third-party-Github: #FFFFFF;
--color-third-party-Github-tertiary: #C8CEDA99;
--color-third-party-Github-secondary: #D9D9DE;
--color-third-party-model-bg-openai: #121212;
--color-third-party-model-bg-anthropic: #1D1917;
--color-third-party-model-bg-default: #0B0B0E;
--color-third-party-aws: #141F2E;
--color-third-party-aws-alt: #192639;
--color-saas-background: #0B0B0E;
--color-saas-pricing-grid-bg: #C8CEDA33;
}

View File

@ -85,8 +85,12 @@ html[data-theme="light"] {
--color-components-button-secondary-accent-border-hover: #10182824;
--color-components-button-secondary-accent-border-disabled: #1018280A;
--color-components-button-indigo-bg: #444CE7;
--color-components-button-indigo-bg-hover: #3538CD;
--color-components-button-indigo-bg-disabled: #6172F324;
--color-components-checkbox-icon: #FFFFFF;
--color-components-checkbox-icon-disabled: #D0D5DC;
--color-components-checkbox-icon-disabled: #FFFFFF80;
--color-components-checkbox-bg: #155AEF;
--color-components-checkbox-bg-hover: #004AEB;
--color-components-checkbox-bg-disabled: #F2F4F7;
@ -95,10 +99,11 @@ html[data-theme="light"] {
--color-components-checkbox-border-disabled: #18181B0A;
--color-components-checkbox-bg-unchecked: #FFFFFF;
--color-components-checkbox-bg-unchecked-hover: #FFFFFF;
--color-components-checkbox-bg-disabled-checked: #B2CAFF;
--color-components-radio-border-checked: #155AEF;
--color-components-radio-border-checked-hover: #004AEB;
--color-components-radio-border-checked-disabled: #F2F4F7;
--color-components-radio-border-checked-disabled: #B2CAFF;
--color-components-radio-bg-disabled: #FFFFFF00;
--color-components-radio-border: #D0D5DC;
--color-components-radio-border-hover: #98A2B2;
@ -135,6 +140,9 @@ html[data-theme="light"] {
--color-components-panel-on-panel-item-bg: #FFFFFF;
--color-components-panel-on-panel-item-bg-hover: #F9FAFB;
--color-components-panel-on-panel-item-bg-alt: #F9FAFB;
--color-components-panel-on-panel-item-bg-transparent: #FFFFFFF2;
--color-components-panel-on-panel-item-bg-hover-transparent: #F9FAFB00;
--color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FEF3F200;
--color-components-panel-bg-transparent: #FFFFFF00;
@ -161,10 +169,10 @@ html[data-theme="light"] {
--color-components-segmented-control-item-active-accent-bg: #FFFFFF;
--color-components-segmented-control-item-active-accent-border: #FFFFFF;
--color-components-option-card-option-bg: #F9FAFB;
--color-components-option-card-option-bg: #FCFCFD;
--color-components-option-card-option-selected-bg: #FFFFFF;
--color-components-option-card-option-selected-border: #296DFF;
--color-components-option-card-option-border: #F2F4F7;
--color-components-option-card-option-border: #E9EBF0;
--color-components-option-card-option-bg-hover: #FFFFFF;
--color-components-option-card-option-border-hover: #D0D5DC;
@ -208,10 +216,12 @@ html[data-theme="light"] {
--color-components-actionbar-bg: #FFFFFFF2;
--color-components-actionbar-border: #1018280A;
--color-components-actionbar-bg-accent: #F5F7FF;
--color-components-actionbar-border-accent: #B2CAFF;
--color-components-dropzone-bg-alt: #F2F4F7;
--color-components-dropzone-bg: #F9FAFB;
--color-components-dropzone-bg-accent: #EFF4FF;
--color-components-dropzone-bg-accent: #155AEF24;
--color-components-dropzone-border: #10182814;
--color-components-dropzone-border-alt: #10182833;
--color-components-dropzone-border-accent: #84ABFF;
@ -228,6 +238,14 @@ html[data-theme="light"] {
--color-components-progress-gray-border: #98A2B2;
--color-components-progress-gray-bg: #C8CEDA05;
--color-components-progress-warning-progress: #F79009;
--color-components-progress-warning-border: #F79009;
--color-components-progress-warning-bg: #F790090A;
--color-components-progress-error-progress: #F04438;
--color-components-progress-error-border: #F04438;
--color-components-progress-error-bg: #F044380A;
--color-components-chat-input-audio-bg: #EFF4FF;
--color-components-chat-input-audio-wave-default: #155AEF33;
--color-components-chat-input-bg-mask-1: #FFFFFF03;
@ -236,13 +254,103 @@ html[data-theme="light"] {
--color-components-chat-input-audio-wave-active: #296DFF;
--color-components-chat-input-audio-bg-alt: #FCFCFD;
--color-components-Avatar-shape-fill-stop-0: #FFFFFF;
--color-components-Avatar-shape-fill-stop-100: #FFFFFFE5;
--color-components-avatar-shape-fill-stop-0: #FFFFFF;
--color-components-avatar-shape-fill-stop-100: #FFFFFFE5;
--color-components-Avatar-bg-mask-stop-0: #FFFFFF1F;
--color-components-Avatar-bg-mask-stop-100: #FFFFFF14;
--color-components-avatar-bg-mask-stop-0: #FFFFFF1F;
--color-components-avatar-bg-mask-stop-100: #FFFFFF14;
--color-components-Avatar-default-avatar-bg: #D0D5DC;
--color-components-avatar-default-avatar-bg: #D0D5DC;
--color-components-avatar-mask-darkmode-dimmed: #FFFFFF00;
--color-components-label-gray: #F2F4F7;
--color-components-premium-badge-blue-bg-stop-0: #5289FF;
--color-components-premium-badge-blue-bg-stop-100: #155AEF;
--color-components-premium-badge-blue-stroke-stop-0: #FFFFFFF2;
--color-components-premium-badge-blue-stroke-stop-100: #155AEF;
--color-components-premium-badge-blue-text-stop-0: #F5F7FF;
--color-components-premium-badge-blue-text-stop-100: #D1E0FF;
--color-components-premium-badge-blue-glow: #00329E;
--color-components-premium-badge-blue-bg-stop-0-hover: #296DFF;
--color-components-premium-badge-blue-bg-stop-100-hover: #004AEB;
--color-components-premium-badge-blue-glow-hover: #84ABFF;
--color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFFF2;
--color-components-premium-badge-blue-stroke-stop-100-hover: #00329E;
--color-components-premium-badge-highlight-stop-0: #FFFFFF1F;
--color-components-premium-badge-highlight-stop-100: #FFFFFF4D;
--color-components-premium-badge-indigo-bg-stop-0: #8098F9;
--color-components-premium-badge-indigo-bg-stop-100: #444CE7;
--color-components-premium-badge-indigo-stroke-stop-0: #FFFFFFF2;
--color-components-premium-badge-indigo-stroke-stop-100: #6172F3;
--color-components-premium-badge-indigo-text-stop-0: #F5F8FF;
--color-components-premium-badge-indigo-text-stop-100: #E0EAFF;
--color-components-premium-badge-indigo-glow: #2D3282;
--color-components-premium-badge-indigo-glow-hover: #A4BCFD;
--color-components-premium-badge-indigo-bg-stop-0-hover: #6172F3;
--color-components-premium-badge-indigo-bg-stop-100-hover: #2D31A6;
--color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFFF2;
--color-components-premium-badge-indigo-stroke-stop-100-hover: #2D31A6;
--color-components-premium-badge-grey-bg-stop-0: #98A2B2;
--color-components-premium-badge-grey-bg-stop-100: #676F83;
--color-components-premium-badge-grey-stroke-stop-0: #FFFFFFF2;
--color-components-premium-badge-grey-stroke-stop-100: #676F83;
--color-components-premium-badge-grey-text-stop-0: #FCFCFD;
--color-components-premium-badge-grey-text-stop-100: #F2F4F7;
--color-components-premium-badge-grey-glow: #101828;
--color-components-premium-badge-grey-glow-hover: #D0D5DC;
--color-components-premium-badge-grey-bg-stop-0-hover: #676F83;
--color-components-premium-badge-grey-bg-stop-100-hover: #354052;
--color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFFF2;
--color-components-premium-badge-grey-stroke-stop-100-hover: #354052;
--color-components-premium-badge-orange-bg-stop-0: #FF692E;
--color-components-premium-badge-orange-bg-stop-100: #E04F16;
--color-components-premium-badge-orange-stroke-stop-0: #FFFFFFF2;
--color-components-premium-badge-orange-stroke-stop-100: #E62E05;
--color-components-premium-badge-orange-text-stop-0: #FEFAF5;
--color-components-premium-badge-orange-text-stop-100: #FDEAD7;
--color-components-premium-badge-orange-glow: #772917;
--color-components-premium-badge-orange-glow-hover: #F7B27A;
--color-components-premium-badge-orange-bg-stop-0-hover: #FF4405;
--color-components-premium-badge-orange-bg-stop-100-hover: #B93815;
--color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFFF2;
--color-components-premium-badge-orange-stroke-stop-100-hover: #BC1B06;
--color-components-progress-bar-bg: #155AEF0A;
--color-components-progress-bar-progress: #155AEF24;
--color-components-progress-bar-border: #1018280A;
--color-components-progress-bar-progress-solid: #296DFF;
--color-components-progress-bar-progress-highlight: #155AEF33;
--color-components-icon-bg-red-solid: #D92D20;
--color-components-icon-bg-rose-solid: #E31B54;
--color-components-icon-bg-pink-solid: #DD2590;
--color-components-icon-bg-orange-dark-solid: #FF4405;
--color-components-icon-bg-yellow-solid: #EAAA08;
--color-components-icon-bg-green-solid: #4CA30D;
--color-components-icon-bg-teal-solid: #0E9384;
--color-components-icon-bg-blue-light-solid: #0BA5EC;
--color-components-icon-bg-blue-solid: #155AEF;
--color-components-icon-bg-indigo-solid: #444CE7;
--color-components-icon-bg-violet-solid: #7839EE;
--color-components-icon-bg-midnight-solid: #828DAD;
--color-components-icon-bg-rose-soft: #FFF1F3;
--color-components-icon-bg-pink-soft: #FDF2FA;
--color-components-icon-bg-orange-dark-soft: #FFF4ED;
--color-components-icon-bg-yellow-soft: #FEFBE8;
--color-components-icon-bg-green-soft: #F3FEE7;
--color-components-icon-bg-teal-soft: #F0FDF9;
--color-components-icon-bg-blue-light-soft: #F0F9FF;
--color-components-icon-bg-blue-soft: #EFF4FF;
--color-components-icon-bg-indigo-soft: #EEF4FF;
--color-components-icon-bg-violet-soft: #F5F3FF;
--color-components-icon-bg-midnight-soft: #F0F2F5;
--color-components-icon-bg-red-soft: #FEF3F2;
--color-components-icon-bg-orange-solid: #F79009;
--color-components-icon-bg-orange-soft: #FFFAEB;
--color-text-primary: #101828;
--color-text-secondary: #354052;
@ -302,6 +410,7 @@ html[data-theme="light"] {
--color-background-overlay-alt: #10182866;
--color-background-surface-white: #FFFFFFF2;
--color-background-overlay-destructive: #F044384D;
--color-background-overlay-backdrop: #F2F4F7F2;
--color-shadow-shadow-1: #09090B08;
--color-shadow-shadow-3: #09090B0D;
@ -317,6 +426,7 @@ html[data-theme="light"] {
--color-workflow-block-border: #FFFFFF;
--color-workflow-block-parma-bg: #F2F4F7;
--color-workflow-block-bg: #FCFCFD;
--color-workflow-block-bg-transparent: #FCFCFDE5;
--color-workflow-block-border-highlight: #155AEF24;
--color-workflow-canvas-workflow-dot-color: #8585AD26;
@ -436,6 +546,7 @@ html[data-theme="light"] {
--color-util-colors-orange-orange-500: #EF6820;
--color-util-colors-orange-orange-600: #E04F16;
--color-util-colors-orange-orange-700: #B93815;
--color-util-colors-orange-orange-100-transparent: #FDEAD700;
--color-util-colors-pink-pink-50: #FDF2FA;
--color-util-colors-pink-pink-100: #FCE7F6;
@ -610,6 +721,17 @@ html[data-theme="light"] {
--color-third-party-LangChain: #1C3C3C;
--color-third-party-Langfuse: #000000;
--color-third-party-Github: #1B1F24;
--color-third-party-Github-tertiary: #1B1F24;
--color-third-party-Github-secondary: #1B1F24;
--color-third-party-model-bg-openai: #E3E5E8;
--color-third-party-model-bg-anthropic: #EEEDE7;
--color-third-party-model-bg-default: #F9FAFB;
--color-third-party-aws: #141F2E;
--color-third-party-aws-alt: #0F1824;
--color-saas-background: #FCFCFD;
--color-saas-pricing-grid-bg: #C8CEDA80;
}

View File

@ -85,6 +85,10 @@ const vars = {
'components-button-secondary-accent-border-hover': 'var(--color-components-button-secondary-accent-border-hover)',
'components-button-secondary-accent-border-disabled': 'var(--color-components-button-secondary-accent-border-disabled)',
'components-button-indigo-bg': 'var(--color-components-button-indigo-bg)',
'components-button-indigo-bg-hover': 'var(--color-components-button-indigo-bg-hover)',
'components-button-indigo-bg-disabled': 'var(--color-components-button-indigo-bg-disabled)',
'components-checkbox-icon': 'var(--color-components-checkbox-icon)',
'components-checkbox-icon-disabled': 'var(--color-components-checkbox-icon-disabled)',
'components-checkbox-bg': 'var(--color-components-checkbox-bg)',
@ -95,6 +99,7 @@ const vars = {
'components-checkbox-border-disabled': 'var(--color-components-checkbox-border-disabled)',
'components-checkbox-bg-unchecked': 'var(--color-components-checkbox-bg-unchecked)',
'components-checkbox-bg-unchecked-hover': 'var(--color-components-checkbox-bg-unchecked-hover)',
'components-checkbox-bg-disabled-checked': 'var(--color-components-checkbox-bg-disabled-checked)',
'components-radio-border-checked': 'var(--color-components-radio-border-checked)',
'components-radio-border-checked-hover': 'var(--color-components-radio-border-checked-hover)',
@ -135,6 +140,9 @@ const vars = {
'components-panel-on-panel-item-bg': 'var(--color-components-panel-on-panel-item-bg)',
'components-panel-on-panel-item-bg-hover': 'var(--color-components-panel-on-panel-item-bg-hover)',
'components-panel-on-panel-item-bg-alt': 'var(--color-components-panel-on-panel-item-bg-alt)',
'components-panel-on-panel-item-bg-transparent': 'var(--color-components-panel-on-panel-item-bg-transparent)',
'components-panel-on-panel-item-bg-hover-transparent': 'var(--color-components-panel-on-panel-item-bg-hover-transparent)',
'components-panel-on-panel-item-bg-destructive-hover-transparent': 'var(--color-components-panel-on-panel-item-bg-destructive-hover-transparent)',
'components-panel-bg-transparent': 'var(--color-components-panel-bg-transparent)',
@ -208,6 +216,8 @@ const vars = {
'components-actionbar-bg': 'var(--color-components-actionbar-bg)',
'components-actionbar-border': 'var(--color-components-actionbar-border)',
'components-actionbar-bg-accent': 'var(--color-components-actionbar-bg-accent)',
'components-actionbar-border-accent': 'var(--color-components-actionbar-border-accent)',
'components-dropzone-bg-alt': 'var(--color-components-dropzone-bg-alt)',
'components-dropzone-bg': 'var(--color-components-dropzone-bg)',
@ -228,6 +238,14 @@ const vars = {
'components-progress-gray-border': 'var(--color-components-progress-gray-border)',
'components-progress-gray-bg': 'var(--color-components-progress-gray-bg)',
'components-progress-warning-progress': 'var(--color-components-progress-warning-progress)',
'components-progress-warning-border': 'var(--color-components-progress-warning-border)',
'components-progress-warning-bg': 'var(--color-components-progress-warning-bg)',
'components-progress-error-progress': 'var(--color-components-progress-error-progress)',
'components-progress-error-border': 'var(--color-components-progress-error-border)',
'components-progress-error-bg': 'var(--color-components-progress-error-bg)',
'components-chat-input-audio-bg': 'var(--color-components-chat-input-audio-bg)',
'components-chat-input-audio-wave-default': 'var(--color-components-chat-input-audio-wave-default)',
'components-chat-input-bg-mask-1': 'var(--color-components-chat-input-bg-mask-1)',
@ -236,13 +254,103 @@ const vars = {
'components-chat-input-audio-wave-active': 'var(--color-components-chat-input-audio-wave-active)',
'components-chat-input-audio-bg-alt': 'var(--color-components-chat-input-audio-bg-alt)',
'components-Avatar-shape-fill-stop-0': 'var(--color-components-Avatar-shape-fill-stop-0)',
'components-Avatar-shape-fill-stop-100': 'var(--color-components-Avatar-shape-fill-stop-100)',
'components-avatar-shape-fill-stop-0': 'var(--color-components-avatar-shape-fill-stop-0)',
'components-avatar-shape-fill-stop-100': 'var(--color-components-avatar-shape-fill-stop-100)',
'components-Avatar-bg-mask-stop-0': 'var(--color-components-Avatar-bg-mask-stop-0)',
'components-Avatar-bg-mask-stop-100': 'var(--color-components-Avatar-bg-mask-stop-100)',
'components-avatar-bg-mask-stop-0': 'var(--color-components-avatar-bg-mask-stop-0)',
'components-avatar-bg-mask-stop-100': 'var(--color-components-avatar-bg-mask-stop-100)',
'components-Avatar-default-avatar-bg': 'var(--color-components-Avatar-default-avatar-bg)',
'components-avatar-default-avatar-bg': 'var(--color-components-avatar-default-avatar-bg)',
'components-avatar-mask-darkmode-dimmed': 'var(--color-components-avatar-mask-darkmode-dimmed)',
'components-label-gray': 'var(--color-components-label-gray)',
'components-premium-badge-blue-bg-stop-0': 'var(--color-components-premium-badge-blue-bg-stop-0)',
'components-premium-badge-blue-bg-stop-100': 'var(--color-components-premium-badge-blue-bg-stop-100)',
'components-premium-badge-blue-stroke-stop-0': 'var(--color-components-premium-badge-blue-stroke-stop-0)',
'components-premium-badge-blue-stroke-stop-100': 'var(--color-components-premium-badge-blue-stroke-stop-100)',
'components-premium-badge-blue-text-stop-0': 'var(--color-components-premium-badge-blue-text-stop-0)',
'components-premium-badge-blue-text-stop-100': 'var(--color-components-premium-badge-blue-text-stop-100)',
'components-premium-badge-blue-glow': 'var(--color-components-premium-badge-blue-glow)',
'components-premium-badge-blue-bg-stop-0-hover': 'var(--color-components-premium-badge-blue-bg-stop-0-hover)',
'components-premium-badge-blue-bg-stop-100-hover': 'var(--color-components-premium-badge-blue-bg-stop-100-hover)',
'components-premium-badge-blue-glow-hover': 'var(--color-components-premium-badge-blue-glow-hover)',
'components-premium-badge-blue-stroke-stop-0-hover': 'var(--color-components-premium-badge-blue-stroke-stop-0-hover)',
'components-premium-badge-blue-stroke-stop-100-hover': 'var(--color-components-premium-badge-blue-stroke-stop-100-hover)',
'components-premium-badge-highlight-stop-0': 'var(--color-components-premium-badge-highlight-stop-0)',
'components-premium-badge-highlight-stop-100': 'var(--color-components-premium-badge-highlight-stop-100)',
'components-premium-badge-indigo-bg-stop-0': 'var(--color-components-premium-badge-indigo-bg-stop-0)',
'components-premium-badge-indigo-bg-stop-100': 'var(--color-components-premium-badge-indigo-bg-stop-100)',
'components-premium-badge-indigo-stroke-stop-0': 'var(--color-components-premium-badge-indigo-stroke-stop-0)',
'components-premium-badge-indigo-stroke-stop-100': 'var(--color-components-premium-badge-indigo-stroke-stop-100)',
'components-premium-badge-indigo-text-stop-0': 'var(--color-components-premium-badge-indigo-text-stop-0)',
'components-premium-badge-indigo-text-stop-100': 'var(--color-components-premium-badge-indigo-text-stop-100)',
'components-premium-badge-indigo-glow': 'var(--color-components-premium-badge-indigo-glow)',
'components-premium-badge-indigo-glow-hover': 'var(--color-components-premium-badge-indigo-glow-hover)',
'components-premium-badge-indigo-bg-stop-0-hover': 'var(--color-components-premium-badge-indigo-bg-stop-0-hover)',
'components-premium-badge-indigo-bg-stop-100-hover': 'var(--color-components-premium-badge-indigo-bg-stop-100-hover)',
'components-premium-badge-indigo-stroke-stop-0-hover': 'var(--color-components-premium-badge-indigo-stroke-stop-0-hover)',
'components-premium-badge-indigo-stroke-stop-100-hover': 'var(--color-components-premium-badge-indigo-stroke-stop-100-hover)',
'components-premium-badge-grey-bg-stop-0': 'var(--color-components-premium-badge-grey-bg-stop-0)',
'components-premium-badge-grey-bg-stop-100': 'var(--color-components-premium-badge-grey-bg-stop-100)',
'components-premium-badge-grey-stroke-stop-0': 'var(--color-components-premium-badge-grey-stroke-stop-0)',
'components-premium-badge-grey-stroke-stop-100': 'var(--color-components-premium-badge-grey-stroke-stop-100)',
'components-premium-badge-grey-text-stop-0': 'var(--color-components-premium-badge-grey-text-stop-0)',
'components-premium-badge-grey-text-stop-100': 'var(--color-components-premium-badge-grey-text-stop-100)',
'components-premium-badge-grey-glow': 'var(--color-components-premium-badge-grey-glow)',
'components-premium-badge-grey-glow-hover': 'var(--color-components-premium-badge-grey-glow-hover)',
'components-premium-badge-grey-bg-stop-0-hover': 'var(--color-components-premium-badge-grey-bg-stop-0-hover)',
'components-premium-badge-grey-bg-stop-100-hover': 'var(--color-components-premium-badge-grey-bg-stop-100-hover)',
'components-premium-badge-grey-stroke-stop-0-hover': 'var(--color-components-premium-badge-grey-stroke-stop-0-hover)',
'components-premium-badge-grey-stroke-stop-100-hover': 'var(--color-components-premium-badge-grey-stroke-stop-100-hover)',
'components-premium-badge-orange-bg-stop-0': 'var(--color-components-premium-badge-orange-bg-stop-0)',
'components-premium-badge-orange-bg-stop-100': 'var(--color-components-premium-badge-orange-bg-stop-100)',
'components-premium-badge-orange-stroke-stop-0': 'var(--color-components-premium-badge-orange-stroke-stop-0)',
'components-premium-badge-orange-stroke-stop-100': 'var(--color-components-premium-badge-orange-stroke-stop-100)',
'components-premium-badge-orange-text-stop-0': 'var(--color-components-premium-badge-orange-text-stop-0)',
'components-premium-badge-orange-text-stop-100': 'var(--color-components-premium-badge-orange-text-stop-100)',
'components-premium-badge-orange-glow': 'var(--color-components-premium-badge-orange-glow)',
'components-premium-badge-orange-glow-hover': 'var(--color-components-premium-badge-orange-glow-hover)',
'components-premium-badge-orange-bg-stop-0-hover': 'var(--color-components-premium-badge-orange-bg-stop-0-hover)',
'components-premium-badge-orange-bg-stop-100-hover': 'var(--color-components-premium-badge-orange-bg-stop-100-hover)',
'components-premium-badge-orange-stroke-stop-0-hover': 'var(--color-components-premium-badge-orange-stroke-stop-0-hover)',
'components-premium-badge-orange-stroke-stop-100-hover': 'var(--color-components-premium-badge-orange-stroke-stop-100-hover)',
'components-progress-bar-bg': 'var(--color-components-progress-bar-bg)',
'components-progress-bar-progress': 'var(--color-components-progress-bar-progress)',
'components-progress-bar-border': 'var(--color-components-progress-bar-border)',
'components-progress-bar-progress-solid': 'var(--color-components-progress-bar-progress-solid)',
'components-progress-bar-progress-highlight': 'var(--color-components-progress-bar-progress-highlight)',
'components-icon-bg-red-solid': 'var(--color-components-icon-bg-red-solid)',
'components-icon-bg-rose-solid': 'var(--color-components-icon-bg-rose-solid)',
'components-icon-bg-pink-solid': 'var(--color-components-icon-bg-pink-solid)',
'components-icon-bg-orange-dark-solid': 'var(--color-components-icon-bg-orange-dark-solid)',
'components-icon-bg-yellow-solid': 'var(--color-components-icon-bg-yellow-solid)',
'components-icon-bg-green-solid': 'var(--color-components-icon-bg-green-solid)',
'components-icon-bg-teal-solid': 'var(--color-components-icon-bg-teal-solid)',
'components-icon-bg-blue-light-solid': 'var(--color-components-icon-bg-blue-light-solid)',
'components-icon-bg-blue-solid': 'var(--color-components-icon-bg-blue-solid)',
'components-icon-bg-indigo-solid': 'var(--color-components-icon-bg-indigo-solid)',
'components-icon-bg-violet-solid': 'var(--color-components-icon-bg-violet-solid)',
'components-icon-bg-midnight-solid': 'var(--color-components-icon-bg-midnight-solid)',
'components-icon-bg-rose-soft': 'var(--color-components-icon-bg-rose-soft)',
'components-icon-bg-pink-soft': 'var(--color-components-icon-bg-pink-soft)',
'components-icon-bg-orange-dark-soft': 'var(--color-components-icon-bg-orange-dark-soft)',
'components-icon-bg-yellow-soft': 'var(--color-components-icon-bg-yellow-soft)',
'components-icon-bg-green-soft': 'var(--color-components-icon-bg-green-soft)',
'components-icon-bg-teal-soft': 'var(--color-components-icon-bg-teal-soft)',
'components-icon-bg-blue-light-soft': 'var(--color-components-icon-bg-blue-light-soft)',
'components-icon-bg-blue-soft': 'var(--color-components-icon-bg-blue-soft)',
'components-icon-bg-indigo-soft': 'var(--color-components-icon-bg-indigo-soft)',
'components-icon-bg-violet-soft': 'var(--color-components-icon-bg-violet-soft)',
'components-icon-bg-midnight-soft': 'var(--color-components-icon-bg-midnight-soft)',
'components-icon-bg-red-soft': 'var(--color-components-icon-bg-red-soft)',
'components-icon-bg-orange-solid': 'var(--color-components-icon-bg-orange-solid)',
'components-icon-bg-orange-soft': 'var(--color-components-icon-bg-orange-soft)',
'text-primary': 'var(--color-text-primary)',
'text-secondary': 'var(--color-text-secondary)',
@ -302,6 +410,7 @@ const vars = {
'background-overlay-alt': 'var(--color-background-overlay-alt)',
'background-surface-white': 'var(--color-background-surface-white)',
'background-overlay-destructive': 'var(--color-background-overlay-destructive)',
'background-overlay-backdrop': 'var(--color-background-overlay-backdrop)',
'shadow-shadow-1': 'var(--color-shadow-shadow-1)',
'shadow-shadow-3': 'var(--color-shadow-shadow-3)',
@ -317,6 +426,7 @@ const vars = {
'workflow-block-border': 'var(--color-workflow-block-border)',
'workflow-block-parma-bg': 'var(--color-workflow-block-parma-bg)',
'workflow-block-bg': 'var(--color-workflow-block-bg)',
'workflow-block-bg-transparent': 'var(--color-workflow-block-bg-transparent)',
'workflow-block-border-highlight': 'var(--color-workflow-block-border-highlight)',
'workflow-canvas-workflow-dot-color': 'var(--color-workflow-canvas-workflow-dot-color)',
@ -436,6 +546,7 @@ const vars = {
'util-colors-orange-orange-500': 'var(--color-util-colors-orange-orange-500)',
'util-colors-orange-orange-600': 'var(--color-util-colors-orange-orange-600)',
'util-colors-orange-orange-700': 'var(--color-util-colors-orange-orange-700)',
'util-colors-orange-orange-100-transparent': 'var(--color-util-colors-orange-orange-100-transparent)',
'util-colors-pink-pink-50': 'var(--color-util-colors-pink-pink-50)',
'util-colors-pink-pink-100': 'var(--color-util-colors-pink-pink-100)',
@ -611,6 +722,17 @@ const vars = {
'third-party-LangChain': 'var(--color-third-party-LangChain)',
'third-party-Langfuse': 'var(--color-third-party-Langfuse)',
'third-party-Github': 'var(--color-third-party-Github)',
}
'third-party-Github-tertiary': 'var(--color-third-party-Github-tertiary)',
'third-party-Github-secondary': 'var(--color-third-party-Github-secondary)',
'third-party-model-bg-openai': 'var(--color-third-party-model-bg-openai)',
'third-party-model-bg-anthropic': 'var(--color-third-party-model-bg-anthropic)',
'third-party-model-bg-default': 'var(--color-third-party-model-bg-default)',
'third-party-aws': 'var(--color-third-party-aws)',
'third-party-aws-alt': 'var(--color-third-party-aws-alt)',
'saas-background': 'var(--color-saas-background)',
'saas-pricing-grid-bg': 'var(--color-saas-pricing-grid-bg)',
}
export default vars