Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/dify_plugin/entities/model/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ class FormOption(BaseModel):
value: str
show_on: list[FormShowOnObject] = Field(default_factory=list)

def __init__(self, **data: object) -> None:
super().__init__(**data)
if not self.label:
self.label = I18nObject(en_us=self.value)
@model_validator(mode="before")
@classmethod
def validate_label(cls, data: dict) -> dict:
if isinstance(data, dict) and not data.get("label") and "value" in data:
data["label"] = I18nObject(en_US=str(data["value"]))

return data


@docs(
Expand Down
4 changes: 2 additions & 2 deletions src/dify_plugin/entities/model/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class ProviderModel(BaseModel):
@classmethod
def validate_label(cls, data: dict) -> dict:
if isinstance(data, dict) and not data.get("label"):
data["label"] = I18nObject(en_us=data["model"])
data["label"] = I18nObject(en_US=data["model"])

return data

Expand Down Expand Up @@ -369,7 +369,7 @@ def validate_label(cls, data: dict) -> dict:
pass

if not data.get("label"):
data["label"] = I18nObject(en_us=data["name"])
data["label"] = I18nObject(en_US=data["name"])

return data

Expand Down
28 changes: 14 additions & 14 deletions src/dify_plugin/entities/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ class I18nObject(BaseModel):
validate_by_name=True,
)

zh_hans: str | None = Field(default=None, alias="zh_Hans")
pt_br: str | None = Field(default=None, alias="pt_BR")
ja_jp: str | None = Field(default=None, alias="ja_JP")
en_us: str = Field(alias="en_US")
zh_Hans: str | None = Field(default=None) # noqa: N815
pt_BR: str | None = Field(default=None) # noqa: N815
ja_JP: str | None = Field(default=None) # noqa: N815
en_US: str # noqa: N815

@model_validator(mode="after")
def fill_missing_translations(self) -> "I18nObject":
if not self.zh_hans:
self.zh_hans = self.en_us
if not self.pt_br:
self.pt_br = self.en_us
if not self.ja_jp:
self.ja_jp = self.en_us
if not self.zh_Hans:
self.zh_Hans = self.en_US
if not self.pt_BR:
self.pt_BR = self.en_US
if not self.ja_JP:
self.ja_JP = self.en_US
return self

def to_dict(self) -> dict:
return {
"zh_Hans": self.zh_hans,
"en_US": self.en_us,
"pt_BR": self.pt_br,
"ja_JP": self.ja_jp,
"zh_Hans": self.zh_Hans,
"en_US": self.en_US,
"pt_BR": self.pt_BR,
"ja_JP": self.ja_JP,
}


Expand Down
10 changes: 5 additions & 5 deletions src/dify_plugin/interfaces/model/ai_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,28 +292,28 @@ def _get_customizable_model_schema(
parameter_rule.required = default_parameter_rule["required"]
if not parameter_rule.help and "help" in default_parameter_rule:
parameter_rule.help = I18nObject(
en_us=default_parameter_rule["help"]["en_US"],
en_US=default_parameter_rule["help"]["en_US"],
)
if (
parameter_rule.help
and not parameter_rule.help.en_us
and not parameter_rule.help.en_US
and (
"help" in default_parameter_rule
and "en_US" in default_parameter_rule["help"]
)
):
parameter_rule.help.en_us = default_parameter_rule["help"][
parameter_rule.help.en_US = default_parameter_rule["help"][
"en_US"
]
if (
parameter_rule.help
and not parameter_rule.help.zh_hans
and not parameter_rule.help.zh_Hans
and (
"help" in default_parameter_rule
and "zh_Hans" in default_parameter_rule["help"]
)
):
parameter_rule.help.zh_hans = default_parameter_rule[
parameter_rule.help.zh_Hans = default_parameter_rule[
"help"
].get("zh_Hans", default_parameter_rule["help"]["en_US"])
except ValueError:
Expand Down
32 changes: 16 additions & 16 deletions src/dify_plugin/interfaces/model/openai_compatible/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def get_customizable_model_schema(

entity = AIModelEntity(
model=model,
label=I18nObject(en_us=model),
label=I18nObject(en_US=model),
model_type=ModelType.LLM,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
features=features,
Expand All @@ -376,16 +376,16 @@ def get_customizable_model_schema(
parameter_rules=[
ParameterRule(
name=DefaultParameterName.TEMPERATURE.value,
label=I18nObject(en_us="Temperature", zh_hans="温度"),
label=I18nObject(en_US="Temperature", zh_Hans="温度"),
help=I18nObject(
en_us=(
en_US=(
"Kernel sampling threshold. Used to determine the "
"randomness of the results."
"The higher the value, the stronger the randomness."
"The higher the possibility of getting different "
"answers to the same question."
),
zh_hans=(
zh_Hans=(
"核采样阈值。用于决定结果随机性,取值越高随机性越强即"
"相同的问题得到的不同答案的可能性越高。"
),
Expand All @@ -398,17 +398,17 @@ def get_customizable_model_schema(
),
ParameterRule(
name=DefaultParameterName.TOP_P.value,
label=I18nObject(en_us="Top P", zh_hans="Top P"),
label=I18nObject(en_US="Top P", zh_Hans="Top P"),
help=I18nObject(
en_us=(
en_US=(
"The probability threshold of the nucleus sampling "
"method during the generation process."
"The larger the value is, the higher the randomness "
"of generation will be."
"The smaller the value is, the higher the certainty "
"of generation will be."
),
zh_hans=(
zh_Hans=(
"生成过程中核采样方法概率阈值。取值越大,生成的随机性"
"越高;取值越小,生成的确定性越高。"
),
Expand All @@ -421,15 +421,15 @@ def get_customizable_model_schema(
),
ParameterRule(
name=DefaultParameterName.FREQUENCY_PENALTY.value,
label=I18nObject(en_us="Frequency Penalty", zh_hans="频率惩罚"),
label=I18nObject(en_US="Frequency Penalty", zh_Hans="频率惩罚"),
help=I18nObject(
en_us=(
en_US=(
"For controlling the repetition rate of words used "
"by the model."
"Increasing this can reduce the repetition of the "
"same words in the model's output."
),
zh_hans=(
zh_Hans=(
"用于控制模型已使用字词的重复率。 提高此项可以降低模型在"
"输出中重复相同字词的重复度。"
),
Expand All @@ -441,15 +441,15 @@ def get_customizable_model_schema(
),
ParameterRule(
name=DefaultParameterName.PRESENCE_PENALTY.value,
label=I18nObject(en_us="Presence Penalty", zh_hans="存在惩罚"),
label=I18nObject(en_US="Presence Penalty", zh_Hans="存在惩罚"),
help=I18nObject(
en_us=(
en_US=(
"Used to control the repetition rate when "
"generating models."
"Increasing this can reduce the repetition rate "
"of model generation."
),
zh_hans="用于控制模型生成时的重复度。提高此项可以降低模型生成的重复度。",
zh_Hans="用于控制模型生成时的重复度。提高此项可以降低模型生成的重复度。",
),
type=ParameterType.FLOAT,
default=float(credentials.get("presence_penalty", 0)),
Expand All @@ -458,10 +458,10 @@ def get_customizable_model_schema(
),
ParameterRule(
name=DefaultParameterName.MAX_TOKENS.value,
label=I18nObject(en_us="Max Tokens", zh_hans="最大标记"),
label=I18nObject(en_US="Max Tokens", zh_Hans="最大标记"),
help=I18nObject(
en_us="Maximum length of tokens for the model response.",
zh_hans="模型回答的tokens的最大长度。",
en_US="Maximum length of tokens for the model response.",
zh_Hans="模型回答的tokens的最大长度。",
),
type=ParameterType.INT,
default=512,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def get_customizable_model_schema(
del credentials
return AIModelEntity(
model=model,
label=I18nObject(en_us=model),
label=I18nObject(en_US=model),
model_type=ModelType.RERANK,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def get_customizable_model_schema(
"""
return AIModelEntity(
model=model,
label=I18nObject(en_us=model),
label=I18nObject(en_US=model),
model_type=ModelType.TEXT_EMBEDDING,
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
Expand Down
2 changes: 1 addition & 1 deletion src/dify_plugin/interfaces/model/openai_compatible/tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def get_customizable_model_schema(

return AIModelEntity(
model=model,
label=I18nObject(en_us=model),
label=I18nObject(en_US=model),
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_type=ModelType.TTS,
model_properties={
Expand Down
9 changes: 9 additions & 0 deletions tests/entities/models/test_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from dify_plugin.entities.model.provider import FormOption


def test_form_option_uses_value_as_default_label() -> None:
option = FormOption(value="gpt-4")

assert option.label.en_US == "gpt-4"
assert option.label.zh_Hans == "gpt-4"
assert option.value == "gpt-4"
48 changes: 48 additions & 0 deletions tests/entities/test_parameters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest
from pydantic import ValidationError

from dify_plugin.entities import I18nObject


def test_i18n_object_uses_legacy_python_attribute_names() -> None:
i18n = I18nObject.model_validate({
"en_US": "English",
"zh_Hans": "简体中文",
"pt_BR": "Português",
"ja_JP": "日本語",
})

assert i18n.en_US == "English"
assert i18n.zh_Hans == "简体中文"
assert i18n.pt_BR == "Português"
assert i18n.ja_JP == "日本語"
assert i18n.model_dump() == {
"en_US": "English",
"zh_Hans": "简体中文",
"pt_BR": "Português",
"ja_JP": "日本語",
}


def test_i18n_object_fills_missing_translations_from_english() -> None:
i18n = I18nObject(en_US="English")

assert i18n.en_US == "English"
assert i18n.zh_Hans == "English"
assert i18n.pt_BR == "English"
assert i18n.ja_JP == "English"

assert i18n.to_dict() == {
"en_US": "English",
"zh_Hans": "English",
"pt_BR": "English",
"ja_JP": "English",
}


def test_i18n_object_does_not_accept_new_python_attribute_names() -> None:
with pytest.raises(AttributeError):
_ = I18nObject(en_US="English").en_us

with pytest.raises(ValidationError):
I18nObject(en_us="English")
2 changes: 1 addition & 1 deletion tests/interfaces/model/test_construct_model_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def validate_provider_credentials(self, credentials: dict) -> None:

provider_schema = ProviderEntity(
provider="test",
label=I18nObject(en_us="test"),
label=I18nObject(en_US="test"),
supported_model_types=[ModelType.LLM],
configurate_methods=[],
)
Expand Down
4 changes: 2 additions & 2 deletions tests/interfaces/model/test_model_registry_get_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_model_provider_get_model_instance_delegates_to_factory() -> None:

provider_schema = ProviderEntity(
provider="test",
label=I18nObject(en_us="test"),
label=I18nObject(en_US="test"),
supported_model_types=[ModelType.LLM],
configurate_methods=[],
)
Expand All @@ -60,7 +60,7 @@ def test_model_provider_get_model_instance_get_multiple_instances() -> None:
provider = MockModelProvider(
provider_schemas=ProviderEntity(
provider="test",
label=I18nObject(en_us="test"),
label=I18nObject(en_US="test"),
supported_model_types=[ModelType.LLM],
configurate_methods=[],
),
Expand Down
2 changes: 1 addition & 1 deletion tests/interfaces/model/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def prepare_model_factory(models: Mapping[ModelType, type[AIModel]]) -> ModelFac
return ModelFactory(
ModelProviderConfiguration(
provider="test",
label=I18nObject(en_us="test"),
label=I18nObject(en_US="test"),
supported_model_types=list(models.keys()),
configurate_methods=[],
extra=ModelProviderConfigurationExtra(
Expand Down
4 changes: 2 additions & 2 deletions tests/interfaces/tool/test_costruct_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def _invoke(

def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
del parameter
return [ParameterOption(value="test", label=I18nObject(en_us="test"))]
return [ParameterOption(value="test", label=I18nObject(en_US="test"))]

session = Session(
session_id="test",
Expand All @@ -95,5 +95,5 @@ def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
session=session,
)
assert tool.fetch_parameter_options("test") == [
ParameterOption(value="test", label=I18nObject(en_us="test"))
ParameterOption(value="test", label=I18nObject(en_US="test"))
]
2 changes: 1 addition & 1 deletion tests/test_model_polling.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def prompt_messages(self) -> list[UserPromptMessage]:
def model_entity(self) -> AIModelEntity:
return AIModelEntity(
model=self.model,
label=I18nObject(en_us=self.model),
label=I18nObject(en_US=self.model),
model_type=ModelType.LLM,
features=[ModelFeature.POLLING],
fetch_from=FetchFrom.PREDEFINED_MODEL,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_model_registry_get_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def mock_resolve_plugin_cls(self: PluginRegistration) -> None:
# add MockLLM to models_mapping
provider_configuration = ModelProviderConfiguration(
provider="test",
label=I18nObject(zh_hans="test", en_us="test"),
label=I18nObject(zh_Hans="test", en_US="test"),
models={},
supported_model_types=[ModelType.LLM],
extra=ModelProviderConfigurationExtra(
Expand All @@ -165,7 +165,7 @@ def mock_resolve_plugin_cls(self: PluginRegistration) -> None:
MockModelProvider(
provider_schemas=ProviderEntity(
provider="test",
label=I18nObject(zh_hans="test", en_us="test"),
label=I18nObject(zh_Hans="test", en_US="test"),
supported_model_types=[ModelType.LLM],
configurate_methods=[],
),
Expand Down
Loading