Merge branch 'fix/chore-fix' into dev/plugin-deploy

This commit is contained in:
Yeuoly 2024-12-27 17:38:10 +08:00
commit 4ee4740657
133 changed files with 2051 additions and 1282 deletions

View File

@ -66,10 +66,17 @@ class MessageFeedbackApi(InstalledAppResource):
parser = reqparse.RequestParser()
parser.add_argument("rating", type=str, choices=["like", "dislike", None], location="json")
parser.add_argument("content", type=str, location="json")
args = parser.parse_args()
try:
MessageService.create_feedback(app_model, message_id, current_user, args.get("rating"), args.get("content"))
MessageService.create_feedback(
app_model=app_model,
message_id=message_id,
user=current_user,
rating=args.get("rating"),
content=args.get("content"),
)
except services.errors.message.MessageNotExistsError:
raise NotFound("Message Not Exists.")

View File

@ -108,7 +108,13 @@ class MessageFeedbackApi(Resource):
args = parser.parse_args()
try:
MessageService.create_feedback(app_model, message_id, end_user, args.get("rating"), args.get("content"))
MessageService.create_feedback(
app_model=app_model,
message_id=message_id,
user=end_user,
rating=args.get("rating"),
content=args.get("content"),
)
except services.errors.message.MessageNotExistsError:
raise NotFound("Message Not Exists.")

View File

@ -8,12 +8,16 @@ from werkzeug.exceptions import NotFound
import services.dataset_service
from controllers.common.errors import FilenameNotExistsError
from controllers.service_api import api
from controllers.service_api.app.error import ProviderNotInitializeError
from controllers.service_api.app.error import (
FileTooLargeError,
NoFileUploadedError,
ProviderNotInitializeError,
TooManyFilesError,
UnsupportedFileTypeError,
)
from controllers.service_api.dataset.error import (
ArchivedDocumentImmutableError,
DocumentIndexingError,
NoFileUploadedError,
TooManyFilesError,
)
from controllers.service_api.wraps import DatasetApiResource, cloud_edition_billing_resource_check
from core.errors.error import ProviderTokenNotInitError
@ -238,13 +242,18 @@ class DocumentUpdateByFileApi(DatasetApiResource):
if not file.filename:
raise FilenameNotExistsError
upload_file = FileService.upload_file(
filename=file.filename,
content=file.read(),
mimetype=file.mimetype,
user=current_user,
source="datasets",
)
try:
upload_file = FileService.upload_file(
filename=file.filename,
content=file.read(),
mimetype=file.mimetype,
user=current_user,
source="datasets",
)
except services.errors.file.FileTooLargeError as file_too_large_error:
raise FileTooLargeError(file_too_large_error.description)
except services.errors.file.UnsupportedFileTypeError:
raise UnsupportedFileTypeError()
data_source = {"type": "upload_file", "info_list": {"file_info_list": {"file_ids": [upload_file.id]}}}
args["data_source"] = data_source
# validate args

View File

@ -369,11 +369,12 @@ class AdvancedChatAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCyc
with Session(db.engine) as session:
workflow_node_execution = self._handle_workflow_node_execution_failed(session=session, event=event)
response_finish = self._workflow_node_finish_to_stream_response(
event=event,
task_id=self._application_generate_entity.task_id,
workflow_node_execution=workflow_node_execution,
)
response_finish = self._workflow_node_finish_to_stream_response(
session=session,
event=event,
task_id=self._application_generate_entity.task_id,
workflow_node_execution=workflow_node_execution,
)
if response_finish:
yield response_finish

View File

@ -114,9 +114,7 @@ class WorkflowAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCycleMa
}
self._task_state = WorkflowTaskState()
self._wip_workflow_node_executions = {}
self._wip_workflow_agent_logs = {}
self.total_tokens: int = 0
self._workflow_run_id = ""
def process(self) -> Union[WorkflowAppBlockingResponse, Generator[WorkflowAppStreamResponse, None, None]]:
"""

View File

@ -67,8 +67,6 @@ class WorkflowCycleManage:
_application_generate_entity: Union[AdvancedChatAppGenerateEntity, WorkflowAppGenerateEntity]
_task_state: WorkflowTaskState
_workflow_system_variables: dict[SystemVariableKey, Any]
_wip_workflow_node_executions: dict[str, WorkflowNodeExecution]
_wip_workflow_agent_logs: dict[str, list[AgentLogStreamResponse.Data]]
def _handle_workflow_run_start(
self,
@ -313,33 +311,11 @@ class WorkflowCycleManage:
inputs = WorkflowEntry.handle_special_values(event.inputs)
process_data = WorkflowEntry.handle_special_values(event.process_data)
outputs = WorkflowEntry.handle_special_values(event.outputs)
execution_metadata_dict = event.execution_metadata
if self._wip_workflow_agent_logs.get(workflow_node_execution.id):
if not execution_metadata_dict:
execution_metadata_dict = {}
execution_metadata_dict[NodeRunMetadataKey.AGENT_LOG] = self._wip_workflow_agent_logs.get(
workflow_node_execution.id, []
)
execution_metadata_dict = dict(event.execution_metadata or {})
execution_metadata = json.dumps(jsonable_encoder(execution_metadata_dict)) if execution_metadata_dict else None
finished_at = datetime.now(UTC).replace(tzinfo=None)
elapsed_time = (finished_at - event.start_at).total_seconds()
db.session.query(WorkflowNodeExecution).filter(WorkflowNodeExecution.id == workflow_node_execution.id).update(
{
WorkflowNodeExecution.status: WorkflowNodeExecutionStatus.SUCCEEDED.value,
WorkflowNodeExecution.inputs: json.dumps(inputs) if inputs else None,
WorkflowNodeExecution.process_data: json.dumps(process_data) if process_data else None,
WorkflowNodeExecution.outputs: json.dumps(outputs) if outputs else None,
WorkflowNodeExecution.execution_metadata: execution_metadata,
WorkflowNodeExecution.finished_at: finished_at,
WorkflowNodeExecution.elapsed_time: elapsed_time,
}
)
db.session.commit()
db.session.close()
process_data = WorkflowEntry.handle_special_values(event.process_data)
workflow_node_execution.status = WorkflowNodeExecutionStatus.SUCCEEDED.value
@ -372,35 +348,9 @@ class WorkflowCycleManage:
outputs = WorkflowEntry.handle_special_values(event.outputs)
finished_at = datetime.now(UTC).replace(tzinfo=None)
elapsed_time = (finished_at - event.start_at).total_seconds()
execution_metadata_dict = event.execution_metadata
if self._wip_workflow_agent_logs.get(workflow_node_execution.id):
if not execution_metadata_dict:
execution_metadata_dict = {}
execution_metadata_dict[NodeRunMetadataKey.AGENT_LOG] = self._wip_workflow_agent_logs.get(
workflow_node_execution.id, []
)
execution_metadata = json.dumps(jsonable_encoder(execution_metadata_dict)) if execution_metadata_dict else None
db.session.query(WorkflowNodeExecution).filter(WorkflowNodeExecution.id == workflow_node_execution.id).update(
{
WorkflowNodeExecution.status: (
WorkflowNodeExecutionStatus.FAILED.value
if not isinstance(event, QueueNodeExceptionEvent)
else WorkflowNodeExecutionStatus.EXCEPTION.value
),
WorkflowNodeExecution.error: event.error,
WorkflowNodeExecution.inputs: json.dumps(inputs) if inputs else None,
WorkflowNodeExecution.process_data: json.dumps(process_data) if process_data else None,
WorkflowNodeExecution.outputs: json.dumps(outputs) if outputs else None,
WorkflowNodeExecution.finished_at: finished_at,
WorkflowNodeExecution.elapsed_time: elapsed_time,
WorkflowNodeExecution.execution_metadata: execution_metadata,
}
execution_metadata = (
json.dumps(jsonable_encoder(event.execution_metadata)) if event.execution_metadata else None
)
db.session.commit()
db.session.close()
process_data = WorkflowEntry.handle_special_values(event.process_data)
workflow_node_execution.status = (
WorkflowNodeExecutionStatus.FAILED.value
@ -889,41 +839,10 @@ class WorkflowCycleManage:
:param event: agent log event
:return:
"""
node_execution = self._wip_workflow_node_executions.get(event.node_execution_id)
if not node_execution:
raise Exception(f"Workflow node execution not found: {event.node_execution_id}")
node_execution_id = node_execution.id
original_agent_logs = self._wip_workflow_agent_logs.get(node_execution_id, [])
# try to find the log with the same id
for log in original_agent_logs:
if log.id == event.id:
# update the log
log.status = event.status
log.error = event.error
log.data = event.data
break
else:
# append the log
original_agent_logs.append(
AgentLogStreamResponse.Data(
id=event.id,
parent_id=event.parent_id,
node_execution_id=node_execution_id,
error=event.error,
status=event.status,
data=event.data,
label=event.label,
)
)
self._wip_workflow_agent_logs[node_execution_id] = original_agent_logs
return AgentLogStreamResponse(
task_id=task_id,
data=AgentLogStreamResponse.Data(
node_execution_id=node_execution_id,
node_execution_id=event.node_execution_id,
id=event.id,
parent_id=event.parent_id,
label=event.label,

View File

@ -31,7 +31,6 @@ from core.rag.splitter.fixed_text_splitter import (
)
from core.rag.splitter.text_splitter import TextSplitter
from core.tools.utils.rag_web_reader import get_image_upload_file_ids
from core.tools.utils.text_processing_utils import remove_leading_symbols
from extensions.ext_database import db
from extensions.ext_redis import redis_client
from extensions.ext_storage import storage

View File

@ -1,770 +0,0 @@
import copy
import json
import logging
from collections.abc import Generator, Sequence
from typing import Optional, Union, cast
import tiktoken
from openai import AzureOpenAI, Stream
from openai.types import Completion
from openai.types.chat import ChatCompletion, ChatCompletionChunk, ChatCompletionMessageToolCall
from openai.types.chat.chat_completion_chunk import ChoiceDeltaToolCall
from core.model_runtime.entities.llm_entities import LLMMode, LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
ImagePromptMessageContent,
PromptMessage,
PromptMessageContentType,
PromptMessageFunction,
PromptMessageTool,
SystemPromptMessage,
TextPromptMessageContent,
ToolPromptMessage,
UserPromptMessage,
)
from core.model_runtime.entities.model_entities import AIModelEntity, ModelPropertyKey
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
from core.model_runtime.model_providers.azure_openai._common import _CommonAzureOpenAI
from core.model_runtime.model_providers.azure_openai._constant import LLM_BASE_MODELS
from core.model_runtime.utils import helper
logger = logging.getLogger(__name__)
class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel):
def _invoke(
self,
model: str,
credentials: dict,
prompt_messages: list[PromptMessage],
model_parameters: dict,
tools: Optional[list[PromptMessageTool]] = None,
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
) -> Union[LLMResult, Generator]:
base_model_name = self._get_base_model_name(credentials)
ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model)
if ai_model_entity and ai_model_entity.entity.model_properties.get(ModelPropertyKey.MODE) == LLMMode.CHAT.value:
# chat model
return self._chat_generate(
model=model,
credentials=credentials,
prompt_messages=prompt_messages,
model_parameters=model_parameters,
tools=tools,
stop=stop,
stream=stream,
user=user,
)
else:
# text completion model
return self._generate(
model=model,
credentials=credentials,
prompt_messages=prompt_messages,
model_parameters=model_parameters,
stop=stop,
stream=stream,
user=user,
)
def get_num_tokens(
self,
model: str,
credentials: dict,
prompt_messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None,
) -> int:
base_model_name = self._get_base_model_name(credentials)
model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model)
if not model_entity:
raise ValueError(f"Base Model Name {base_model_name} is invalid")
model_mode = model_entity.entity.model_properties.get(ModelPropertyKey.MODE)
if model_mode == LLMMode.CHAT.value:
# chat model
return self._num_tokens_from_messages(credentials, prompt_messages, tools)
else:
# text completion model, do not support tool calling
content = prompt_messages[0].content
assert isinstance(content, str)
return self._num_tokens_from_string(credentials, content)
def validate_credentials(self, model: str, credentials: dict) -> None:
if "openai_api_base" not in credentials:
raise CredentialsValidateFailedError("Azure OpenAI API Base Endpoint is required")
if "openai_api_key" not in credentials:
raise CredentialsValidateFailedError("Azure OpenAI API key is required")
if "base_model_name" not in credentials:
raise CredentialsValidateFailedError("Base Model Name is required")
base_model_name = self._get_base_model_name(credentials)
ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model)
if not ai_model_entity:
raise CredentialsValidateFailedError(f'Base Model Name {credentials["base_model_name"]} is invalid')
try:
client = AzureOpenAI(**self._to_credential_kwargs(credentials))
if model.startswith("o1"):
client.chat.completions.create(
messages=[{"role": "user", "content": "ping"}],
model=model,
temperature=1,
max_completion_tokens=20,
stream=False,
)
elif ai_model_entity.entity.model_properties.get(ModelPropertyKey.MODE) == LLMMode.CHAT.value:
# chat model
client.chat.completions.create(
messages=[{"role": "user", "content": "ping"}],
model=model,
temperature=0,
max_tokens=20,
stream=False,
)
else:
# text completion model
client.completions.create(
prompt="ping",
model=model,
temperature=0,
max_tokens=20,
stream=False,
)
except Exception as ex:
raise CredentialsValidateFailedError(str(ex))
def get_customizable_model_schema(self, model: str, credentials: dict) -> Optional[AIModelEntity]:
base_model_name = self._get_base_model_name(credentials)
ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model)
return ai_model_entity.entity if ai_model_entity else None
def _generate(
self,
model: str,
credentials: dict,
prompt_messages: list[PromptMessage],
model_parameters: dict,
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
) -> Union[LLMResult, Generator]:
client = AzureOpenAI(**self._to_credential_kwargs(credentials))
extra_model_kwargs = {}
if stop:
extra_model_kwargs["stop"] = stop
if user:
extra_model_kwargs["user"] = user
# text completion model
response = client.completions.create(
prompt=prompt_messages[0].content, model=model, stream=stream, **model_parameters, **extra_model_kwargs
)
if stream:
return self._handle_generate_stream_response(model, credentials, response, prompt_messages)
return self._handle_generate_response(model, credentials, response, prompt_messages)
def _handle_generate_response(
self, model: str, credentials: dict, response: Completion, prompt_messages: list[PromptMessage]
):
assistant_text = response.choices[0].text
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(content=assistant_text)
# calculate num tokens
if response.usage:
# transform usage
prompt_tokens = response.usage.prompt_tokens
completion_tokens = response.usage.completion_tokens
else:
# calculate num tokens
content = prompt_messages[0].content
assert isinstance(content, str)
prompt_tokens = self._num_tokens_from_string(credentials, content)
completion_tokens = self._num_tokens_from_string(credentials, assistant_text)
# transform usage
usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens)
# transform response
result = LLMResult(
model=response.model,
prompt_messages=prompt_messages,
message=assistant_prompt_message,
usage=usage,
system_fingerprint=response.system_fingerprint,
)
return result
def _handle_generate_stream_response(
self, model: str, credentials: dict, response: Stream[Completion], prompt_messages: list[PromptMessage]
) -> Generator:
full_text = ""
for chunk in response:
if len(chunk.choices) == 0:
continue
delta = chunk.choices[0]
if delta.finish_reason is None and (delta.text is None or delta.text == ""):
continue
# transform assistant message to prompt message
text = delta.text or ""
assistant_prompt_message = AssistantPromptMessage(content=text)
full_text += text
if delta.finish_reason is not None:
# calculate num tokens
if chunk.usage:
# transform usage
prompt_tokens = chunk.usage.prompt_tokens
completion_tokens = chunk.usage.completion_tokens
else:
# calculate num tokens
content = prompt_messages[0].content
assert isinstance(content, str)
prompt_tokens = self._num_tokens_from_string(credentials, content)
completion_tokens = self._num_tokens_from_string(credentials, full_text)
# transform usage
usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens)
yield LLMResultChunk(
model=chunk.model,
prompt_messages=prompt_messages,
system_fingerprint=chunk.system_fingerprint,
delta=LLMResultChunkDelta(
index=delta.index,
message=assistant_prompt_message,
finish_reason=delta.finish_reason,
usage=usage,
),
)
else:
yield LLMResultChunk(
model=chunk.model,
prompt_messages=prompt_messages,
system_fingerprint=chunk.system_fingerprint,
delta=LLMResultChunkDelta(
index=delta.index,
message=assistant_prompt_message,
),
)
def _chat_generate(
self,
model: str,
credentials: dict,
prompt_messages: list[PromptMessage],
model_parameters: dict,
tools: Optional[list[PromptMessageTool]] = None,
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
) -> Union[LLMResult, Generator]:
client = AzureOpenAI(**self._to_credential_kwargs(credentials))
response_format = model_parameters.get("response_format")
if response_format:
if response_format == "json_schema":
json_schema = model_parameters.get("json_schema")
if not json_schema:
raise ValueError("Must define JSON Schema when the response format is json_schema")
try:
schema = json.loads(json_schema)
except:
raise ValueError(f"not correct json_schema format: {json_schema}")
model_parameters.pop("json_schema")
model_parameters["response_format"] = {"type": "json_schema", "json_schema": schema}
else:
model_parameters["response_format"] = {"type": response_format}
extra_model_kwargs = {}
if tools:
extra_model_kwargs["tools"] = [helper.dump_model(PromptMessageFunction(function=tool)) for tool in tools]
if stop:
extra_model_kwargs["stop"] = stop
if user:
extra_model_kwargs["user"] = user
# clear illegal prompt messages
prompt_messages = self._clear_illegal_prompt_messages(model, prompt_messages)
block_as_stream = False
if model.startswith("o1"):
if "max_tokens" in model_parameters:
model_parameters["max_completion_tokens"] = model_parameters["max_tokens"]
del model_parameters["max_tokens"]
if stream:
block_as_stream = True
stream = False
if "stream_options" in extra_model_kwargs:
del extra_model_kwargs["stream_options"]
if "stop" in extra_model_kwargs:
del extra_model_kwargs["stop"]
# chat model
response = client.chat.completions.create(
messages=[self._convert_prompt_message_to_dict(m) for m in prompt_messages],
model=model,
stream=stream,
**model_parameters,
**extra_model_kwargs,
)
if stream:
return self._handle_chat_generate_stream_response(model, credentials, response, prompt_messages, tools)
block_result = self._handle_chat_generate_response(model, credentials, response, prompt_messages, tools)
if block_as_stream:
return self._handle_chat_block_as_stream_response(block_result, prompt_messages, stop)
return block_result
def _handle_chat_block_as_stream_response(
self,
block_result: LLMResult,
prompt_messages: list[PromptMessage],
stop: Optional[list[str]] = None,
) -> Generator[LLMResultChunk, None, None]:
"""
Handle llm chat response
:param model: model name
:param credentials: credentials
:param response: response
:param prompt_messages: prompt messages
:param tools: tools for tool calling
:param stop: stop words
:return: llm response chunk generator
"""
text = block_result.message.content
text = cast(str, text)
if stop:
text = self.enforce_stop_tokens(text, stop)
yield LLMResultChunk(
model=block_result.model,
prompt_messages=prompt_messages,
system_fingerprint=block_result.system_fingerprint,
delta=LLMResultChunkDelta(
index=0,
message=AssistantPromptMessage(content=text),
finish_reason="stop",
usage=block_result.usage,
),
)
def _clear_illegal_prompt_messages(self, model: str, prompt_messages: list[PromptMessage]) -> list[PromptMessage]:
"""
Clear illegal prompt messages for OpenAI API
:param model: model name
:param prompt_messages: prompt messages
:return: cleaned prompt messages
"""
checklist = ["gpt-4-turbo", "gpt-4-turbo-2024-04-09"]
if model in checklist:
# count how many user messages are there
user_message_count = len([m for m in prompt_messages if isinstance(m, UserPromptMessage)])
if user_message_count > 1:
for prompt_message in prompt_messages:
if isinstance(prompt_message, UserPromptMessage):
if isinstance(prompt_message.content, list):
prompt_message.content = "\n".join(
[
item.data
if item.type == PromptMessageContentType.TEXT
else "[IMAGE]"
if item.type == PromptMessageContentType.IMAGE
else ""
for item in prompt_message.content
]
)
if model.startswith("o1"):
system_message_count = len([m for m in prompt_messages if isinstance(m, SystemPromptMessage)])
if system_message_count > 0:
new_prompt_messages = []
for prompt_message in prompt_messages:
if isinstance(prompt_message, SystemPromptMessage):
prompt_message = UserPromptMessage(
content=prompt_message.content,
name=prompt_message.name,
)
new_prompt_messages.append(prompt_message)
prompt_messages = new_prompt_messages
return prompt_messages
def _handle_chat_generate_response(
self,
model: str,
credentials: dict,
response: ChatCompletion,
prompt_messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None,
):
assistant_message = response.choices[0].message
assistant_message_tool_calls = assistant_message.tool_calls
# extract tool calls from response
tool_calls = []
self._update_tool_calls(tool_calls=tool_calls, tool_calls_response=assistant_message_tool_calls)
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(content=assistant_message.content, tool_calls=tool_calls)
# calculate num tokens
if response.usage:
# transform usage
prompt_tokens = response.usage.prompt_tokens
completion_tokens = response.usage.completion_tokens
else:
# calculate num tokens
prompt_tokens = self._num_tokens_from_messages(credentials, prompt_messages, tools)
completion_tokens = self._num_tokens_from_messages(credentials, [assistant_prompt_message])
# transform usage
usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens)
# transform response
result = LLMResult(
model=response.model or model,
prompt_messages=prompt_messages,
message=assistant_prompt_message,
usage=usage,
system_fingerprint=response.system_fingerprint,
)
return result
def _handle_chat_generate_stream_response(
self,
model: str,
credentials: dict,
response: Stream[ChatCompletionChunk],
prompt_messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None,
):
index = 0
full_assistant_content = ""
real_model = model
system_fingerprint = None
completion = ""
tool_calls = []
for chunk in response:
if len(chunk.choices) == 0:
continue
delta = chunk.choices[0]
# NOTE: For fix https://github.com/langgenius/dify/issues/5790
if delta.delta is None:
continue
# extract tool calls from response
self._update_tool_calls(tool_calls=tool_calls, tool_calls_response=delta.delta.tool_calls)
# Handling exceptions when content filters' streaming mode is set to asynchronous modified filter
if delta.finish_reason is None and not delta.delta.content:
continue
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(content=delta.delta.content or "", tool_calls=tool_calls)
full_assistant_content += delta.delta.content or ""
real_model = chunk.model
system_fingerprint = chunk.system_fingerprint
completion += delta.delta.content or ""
yield LLMResultChunk(
model=real_model,
prompt_messages=prompt_messages,
system_fingerprint=system_fingerprint,
delta=LLMResultChunkDelta(
index=index,
message=assistant_prompt_message,
),
)
index += 1
# calculate num tokens
prompt_tokens = self._num_tokens_from_messages(credentials, prompt_messages, tools)
full_assistant_prompt_message = AssistantPromptMessage(content=completion)
completion_tokens = self._num_tokens_from_messages(credentials, [full_assistant_prompt_message])
# transform usage
usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens)
yield LLMResultChunk(
model=real_model,
prompt_messages=prompt_messages,
system_fingerprint=system_fingerprint,
delta=LLMResultChunkDelta(
index=index, message=AssistantPromptMessage(content=""), finish_reason="stop", usage=usage
),
)
@staticmethod
def _update_tool_calls(
tool_calls: list[AssistantPromptMessage.ToolCall],
tool_calls_response: Optional[Sequence[ChatCompletionMessageToolCall | ChoiceDeltaToolCall]],
) -> None:
if tool_calls_response:
for response_tool_call in tool_calls_response:
if isinstance(response_tool_call, ChatCompletionMessageToolCall):
function = AssistantPromptMessage.ToolCall.ToolCallFunction(
name=response_tool_call.function.name, arguments=response_tool_call.function.arguments
)
tool_call = AssistantPromptMessage.ToolCall(
id=response_tool_call.id, type=response_tool_call.type, function=function
)
tool_calls.append(tool_call)
elif isinstance(response_tool_call, ChoiceDeltaToolCall):
index = response_tool_call.index
if index < len(tool_calls):
tool_calls[index].id = response_tool_call.id or tool_calls[index].id
tool_calls[index].type = response_tool_call.type or tool_calls[index].type
if response_tool_call.function:
tool_calls[index].function.name = (
response_tool_call.function.name or tool_calls[index].function.name
)
tool_calls[index].function.arguments += response_tool_call.function.arguments or ""
else:
assert response_tool_call.id is not None
assert response_tool_call.type is not None
assert response_tool_call.function is not None
assert response_tool_call.function.name is not None
assert response_tool_call.function.arguments is not None
function = AssistantPromptMessage.ToolCall.ToolCallFunction(
name=response_tool_call.function.name, arguments=response_tool_call.function.arguments
)
tool_call = AssistantPromptMessage.ToolCall(
id=response_tool_call.id, type=response_tool_call.type, function=function
)
tool_calls.append(tool_call)
@staticmethod
def _convert_prompt_message_to_dict(message: PromptMessage):
if isinstance(message, UserPromptMessage):
message = cast(UserPromptMessage, message)
if isinstance(message.content, str):
message_dict = {"role": "user", "content": message.content}
else:
sub_messages = []
assert message.content is not None
for message_content in message.content:
if message_content.type == PromptMessageContentType.TEXT:
message_content = cast(TextPromptMessageContent, message_content)
sub_message_dict = {"type": "text", "text": message_content.data}
sub_messages.append(sub_message_dict)
elif message_content.type == PromptMessageContentType.IMAGE:
message_content = cast(ImagePromptMessageContent, message_content)
sub_message_dict = {
"type": "image_url",
"image_url": {"url": message_content.data, "detail": message_content.detail.value},
}
sub_messages.append(sub_message_dict)
message_dict = {"role": "user", "content": sub_messages}
elif isinstance(message, AssistantPromptMessage):
# message = cast(AssistantPromptMessage, message)
message_dict = {"role": "assistant", "content": message.content}
if message.tool_calls:
# fix azure when enable json schema cant process content = "" in assistant fix with None
if not message.content:
message_dict["content"] = None
message_dict["tool_calls"] = [helper.dump_model(tool_call) for tool_call in message.tool_calls]
elif isinstance(message, SystemPromptMessage):
message = cast(SystemPromptMessage, message)
message_dict = {"role": "system", "content": message.content}
elif isinstance(message, ToolPromptMessage):
message = cast(ToolPromptMessage, message)
message_dict = {
"role": "tool",
"name": message.name,
"content": message.content,
"tool_call_id": message.tool_call_id,
}
else:
raise ValueError(f"Got unknown type {message}")
if message.name:
message_dict["name"] = message.name
return message_dict
def _num_tokens_from_string(
self, credentials: dict, text: str, tools: Optional[list[PromptMessageTool]] = None
) -> int:
try:
encoding = tiktoken.encoding_for_model(credentials["base_model_name"])
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
num_tokens = len(encoding.encode(text))
if tools:
num_tokens += self._num_tokens_for_tools(encoding, tools)
return num_tokens
def _num_tokens_from_messages(
self, credentials: dict, messages: list[PromptMessage], tools: Optional[list[PromptMessageTool]] = None
) -> int:
"""Calculate num tokens for gpt-3.5-turbo and gpt-4 with tiktoken package.
Official documentation: https://github.com/openai/openai-cookbook/blob/
main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb"""
model = credentials["base_model_name"]
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
logger.warning("Warning: model not found. Using cl100k_base encoding.")
model = "cl100k_base"
encoding = tiktoken.get_encoding(model)
if model.startswith("gpt-35-turbo-0301"):
# every message follows <im_start>{role/name}\n{content}<im_end>\n
tokens_per_message = 4
# if there's a name, the role is omitted
tokens_per_name = -1
elif model.startswith("gpt-35-turbo") or model.startswith("gpt-4") or "o1" in model:
tokens_per_message = 3
tokens_per_name = 1
else:
raise NotImplementedError(
f"get_num_tokens_from_messages() is not presently implemented "
f"for model {model}."
"See https://github.com/openai/openai-python/blob/main/chatml.md for "
"information on how messages are converted to tokens."
)
num_tokens = 0
messages_dict = [self._convert_prompt_message_to_dict(m) for m in messages]
for message in messages_dict:
num_tokens += tokens_per_message
for key, value in message.items():
# Cast str(value) in case the message value is not a string
# This occurs with function messages
# TODO: The current token calculation method for the image type is not implemented,
# which need to download the image and then get the resolution for calculation,
# and will increase the request delay
if isinstance(value, list):
text = ""
for item in value:
if isinstance(item, dict) and item["type"] == "text":
text += item["text"]
value = text
if key == "tool_calls":
for tool_call in value:
assert isinstance(tool_call, dict)
for t_key, t_value in tool_call.items():
num_tokens += len(encoding.encode(t_key))
if t_key == "function":
for f_key, f_value in t_value.items():
num_tokens += len(encoding.encode(f_key))
num_tokens += len(encoding.encode(f_value))
else:
num_tokens += len(encoding.encode(t_key))
num_tokens += len(encoding.encode(t_value))
else:
num_tokens += len(encoding.encode(str(value)))
if key == "name":
num_tokens += tokens_per_name
# every reply is primed with <im_start>assistant
num_tokens += 3
if tools:
num_tokens += self._num_tokens_for_tools(encoding, tools)
return num_tokens
@staticmethod
def _num_tokens_for_tools(encoding: tiktoken.Encoding, tools: list[PromptMessageTool]) -> int:
num_tokens = 0
for tool in tools:
num_tokens += len(encoding.encode("type"))
num_tokens += len(encoding.encode("function"))
# calculate num tokens for function object
num_tokens += len(encoding.encode("name"))
num_tokens += len(encoding.encode(tool.name))
num_tokens += len(encoding.encode("description"))
num_tokens += len(encoding.encode(tool.description))
parameters = tool.parameters
num_tokens += len(encoding.encode("parameters"))
if "title" in parameters:
num_tokens += len(encoding.encode("title"))
num_tokens += len(encoding.encode(parameters["title"]))
num_tokens += len(encoding.encode("type"))
num_tokens += len(encoding.encode(parameters["type"]))
if "properties" in parameters:
num_tokens += len(encoding.encode("properties"))
for key, value in parameters["properties"].items():
num_tokens += len(encoding.encode(key))
for field_key, field_value in value.items():
num_tokens += len(encoding.encode(field_key))
if field_key == "enum":
for enum_field in field_value:
num_tokens += 3
num_tokens += len(encoding.encode(enum_field))
else:
num_tokens += len(encoding.encode(field_key))
num_tokens += len(encoding.encode(str(field_value)))
if "required" in parameters:
num_tokens += len(encoding.encode("required"))
for required_field in parameters["required"]:
num_tokens += 3
num_tokens += len(encoding.encode(required_field))
return num_tokens
@staticmethod
def _get_ai_model_entity(base_model_name: str, model: str):
for ai_model_entity in LLM_BASE_MODELS:
if ai_model_entity.base_model_name == base_model_name:
ai_model_entity_copy = copy.deepcopy(ai_model_entity)
ai_model_entity_copy.entity.model = model
ai_model_entity_copy.entity.label.en_US = model
ai_model_entity_copy.entity.label.zh_Hans = model
return ai_model_entity_copy
def _get_base_model_name(self, credentials: dict) -> str:
base_model_name = credentials.get("base_model_name")
if not base_model_name:
raise ValueError("Base Model Name is required")
return base_model_name

View File

@ -1,5 +1,5 @@
import re
from typing import Optional
from typing import Optional, cast
class JiebaKeywordTableHandler:
@ -8,18 +8,20 @@ class JiebaKeywordTableHandler:
from core.rag.datasource.keyword.jieba.stopwords import STOPWORDS
jieba.analyse.default_tfidf.stop_words = STOPWORDS
jieba.analyse.default_tfidf.stop_words = STOPWORDS # type: ignore
def extract_keywords(self, text: str, max_keywords_per_chunk: Optional[int] = 10) -> set[str]:
"""Extract keywords with JIEBA tfidf."""
import jieba # type: ignore
import jieba.analyse # type: ignore
keywords = jieba.analyse.extract_tags(
sentence=text,
topK=max_keywords_per_chunk,
)
# jieba.analyse.extract_tags returns list[Any] when withFlag is False by default.
keywords = cast(list[str], keywords)
return set(self._expand_tokens_with_subtokens(keywords))
return set(self._expand_tokens_with_subtokens(set(keywords)))
def _expand_tokens_with_subtokens(self, tokens: set[str]) -> set[str]:
"""Get subtokens from a list of tokens., filtering for stopwords."""

View File

@ -1,355 +0,0 @@
from abc import ABC, abstractmethod
from collections.abc import Mapping
from copy import deepcopy
from enum import Enum, StrEnum
from typing import TYPE_CHECKING, Any, Optional, Union
from pydantic import BaseModel, ConfigDict, field_validator
from pydantic_core.core_schema import ValidationInfo
from core.app.entities.app_invoke_entities import InvokeFrom
from core.tools.entities.tool_entities import (
ToolDescription,
ToolIdentity,
ToolInvokeFrom,
ToolInvokeMessage,
ToolParameter,
ToolProviderType,
ToolRuntimeImageVariable,
ToolRuntimeVariable,
ToolRuntimeVariablePool,
)
from core.tools.tool_file_manager import ToolFileManager
if TYPE_CHECKING:
from core.file.models import File
class Tool(BaseModel, ABC):
identity: Optional[ToolIdentity] = None
parameters: Optional[list[ToolParameter]] = None
description: Optional[ToolDescription] = None
is_team_authorization: bool = False
# pydantic configs
model_config = ConfigDict(protected_namespaces=())
@field_validator("parameters", mode="before")
@classmethod
def set_parameters(cls, v, validation_info: ValidationInfo) -> list[ToolParameter]:
return v or []
class Runtime(BaseModel):
"""
Meta data of a tool call processing
"""
def __init__(self, **data: Any):
super().__init__(**data)
if not self.runtime_parameters:
self.runtime_parameters = {}
tenant_id: Optional[str] = None
tool_id: Optional[str] = None
invoke_from: Optional[InvokeFrom] = None
tool_invoke_from: Optional[ToolInvokeFrom] = None
credentials: Optional[dict[str, Any]] = None
runtime_parameters: Optional[dict[str, Any]] = None
runtime: Optional[Runtime] = None
variables: Optional[ToolRuntimeVariablePool] = None
def __init__(self, **data: Any):
super().__init__(**data)
class VariableKey(StrEnum):
IMAGE = "image"
DOCUMENT = "document"
VIDEO = "video"
AUDIO = "audio"
CUSTOM = "custom"
def fork_tool_runtime(self, runtime: dict[str, Any]) -> "Tool":
"""
fork a new tool with meta data
:param meta: the meta data of a tool call processing, tenant_id is required
:return: the new tool
"""
return self.__class__(
identity=self.identity.model_copy() if self.identity else None,
parameters=self.parameters.copy() if self.parameters else None,
description=self.description.model_copy() if self.description else None,
runtime=Tool.Runtime(**runtime),
)
@abstractmethod
def tool_provider_type(self) -> ToolProviderType:
"""
get the tool provider type
:return: the tool provider type
"""
def load_variables(self, variables: ToolRuntimeVariablePool | None) -> None:
"""
load variables from database
:param conversation_id: the conversation id
"""
self.variables = variables
def set_image_variable(self, variable_name: str, image_key: str) -> None:
"""
set an image variable
"""
if not self.variables:
return
if self.identity is None:
return
self.variables.set_file(self.identity.name, variable_name, image_key)
def set_text_variable(self, variable_name: str, text: str) -> None:
"""
set a text variable
"""
if not self.variables:
return
if self.identity is None:
return
self.variables.set_text(self.identity.name, variable_name, text)
def get_variable(self, name: Union[str, Enum]) -> Optional[ToolRuntimeVariable]:
"""
get a variable
:param name: the name of the variable
:return: the variable
"""
if not self.variables:
return None
if isinstance(name, Enum):
name = name.value
for variable in self.variables.pool:
if variable.name == name:
return variable
return None
def get_default_image_variable(self) -> Optional[ToolRuntimeVariable]:
"""
get the default image variable
:return: the image variable
"""
if not self.variables:
return None
return self.get_variable(self.VariableKey.IMAGE)
def get_variable_file(self, name: Union[str, Enum]) -> Optional[bytes]:
"""
get a variable file
:param name: the name of the variable
:return: the variable file
"""
variable = self.get_variable(name)
if not variable:
return None
if not isinstance(variable, ToolRuntimeImageVariable):
return None
message_file_id = variable.value
# get file binary
file_binary = ToolFileManager.get_file_binary_by_message_file_id(message_file_id)
if not file_binary:
return None
return file_binary[0]
def list_variables(self) -> list[ToolRuntimeVariable]:
"""
list all variables
:return: the variables
"""
if not self.variables:
return []
return self.variables.pool
def list_default_image_variables(self) -> list[ToolRuntimeVariable]:
"""
list all image variables
:return: the image variables
"""
if not self.variables:
return []
result = []
for variable in self.variables.pool:
if variable.name.startswith(self.VariableKey.IMAGE.value):
result.append(variable)
return result
def invoke(self, user_id: str, tool_parameters: Mapping[str, Any]) -> list[ToolInvokeMessage]:
# update tool_parameters
# TODO: Fix type error.
if self.runtime is None:
return []
if self.runtime.runtime_parameters:
# Convert Mapping to dict before updating
tool_parameters = dict(tool_parameters)
tool_parameters.update(self.runtime.runtime_parameters)
# try parse tool parameters into the correct type
tool_parameters = self._transform_tool_parameters_type(tool_parameters)
result = self._invoke(
user_id=user_id,
tool_parameters=tool_parameters,
)
if not isinstance(result, list):
result = [result]
if not all(isinstance(message, ToolInvokeMessage) for message in result):
raise ValueError(
f"Invalid return type from {self.__class__.__name__}._invoke method. "
"Expected ToolInvokeMessage or list of ToolInvokeMessage."
)
return result
def _transform_tool_parameters_type(self, tool_parameters: Mapping[str, Any]) -> dict[str, Any]:
"""
Transform tool parameters type
"""
# Temp fix for the issue that the tool parameters will be converted to empty while validating the credentials
result: dict[str, Any] = deepcopy(dict(tool_parameters))
for parameter in self.parameters or []:
if parameter.name in tool_parameters:
result[parameter.name] = parameter.type.cast_value(tool_parameters[parameter.name])
return result
@abstractmethod
def _invoke(
self, user_id: str, tool_parameters: dict[str, Any]
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
pass
def validate_credentials(
self, credentials: dict[str, Any], parameters: dict[str, Any], format_only: bool = False
) -> str | None:
"""
validate the credentials
:param credentials: the credentials
:param parameters: the parameters
:param format_only: only return the formatted
"""
pass
def get_runtime_parameters(self) -> list[ToolParameter]:
"""
get the runtime parameters
interface for developer to dynamic change the parameters of a tool depends on the variables pool
:return: the runtime parameters
"""
return self.parameters or []
def get_all_runtime_parameters(self) -> list[ToolParameter]:
"""
get all runtime parameters
:return: all runtime parameters
"""
parameters = self.parameters or []
parameters = parameters.copy()
user_parameters = self.get_runtime_parameters()
user_parameters = user_parameters.copy()
# override parameters
for parameter in user_parameters:
# check if parameter in tool parameters
found = False
for tool_parameter in parameters:
if tool_parameter.name == parameter.name:
found = True
break
if found:
# override parameter
tool_parameter.type = parameter.type
tool_parameter.form = parameter.form
tool_parameter.required = parameter.required
tool_parameter.default = parameter.default
tool_parameter.options = parameter.options
tool_parameter.llm_description = parameter.llm_description
else:
# add new parameter
parameters.append(parameter)
return parameters
def create_image_message(self, image: str, save_as: str = "") -> ToolInvokeMessage:
"""
create an image message
:param image: the url of the image
:return: the image message
"""
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.IMAGE, message=image, save_as=save_as)
def create_file_message(self, file: "File") -> ToolInvokeMessage:
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.FILE, message="", meta={"file": file}, save_as="")
def create_link_message(self, link: str, save_as: str = "") -> ToolInvokeMessage:
"""
create a link message
:param link: the url of the link
:return: the link message
"""
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.LINK, message=link, save_as=save_as)
def create_text_message(self, text: str, save_as: str = "") -> ToolInvokeMessage:
"""
create a text message
:param text: the text
:return: the text message
"""
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.TEXT, message=text, save_as=save_as)
def create_blob_message(self, blob: bytes, meta: Optional[dict] = None, save_as: str = "") -> ToolInvokeMessage:
"""
create a blob message
:param blob: the blob
:return: the blob message
"""
return ToolInvokeMessage(
type=ToolInvokeMessage.MessageType.BLOB,
message=blob,
meta=meta or {},
save_as=save_as,
)
def create_json_message(self, object: dict) -> ToolInvokeMessage:
"""
create a json message
"""
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.JSON, message=object)

View File

@ -613,10 +613,10 @@ class Graph(BaseModel):
for (node_id, node_id2), branch_node_ids in duplicate_end_node_ids.items():
# check which node is after
if cls._is_node2_after_node1(node1_id=node_id, node2_id=node_id2, edge_mapping=edge_mapping):
if node_id in merge_branch_node_ids:
if node_id in merge_branch_node_ids and node_id2 in merge_branch_node_ids:
del merge_branch_node_ids[node_id2]
elif cls._is_node2_after_node1(node1_id=node_id2, node2_id=node_id, edge_mapping=edge_mapping):
if node_id2 in merge_branch_node_ids:
if node_id in merge_branch_node_ids and node_id2 in merge_branch_node_ids:
del merge_branch_node_ids[node_id]
branches_merge_node_ids: dict[str, str] = {}

View File

@ -5,7 +5,7 @@ from sqlalchemy import select
from sqlalchemy.orm import Session
from core.callback_handler.workflow_tool_callback_handler import DifyWorkflowCallbackHandler
from core.file import File, FileTransferMethod, FileType
from core.file import File, FileTransferMethod
from core.plugin.manager.exc import PluginDaemonClientSideError
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
from core.tools.tool_engine import ToolEngine
@ -189,10 +189,12 @@ class ToolNode(BaseNode[ToolNodeData]):
conversation_id=None,
)
files: list[File] = []
text = ""
files: list[File] = []
json: list[dict] = []
agent_logs: list[AgentLog] = []
variables: dict[str, Any] = {}
for message in message_stream:
@ -239,14 +241,16 @@ class ToolNode(BaseNode[ToolNodeData]):
tool_file = session.scalar(stmt)
if tool_file is None:
raise ToolFileError(f"tool file {tool_file_id} not exists")
mapping = {
"tool_file_id": tool_file_id,
"transfer_method": FileTransferMethod.TOOL_FILE,
}
files.append(
File(
file_factory.build_from_mapping(
mapping=mapping,
tenant_id=self.tenant_id,
type=FileType.IMAGE,
transfer_method=FileTransferMethod.TOOL_FILE,
related_id=tool_file_id,
extension=None,
mime_type=message.meta.get("mime_type", "application/octet-stream"),
)
)
elif message.type == ToolInvokeMessage.MessageType.TEXT:

View File

@ -69,6 +69,7 @@ def init_app(app: DifyApp) -> Celery:
"schedule.create_tidb_serverless_task",
"schedule.update_tidb_serverless_status_task",
"schedule.clean_messages",
"schedule.mail_clean_document_notify_task",
]
day = dify_config.CELERY_BEAT_SCHEDULER_TIME
beat_schedule = {
@ -92,6 +93,11 @@ def init_app(app: DifyApp) -> Celery:
"task": "schedule.clean_messages.clean_messages",
"schedule": timedelta(days=day),
},
# every Monday
"mail_clean_document_notify_task": {
"task": "schedule.mail_clean_document_notify_task.mail_clean_document_notify_task",
"schedule": crontab(minute="0", hour="10", day_of_week="1"),
},
}
celery_app.conf.update(beat_schedule=beat_schedule, imports=imports)

View File

@ -1,6 +1,6 @@
import json
from datetime import datetime
from typing import Optional
from typing import Optional, Any
import sqlalchemy as sa
from deprecated import deprecated

View File

@ -424,6 +424,18 @@ class WorkflowRun(Base):
finished_at = db.Column(db.DateTime)
exceptions_count = db.Column(db.Integer, server_default=db.text("0"))
@property
def created_by_account(self):
created_by_role = CreatedByRole(self.created_by_role)
return db.session.get(Account, self.created_by) if created_by_role == CreatedByRole.ACCOUNT else None
@property
def created_by_end_user(self):
from models.model import EndUser
created_by_role = CreatedByRole(self.created_by_role)
return db.session.get(EndUser, self.created_by) if created_by_role == CreatedByRole.END_USER else None
@property
def graph_dict(self):
return json.loads(self.graph) if self.graph else {}

View File

@ -28,7 +28,6 @@ def clean_messages():
plan_sandbox_clean_message_day = datetime.datetime.now() - datetime.timedelta(
days=dify_config.PLAN_SANDBOX_CLEAN_MESSAGE_DAY_SETTING
)
page = 1
while True:
try:
# Main query with join and filter
@ -79,4 +78,4 @@ def clean_messages():
db.session.query(Message).filter(Message.id == message.id).delete()
db.session.commit()
end_at = time.perf_counter()
click.echo(click.style("Cleaned unused dataset from db success latency: {}".format(end_at - start_at), fg="green"))
click.echo(click.style("Cleaned messages from db success latency: {}".format(end_at - start_at), fg="green"))

View File

@ -3,14 +3,18 @@ import time
from collections import defaultdict
import click
from celery import shared_task # type: ignore
from flask import render_template # type: ignore
import app
from configs import dify_config
from extensions.ext_database import db
from extensions.ext_mail import mail
from models.account import Account, Tenant, TenantAccountJoin
from models.dataset import Dataset, DatasetAutoDisableLog
from services.feature_service import FeatureService
@shared_task(queue="mail")
@app.celery.task(queue="dataset")
def send_document_clean_notify_task():
"""
Async Send document clean notify mail
@ -29,35 +33,58 @@ def send_document_clean_notify_task():
# group by tenant_id
dataset_auto_disable_logs_map: dict[str, list[DatasetAutoDisableLog]] = defaultdict(list)
for dataset_auto_disable_log in dataset_auto_disable_logs:
if dataset_auto_disable_log.tenant_id not in dataset_auto_disable_logs_map:
dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id] = []
dataset_auto_disable_logs_map[dataset_auto_disable_log.tenant_id].append(dataset_auto_disable_log)
url = f"{dify_config.CONSOLE_WEB_URL}/datasets"
for tenant_id, tenant_dataset_auto_disable_logs in dataset_auto_disable_logs_map.items():
knowledge_details = []
tenant = Tenant.query.filter(Tenant.id == tenant_id).first()
if not tenant:
continue
current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first()
if not current_owner_join:
continue
account = Account.query.filter(Account.id == current_owner_join.account_id).first()
if not account:
continue
features = FeatureService.get_features(tenant_id)
plan = features.billing.subscription.plan
if plan != "sandbox":
knowledge_details = []
# check tenant
tenant = Tenant.query.filter(Tenant.id == tenant_id).first()
if not tenant:
continue
# check current owner
current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first()
if not current_owner_join:
continue
account = Account.query.filter(Account.id == current_owner_join.account_id).first()
if not account:
continue
dataset_auto_dataset_map = {} # type: ignore
dataset_auto_dataset_map = {} # type: ignore
for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
if dataset_auto_disable_log.dataset_id not in dataset_auto_dataset_map:
dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id] = []
dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id].append(
dataset_auto_disable_log.document_id
)
for dataset_id, document_ids in dataset_auto_dataset_map.items():
dataset = Dataset.query.filter(Dataset.id == dataset_id).first()
if dataset:
document_count = len(document_ids)
knowledge_details.append(rf"Knowledge base {dataset.name}: {document_count} documents")
if knowledge_details:
html_content = render_template(
"clean_document_job_mail_template-US.html",
userName=account.email,
knowledge_details=knowledge_details,
url=url,
)
mail.send(
to=account.email, subject="Dify Knowledge base auto disable notification", html=html_content
)
# update notified to True
for dataset_auto_disable_log in tenant_dataset_auto_disable_logs:
dataset_auto_dataset_map[dataset_auto_disable_log.dataset_id].append(
dataset_auto_disable_log.document_id
)
for dataset_id, document_ids in dataset_auto_dataset_map.items():
dataset = Dataset.query.filter(Dataset.id == dataset_id).first()
if dataset:
document_count = len(document_ids)
knowledge_details.append(f"<li>Knowledge base {dataset.name}: {document_count} documents</li>")
dataset_auto_disable_log.notified = True
db.session.commit()
end_at = time.perf_counter()
logging.info(
click.style("Send document clean notify mail succeeded: latency: {}".format(end_at - start_at), fg="green")
)
except Exception:
logging.exception("Send invite member mail to failed")
logging.exception("Send document clean notify mail failed")

View File

@ -196,6 +196,9 @@ class AppDslService:
data["kind"] = "app"
imported_version = data.get("version", "0.1.0")
# check if imported_version is a float-like string
if not isinstance(imported_version, str):
raise ValueError(f"Invalid version type, expected str, got {type(imported_version)}")
status = _check_version_compatibility(imported_version)
# Extract app data

View File

@ -1,6 +1,6 @@
from typing import Optional
class BaseServiceError(Exception):
class BaseServiceError(ValueError):
def __init__(self, description: Optional[str] = None):
self.description = description

View File

@ -152,6 +152,7 @@ class MessageService:
@classmethod
def create_feedback(
cls,
*,
app_model: App,
message_id: str,
user: Optional[Union[Account, EndUser]],

View File

@ -64,7 +64,10 @@ class ToolTransformService:
)
elif isinstance(provider, ToolProviderApiEntity):
if provider.plugin_id:
provider.icon = ToolTransformService.get_plugin_icon_url(tenant_id=tenant_id, filename=provider.icon)
if isinstance(provider.icon, str):
provider.icon = ToolTransformService.get_plugin_icon_url(
tenant_id=tenant_id, filename=provider.icon
)
else:
provider.icon = ToolTransformService.get_tool_provider_icon_url(
provider_type=provider.type.value, provider_name=provider.name, icon=provider.icon

View File

@ -3,6 +3,7 @@ import time
from collections.abc import Callable, Generator, Sequence
from datetime import UTC, datetime
from typing import Any, Optional
from uuid import uuid4
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager
@ -333,6 +334,7 @@ class WorkflowService:
error = e.error
workflow_node_execution = WorkflowNodeExecution()
workflow_node_execution.id = str(uuid4())
workflow_node_execution.tenant_id = tenant_id
workflow_node_execution.triggered_from = WorkflowNodeExecutionTriggeredFrom.SINGLE_STEP.value
workflow_node_execution.index = 1

View File

@ -45,14 +45,14 @@
.content ul li {
margin-bottom: 10px;
}
.cta-button {
.cta-button, .cta-button:hover, .cta-button:active, .cta-button:visited, .cta-button:focus {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: #4e89f9;
color: #ffffff;
color: #ffffff !important;
text-align: center;
text-decoration: none;
text-decoration: none !important;
border-radius: 5px;
width: fit-content;
}
@ -69,7 +69,7 @@
<div class="email-container">
<!-- Header -->
<div class="header">
<img src="https://via.placeholder.com/150x40?text=Dify" alt="Dify Logo">
<img src="https://img.mailinblue.com/6365111/images/content_library/original/64cb67ca60532312c211dc72.png" alt="Dify Logo">
</div>
<!-- Content -->
@ -78,11 +78,13 @@
<p>Dear {{userName}},</p>
<p>
We're sorry for the inconvenience. To ensure optimal performance, documents
that havent been updated or accessed in the past 7 days have been disabled in
that havent been updated or accessed in the past 30 days have been disabled in
your knowledge bases:
</p>
<ul>
{{knowledge_details}}
{% for item in knowledge_details %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<p>You can re-enable them anytime.</p>
<a href={{url}} class="cta-button">Re-enable in Dify</a>

View File

@ -37,7 +37,7 @@ function useAppsQueryState() {
const syncSearchParams = useCallback((params: URLSearchParams) => {
const search = params.toString()
const query = search ? `?${search}` : ''
router.push(`${pathname}${query}`)
router.push(`${pathname}${query}`, { scroll: false })
}, [router, pathname])
// Update the URL search string whenever the query changes.

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: 'Vergrößern',
openInNewTab: 'In neuem Tab öffnen',
copyImage: 'Bild kopieren',
close: 'Schließen',
viewMore: 'MEHR SEHEN',
regenerate: 'Erneuern',
saveAndRegenerate: 'Speichern und Regenerieren von untergeordneten Chunks',
view: 'Ansehen',
},
placeholder: {
input: 'Bitte eingeben',
@ -474,6 +479,7 @@ const translation = {
emptyTip: 'Das Wissen wurde nicht zugeordnet, bitte gehen Sie zur Anwendung oder zum Plug-in, um die Zuordnung abzuschließen.',
viewDoc: 'Dokumentation anzeigen',
relatedApp: 'verbundene Apps',
noRelatedApp: 'Keine verknüpften Apps',
},
voiceInput: {
speaking: 'Sprechen Sie jetzt...',

View File

@ -82,6 +82,7 @@ const translation = {
useSitemapTooltip: 'Folgen Sie der Sitemap, um die Website zu crawlen. Ist dies nicht der Fall, crawlt Jina Reader iterativ basierend auf der Seitenrelevanz, sodass weniger, aber qualitativ hochwertigere Seiten angezeigt werden.',
jinaReaderDoc: 'Erfahre mehr über Jina Reader',
},
cancel: 'Abbrechen',
},
stepTwo: {
segmentation: 'Chunk-Einstellungen',
@ -143,6 +144,28 @@ const translation = {
webpageUnit: 'Seiten',
separatorTip: 'Ein Trennzeichen ist das Zeichen, das zum Trennen von Text verwendet wird. \\n\\n und \\n sind häufig verwendete Trennzeichen zum Trennen von Absätzen und Zeilen. In Kombination mit Kommas (\\n\\n,\\n) werden Absätze nach Zeilen segmentiert, wenn die maximale Blocklänge überschritten wird. Sie können auch spezielle, von Ihnen selbst definierte Trennzeichen verwenden (z. B. ***).',
maxLengthCheck: 'Die maximale Stücklänge sollte weniger als {{limit}} betragen',
switch: 'Schalter',
previewChunk: 'Vorschau Chunk',
highQualityTip: 'Sobald die Einbettung im Modus "Hohe Qualität" abgeschlossen ist, ist es nicht mehr möglich, in den Modus "Wirtschaftlich" zurückzukehren.',
parentChildTip: 'Wenn Sie den Parent-Child-Modus verwenden, wird der Child-Chunk für den Abruf und der Parent-Chunk für den Abruf als Kontext verwendet.',
fullDoc: 'Vollständiges Dokument',
parentChildDelimiterTip: 'Ein Trennzeichen ist das Zeichen, das zum Trennen von Text verwendet wird. \\n\\n wird empfohlen, um das Originaldokument in große übergeordnete Blöcke aufzuteilen. Sie können auch spezielle Trennzeichen verwenden, die Sie selbst definiert haben.',
qaSwitchHighQualityTipContent: 'Derzeit unterstützt nur eine hochwertige Indexmethode das Q&A-Format-Chunking. Möchten Sie in den High-Quality-Modus wechseln?',
childChunkForRetrieval: 'Child-Chunk zum Abrufen',
previewChunkCount: '{{Anzahl}} Geschätzte Chunks',
previewChunkTip: 'Klicken Sie auf die Schaltfläche "Preview Chunk" auf der linken Seite, um die Vorschau zu laden',
qaSwitchHighQualityTipTitle: 'Das Q&A-Format erfordert eine qualitativ hochwertige Indizierungsmethode',
general: 'Allgemein',
generalTip: 'Allgemeiner Text-Chunking-Modus, die abgerufenen und zurückgerufenen Chunks sind gleich.',
notAvailableForQA: 'Nicht verfügbar für Q&A Index',
notAvailableForParentChild: 'Nicht verfügbar für den Parent-Child-Index',
parentChild: 'Eltern-Kind',
parentChunkForContext: 'Parent-chunk für Context',
parentChildChunkDelimiterTip: 'Ein Trennzeichen ist das Zeichen, das zum Trennen von Text verwendet wird. \\n wird empfohlen, um übergeordnete Blöcke in kleine untergeordnete Blöcke aufzuteilen. Sie können auch spezielle Trennzeichen verwenden, die Sie selbst definiert haben.',
useQALanguage: 'Chunk im Q&A-Format in',
paragraph: 'Absatz',
fullDocTip: 'Das gesamte Dokument wird als übergeordneter Block verwendet und direkt abgerufen. Bitte beachten Sie, dass aus Leistungsgründen Texte, die 10000 Token überschreiten, automatisch abgeschnitten werden.',
paragraphTip: 'In diesem Modus wird der Text basierend auf Trennzeichen und der maximalen Blocklänge in Absätze aufgeteilt, wobei der geteilte Text als übergeordneter Block für den Abruf verwendet wird.',
},
stepThree: {
creationTitle: '🎉 Wissen erstellt',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'API-Schlüssel von jina.ai',
getApiKeyLinkText: 'Holen Sie sich Ihren kostenlosen API-Schlüssel bei jina.ai',
},
otherDataSource: {
learnMore: 'Weitere Informationen',
title: 'Verbinden Sie sich mit anderen Datenquellen?',
description: 'Derzeit verfügt die Wissensdatenbank von Dify nur über begrenzte Datenquellen. Das Beitragen einer Datenquelle zur Dify-Wissensdatenbank ist eine fantastische Möglichkeit, die Flexibilität und Leistungsfähigkeit der Plattform für alle Benutzer zu verbessern. Unser Beitragsleitfaden erleichtert Ihnen den Einstieg. Bitte klicken Sie auf den untenstehenden Link, um mehr zu erfahren.',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: 'HOCHLADEZEIT',
status: 'STATUS',
action: 'AKTION',
chunkingMode: 'CHUNKING-MODUS',
},
name: 'Name',
rename: 'Umbenennen',
@ -77,6 +78,7 @@ const translation = {
ok: 'OK',
},
addUrl: 'URL hinzufügen',
learnMore: 'Weitere Informationen',
},
metadata: {
title: 'Metadaten',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Automatisch',
custom: 'Benutzerdefiniert',
previewTip: 'Absatzvorschau ist nach Abschluss der Einbettung verfügbar',
parentMaxTokens: 'Elternteil',
childMaxTokens: 'Kind',
hierarchical: 'Eltern-Kind',
pause: 'Pause',
},
segment: {
paragraphs: 'Absätze',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Neues Textsegment',
newQaSegment: 'Neues Q&A-Segment',
delete: 'Diesen Chunk löschen?',
parentChunks_one: 'ÜBERGEORDNETER CHUNK',
searchResults_other: 'BEFUND',
clearFilter: 'Filter löschen',
chunk: 'Stück',
childChunk: 'Untergeordneter Brocken',
newChildChunk: 'Neuer untergeordneter Block',
chunkDetail: 'Chunk-Detail',
regeneratingMessage: 'Das kann einen Moment dauern, bitte warten...',
searchResults_zero: 'ERGEBNIS',
parentChunks_other: 'ÜBERGEORDNETE BLÖCKE',
editParentChunk: 'Übergeordneter Block bearbeiten',
childChunks_other: 'UNTERGEORDNETE BLÖCKE',
editChunk: 'Chunk bearbeiten',
regenerationSuccessTitle: 'Regeneration abgeschlossen',
parentChunk: 'Übergeordneter Chunk',
childChunkAdded: '1 untergeordneter Block hinzugefügt',
edited: 'BEARBEITETE',
collapseChunks: 'Blöcke reduzieren',
empty: 'Kein Chunk gefunden',
regenerationSuccessMessage: 'Sie können dieses Fenster schließen.',
chunks_other: 'STÜCKE',
regenerationConfirmMessage: 'Beim Regenerieren von untergeordneten Blöcken werden die aktuellen untergeordneten Blöcke überschrieben, einschließlich bearbeiteter und neu hinzugefügter Blöcke. Die Regeneration kann nicht rückgängig gemacht werden.',
childChunks_one: 'UNTERGEORDNETER CHUNK',
characters_other: 'Zeichen',
newChunk: 'Neuer Brocken',
editChildChunk: 'Untergeordneten Block bearbeiten',
chunkAdded: '1 Stück hinzugefügt',
expandChunks: 'Blöcke erweitern',
editedAt: 'Bearbeitet am',
addChunk: 'Block hinzufügen',
addAnother: 'Fügen Sie eine weitere hinzu',
regeneratingTitle: 'Regenerieren von untergeordneten Blöcken',
chunks_one: 'STÜCK',
characters_one: 'Zeichen',
addChildChunk: 'Untergeordneten Block hinzufügen',
regenerationConfirmTitle: 'Möchten Sie untergeordnete Chunks regenerieren?',
searchResults_one: 'ERGEBNIS',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'VEKTORDIAGRAMM ansehen',
viewDetail: 'Im Detail sehen',
settingTitle: 'Einstellung für den Abruf',
records: 'Aufzeichnungen',
open: 'Offen',
hitChunks: 'Klicken Sie auf {{num}} untergeordnete Chunks',
keyword: 'Schlüsselwörter',
chunkDetail: 'Chunk-Detail',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeID: 'ID für externes Wissen',
externalKnowledgeAPI: 'API für externes Wissen',
retrievalSettings: 'Einstellungen für den Abruf',
upgradeHighQualityTip: 'Nach dem Upgrade auf den Modus "Hohe Qualität" ist das Zurücksetzen auf den Modus "Wirtschaftlich" nicht mehr möglich',
helpText: 'Erfahren Sie, wie Sie eine gute Datensatzbeschreibung schreiben.',
indexMethodChangeToEconomyDisabledTip: 'Nicht verfügbar für ein Downgrade von HQ auf ECO',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
mixtureInternalAndExternalTip: 'Das Rerank-Modell ist für die Mischung von internem und externem Wissen erforderlich.',
externalKnowledgeId: 'ID für externes Wissen',
editExternalAPIFormTitle: 'Bearbeiten der API für externes Wissen',
chunkingMode: {
parentChild: 'Eltern-Kind',
general: 'Allgemein',
},
parentMode: {
paragraph: 'Absatz',
fullDoc: 'Vollständiges Dokument',
},
batchAction: {
selected: 'Ausgewählt',
cancel: 'Abbrechen',
archive: 'Archiv',
disable: 'Abschalten',
delete: 'Löschen',
enable: 'Ermöglichen',
},
enable: 'Ermöglichen',
localDocs: 'Lokale Dokumente',
preprocessDocument: '{{num}} Vorverarbeiten von Dokumenten',
documentsDisabled: '{{num}} Dokumente deaktiviert - seit über 30 Tagen inaktiv',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: 'Acercar',
openInNewTab: 'Abrir en una nueva pestaña',
copyImage: 'Copiar imagen',
viewMore: 'VER MÁS',
regenerate: 'Regenerar',
close: 'Cerrar',
saveAndRegenerate: 'Guardar y regenerar fragmentos secundarios',
view: 'Vista',
},
errorMsg: {
fieldRequired: '{{field}} es requerido',
@ -478,6 +483,7 @@ const translation = {
emptyTip: 'El Conocimiento no ha sido asociado, por favor ve a la aplicación o plugin para completar la asociación.',
viewDoc: 'Ver documentación',
relatedApp: 'aplicaciones vinculadas',
noRelatedApp: 'No hay aplicaciones vinculadas',
},
voiceInput: {
speaking: 'Habla ahora...',

View File

@ -87,6 +87,7 @@ const translation = {
chooseProvider: 'Seleccione un proveedor',
jinaReaderDoc: 'Más información sobre Jina Reader',
},
cancel: 'Cancelar',
},
stepTwo: {
segmentation: 'Configuración de fragmentos',
@ -148,6 +149,28 @@ const translation = {
datasetSettingLink: 'configuración del conocimiento.',
separatorTip: 'Un delimitador es el carácter que se utiliza para separar el texto. \\n\\n y \\n son delimitadores comúnmente utilizados para separar párrafos y líneas. Combinado con comas (\\n\\n,\\n), los párrafos se segmentarán por líneas cuando excedan la longitud máxima del fragmento. También puede utilizar delimitadores especiales definidos por usted mismo (por ejemplo, ***).',
maxLengthCheck: 'La longitud máxima del fragmento debe ser inferior a {{limit}}',
previewChunkTip: 'Haga clic en el botón \'Vista previa de fragmento\' a la izquierda para cargar la vista previa',
parentChildChunkDelimiterTip: 'Un delimitador es el carácter que se utiliza para separar el texto. \\n se recomienda para dividir fragmentos primarios en fragmentos secundarios pequeños. También puede utilizar delimitadores especiales definidos por usted mismo.',
parentChildTip: 'Cuando se utiliza el modo padre-hijo, el fragmento secundario se utiliza para la recuperación y el fragmento primario se utiliza para la recuperación como contexto.',
switch: 'Interruptor',
parentChild: 'Padre-hijo',
childChunkForRetrieval: 'Fragmento secundario para la recuperación',
previewChunk: 'Fragmento de vista previa',
notAvailableForParentChild: 'No disponible para el índice de elementos primarios y secundarios',
paragraph: 'Párrafo',
parentChunkForContext: 'Fragmento primario para contexto',
fullDoc: 'Documento completo',
parentChildDelimiterTip: 'Un delimitador es el carácter que se utiliza para separar el texto. \\n\\n se recomienda para dividir el documento original en grandes fragmentos principales. También puede utilizar delimitadores especiales definidos por usted mismo.',
generalTip: 'Modo de fragmentación de texto general, los fragmentos recuperados y recuperados son los mismos.',
qaSwitchHighQualityTipContent: 'Actualmente, solo el método de índice de alta calidad admite la fragmentación en formato de preguntas y respuestas. ¿Le gustaría cambiar al modo de alta calidad?',
useQALanguage: 'Fragmento usando el formato de preguntas y respuestas en',
fullDocTip: 'Todo el documento se utiliza como fragmento principal y se recupera directamente. Tenga en cuenta que, por razones de rendimiento, el texto que supere los 10000 tokens se trunqueará automáticamente.',
paragraphTip: 'Este modo divide el texto en párrafos en función de los delimitadores y la longitud máxima del fragmento, utilizando el texto dividido como fragmento principal para la recuperación.',
highQualityTip: 'Una vez finalizada la incrustación en el modo de alta calidad, no está disponible volver al modo económico.',
notAvailableForQA: 'No disponible para el índice de preguntas y respuestas',
qaSwitchHighQualityTipTitle: 'El formato de preguntas y respuestas requiere un método de indexación de alta calidad',
previewChunkCount: '{{conteo}} Fragmentos estimados',
general: 'General',
},
stepThree: {
creationTitle: '🎉 Conocimiento creado',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'Clave de API de jina.ai',
getApiKeyLinkText: 'Obtén tu clave API gratuita en jina.ai',
},
otherDataSource: {
learnMore: 'Aprende más',
description: 'Actualmente, la base de conocimientos de Ifiy solo tiene fuentes de datos limitadas. Contribuir con una fuente de datos a la base de conocimientos de Dify es una manera fantástica de ayudar a mejorar la flexibilidad y el poder de la plataforma para todos los usuarios. Nuestra guía de contribuciones hace que sea fácil comenzar. Haga clic en el enlace a continuación para obtener más información.',
title: '¿Conectarse a otras fuentes de datos?',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'TIEMPO DE CARGA',
status: 'ESTADO',
action: 'ACCIÓN',
chunkingMode: 'MODO DE FRAGMENTACIÓN',
},
rename: 'Renombrar',
name: 'Nombre',
@ -77,6 +78,7 @@ const translation = {
error: 'Error de importación',
ok: 'Aceptar',
},
learnMore: 'Aprende más',
},
metadata: {
title: 'Metadatos',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Automático',
custom: 'Personalizado',
previewTip: 'La vista previa del párrafo estará disponible después de que se complete la incrustación',
pause: 'Pausa',
childMaxTokens: 'Niño',
hierarchical: 'Padre-hijo',
parentMaxTokens: 'Padre',
},
segment: {
paragraphs: 'Párrafos',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Nuevo segmento de texto',
newQaSegment: 'Nuevo segmento de preguntas y respuestas',
delete: '¿Eliminar este fragmento?',
chunks_one: 'PEDAZO',
childChunks_one: 'FRAGMENTO SECUNDARIO',
searchResults_other: 'RESULTADOS',
newChunk: 'Nuevo fragmento',
childChunk: 'Fragmento secundario',
addChunk: 'Agregar fragmento',
editParentChunk: 'Editar fragmento principal',
regenerationConfirmMessage: 'La regeneración de fragmentos secundarios sobrescribirá los fragmentos secundarios actuales, incluidos los fragmentos editados y los fragmentos recién agregados. La regeneración no se puede deshacer.',
addAnother: 'Añade otro',
regeneratingMessage: 'Esto puede tardar un momento, por favor espere...',
addChildChunk: 'Agregar fragmento secundario',
chunks_other: 'TROZOS',
editChunk: 'Editar fragmento',
searchResults_one: 'RESULTADO',
parentChunks_one: 'FRAGMENTO PRIMARIO',
edited: 'EDITADO',
childChunkAdded: 'Se ha añadido 1 fragmento secundario',
childChunks_other: 'FRAGMENTOS SECUNDARIOS',
chunkAdded: '1 trozo añadido',
parentChunk: 'Fragmento primario',
editChildChunk: 'Editar fragmento secundario',
regeneratingTitle: 'Regeneración de fragmentos secundarios',
editedAt: 'Editado en',
searchResults_zero: 'RESULTADO',
clearFilter: 'Borrar filtro',
newChildChunk: 'Nuevo fragmento secundario',
chunkDetail: 'Detalle de fragmentos',
chunk: 'Pedazo',
parentChunks_other: 'FRAGMENTOS PRINCIPALES',
expandChunks: 'Expandir fragmentos',
empty: 'No se ha encontrado ningún fragmento',
regenerationSuccessTitle: 'Regeneración completada',
collapseChunks: 'Contraer fragmentos',
characters_other: 'Caracteres',
characters_one: 'carácter',
regenerationSuccessMessage: 'Puede cerrar esta ventana.',
regenerationConfirmTitle: '¿Desea regenerar fragmentos secundarios?',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Ver GRÁFICO VECTORIAL',
viewDetail: 'Ver Detalle',
settingTitle: 'Configuración de recuperación',
open: 'Abrir',
records: 'Archivo',
chunkDetail: 'Detalle de fragmentos',
keyword: 'Palabras clave',
hitChunks: 'Golpea {{num}} fragmentos secundarios',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
retrievalSettings: 'Configuración de recuperación',
externalKnowledgeID: 'ID de conocimiento externo',
externalKnowledgeAPI: 'API de conocimiento externo',
indexMethodChangeToEconomyDisabledTip: 'No disponible para degradar de HQ a ECO',
helpText: 'Aprenda a escribir una buena descripción del conjunto de datos.',
upgradeHighQualityTip: 'Una vez que se actualiza al modo de alta calidad, no está disponible volver al modo económico',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
learnHowToWriteGoodKnowledgeDescription: 'Aprende a escribir una buena descripción del conocimiento',
externalAPIPanelDocumentation: 'Más información sobre cómo crear una API de conocimiento externo',
mixtureInternalAndExternalTip: 'El modelo de Rerank es necesario para la mezcla de conocimiento interno y externo.',
chunkingMode: {
parentChild: 'Padre-hijo',
general: 'General',
},
parentMode: {
fullDoc: 'Documento completo',
paragraph: 'Párrafo',
},
batchAction: {
selected: 'Seleccionado',
enable: 'Habilitar',
disable: 'Inutilizar',
cancel: 'Cancelar',
archive: 'Archivo',
delete: 'Borrar',
},
enable: 'Habilitar',
documentsDisabled: '{{num}} Documentos desactivados - inactivos durante más de 30 días',
preprocessDocument: '{{num}} Documentos de preprocesamiento',
localDocs: 'Documentos locales',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
copyImage: 'کپی تصویر',
openInNewTab: 'باز کردن در برگه جدید',
zoomOut: 'کوچک نمایی',
close: 'نزدیک',
regenerate: 'بازسازی',
view: 'مشاهده',
viewMore: 'بیشتر ببینید',
saveAndRegenerate: 'ذخیره و بازسازی تکه های فرزند',
},
errorMsg: {
fieldRequired: '{{field}} الزامی است',
@ -478,6 +483,7 @@ const translation = {
emptyTip: 'دانش مرتبط نشده است، لطفاً به برنامه یا افزونه بروید تا ارتباط را کامل کنید.',
viewDoc: 'مشاهده مستندات',
relatedApp: 'برنامه‌های مرتبط',
noRelatedApp: 'هیچ برنامه پیوندی وجود ندارد',
},
voiceInput: {
speaking: 'اکنون صحبت کنید...',

View File

@ -87,6 +87,7 @@ const translation = {
jinaReaderNotConfiguredDescription: 'با وارد کردن کلید API رایگان خود برای دسترسی، Jina Reader را راه اندازی کنید.',
useSitemapTooltip: 'نقشه سایت را دنبال کنید تا سایت را بخزید. در غیر این صورت، Jina Reader بر اساس ارتباط صفحه به صورت تکراری می خزد و صفحات کمتر اما با کیفیت بالاتر را به دست می آورد.',
},
cancel: 'لغو',
},
stepTwo: {
segmentation: 'تنظیمات بخشبندی',
@ -148,6 +149,28 @@ const translation = {
datasetSettingLink: 'تنظیمات دانش بروید.',
separatorTip: 'جداکننده نویسه ای است که برای جداسازی متن استفاده می شود. \\n\\n و \\n معمولا برای جداسازی پاراگراف ها و خطوط استفاده می شوند. همراه با کاما (\\n\\n,\\n)، پاراگراف ها زمانی که از حداکثر طول تکه فراتر می روند، با خطوط تقسیم بندی می شوند. همچنین می توانید از جداکننده های خاصی که توسط خودتان تعریف شده اند استفاده کنید (مثلا ***).',
maxLengthCheck: 'حداکثر طول تکه باید کمتر از {{limit}} باشد',
notAvailableForQA: 'برای شاخص پرسش و پاسخ در دسترس نیست',
parentChild: 'پدر و مادر و فرزند',
qaSwitchHighQualityTipContent: 'در حال حاضر، فقط روش شاخص با کیفیت بالا از تکه تکه کردن فرمت پرسش و پاسخ پشتیبانی می کند. آیا می خواهید به حالت با کیفیت بالا بروید؟',
previewChunk: 'پیش نمایش تکه',
previewChunkCount: '{{تعداد}} تکه های تخمینی',
previewChunkTip: 'روی دکمه "پیش نمایش قطعه" در سمت چپ کلیک کنید تا پیش نمایش بارگیری شود',
general: 'عمومی',
paragraphTip: 'این حالت متن را بر اساس جداکننده ها و حداکثر طول تکه به پاراگراف ها تقسیم می کند و از متن تقسیم شده به عنوان تکه والد برای بازیابی استفاده می کند.',
parentChunkForContext: 'تکه والد برای زمینه',
fullDoc: 'مستند کامل',
switch: 'سوئیچ',
parentChildChunkDelimiterTip: 'جداکننده نویسه ای است که برای جداسازی متن استفاده می شود. \\n برای تقسیم تکه های والد به تکه های کوچک کودک توصیه می شود. همچنین می توانید از جداکننده های ویژه ای که توسط خودتان تعریف شده است استفاده کنید.',
generalTip: 'حالت تکه تکه کردن متن عمومی، تکه های بازیابی شده و فراخوانی شده یکسان هستند.',
paragraph: 'پاراگراف',
highQualityTip: 'پس از اتمام جاسازی در حالت کیفیت بالا، بازگشت به حالت اقتصادی در دسترس نیست.',
parentChildTip: 'هنگام استفاده از حالت والد-فرزند، تکه فرزند برای بازیابی و تکه والد برای یادآوری به عنوان زمینه استفاده می شود.',
notAvailableForParentChild: 'برای نمایه والد-فرزند در دسترس نیست',
parentChildDelimiterTip: 'جداکننده نویسه ای است که برای جداسازی متن استفاده می شود. \\n\\n برای تقسیم سند اصلی به تکه های والد بزرگ توصیه می شود. همچنین می توانید از جداکننده های ویژه ای که توسط خودتان تعریف شده است استفاده کنید.',
childChunkForRetrieval: 'تکه کودک برای بازیابی',
fullDocTip: 'کل سند به عنوان تکه والد استفاده می شود و مستقیما بازیابی می شود. لطفا توجه داشته باشید که به دلایل عملکردی، متن بیش از 10000 توکن به طور خودکار کوتاه می شود.',
qaSwitchHighQualityTipTitle: 'فرمت پرسش و پاسخ به روش نمایه سازی با کیفیت بالا نیاز دارد',
useQALanguage: 'تکه با استفاده از فرمت پرسش و پاسخ در',
},
stepThree: {
creationTitle: ' دانش ایجاد شد',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'کلید API از jina.ai',
getApiKeyLinkText: 'کلید API رایگان خود را در jina.ai دریافت کنید',
},
otherDataSource: {
learnMore: 'بیشتر بدانید',
description: 'در حال حاضر، پایگاه دانش Dify فقط منابع داده محدودی دارد. کمک به یک منبع داده به پایگاه دانش Dify راهی فوق العاده برای کمک به افزایش انعطاف پذیری و قدرت پلتفرم برای همه کاربران است. راهنمای مشارکت ما شروع کار را آسان می کند. لطفا برای کسب اطلاعات بیشتر روی لینک زیر کلیک کنید.',
title: 'به منابع داده دیگر متصل شوید؟',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'زمان بارگذاری',
status: 'وضعیت',
action: 'اقدام',
chunkingMode: 'حالت تکه تکه کردن',
},
rename: 'تغییر نام',
name: 'نام',
@ -77,6 +78,7 @@ const translation = {
error: 'خطای واردات',
ok: 'تأیید',
},
learnMore: 'بیشتر بدانید',
},
metadata: {
title: 'اطلاعات متا',
@ -327,6 +329,10 @@ const translation = {
automatic: 'خودکار',
custom: 'سفارشی',
previewTip: 'پیش‌نمایش پاراگراف پس از اتمام جاسازی در دسترس خواهد بود',
parentMaxTokens: 'مادر',
pause: 'مکث',
childMaxTokens: 'کودک',
hierarchical: 'پدر و مادر و فرزند',
},
segment: {
paragraphs: 'پاراگراف‌ها',
@ -345,6 +351,43 @@ const translation = {
newTextSegment: 'قطعه متن جدید',
newQaSegment: 'قطعه پرسش و پاسخ جدید',
delete: 'حذف این قطعه؟',
chunks_other: 'تکه',
characters_one: 'شخصیت',
editedAt: 'ویرایش شده در',
parentChunks_other: 'تکه های والدین',
editChunk: 'ویرایش تکه',
collapseChunks: 'جمع کردن تکه ها',
clearFilter: 'فیلتر را پاک کنید',
characters_other: 'کاراکتر',
chunkDetail: 'جزئیات تکه',
searchResults_other: 'نتیجه',
addAnother: 'اضافه کردن دیگری',
parentChunks_one: 'تکه والدین',
childChunk: 'تکه کودک',
regenerationSuccessTitle: 'بازسازی به پایان رسید',
chunk: 'تکه',
addChildChunk: 'افزودن تکه فرزند',
chunkAdded: '1 تکه اضافه شد',
childChunks_one: 'تکه کودک',
edited: 'ویرایش',
editParentChunk: 'ویرایش تکه والد',
regeneratingTitle: 'بازسازی تکه های فرزند',
expandChunks: 'تکه ها را گسترش دهید',
childChunks_other: 'تکه های کودک',
newChildChunk: 'تکه کودک جدید',
editChildChunk: 'ویرایش Child Chunk',
parentChunk: 'تکه والدین',
chunks_one: 'تکه',
empty: 'هیچ تکه ای یافت نشد',
addChunk: 'افزودن تکه',
searchResults_one: 'نتیجه',
regenerationConfirmMessage: 'بازآفرینی تکه های فرزند تکه های فرزند فعلی، از جمله تکه های ویرایش شده و تکه های تازه اضافه شده را بازنویسی می کند. بازسازی را نمی توان خنثی کرد.',
childChunkAdded: '1 تکه کودک اضافه شد',
searchResults_zero: 'نتیجه',
newChunk: 'تکه جدید',
regeneratingMessage: 'این ممکن است یک لحظه طول بکشد، لطفا صبر کنید...',
regenerationConfirmTitle: 'آیا می خواهید تکه های کودک را بازسازی کنید؟',
regenerationSuccessMessage: 'می توانید این پنجره را ببندید.',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'مشاهده نمودار بُرداری',
settingTitle: 'تنظیمات بازیابی',
viewDetail: 'نمایش جزئیات',
records: 'سوابق',
keyword: 'کليدواژه',
hitChunks: '{{num}} را بزنید تکه های فرزند',
chunkDetail: 'جزئیات تکه',
open: 'باز',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeAPI: 'API دانش خارجی',
retrievalSettings: 'تنظیمات بازیابی',
externalKnowledgeID: 'شناسه دانش خارجی',
indexMethodChangeToEconomyDisabledTip: 'برای تنزل رتبه از HQ به ECO در دسترس نیست',
helpText: 'یاد بگیرید که چگونه یک توضیحات مجموعه داده خوب بنویسید.',
upgradeHighQualityTip: 'پس از ارتقاء به حالت کیفیت بالا، بازگشت به حالت اقتصادی در دسترس نیست',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
externalAPIPanelDescription: 'API دانش خارجی برای اتصال به یک پایگاه دانش خارج از Dify و بازیابی دانش از آن پایگاه دانش استفاده می شود.',
allExternalTip: 'هنگامی که فقط از دانش خارجی استفاده می کنید، کاربر می تواند انتخاب کند که آیا مدل Rerank را فعال کند یا خیر. اگر فعال نباشد، تکه های بازیابی شده بر اساس امتیازات مرتب می شوند. هنگامی که استراتژی های بازیابی پایگاه های دانش مختلف متناقض باشد، نادرست خواهد بود.',
mixtureInternalAndExternalTip: 'مدل Rerank برای آمیختگی دانش درونی و بیرونی مورد نیاز است.',
chunkingMode: {
parentChild: 'پدر و مادر و فرزند',
general: 'عمومی',
},
parentMode: {
fullDoc: 'مستند کامل',
paragraph: 'پاراگراف',
},
batchAction: {
disable: 'غیر فعال کردن',
cancel: 'لغو',
selected: 'انتخاب',
enable: 'فعال',
delete: 'حذف',
archive: 'بایگانی',
},
enable: 'فعال',
documentsDisabled: '{{num}} اسناد غیرفعال - غیرفعال برای بیش از 30 روز',
preprocessDocument: '{{عدد}} اسناد پیش پردازش',
localDocs: 'اسناد محلی',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: 'Zoom avant',
openInNewTab: 'Ouvrir dans un nouvel onglet',
copyImage: 'Copier limage',
view: 'Vue',
viewMore: 'VOIR PLUS',
close: 'Fermer',
saveAndRegenerate: 'Enregistrer et régénérer des morceaux enfants',
regenerate: 'Régénérer',
},
placeholder: {
input: 'Veuillez entrer',
@ -474,6 +479,7 @@ const translation = {
emptyTip: 'La Connaissance n\'a pas été associée, veuillez aller à l\'application ou au plug-in pour compléter l\'association.',
viewDoc: 'Voir la documentation',
relatedApp: 'applications liées',
noRelatedApp: 'Pas dapplications liées',
},
voiceInput: {
speaking: 'Parle maintenant...',

View File

@ -82,6 +82,7 @@ const translation = {
chooseProvider: 'Sélectionnez un fournisseur',
jinaReaderTitle: 'Convertir lintégralité du site en Markdown',
},
cancel: 'Annuler',
},
stepTwo: {
segmentation: 'Paramètres de bloc',
@ -143,6 +144,28 @@ const translation = {
websiteSource: 'Site web de prétraitement',
separatorTip: 'Un délimiteur est le caractère utilisé pour séparer le texte. \\n\\n et \\n sont des délimiteurs couramment utilisés pour séparer les paragraphes et les lignes. Combiné à des virgules (\\n\\n,\\n), les paragraphes seront segmentés par des lignes lorsquils dépasseront la longueur maximale des morceaux. Vous pouvez également utiliser des délimiteurs spéciaux définis par vous-même (par exemple ***).',
maxLengthCheck: 'La longueur maximale des morceaux doit être inférieure à {{limit}}',
parentChunkForContext: 'Parent-chunk pour le contexte',
notAvailableForParentChild: 'Non disponible pour lindice parent-enfant',
parentChild: 'Parent-enfant',
useQALanguage: 'Chunk utilisant le format Q&A dans',
highQualityTip: 'Une fois lintégration terminée en mode Haute qualité, il nest pas possible de revenir au mode économique.',
switch: 'Interrupteur',
paragraph: 'Paragraphe',
general: 'Généralités',
fullDocTip: 'Lintégralité du document est utilisée comme morceau parent et récupérée directement. Veuillez noter que pour des raisons de performance, le texte dépassant 10000 jetons sera automatiquement tronqué.',
fullDoc: 'Doc complet',
previewChunkCount: '{{compte}} Tronçons estimés',
childChunkForRetrieval: 'Child-chunk pour lextraction',
parentChildDelimiterTip: 'Un délimiteur est le caractère utilisé pour séparer le texte. \\n\\n est recommandé pour diviser le document dorigine en gros morceaux parents. Vous pouvez également utiliser des délimiteurs spéciaux définis par vous-même.',
qaSwitchHighQualityTipTitle: 'Le format Q&R nécessite une méthode dindexation de haute qualité',
notAvailableForQA: 'Non disponible pour lindice Q&R',
previewChunk: 'Aperçu du morceau',
parentChildTip: 'Lors de lutilisation du mode parent-enfant, le morceau enfant est utilisé pour la récupération et le morceau parent est utilisé pour le rappel en tant que contexte.',
paragraphTip: 'Ce mode divise le texte en paragraphes en fonction des délimiteurs et de la longueur maximale du morceau, en utilisant le texte scindé comme morceau parent pour la récupération.',
qaSwitchHighQualityTipContent: 'Actuellement, seule la méthode dindex de haute qualité prend en charge la segmentation du format Q&R. Vous souhaitez passer en mode haute qualité ?',
previewChunkTip: 'Cliquez sur le bouton « Preview Chunk » sur la gauche pour charger laperçu',
parentChildChunkDelimiterTip: 'Un délimiteur est le caractère utilisé pour séparer le texte. \\n est recommandé pour diviser les blocs parents en petits blocs enfants. Vous pouvez également utiliser des délimiteurs spéciaux définis par vous-même.',
generalTip: 'Mode général de segmentation du texte, les morceaux récupérés et rappelés sont les mêmes.',
},
stepThree: {
creationTitle: '🎉 Connaissance créée',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'Clé API de jina.ai',
configJinaReader: 'Configurer Jina Reader',
},
otherDataSource: {
learnMore: 'Pour en savoir plus',
description: 'Actuellement, la base de connaissances de Dify ne dispose que de sources de données limitées. Contribuer à une source de données dans la base de connaissances Dify est un moyen fantastique daméliorer la flexibilité et la puissance de la plateforme pour tous les utilisateurs. Notre guide de contribution facilite la prise en main. Veuillez cliquer sur le lien ci-dessous pour en savoir plus.',
title: 'Se connecter à dautres sources de données ?',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: 'TEMPS DE TÉLÉCHARGEMENT',
status: 'STATUT',
action: 'ACTION',
chunkingMode: 'MODE DE MORCEAU',
},
rename: 'Renommer',
name: 'Nom',
@ -77,6 +78,7 @@ const translation = {
ok: 'D\'accord',
},
addUrl: 'Ajouter une URL',
learnMore: 'Pour en savoir plus',
},
metadata: {
title: 'Métadonnées',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Automatique',
custom: 'Personnalisé',
previewTip: 'L\'aperçu du paragraphe sera disponible après la fin de l\'embedding.',
childMaxTokens: 'Enfant',
hierarchical: 'Parent-enfant',
pause: 'Pause',
parentMaxTokens: 'Parent',
},
segment: {
paragraphs: 'Paragraphes',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Nouveau Segment de Texte',
newQaSegment: 'Nouveau Segment Q&R',
delete: 'Supprimer ce morceau ?',
chunks_other: 'MORCEAUX',
childChunks_other: 'MORCEAUX ENFANTS',
clearFilter: 'Effacer le filtre',
newChunk: 'Nouveau Chunk',
childChunk: 'Enfant-Chunk',
newChildChunk: 'Nouveau morceau enfant',
addChunk: 'Ajouter un morceau',
chunkAdded: '1 morceau ajouté',
editChunk: 'Modifier le morceau',
regenerationConfirmMessage: 'La régénération des blocs enfants remplacera les blocs enfants actuels, y compris les blocs modifiés et les blocs nouvellement ajoutés. La régénération ne peut pas être annulée.',
regenerationSuccessTitle: 'Régénération terminée',
edited: 'ÉDITION',
collapseChunks: 'Réduire les morceaux',
childChunkAdded: '1 morceau enfant ajouté',
addAnother: 'Ajouter un autre',
searchResults_one: 'RÉSULTAT',
regeneratingTitle: 'Régénération de blocs enfants',
expandChunks: 'Développer des blocs',
characters_other: 'caractères',
editedAt: 'Édité le',
searchResults_other: 'RÉSULTATS',
regenerationSuccessMessage: 'Vous pouvez fermer cette fenêtre.',
parentChunks_one: 'MORCEAU PARENT',
regenerationConfirmTitle: 'Voulez-vous régénérer des morceaux enfants ?',
chunks_one: 'MORCEAU',
childChunks_one: 'MORCEAU ENFANT',
parentChunk: 'Parent-Chunk',
chunkDetail: 'Détail du morceau',
chunk: 'Morceau',
parentChunks_other: 'MORCEAUX PARENTS',
regeneratingMessage: 'Cela peut prendre un moment, veuillez patienter...',
addChildChunk: 'Ajouter un morceau enfant',
editParentChunk: 'Modifier le bloc parent',
characters_one: 'personnage',
searchResults_zero: 'RÉSULTAT',
empty: 'Aucun Chunk trouvé',
editChildChunk: 'Modifier le morceau enfant',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Voir GRAPHIQUE VECTORIEL',
settingTitle: 'Réglage de récupération',
viewDetail: 'Voir les détails',
hitChunks: 'Appuyez sur {{num}} morceaux enfants',
records: 'Archives',
chunkDetail: 'Détail du morceau',
open: 'Ouvrir',
keyword: 'Mots-clés',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
retrievalSettings: 'Paramètres de récupération',
externalKnowledgeAPI: 'API de connaissances externes',
externalKnowledgeID: 'Identification des connaissances externes',
indexMethodChangeToEconomyDisabledTip: 'Non disponible pour le déclassement de HQ à ECO',
upgradeHighQualityTip: 'Une fois la mise à niveau vers le mode Haute Qualité, il nest pas possible de revenir au mode Économique',
helpText: 'Apprenez à rédiger une bonne description de jeu de données.',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
externalAPIPanelTitle: 'API de connaissances externes',
noExternalKnowledge: 'Il ny a pas encore dAPI de connaissances externes, cliquez ici pour créer',
learnHowToWriteGoodKnowledgeDescription: 'Apprenez à rédiger une bonne description des connaissances',
chunkingMode: {
general: 'Généralités',
parentChild: 'Parent-enfant',
},
parentMode: {
paragraph: 'Paragraphe',
fullDoc: 'Doc complet',
},
batchAction: {
archive: 'Archiver',
disable: 'Désactiver',
delete: 'Supprimer',
cancel: 'Annuler',
enable: 'Activer',
selected: 'Sélectionné',
},
preprocessDocument: '{{num}} Prétraiter les documents',
documentsDisabled: '{{num}} documents désactivés - inactifs depuis plus de 30 jours',
localDocs: 'Docs locaux',
enable: 'Activer',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomOut: 'ज़ूम आउट करें',
openInNewTab: 'नए टैब में खोलें',
zoomIn: 'ज़ूम इन करें',
view: 'देखना',
viewMore: 'और देखें',
regenerate: 'पुनर्जन्म',
close: 'बंद करना',
saveAndRegenerate: 'सहेजें और पुन: उत्पन्न करें बाल विखंडू',
},
errorMsg: {
fieldRequired: '{{field}} आवश्यक है',
@ -496,6 +501,7 @@ const translation = {
'ज्ञान को संबद्ध नहीं किया गया है, कृपया संबद्धता पूरी करने के लिए एप्लिकेशन या प्लग-इन पर जाएं।',
viewDoc: 'दस्तावेज़ देखें',
relatedApp: 'संबंधित ऐप्स',
noRelatedApp: 'कोई लिंक नहीं किए गए ऐप्स',
},
voiceInput: {
speaking: 'अब बोलें...',

View File

@ -92,6 +92,7 @@ const translation = {
jinaReaderTitle: 'पूरी साइट को मार्कडाउन में बदलें',
jinaReaderNotConfiguredDescription: 'एक्सेस के लिए अपनी मुफ्त एपीआई कुंजी दर्ज करके जीना रीडर सेट करें।',
},
cancel: 'रद्द करना',
},
stepTwo: {
segmentation: 'खंड सेटिंग्स',
@ -165,6 +166,28 @@ const translation = {
datasetSettingLink: 'ज्ञान सेटिंग्स।',
separatorTip: 'एक सीमांकक पाठ को अलग करने के लिए उपयोग किया जाने वाला वर्ण है। \\n\\n और \\n आमतौर पर पैराग्राफ और लाइनों को अलग करने के लिए उपयोग किए जाने वाले सीमांकक हैं। अल्पविराम (\\n\\n,\\n) के साथ संयुक्त, अधिकतम खंड लंबाई से अधिक होने पर अनुच्छेदों को पंक्तियों द्वारा खंडित किया जाएगा। आप स्वयं द्वारा परिभाषित विशेष सीमांकक का भी उपयोग कर सकते हैं (उदा. ***).',
maxLengthCheck: 'अधिकतम चंक लंबाई {{limit}} से कम होनी चाहिए',
useQALanguage: 'में क्यू एंड ए प्रारूप का उपयोग करके चंक करें',
previewChunkCount: '{{गिनती}} अनुमानित खंड',
previewChunk: 'पूर्वावलोकन चंक',
paragraph: 'अनुच्‍छेद',
general: 'सामान्य',
highQualityTip: 'एक बार उच्च गुणवत्ता मोड में एम्बेडिंग समाप्त करने के बाद, किफायती मोड पर वापस जाना उपलब्ध नहीं है।',
parentChunkForContext: 'संदर्भ के लिए माता-पिता का हिस्सा',
notAvailableForQA: 'Q&A इंडेक्स के लिए उपलब्ध नहीं है',
fullDoc: 'पूर्ण डॉक्टर',
fullDocTip: 'पूरे दस्तावेज़ को मूल खंड के रूप में उपयोग किया जाता है और सीधे पुनर्प्राप्त किया जाता है। कृपया ध्यान दें कि प्रदर्शन कारणों से, 10000 टोकन से अधिक का पाठ स्वचालित रूप से छोटा कर दिया जाएगा।',
previewChunkTip: 'पूर्वावलोकन लोड करने के लिए बाईं ओर \'पूर्वावलोकन चंक\' बटन पर क्लिक करें',
generalTip: 'सामान्य पाठ चंकिंग मोड, पुनर्प्राप्त और याद किए गए चंक्स समान हैं।',
qaSwitchHighQualityTipTitle: 'Q&A प्रारूप के लिए उच्च-गुणवत्ता अनुक्रमण विधि की आवश्यकता होती है',
qaSwitchHighQualityTipContent: 'वर्तमान में, केवल उच्च-गुणवत्ता वाली अनुक्रमणिका विधि Q & A प्रारूप चंकिंग का समर्थन करती है। क्या आप उच्च-गुणवत्ता मोड पर स्विच करना चाहेंगे?',
parentChildChunkDelimiterTip: 'एक सीमांकक पाठ को अलग करने के लिए उपयोग किया जाने वाला वर्ण है। माता-पिता के टुकड़ों को छोटे बच्चे के टुकड़ों में विभाजित करने के लिए \\n की सिफारिश की जाती है। आप स्वयं द्वारा परिभाषित विशेष सीमांकक का भी उपयोग कर सकते हैं।',
childChunkForRetrieval: 'पुनर्प्राप्ति के लिए बाल-खंड',
switch: 'स्विच',
parentChildDelimiterTip: 'एक सीमांकक पाठ को अलग करने के लिए उपयोग किया जाने वाला वर्ण है। \\n\\n मूल दस्तावेज़ को बड़े पैरेंट विखंडू में विभाजित करने के लिए अनुशंसित है। आप स्वयं द्वारा परिभाषित विशेष सीमांकक का भी उपयोग कर सकते हैं।',
notAvailableForParentChild: 'पैरेंट-चाइल्ड इंडेक्स के लिए उपलब्ध नहीं है',
parentChild: 'माता-पिता का बच्चा',
parentChildTip: 'पैरेंट-चाइल्ड मोड का उपयोग करते समय, चाइल्ड-चंक का उपयोग पुनर्प्राप्ति के लिए किया जाता है और पैरेंट-चंक का उपयोग संदर्भ के रूप में रिकॉल के लिए किया जाता है।',
paragraphTip: 'यह मोड पाठ को सीमांकक और अधिकतम खंड लंबाई के आधार पर पैराग्राफ में विभाजित करता है, पुनर्प्राप्ति के लिए मूल खंड के रूप में विभाजित पाठ का उपयोग करता है।',
},
stepThree: {
creationTitle: '🎉 ज्ञान बनाया गया',
@ -191,6 +214,11 @@ const translation = {
apiKeyPlaceholder: 'jina.ai से एपीआई कुंजी',
getApiKeyLinkText: 'jina.ai पर अपनी निःशुल्क एपीआई कुंजी प्राप्त करें',
},
otherDataSource: {
title: 'अन्य डेटा स्रोतों से कनेक्ट करें?',
learnMore: 'और जानो',
description: 'वर्तमान में, Dify के ज्ञानकोष में केवल सीमित डेटा स्रोत हैं। Dify नॉलेज बेस में डेटा स्रोत का योगदान करना सभी उपयोगकर्ताओं के लिए प्लेटफॉर्म के लचीलेपन और शक्ति को बढ़ाने में मदद करने का एक शानदार तरीका है। हमारी योगदान मार्गदर्शिका आरंभ करना आसान बनाती है। अधिक जानने के लिए कृपया नीचे दिए गए लिंक पर क्लिक करें।',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'अपलोड का समय',
status: 'स्थिति',
action: 'क्रिया',
chunkingMode: 'चंकिंग मोड',
},
rename: 'नाम बदलें',
name: 'नाम',
@ -78,6 +79,7 @@ const translation = {
error: 'आयात त्रुटि',
ok: 'ठीक है',
},
learnMore: 'और जानो',
},
metadata: {
title: 'मेटाडेटा',
@ -329,6 +331,10 @@ const translation = {
automatic: 'स्वचालित',
custom: 'अनुकूलित',
previewTip: 'पैराग्राफ पूर्वावलोकन एम्बेडिंग पूरी होने के बाद उपलब्ध होगा',
parentMaxTokens: 'जनक',
pause: 'रुकना',
hierarchical: 'माता-पिता का बच्चा',
childMaxTokens: 'बच्चा',
},
segment: {
paragraphs: 'पैराग्राफ',
@ -347,6 +353,43 @@ const translation = {
newTextSegment: 'नया पाठ खंड',
newQaSegment: 'नया Q&A खंड',
delete: 'इस खंड को हटाएँ ?',
parentChunks_other: 'जनक चंक्स',
childChunks_one: 'चाइल्ड चंक',
searchResults_other: 'परिणाम',
parentChunks_one: 'जनक चंक',
searchResults_one: 'परिणाम',
addChildChunk: 'Child chunk जोड़ें',
childChunks_other: 'बच्चे के टुकड़े',
collapseChunks: 'चंक्स संक्षिप्त करें',
characters_one: 'अक्षर',
childChunkAdded: '1 चाइल्ड चंक जोड़ा गया',
chunks_other: 'हिस्सा',
addAnother: 'एक और जोड़ें',
newChunk: 'नया हिस्सा',
searchResults_zero: 'परिणाम',
chunk: 'हिस्सा',
addChunk: 'चंक जोड़ें',
editChildChunk: 'संपादित करें बाल चंक',
editedAt: 'पर संपादित',
childChunk: 'चाइल्ड-चंक',
parentChunk: 'माता-पिता-चंक',
empty: 'कोई हिस्सा नहीं मिला',
editChunk: 'चंक संपादित करें',
characters_other: 'वर्ण',
regeneratingMessage: 'इसमें कुछ समय लग सकता है, कृपया प्रतीक्षा करें...',
regenerationConfirmTitle: 'क्या आप बच्चे के टुकड़ों को पुन: उत्पन्न करना चाहते हैं?',
regeneratingTitle: 'बच्चे के टुकड़ों को पुनर्जीवित करना',
chunks_one: 'हिस्सा',
edited: 'संपादित',
editParentChunk: 'पेरेंट चंक संपादित करें',
newChildChunk: 'न्यू चाइल्ड चंक',
clearFilter: 'फ़िल्टर साफ़ करें',
regenerationSuccessMessage: 'आप इस विंडो को बंद कर सकते हैं।',
expandChunks: 'विखंडू का विस्तार करें',
regenerationSuccessTitle: 'पुनर्जनन पूरा हुआ',
chunkAdded: '1 हिस्सा जोड़ा गया',
chunkDetail: 'चंक विवरण',
regenerationConfirmMessage: 'चाइल्ड चंक्स को रीजनरेट करने से वर्तमान चाइल्ड चंक्स ओवरराइट हो जाएंगे, जिसमें संपादित चंक्स और नए जोड़े गए चंक्स शामिल हैं। पुनरुत्थान को पूर्ववत नहीं किया जा सकता है।',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'वेक्टर चार्ट देखें',
viewDetail: 'विस्तार से देखें',
settingTitle: 'पुनर्प्राप्ति सेटिंग',
hitChunks: '{{num}} बच्चे के टुकड़े मारो',
keyword: 'खोजशब्दों',
chunkDetail: 'चंक विवरण',
open: 'खोलना',
records: 'रिकॉर्ड',
}
export default translation

View File

@ -37,6 +37,9 @@ const translation = {
externalKnowledgeID: 'बाहरी ज्ञान ID',
externalKnowledgeAPI: 'बाहरी ज्ञान एपीआई',
retrievalSettings: 'पुनर्प्राप्ति सेटिंग्स',
indexMethodChangeToEconomyDisabledTip: 'मुख्यालय से ईसीओ में डाउनग्रेड करने के लिए उपलब्ध नहीं है',
helpText: 'एक अच्छा डेटासेट विवरण लिखना सीखें।',
upgradeHighQualityTip: 'एक बार उच्च गुणवत्ता मोड में अपग्रेड करने के बाद, किफायती मोड में वापस जाना उपलब्ध नहीं है',
},
}

View File

@ -153,6 +153,26 @@ const translation = {
noExternalKnowledge: 'अभी तक कोई बाहरी ज्ञान एपीआई नहीं है, बनाने के लिए यहां क्लिक करें',
createNewExternalAPI: 'एक नया बाहरी नॉलेज API बनाएँ',
learnHowToWriteGoodKnowledgeDescription: 'एक अच्छा ज्ञान विवरण लिखना सीखें',
chunkingMode: {
parentChild: 'माता-पिता का बच्चा',
general: 'सामान्य',
},
parentMode: {
fullDoc: 'पूर्ण-दस्तावेज़',
paragraph: 'अनुच्‍छेद',
},
batchAction: {
cancel: 'रद्द करना',
disable: 'अक्षम',
enable: 'योग्य बनाना',
selected: 'चयनित',
delete: 'मिटाना',
archive: 'पुरालेख',
},
localDocs: 'स्थानीय डॉक्स',
preprocessDocument: '{{num}} प्रीप्रोसेस दस्तावेज़',
enable: 'योग्य बनाना',
documentsDisabled: '{{num}} दस्तावेज़ अक्षम - 30 दिनों से अधिक समय से निष्क्रिय',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: 'Ingrandisci',
openInNewTab: 'Apri in una nuova scheda',
copyImage: 'Copia immagine',
close: 'Chiudere',
view: 'Vista',
saveAndRegenerate: 'Salva e rigenera i blocchi figlio',
regenerate: 'Rigenerare',
viewMore: 'SCOPRI DI PIÙ',
},
errorMsg: {
fieldRequired: '{{field}} è obbligatorio',
@ -504,6 +509,7 @@ const translation = {
'La Conoscenza non è stata associata, per favore vai all\'applicazione o al plug-in per completare l\'associazione.',
viewDoc: 'Visualizza documentazione',
relatedApp: 'app collegate',
noRelatedApp: 'Nessuna app collegata',
},
voiceInput: {
speaking: 'Parla ora...',

View File

@ -94,6 +94,7 @@ const translation = {
useSitemap: 'Usa la mappa del sito',
chooseProvider: 'Seleziona un fornitore',
},
cancel: 'Annulla',
},
stepTwo: {
segmentation: 'Impostazioni dei blocchi',
@ -168,6 +169,28 @@ const translation = {
datasetSettingLink: 'impostazioni della Conoscenza.',
separatorTip: 'Un delimitatore è il carattere utilizzato per separare il testo. \\n\\n e \\n sono delimitatori comunemente usati per separare paragrafi e righe. In combinazione con le virgole (\\n\\n,\\n), i paragrafi verranno segmentati per righe quando superano la lunghezza massima del blocco. È inoltre possibile utilizzare delimitatori speciali definiti dall\'utente (ad es. ***).',
maxLengthCheck: 'La lunghezza massima del blocco deve essere inferiore a {{limit}}',
useQALanguage: 'Blocco con il formato Q&A in',
previewChunkTip: 'Fai clic sul pulsante "Anteprima blocco" a sinistra per caricare l\'anteprima',
paragraph: 'Paragrafo',
childChunkForRetrieval: 'Child-chunk per il recupero',
general: 'Generale',
fullDoc: 'Documento completo',
previewChunkCount: '{{conteggio}} Blocchi stimati',
generalTip: 'Modalità generale di suddivisione in blocchi del testo, i blocchi recuperati e richiamati sono gli stessi.',
parentChildChunkDelimiterTip: 'Un delimitatore è il carattere utilizzato per separare il testo. \\n è consigliato per dividere i blocchi principali in piccoli blocchi figlio. È inoltre possibile utilizzare delimitatori speciali definiti dall\'utente.',
fullDocTip: 'L\'intero documento viene utilizzato come blocco principale e recuperato direttamente. Si prega di notare che per motivi di prestazioni, il testo che supera i 10000 token verrà automaticamente troncato.',
parentChild: 'Genitore-figlio',
qaSwitchHighQualityTipContent: 'Attualmente, solo il metodo dell\'indice di alta qualità supporta la suddivisione in blocchi del formato Domande e risposte. Volete passare alla modalità di alta qualità?',
parentChunkForContext: 'Parent-chunk per il contesto',
switch: 'Interruttore',
paragraphTip: 'Questa modalità suddivide il testo in paragrafi in base ai delimitatori e alla lunghezza massima del blocco, utilizzando il testo diviso come blocco principale per il recupero.',
notAvailableForQA: 'Non disponibile per l\'indice Q&A',
parentChildTip: 'Quando si utilizza la modalità genitore-figlio, il blocco figlio viene utilizzato per il recupero e il blocco padre viene utilizzato per il richiamo come contesto.',
highQualityTip: 'Una volta terminato l\'incorporamento in modalità Alta qualità, il ripristino della modalità Economica non è disponibile.',
parentChildDelimiterTip: 'Un delimitatore è il carattere utilizzato per separare il testo. \\n\\n è consigliato per dividere il documento originale in blocchi principali di grandi dimensioni. È inoltre possibile utilizzare delimitatori speciali definiti dall\'utente.',
previewChunk: 'Blocco di anteprima',
notAvailableForParentChild: 'Non disponibile per l\'indice padre-figlio',
qaSwitchHighQualityTipTitle: 'Il formato Domande e risposte richiede un metodo di indicizzazione di alta qualità',
},
stepThree: {
creationTitle: '🎉 Conoscenza creata',
@ -194,6 +217,11 @@ const translation = {
apiKeyPlaceholder: 'Chiave API da jina.ai',
configJinaReader: 'Configura Jina Reader',
},
otherDataSource: {
learnMore: 'Ulteriori informazioni',
title: 'Connettersi ad altre origini dati?',
description: 'Attualmente, la knowledge base di Dify ha solo fonti di dati limitate. Contribuire con una fonte di dati alla knowledge base di Dify è un modo fantastico per migliorare la flessibilità e la potenza della piattaforma per tutti gli utenti. La nostra guida ai contributi ti aiuta a iniziare. Clicca sul link sottostante per saperne di più.',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'ORA DI CARICAMENTO',
status: 'STATO',
action: 'AZIONE',
chunkingMode: 'MODALITÀ DI SUDDIVISIONE IN BLOCCHI',
},
rename: 'Rinomina',
name: 'Nome',
@ -78,6 +79,7 @@ const translation = {
error: 'Errore di importazione',
ok: 'OK',
},
learnMore: 'Ulteriori informazioni',
},
metadata: {
title: 'Metadati',
@ -330,6 +332,10 @@ const translation = {
custom: 'Personalizzato',
previewTip:
'L\'anteprima del paragrafo sarà disponibile dopo il completamento dell\'embedding',
childMaxTokens: 'Bambino',
pause: 'Pausa',
hierarchical: 'Genitore-figlio',
parentMaxTokens: 'Genitore',
},
segment: {
paragraphs: 'Paragrafi',
@ -348,6 +354,43 @@ const translation = {
newTextSegment: 'Nuovo Segmento di Testo',
newQaSegment: 'Nuovo Segmento di Domanda & Risposta',
delete: 'Eliminare questo blocco?',
searchResults_zero: 'RISULTATO',
searchResults_other: 'RISULTATI',
newChunk: 'Nuovo blocco',
characters_one: 'carattere',
addChildChunk: 'Aggiungi blocco figlio',
addAnother: 'Aggiungi un altro',
parentChunks_one: 'BLOCCO PADRE',
regenerationConfirmMessage: 'La rigenerazione dei blocchi figlio sovrascriverà i blocchi figlio correnti, inclusi i blocchi modificati e i blocchi appena aggiunti. La rigenerazione non può essere annullata.',
regenerationSuccessTitle: 'Rigenerazione completata',
regeneratingTitle: 'Rigenerazione di blocchi figlio',
chunkAdded: '1 pezzo aggiunto',
empty: 'Nessun blocco trovato',
parentChunk: 'Blocco genitore',
edited: 'MODIFICATO',
characters_other: 'personaggi',
parentChunks_other: 'BLOCCHI PRINCIPALI',
chunk: 'Pezzo',
newChildChunk: 'Nuovo blocco figlio',
editChildChunk: 'Modifica blocco figlio',
addChunk: 'Aggiungi blocco',
childChunks_one: 'BLOCCO FIGLIO',
regenerationConfirmTitle: 'Si desidera rigenerare i blocchi figlio?',
chunks_other: 'BLOCCHI',
editedAt: 'A cura di',
collapseChunks: 'Comprimi blocchi',
clearFilter: 'Cancella filtro',
chunks_one: 'PEZZO',
editParentChunk: 'Modifica blocco padre',
expandChunks: 'Espandi blocchi',
chunkDetail: 'Dettaglio pezzo',
searchResults_one: 'RISULTATO',
regeneratingMessage: 'Questo potrebbe richiedere un momento, si prega di attendere...',
childChunk: 'Figlio-Chunk',
editChunk: 'Modifica blocco',
regenerationSuccessMessage: 'È possibile chiudere questa finestra.',
childChunkAdded: '1 blocco figlio aggiunto',
childChunks_other: 'BLOCCHI FIGLIO',
},
}

View File

@ -26,6 +26,11 @@ const translation = {
viewChart: 'Visualizza GRAFICO VETTORIALE',
settingTitle: 'Impostazione di recupero',
viewDetail: 'vedi dettagli',
chunkDetail: 'Dettaglio pezzo',
hitChunks: 'Premi {{num}} blocchi figlio',
open: 'Aperto',
keyword: 'Parole chiavi',
records: 'Archivio',
}
export default translation

View File

@ -37,6 +37,9 @@ const translation = {
retrievalSettings: 'Impostazioni di recupero',
externalKnowledgeID: 'ID conoscenza esterna',
externalKnowledgeAPI: 'API di conoscenza esterna',
helpText: 'Scopri come scrivere una buona descrizione del set di dati.',
upgradeHighQualityTip: 'Una volta effettuato l\'aggiornamento alla modalità Alta qualità, il ripristino della modalità Risparmio non è disponibile',
indexMethodChangeToEconomyDisabledTip: 'Non disponibile per il downgrade da HQ a ECO',
},
}

View File

@ -153,6 +153,26 @@ const translation = {
allExternalTip: 'Quando si utilizzano solo conoscenze esterne, l\'utente può scegliere se abilitare il modello Rerank. Se non è abilitato, i blocchi recuperati verranno ordinati in base ai punteggi. Quando le strategie di recupero di diverse basi di conoscenza sono incoerenti, saranno imprecise.',
externalKnowledgeDescriptionPlaceholder: 'Descrivi cosa c\'è in questa Knowledge Base (facoltativo)',
noExternalKnowledge: 'Non esiste ancora un\'API di conoscenza esterna, fai clic qui per creare',
chunkingMode: {
general: 'Generale',
parentChild: 'Genitore-figlio',
},
parentMode: {
paragraph: 'Paragrafo',
fullDoc: 'Full-doc',
},
batchAction: {
archive: 'Archivio',
enable: 'Abilitare',
cancel: 'Annulla',
selected: 'Selezionato',
disable: 'Disabilitare',
delete: 'Cancellare',
},
preprocessDocument: '{{num}} Pre-elaborazione dei documenti',
enable: 'Abilitare',
documentsDisabled: '{{num}} documenti disabilitati - inattivi da oltre 30 giorni',
localDocs: 'Documenti locali',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
openInNewTab: '新しいタブで開く',
zoomOut: 'ズームアウト',
copyImage: '画像をコピー',
viewMore: 'もっと見る',
view: '眺める',
close: '閉める',
saveAndRegenerate: '子チャンクの保存と再生成',
regenerate: '再生',
},
errorMsg: {
fieldRequired: '{{field}}は必要です',
@ -478,6 +483,7 @@ const translation = {
emptyTip: '関連付けられた知識がありません。アプリケーションやプラグインに移動して関連付けを完了してください。',
viewDoc: 'ドキュメントを表示',
relatedApp: '関連アプリ',
noRelatedApp: 'リンクされたアプリはありません',
},
voiceInput: {
speaking: '今話しています...',

View File

@ -87,6 +87,7 @@ const translation = {
jinaReaderNotConfiguredDescription: '無料のAPIキーを入力してJina Readerを設定します。',
useSitemapTooltip: 'サイトマップに沿ってサイトをクロールします。そうでない場合、Jina Readerはページの関連性に基づいて繰り返しクロールし、ページ数は少なくなりますが、高品質のページが得られます。',
},
cancel: 'キャンセル',
},
stepTwo: {
segmentation: 'チャンク設定',
@ -148,6 +149,28 @@ const translation = {
datasetSettingLink: 'ナレッジ設定',
separatorTip: '区切り文字は、テキストを区切るために使用される文字です。\\n\\n と \\n は、段落と行を区切るために一般的に使用される区切り記号です。カンマ (\\n\\n,\\n) と組み合わせると、最大チャンク長を超えると、段落は行で区切られます。自分で定義した特別な区切り文字を使用することもできます(例:***)。',
maxLengthCheck: 'チャンクの最大長は {{limit}} 未満にする必要があります',
useQALanguage: 'Q&A 形式を使用したチャンク',
previewChunkTip: '左側の「Preview Chunk」ボタンをクリックして、プレビューをロードします',
qaSwitchHighQualityTipTitle: 'Q&A 形式には高品質のインデックス作成方法が必要',
qaSwitchHighQualityTipContent: '現在、Q&A 形式のチャンク化をサポートしているのは、高品質のインデックス メソッドのみです。高品質モードに切り替えますか?',
childChunkForRetrieval: '取得用の子チャンク',
fullDoc: 'フルドキュメント',
parentChildDelimiterTip: '区切り文字は、テキストを区切るために使用される文字です。\\n\\n は、元のドキュメントを大きな親チャンクに分割する場合に推奨されます。また、自分で定義した特別な区切り文字を使用することもできます。',
general: '全般',
switch: 'スイッチ',
parentChild: '親子',
parentChildChunkDelimiterTip: '区切り文字は、テキストを区切るために使用される文字です。\\n は、親チャンクを小さな子チャンクに分割する場合に推奨されます。また、自分で定義した特別な区切り文字を使用することもできます。',
generalTip: '一般的なテキストチャンクモードでは、取得されたチャンクとリコールされたチャンクは同じです。',
previewChunk: 'プレビューチャンク',
parentChunkForContext: 'コンテキストの親チャンク',
notAvailableForQA: 'Q&Aインデックスでは使用できません',
paragraph: '段落',
notAvailableForParentChild: '親子インデックスでは使用できません',
fullDocTip: 'ドキュメント全体が親チャンクとして使用され、直接取得されます。パフォーマンス上の理由から、10000トークンを超えるテキストは自動的に切り捨てられることに注意してください。',
previewChunkCount: '{{カウント}}推定チャンク',
paragraphTip: 'このモードでは、区切り記号とチャンクの最大長に基づいてテキストを段落に分割し、分割されたテキストを取得用の親チャンクとして使用します。',
highQualityTip: '高品質モードでの埋め込みが完了すると、経済モードに戻すことはできません。',
parentChildTip: '親子モードを使用する場合、子チャンクは取得に使用され、親チャンクはコンテキストとしての再呼び出しに使用されます。',
},
stepThree: {
creationTitle: '🎉 ナレッジが作成されました',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'jina.ai からの API キー',
configJinaReader: 'Jina Readerの設定',
},
otherDataSource: {
description: '現在、Difyのナレッジベースには限られたデータソースしかありません。データソースをDifyナレッジベースに投稿することは、すべてのユーザーにとってプラットフォームの柔軟性とパワーを向上させるのに役立つ素晴らしい方法です。私たちのコントリビューションガイドは、簡単に始めることができます。詳細については、以下のリンクをクリックしてください。',
title: '他のデータソースに接続しますか?',
learnMore: '詳細情報',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'アップロード時間',
status: 'ステータス',
action: 'アクション',
chunkingMode: 'チャンクモード',
},
rename: '名前を変更',
name: '名前',
@ -77,6 +78,7 @@ const translation = {
error: 'インポートエラー',
ok: 'OK',
},
learnMore: '詳細情報',
},
metadata: {
title: 'メタデータ',
@ -328,6 +330,10 @@ const translation = {
automatic: '自動',
custom: 'カスタム',
previewTip: '埋め込みが完了した後、段落のプレビューが利用可能になります',
parentMaxTokens: '親',
hierarchical: '親子',
pause: '休止',
childMaxTokens: '子供',
},
segment: {
paragraphs: '段落',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: '新しいテキストセグメント',
newQaSegment: '新しいQ&Aセグメント',
delete: 'このチャンクを削除しますか?',
searchResults_other: '業績',
edited: '編集',
parentChunk: '親チャンク',
regeneratingTitle: '子チャンクの再生成',
collapseChunks: 'チャンクの折りたたみ',
characters_other: '文字',
childChunk: '子チャンク',
regenerationSuccessMessage: 'このウィンドウは閉じることができます。',
editChildChunk: '子チャンクの編集',
clearFilter: 'フィルターをクリア',
chunkDetail: 'チャンクの詳細',
regenerationSuccessTitle: '再生完了',
parentChunks_one: '親チャンク',
newChunk: '新しいチャンク',
childChunks_other: '子チャンク',
searchResults_zero: '結果',
addChildChunk: '子チャンクを追加',
searchResults_one: '結果',
regeneratingMessage: 'これには少し時間がかかる場合がありますので、お待ちください...',
empty: 'チャンクが見つかりません',
editedAt: 'で編集',
addAnother: '別のものを追加',
chunkAdded: '1チャンク追加',
childChunks_one: '子チャンク',
regenerationConfirmMessage: '子チャンクを再生成すると、編集されたチャンクや新しく追加されたチャンクなど、現在の子チャンクが上書きされます。再生は元に戻せません。',
newChildChunk: '新しい子チャンク',
childChunkAdded: '子チャンクが1つ追加',
regenerationConfirmTitle: '子チャンクを再生成しますか?',
expandChunks: 'チャンクの展開',
chunks_one: 'チャンク',
editChunk: 'チャンクの編集',
editParentChunk: '親チャンクの編集',
parentChunks_other: '親チャンク',
characters_one: '文字',
chunks_other: 'チャンク',
addChunk: 'チャンクを追加',
chunk: 'チャンク',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'ベクトルチャートを表示',
settingTitle: '取得設定',
viewDetail: '詳細を表示',
records: '誌',
hitChunks: '{{num}}子チャンクをヒット',
open: '開ける',
keyword: 'キーワード',
chunkDetail: 'チャンクの詳細',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeID: '外部ナレッジID',
retrievalSettings: '取得設定',
externalKnowledgeAPI: '外部ナレッジAPI',
upgradeHighQualityTip: 'ハイクオリティモードにアップグレードすると、エコノミーモードに戻すことはできません',
indexMethodChangeToEconomyDisabledTip: '本社からECOへのダウングレードは対象外です',
helpText: '適切なデータセットの説明を書く方法を学びます。',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
externalKnowledgeDescriptionPlaceholder: 'このナレッジベースの内容を説明する(オプション)',
allExternalTip: '外部ナレッジのみを使用する場合、ユーザーは Rerank モデルを有効にするかどうかを選択できます。有効にしない場合、取得されたチャンクはスコアに基づいて並べ替えられます。異なるナレッジベースの検索戦略に一貫性がない場合、不正確になります。',
externalAPIPanelDescription: '外部ナレッジAPIは、Difyの外部のナレッジベースに接続し、そのナレッジベースからナレッジを取得するために使用されます。',
chunkingMode: {
general: '全般',
parentChild: '親子',
},
parentMode: {
fullDoc: 'フルドキュメント',
paragraph: '段落',
},
batchAction: {
delete: '削除',
selected: '入選',
archive: 'アーカイブ',
enable: 'エネーブル',
disable: '無効にする',
cancel: 'キャンセル',
},
documentsDisabled: '{{num}}ドキュメントが無効 - 30日以上非アクティブ',
localDocs: 'ローカルドキュメント',
enable: 'エネーブル',
preprocessDocument: '{{数値}}ドキュメントの前処理',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: '확대',
copyImage: '이미지 복사',
zoomOut: '축소',
close: '닫다',
viewMore: '더보기',
regenerate: '재생성',
view: '보기',
saveAndRegenerate: '저장 및 자식 청크 재생성',
},
placeholder: {
input: '입력해주세요',
@ -470,6 +475,7 @@ const translation = {
emptyTip: '연결된 지식이 없습니다. 애플리케이션 또는 플러그인으로 이동하여 연결을 완료하세요.',
viewDoc: '문서 보기',
relatedApp: '관련 앱',
noRelatedApp: '연결된 앱 없음',
},
voiceInput: {
speaking: '지금 말하고 있습니다...',

View File

@ -82,6 +82,7 @@ const translation = {
jinaReaderNotConfigured: 'Jina Reader가 구성되지 않았습니다.',
useSitemapTooltip: '사이트맵을 따라 사이트를 크롤링합니다. 그렇지 않은 경우 Jina Reader는 페이지 관련성에 따라 반복적으로 크롤링하여 더 적지만 더 높은 품질의 페이지를 생성합니다.',
},
cancel: '취소',
},
stepTwo: {
segmentation: '청크 설정',
@ -143,6 +144,28 @@ const translation = {
websiteSource: '웹 사이트 전처리',
separatorTip: '구분 기호는 텍스트를 구분하는 데 사용되는 문자입니다. \\n\\n 및 \\n은 단락과 줄을 구분하는 데 일반적으로 사용되는 구분 기호입니다. 쉼표(\\n\\n,\\n)와 함께 사용하면 최대 청크 길이를 초과할 경우 단락이 줄로 분할됩니다. 직접 정의한 특수 구분 기호(예: ***)를 사용할 수도 있습니다.',
maxLengthCheck: '최대 청크 길이는 {{limit}} 미만이어야 합니다.',
childChunkForRetrieval: '검색을 위한 자식 청크',
qaSwitchHighQualityTipContent: '현재 고품질 인덱스 방법만 Q&A 형식 청크를 지원합니다. 고화질 모드로 전환하시겠습니까?',
previewChunkTip: '왼쪽의 \'Preview Chunk\' 버튼을 클릭하여 프리뷰를 로드합니다',
general: '일반',
fullDoc: '전체 문서',
previewChunk: '프리뷰 청크(Preview Chunk)',
parentChunkForContext: '컨텍스트에 대한 Parent-chunk',
parentChildDelimiterTip: '구분 기호는 텍스트를 구분하는 데 사용되는 문자입니다. \\n\\n은 원본 문서를 큰 부모 청크로 분할하는 데 권장됩니다. 직접 정의한 특수 구분 기호를 사용할 수도 있습니다.',
paragraph: '단락',
parentChild: '부모-자식',
useQALanguage: 'Q&A 형식을 사용하는 청크',
highQualityTip: '고품질 모드에서 삽입을 마치면 경제적 모드로 되돌릴 수 없습니다.',
notAvailableForQA: 'Q&A 인덱스에는 사용할 수 없습니다.',
qaSwitchHighQualityTipTitle: 'Q&A 형식에는 고품질 인덱싱 방법이 필요합니다.',
notAvailableForParentChild: '부모-자식 인덱스에는 사용할 수 없습니다.',
previewChunkCount: '{{개수}} 추정된 청크',
parentChildTip: '부모-자식 모드를 사용할 때 자식 청크는 검색에 사용되고 부모 청크는 컨텍스트로 회수에 사용됩니다.',
generalTip: '일반적인 텍스트 청크 모드에서는 검색된 청크와 회수된 청크가 동일합니다.',
fullDocTip: '전체 문서가 상위 청크로 사용되며 직접 검색됩니다. 성능상의 이유로 10000 토큰을 초과하는 텍스트는 자동으로 잘립니다.',
parentChildChunkDelimiterTip: '구분 기호는 텍스트를 구분하는 데 사용되는 문자입니다. \\n 은 부모 청크를 작은 자식 청크로 분할하는 데 권장됩니다. 직접 정의한 특수 구분 기호를 사용할 수도 있습니다.',
switch: '스위치',
paragraphTip: '이 모드는 구분 기호와 최대 청크 길이에 따라 텍스트를 단락으로 분할하며, 분할된 텍스트를 검색을 위한 부모 청크로 사용합니다.',
},
stepThree: {
creationTitle: '🎉 지식이 생성되었습니다',
@ -172,6 +195,11 @@ const translation = {
getApiKeyLinkText: 'jina.ai 에서 무료 API 키 받기',
configJinaReader: 'Jina Reader 구성',
},
otherDataSource: {
learnMore: '더 알아보세요',
title: '다른 데이터 소스에 연결하시겠습니까?',
description: '현재 Dify의 기술 자료에는 제한된 데이터 소스만 있습니다. Dify 기술 자료에 데이터 소스를 제공하는 것은 모든 사용자를 위해 플랫폼의 유연성과 기능을 향상시키는 데 도움이 되는 환상적인 방법입니다. 기여 가이드를 통해 쉽게 시작할 수 있습니다. 자세한 내용은 아래 링크를 클릭하십시오.',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: '업로드 시간',
status: '상태',
action: '동작',
chunkingMode: '청크 모드',
},
name: '이름',
rename: '이름 바꾸기',
@ -77,6 +78,7 @@ const translation = {
ok: '확인',
},
addUrl: 'URL 추가',
learnMore: '더 알아보세요',
},
metadata: {
title: '메타데이터',
@ -327,6 +329,10 @@ const translation = {
automatic: '자동',
custom: '사용자 정의',
previewTip: '임베딩이 완료된 후에 세그먼트 미리보기를 사용할 수 있습니다',
childMaxTokens: '아이',
parentMaxTokens: '부모',
pause: '일시 중지',
hierarchical: '부모-자식',
},
segment: {
paragraphs: '단락',
@ -345,6 +351,43 @@ const translation = {
newTextSegment: '새로운 텍스트 세그먼트',
newQaSegment: '새로운 Q&A 세그먼트',
delete: '이 청크를 삭제하시겠습니까?',
parentChunks_one: '부모 청크(PARENT CHUNK)',
newChunk: '새 청크',
addChildChunk: '자손 청크 추가(Add Child Chunk)',
editChildChunk: '자손 청크 편집(Edit Child Chunk)',
chunkDetail: '청크 디테일(Chunk Detail)',
editChunk: '청크 편집(Edit Chunk)',
regeneratingTitle: '자식 청크 재생성',
newChildChunk: '새 자손 청크(New Child Chunk)',
childChunkAdded: '자식 청크 1개 추가됨',
chunk: '덩어리',
searchResults_zero: '결과',
empty: '청크를 찾을 수 없습니다.',
editParentChunk: '부모 청크 편집(Edit Parent Chunk)',
chunks_one: '덩어리',
regenerationSuccessMessage: '이 창을 닫을 수 있습니다.',
childChunks_one: '자식 청크(CHILD CHUNK)',
regenerationSuccessTitle: '재생이 완료되었습니다.',
editedAt: '편집 위치',
addAnother: '다른 항목 추가',
chunkAdded: '청크 1개 추가됨',
searchResults_one: '결과',
searchResults_other: '결과',
regenerationConfirmMessage: '자식 청크를 다시 생성하면 편집된 청크와 새로 추가된 청크를 포함하여 현재 자식 청크를 덮어씁니다. 재생성은 취소할 수 없습니다.',
regenerationConfirmTitle: '자식 청크를 다시 생성하시겠습니까?',
clearFilter: '필터 지우기',
characters_one: '문자',
parentChunk: '부모-청크',
expandChunks: '청크 확장',
collapseChunks: '청크 축소',
parentChunks_other: '부모 청크(PARENT CHUNKS)',
childChunk: '자식 청크',
childChunks_other: '자식 청크',
chunks_other: '청크',
edited: '편집',
addChunk: '청크 추가(Add Chunk)',
characters_other: '문자',
regeneratingMessage: '시간이 걸릴 수 있으니 잠시만 기다려 주십시오...',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: '벡터 차트 보기',
settingTitle: '검색 설정',
viewDetail: '자세히보기',
open: '열다',
records: '레코드',
hitChunks: '{{num}}개의 자식 청크를 히트했습니다.',
keyword: '키워드',
chunkDetail: '청크 디테일(Chunk Detail)',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeAPI: '외부 지식 API',
externalKnowledgeID: '외부 지식 ID',
retrievalSettings: '검색 설정',
upgradeHighQualityTip: '고품질 모드로 업그레이드한 후에는 경제적 모드로 되돌릴 수 없습니다.',
indexMethodChangeToEconomyDisabledTip: 'HQ에서 ECO로 다운그레이드할 수 없습니다.',
helpText: '좋은 데이터 세트 설명을 작성하는 방법을 알아보세요.',
},
}

View File

@ -145,6 +145,26 @@ const translation = {
allExternalTip: '외부 지식만 사용하는 경우 사용자는 리랭크 모델을 사용할지 여부를 선택할 수 있습니다. 활성화하지 않으면 검색된 청크가 점수에 따라 정렬됩니다. 서로 다른 기술 자료의 검색 전략이 일관되지 않으면 부정확합니다.',
externalAPIPanelDescription: '외부 지식 API는 Dify 외부의 기술 자료에 연결하고 해당 기술 자료에서 지식을 검색하는 데 사용됩니다.',
noExternalKnowledge: '아직 외부 지식 API가 없으므로 여기를 클릭하여 생성하십시오.',
chunkingMode: {
parentChild: '부모-자식',
general: '일반',
},
parentMode: {
fullDoc: '전체 문서',
paragraph: '단락',
},
batchAction: {
delete: '삭제하다',
enable: '사용',
cancel: '취소',
archive: '보관',
selected: '선택한',
disable: '비활성화',
},
localDocs: '로컬 문서',
preprocessDocument: '{{숫자}} 문서 전처리',
enable: '사용',
documentsDisabled: '{{num}} 문서 사용 안 함 - 30일 이상 비활성 상태',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
openInNewTab: 'Otwórz w nowej karcie',
zoomIn: 'Powiększenie',
zoomOut: 'Pomniejszanie',
saveAndRegenerate: 'Zapisywanie i regeneracja fragmentów podrzędnych',
view: 'Widok',
regenerate: 'Ponownie wygenerować',
viewMore: 'ZOBACZ WIĘCEJ',
close: 'Zamykać',
},
placeholder: {
input: 'Proszę wprowadzić',
@ -489,6 +494,7 @@ const translation = {
'Wiedza nie została powiązana, przejdź do aplikacji lub wtyczki, aby ukończyć powiązanie.',
viewDoc: 'Zobacz dokumentację',
relatedApp: 'powiązane aplikacje',
noRelatedApp: 'Brak połączonych aplikacji',
},
voiceInput: {
speaking: 'Mów teraz...',

View File

@ -83,6 +83,7 @@ const translation = {
jinaReaderTitle: 'Konwertowanie całej witryny na język Markdown',
jinaReaderNotConfiguredDescription: 'Skonfiguruj Jina Reader, wprowadzając bezpłatny klucz API, aby uzyskać dostęp.',
},
cancel: 'Anuluj',
},
stepTwo: {
segmentation: 'Ustawienia bloków tekstu',
@ -156,6 +157,28 @@ const translation = {
websiteSource: 'Witryna internetowa przetwarzania wstępnego',
separatorTip: 'Ogranicznik to znak używany do oddzielania tekstu. \\n\\n i \\n są powszechnie używanymi ogranicznikami do oddzielania akapitów i wierszy. W połączeniu z przecinkami (\\n\\n,\\n), akapity będą segmentowane wierszami po przekroczeniu maksymalnej długości fragmentu. Możesz również skorzystać ze zdefiniowanych przez siebie specjalnych ograniczników (np. ***).',
maxLengthCheck: 'Maksymalna długość porcji powinna być mniejsza niż {{limit}}',
parentChunkForContext: 'Fragment nadrzędny dla kontekstu',
generalTip: 'Ogólny tryb fragmentowania tekstu, fragmenty pobierane i odwoływane są takie same.',
parentChildDelimiterTip: 'Ogranicznik to znak używany do oddzielania tekstu. \\n\\n jest zalecane do dzielenia oryginalnego dokumentu na duże fragmenty nadrzędne. Możesz również użyć specjalnych ograniczników zdefiniowanych przez siebie.',
switch: 'Przełącznik',
parentChildChunkDelimiterTip: 'Ogranicznik to znak używany do oddzielania tekstu. \\n jest zalecane do dzielenia fragmentów nadrzędnych na małe fragmenty podrzędne. Możesz również użyć specjalnych ograniczników zdefiniowanych przez siebie.',
paragraphTip: 'W tym trybie tekst jest dzielony na akapity na podstawie ograniczników i maksymalnej długości fragmentu, używając podzielonego tekstu jako fragmentu nadrzędnego do pobierania.',
general: 'Ogólne',
notAvailableForQA: 'Niedostępne dla indeksu pytań i odpowiedziNot available for Q&A Index',
childChunkForRetrieval: 'Fragment podrzędny do pobrania',
fullDoc: 'Pełna wersja dokumentu',
fullDocTip: 'Cały dokument jest używany jako fragment nadrzędny i pobierany bezpośrednio. Należy pamiętać, że ze względu na wydajność, tekst przekraczający 10000 tokenów zostanie automatycznie obcięty.',
previewChunkCount: '{{liczba}} Szacowane porcje',
paragraph: 'Akapit',
parentChild: 'Rodzic-dziecko',
previewChunk: 'Fragment podglądu',
notAvailableForParentChild: 'Niedostępne dla indeksu nadrzędny-podrzędny',
highQualityTip: 'Po zakończeniu osadzania w trybie wysokiej jakości powrót do trybu ekonomicznego nie jest dostępny.',
previewChunkTip: 'Kliknij przycisk "Podgląd fragmentu" po lewej stronie, aby załadować podgląd',
qaSwitchHighQualityTipContent: 'Obecnie tylko metoda indeksu wysokiej jakości obsługuje fragmentowanie formatu pytań i odpowiedzi. Czy chcesz przełączyć się w tryb wysokiej jakości?',
useQALanguage: 'Fragment przy użyciu formatu Q&A w',
parentChildTip: 'W przypadku korzystania z trybu nadrzędny-podrzędny fragment podrzędny jest używany do pobierania, a fragment nadrzędny jest używany do przywoływania jako kontekstu.',
qaSwitchHighQualityTipTitle: 'Format Q&A wymaga metody indeksowania wysokiej jakości',
},
stepThree: {
creationTitle: '🎉 Utworzono Wiedzę',
@ -187,6 +210,11 @@ const translation = {
apiKeyPlaceholder: 'Klucz API od jina.ai',
configJinaReader: 'Konfiguracja czytnika Jina',
},
otherDataSource: {
learnMore: 'Dowiedz się więcej',
title: 'Połączyć się z innymi źródłami danych?',
description: 'Obecnie baza wiedzy Dify ma tylko ograniczone źródła danych. Dodanie źródła danych do bazy wiedzy Dify to fantastyczny sposób na zwiększenie elastyczności i możliwości platformy dla wszystkich użytkowników. Nasz przewodnik po wkładach ułatwia rozpoczęcie pracy. Kliknij poniższy link, aby dowiedzieć się więcej.',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: 'CZAS WGRANIA',
status: 'STATUS',
action: 'AKCJA',
chunkingMode: 'TRYB CHUNKINGU',
},
name: 'Nazwa',
rename: 'Przemianować',
@ -78,6 +79,7 @@ const translation = {
ok: 'OK',
},
addUrl: 'Dodaj adres URL',
learnMore: 'Dowiedz się więcej',
},
metadata: {
title: 'Metadane',
@ -329,6 +331,10 @@ const translation = {
automatic: 'Automatyczny',
custom: 'Niestandardowy',
previewTip: 'Podgląd akapitu będzie dostępny po zakończeniu osadzania',
parentMaxTokens: 'Rodzic',
hierarchical: 'Rodzic-dziecko',
childMaxTokens: 'Dziecko',
pause: 'Pauza',
},
segment: {
paragraphs: 'Akapity',
@ -347,6 +353,43 @@ const translation = {
newTextSegment: 'Nowy segment tekstowy',
newQaSegment: 'Nowy segment Q&A',
delete: 'Usunąć ten fragment?',
parentChunks_one: 'FRAGMENT NADRZĘDNY',
parentChunks_other: 'FRAGMENTY NADRZĘDNE',
searchResults_one: 'WYNIK',
chunk: 'Kawał',
parentChunk: 'Fragment nadrzędny',
characters_other: 'Znaków',
addChunk: 'Dodaj kawałek',
addChildChunk: 'Dodaj fragment podrzędny',
addAnother: 'Dodaj kolejny',
childChunkAdded: 'Dodano 1 fragment podrzędny',
editChunk: 'Edytuj fragment',
regenerationSuccessTitle: 'Regeneracja zakończona',
edited: 'EDYTOWANE',
editedAt: 'Zredagowane w',
collapseChunks: 'Zwijanie fragmentów',
empty: 'Nie znaleziono fragmentu',
newChunk: 'Nowy fragment',
regenerationConfirmTitle: 'Czy chcesz zregenerować fragmenty podrzędne?',
chunks_other: 'KAWAŁKI',
editChildChunk: 'Edytuj fragment podrzędny',
characters_one: 'znak',
regeneratingMessage: 'To może chwilę potrwać, proszę czekać...',
chunkDetail: 'Szczegóły kawałka',
chunkAdded: 'Dodano 1 kawałek',
regeneratingTitle: 'Regenerowanie fragmentów podrzędnych',
childChunks_other: 'FRAGMENTY POTOMNE',
expandChunks: 'Rozwijanie fragmentów',
childChunk: 'Fragment podrzędny',
regenerationConfirmMessage: 'Ponowne wygenerowanie fragmentów podrzędnych spowoduje zastąpienie bieżących fragmentów podrzędnych, w tym fragmentów edytowanych i nowo dodanych fragmentów. Regeneracji nie można cofnąć.',
regenerationSuccessMessage: 'Możesz zamknąć to okno.',
searchResults_other: 'WYNIKI',
searchResults_zero: 'WYNIK',
chunks_one: 'KAWAŁ',
editParentChunk: 'Edytuj fragment nadrzędny',
newChildChunk: 'Nowy fragment podrzędny',
clearFilter: 'Wyczyść filtr',
childChunks_one: 'FRAGMENT POTOMNY',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Zobacz WYKRES WEKTOROWY',
settingTitle: 'Ustawienie pobierania',
viewDetail: 'Pokaż szczegóły',
keyword: 'Słowa kluczowe',
hitChunks: 'Trafienie w {{num}} fragmentów podrzędnych',
open: 'Otwierać',
records: 'Rekordy',
chunkDetail: 'Szczegóły kawałka',
}
export default translation

View File

@ -37,6 +37,9 @@ const translation = {
externalKnowledgeAPI: 'Interfejs API wiedzy zewnętrznej',
retrievalSettings: 'Ustawienia pobierania',
externalKnowledgeID: 'Zewnętrzny identyfikator wiedzy',
helpText: 'Dowiedz się, jak napisać dobry opis zestawu danych.',
upgradeHighQualityTip: 'Po uaktualnieniu do trybu wysokiej jakości powrót do trybu ekonomicznego nie jest dostępny',
indexMethodChangeToEconomyDisabledTip: 'Niedostępne w przypadku zmiany z HQ na ECO',
},
}

View File

@ -152,6 +152,26 @@ const translation = {
learnHowToWriteGoodKnowledgeDescription: 'Dowiedz się, jak napisać dobry opis wiedzy',
externalKnowledgeNamePlaceholder: 'Podaj nazwę bazy wiedzy',
externalAPIPanelDescription: 'Interfejs API wiedzy zewnętrznej służy do łączenia się z bazą wiedzy poza Dify i pobierania wiedzy z tej bazy wiedzy.',
chunkingMode: {
parentChild: 'Rodzic-dziecko',
general: 'Ogólne',
},
parentMode: {
fullDoc: 'Pełna wersja dokumentu',
paragraph: 'Akapit',
},
batchAction: {
selected: 'Wybrany',
archive: 'Archiwum',
enable: 'Umożliwiać',
disable: 'Wyłączać',
delete: 'Usunąć',
cancel: 'Anuluj',
},
preprocessDocument: '{{liczba}} Przetwarzanie wstępne dokumentów',
localDocs: 'Lokalne dokumenty',
documentsDisabled: '{{num}} dokumenty wyłączone - nieaktywne przez ponad 30 dni',
enable: 'Umożliwiać',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomIn: 'Ampliar',
copyImage: 'Copiar imagem',
openInNewTab: 'Abrir em nova guia',
viewMore: 'VER MAIS',
regenerate: 'Regenerar',
close: 'Fechar',
saveAndRegenerate: 'Salvar e regenerar pedaços filhos',
view: 'Vista',
},
placeholder: {
input: 'Por favor, insira',
@ -474,6 +479,7 @@ const translation = {
emptyTip: 'O Conhecimento não foi associado, por favor, vá para o aplicativo ou plug-in para completar a associação.',
viewDoc: 'Ver documentação',
relatedApp: 'aplicativos relacionados',
noRelatedApp: 'Nenhum aplicativo vinculado',
},
voiceInput: {
speaking: 'Fale agora...',

View File

@ -82,6 +82,7 @@ const translation = {
useSitemapTooltip: 'Siga o mapa do site para rastrear o site. Caso contrário, o Jina Reader rastreará iterativamente com base na relevância da página, produzindo menos páginas, mas de maior qualidade.',
jinaReaderTitle: 'Converter todo o site em Markdown',
},
cancel: 'Cancelar',
},
stepTwo: {
segmentation: 'Configurações de fragmentação',
@ -143,6 +144,28 @@ const translation = {
webpageUnit: 'Páginas',
separatorTip: 'Um delimitador é o caractere usado para separar o texto. \\n\\n e \\n são delimitadores comumente usados para separar parágrafos e linhas. Combinado com vírgulas (\\n\\n,\\n), os parágrafos serão segmentados por linhas ao exceder o comprimento máximo do bloco. Você também pode usar delimitadores especiais definidos por você (por exemplo, ***).',
maxLengthCheck: 'O comprimento máximo do chunk deve ser inferior a {{limit}}',
parentChildDelimiterTip: 'Um delimitador é o caractere usado para separar o texto. \\n\\n é recomendado para dividir o documento original em grandes partes pai. Você também pode usar delimitadores especiais definidos por você.',
parentChildChunkDelimiterTip: 'Um delimitador é o caractere usado para separar o texto. \\n é recomendado para dividir partes pai em pequenas partes filhas. Você também pode usar delimitadores especiais definidos por você.',
notAvailableForQA: 'Não disponível para o Índice de P e R',
parentChild: 'Pai-filho',
general: 'Geral',
qaSwitchHighQualityTipTitle: 'O formato de perguntas e respostas requer um método de indexação de alta qualidade',
parentChunkForContext: 'Parte-pai para contexto',
switch: 'Interruptor',
fullDoc: 'Doc completo',
qaSwitchHighQualityTipContent: 'Atualmente, apenas o método de índice de alta qualidade dá suporte ao agrupamento no formato Q&A. Gostaria de mudar para o modo de alta qualidade?',
childChunkForRetrieval: 'Filho-pedaço para recuperação',
useQALanguage: 'Chunk usando o formato de perguntas e respostas em',
previewChunk: 'Visualizar parte',
notAvailableForParentChild: 'Não disponível para Índice pai-filho',
paragraph: 'Parágrafo',
parentChildTip: 'Ao usar o modo pai-filho, o filho-chunk é usado para recuperação e o pai-chunk é usado para recall como contexto.',
generalTip: 'Modo de agrupamento de texto geral, os pedaços recuperados e recuperados são os mesmos.',
highQualityTip: 'Depois de concluir a incorporação no modo de alta qualidade, a reversão para o modo econômico não estará disponível.',
previewChunkTip: 'Clique no botão \'Preview Chunk\' à esquerda para carregar a visualização',
fullDocTip: 'O documento inteiro é usado como parte pai e recuperado diretamente. Observe que, por motivos de desempenho, o texto que exceder 10000 tokens será truncado automaticamente.',
paragraphTip: 'Esse modo divide o texto em parágrafos com base em delimitadores e no comprimento máximo da parte, usando o texto dividido como a parte pai para recuperação.',
previewChunkCount: '{{contagem}} Partes estimadas',
},
stepThree: {
creationTitle: '🎉 Conhecimento criado',
@ -171,6 +194,11 @@ const translation = {
configJinaReader: 'Configurar o Jina Reader',
apiKeyPlaceholder: 'Chave de API do jina.ai',
},
otherDataSource: {
learnMore: 'Saiba Mais',
description: 'Atualmente, a base de conhecimento da Dify possui apenas fontes de dados limitadas. Contribuir com uma fonte de dados para a base de conhecimento Dify é uma maneira fantástica de ajudar a aumentar a flexibilidade e o poder da plataforma para todos os usuários. Nosso guia de contribuição facilita o início. Clique no link abaixo para saber mais.',
title: 'Conectar-se a outras fontes de dados?',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: 'HORA DO UPLOAD',
status: 'STATUS',
action: 'AÇÃO',
chunkingMode: 'MODO DE FRAGMENTAÇÃO',
},
name: 'Nome',
rename: 'Renomear',
@ -77,6 +78,7 @@ const translation = {
ok: 'OK',
},
addUrl: 'Adicionar URL',
learnMore: 'Saiba Mais',
},
metadata: {
title: 'Metadados',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Automático',
custom: 'Personalizado',
previewTip: 'A visualização do parágrafo estará disponível após a incorporação ser concluída',
pause: 'Pausa',
hierarchical: 'Pai-filho',
parentMaxTokens: 'Pai',
childMaxTokens: 'Criança',
},
segment: {
paragraphs: 'Parágrafos',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Novo fragmento de texto',
newQaSegment: 'Novo fragmento de P&R',
delete: 'Excluir este fragmento?',
chunks_other: 'PEDAÇOS',
parentChunks_other: 'PARTES PAI',
childChunks_one: 'PEDAÇO FILHO',
searchResults_zero: 'RESULTADO',
searchResults_one: 'RESULTADO',
searchResults_other: 'RESULTADOS',
empty: 'Nenhum pedaço encontrado',
chunk: 'Pedaço',
newChunk: 'Novo pedaço',
childChunk: 'Pedaço filho',
characters_other: 'Caracteres',
addChunk: 'Adicionar pedaço',
addChildChunk: 'Adicionar pedaço filho',
addAnother: 'Adicionar outro',
editChunk: 'Editar Chunk',
editParentChunk: 'Editar parte pai',
editChildChunk: 'Editar parte filho',
regenerationConfirmTitle: 'Deseja regenerar partes filhas?',
regeneratingTitle: 'Regenerando partes filhas',
regeneratingMessage: 'Isso pode demorar um pouco, por favor aguarde...',
edited: 'EDIÇÃO',
editedAt: 'Editado em',
expandChunks: 'Expandir pedaços',
collapseChunks: 'Recolher partes',
regenerationConfirmMessage: 'A regeneração de partes filhas substituirá as partes filhas atuais, incluindo partes editadas e partes recém-adicionadas. A regeneração não pode ser desfeita.',
parentChunks_one: 'PEDAÇO PAI',
regenerationSuccessMessage: 'Você pode fechar esta janela.',
chunks_one: 'PEDAÇO',
childChunkAdded: '1 pedaço filho adicionado',
clearFilter: 'Limpar filtro',
regenerationSuccessTitle: 'Regeneração concluída',
chunkDetail: 'Detalhe do pedaço',
childChunks_other: 'PEDAÇOS FILHOS',
chunkAdded: '1 pedaço adicionado',
newChildChunk: 'Novo pedaço filho',
characters_one: 'personagem',
parentChunk: 'Pedaço pai',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Ver GRÁFICO DE VETORES',
viewDetail: 'Ver detalhes',
settingTitle: 'Configuração de recuperação',
records: 'Arquivo',
hitChunks: 'Hit {{num}} pedaços filhos',
open: 'Abrir',
chunkDetail: 'Detalhe do pedaço',
keyword: 'Palavras-chave',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
retrievalSettings: 'Configurações de recuperação',
externalKnowledgeID: 'ID de conhecimento externo',
externalKnowledgeAPI: 'API de conhecimento externo',
indexMethodChangeToEconomyDisabledTip: 'Não disponível para rebaixamento de HQ para ECO',
helpText: 'Aprenda a escrever uma boa descrição do conjunto de dados.',
upgradeHighQualityTip: 'Depois de atualizar para o modo de alta qualidade, reverter para o modo econômico não está disponível',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
learnHowToWriteGoodKnowledgeDescription: 'Aprenda a escrever uma boa descrição de conhecimento',
externalAPIPanelDocumentation: 'Saiba como criar uma API de conhecimento externo',
externalKnowledgeDescription: 'Descrição do Conhecimento',
chunkingMode: {
parentChild: 'Pai-filho',
general: 'Geral',
},
parentMode: {
fullDoc: 'Documento completo',
paragraph: 'Parágrafo',
},
batchAction: {
selected: 'Selecionado',
delete: 'Excluir',
enable: 'Habilitar',
archive: 'Arquivo',
disable: 'Desabilitar',
cancel: 'Cancelar',
},
documentsDisabled: '{{num}} documentos desativados - inativos por mais de 30 dias',
enable: 'Habilitar',
preprocessDocument: '{{num}} Documentos de pré-processamento',
localDocs: 'Documentos locais',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomOut: 'Micșorare',
openInNewTab: 'Deschide într-o filă nouă',
zoomIn: 'Măriți',
close: 'Închide',
viewMore: 'VEZI MAI MULT',
regenerate: 'Regenera',
saveAndRegenerate: 'Salvați și regenerați bucățile secundare',
view: 'Vedere',
},
placeholder: {
input: 'Vă rugăm să introduceți',
@ -474,6 +479,7 @@ const translation = {
emptyTip: 'Cunoștințele nu au fost asociate, vă rugăm să mergeți la aplicație sau la plug-in pentru a finaliza asocierea.',
viewDoc: 'Vizualizați documentația',
relatedApp: 'aplicații asociate',
noRelatedApp: 'Fără aplicații conectate',
},
voiceInput: {
speaking: 'Vorbiți acum...',

View File

@ -82,6 +82,7 @@ const translation = {
jinaReaderNotConfigured: 'Jina Reader nu este configurat',
useSitemapTooltip: 'Urmați harta site-ului pentru a accesa cu crawlere site-ul. Dacă nu, Jina Reader va accesa cu crawlere iterativ în funcție de relevanța paginii, producând mai puține pagini, dar de calitate superioară.',
},
cancel: 'Anula',
},
stepTwo: {
segmentation: 'Setări de segmentare',
@ -143,6 +144,28 @@ const translation = {
websiteSource: 'Site-ul web de preprocesare',
separatorTip: 'Un delimitator este caracterul folosit pentru a separa textul. \\n\\n și \\n sunt delimitatori utilizați în mod obișnuit pentru separarea paragrafelor și liniilor. Combinate cu virgule (\\n\\n,\\n), paragrafele vor fi segmentate pe linii atunci când depășesc lungimea maximă a bucății. De asemenea, puteți utiliza delimitatori speciali definiți de dumneavoastră (de exemplu, ***).',
maxLengthCheck: 'Lungimea maximă a bucății trebuie să fie mai mică de {{limit}}',
notAvailableForQA: 'Nu este disponibil pentru Indexul de întrebări și răspunsuri',
generalTip: 'Modul general de fragmentare a textului, bucățile recuperate și rechemate sunt aceleași.',
previewChunk: 'Previzualizare bucată',
previewChunkTip: 'Faceți clic pe butonul "Previzualizare bucată" din stânga pentru a încărca previzualizarea',
fullDoc: 'Documentul complet',
parentChildDelimiterTip: 'Un delimitator este caracterul folosit pentru a separa textul. \\n\\n este recomandat pentru împărțirea documentului original în bucăți părinte mari. De asemenea, puteți utiliza delimitatori speciali definiți de dvs.',
fullDocTip: 'Întregul document este folosit ca bucată părinte și preluat direct. Vă rugăm să rețineți că, din motive de performanță, textul care depășește 10000 de jetoane va fi trunchiat automat.',
switch: 'Comutator',
previewChunkCount: '{{număr}} Bucăți estimate',
parentChunkForContext: 'Părinte-bucată pentru context',
paragraph: 'Paragraf',
childChunkForRetrieval: 'Child-chunk pentru recuperare',
parentChild: 'Părinte-copil',
parentChildTip: 'Când utilizați modul părinte-copil, fragmentul copil este utilizat pentru recuperare, iar fragmentul părinte este utilizat pentru reamintire ca context.',
highQualityTip: 'După terminarea încorporarii în modul Înaltă calitate, revenirea la modul Economic nu este disponibilă.',
qaSwitchHighQualityTipTitle: 'Formatul de întrebări și răspunsuri necesită o metodă de indexare de înaltă calitate',
paragraphTip: 'Acest mod împarte textul în paragrafe pe baza delimitatorilor și a lungimii maxime a bucății, folosind textul împărțit ca bucată părinte pentru recuperare.',
general: 'General',
notAvailableForParentChild: 'Nu este disponibil pentru Indexul părinte-copil',
qaSwitchHighQualityTipContent: 'În prezent, numai metoda de index de înaltă calitate acceptă fragmentarea formatului de întrebări și răspunsuri. Doriți să treceți la modul de înaltă calitate?',
parentChildChunkDelimiterTip: 'Un delimitator este caracterul folosit pentru a separa textul. \\n este recomandat pentru împărțirea bucăților părinte în bucăți copii mici. De asemenea, puteți utiliza delimitatori speciali definiți de dvs.',
useQALanguage: 'Fragmentați folosind formatul Întrebări și răspunsuri în',
},
stepThree: {
creationTitle: '🎉 Cunoștință creată',
@ -171,6 +194,11 @@ const translation = {
apiKeyPlaceholder: 'Cheie API de la jina.ai',
getApiKeyLinkText: 'Obțineți cheia API gratuită la jina.ai',
},
otherDataSource: {
title: 'Conectați-vă la alte surse de date?',
description: 'În prezent, baza de cunoștințe a Dify are doar surse de date limitate. Contribuția cu o sursă de date la baza de cunoștințe Dify este o modalitate fantastică de a ajuta la îmbunătățirea flexibilității și puterii platformei pentru toți utilizatorii. Ghidul nostru de contribuție vă ajută să începeți. Vă rugăm să faceți clic pe linkul de mai jos pentru a afla mai multe.',
learnMore: 'Află mai multe',
},
}
export default translation

View File

@ -12,6 +12,7 @@ const translation = {
uploadTime: 'TIMP DE ÎNCĂRCARE',
status: 'STARE',
action: 'ACȚIUNE',
chunkingMode: 'MOD DE FRAGMENTARE',
},
name: 'Nume',
rename: 'Redenumire',
@ -77,6 +78,7 @@ const translation = {
ok: 'OK',
},
addUrl: 'Adăugați adresa URL',
learnMore: 'Află mai multe',
},
metadata: {
title: 'Metadate',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Automat',
custom: 'Personalizat',
previewTip: 'Previzualizarea paragrafului va fi disponibilă după finalizarea încorporării',
hierarchical: 'Părinte-copil',
childMaxTokens: 'Copil',
parentMaxTokens: 'Părinte',
pause: 'Pauză',
},
segment: {
paragraphs: 'Paragrafe',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Nou segment de text',
newQaSegment: 'Nou segment de întrebări și răspunsuri',
delete: 'Ștergeți acest fragment?',
searchResults_zero: 'REZULTAT',
searchResults_one: 'REZULTAT',
characters_other: 'Caractere',
chunkAdded: '1 bucată adăugată',
chunks_other: 'BUCĂŢI',
characters_one: 'caracter',
regenerationSuccessTitle: 'Regenerare finalizată',
editedAt: 'Editat la',
addChunk: 'Adăugați o bucată',
chunk: 'Bucată',
chunks_one: 'BUCATĂ',
empty: 'Nu s-a găsit nicio bucată',
expandChunks: 'Extindeți bucățile',
editParentChunk: 'Editați bucata părinte',
regenerationSuccessMessage: 'Puteți închide această fereastră.',
chunkDetail: 'Detalii bucăți',
childChunk: 'Bucată de copil',
edited: 'EDITATE',
childChunks_one: 'BUCATĂ COPIL',
childChunkAdded: '1 bucată de copil adăugată',
regenerationConfirmTitle: 'Doriți să regenerați bucățile copil?',
newChildChunk: 'Bucată copil nouă',
editChildChunk: 'Editați fragmentul copil',
childChunks_other: 'BUCĂȚI COPIL',
newChunk: 'Bucată nouă',
clearFilter: 'Ștergeți filtrul',
editChunk: 'Editați bucata',
addAnother: 'Adăugați altul',
parentChunks_other: 'BUCĂȚI PĂRINTE',
collapseChunks: 'Restrângerea bucăților',
parentChunk: 'Părinte-bucată',
regeneratingMessage: 'Acest lucru poate dura un moment, vă rugăm să așteptați...',
parentChunks_one: 'FRAGMENT PĂRINTE',
regenerationConfirmMessage: 'Regenerarea bucăților copii va suprascrie bucățile copil curente, inclusiv bucățile editate și bucățile nou adăugate. Regenerarea nu poate fi anulată.',
regeneratingTitle: 'Regenerarea bucăților secundare',
addChildChunk: 'Adăugați o bucată copil',
searchResults_other: 'REZULTATELE',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Vizualizați GRAFICUL VECTORIAL',
settingTitle: 'Setare de recuperare',
viewDetail: 'Vezi detalii',
keyword: 'Cuvinte cheie',
chunkDetail: 'Detalii bucăți',
open: 'Deschide',
hitChunks: 'Accesează {{num}} bucăți copil',
records: 'Înregistrări',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeID: 'ID de cunoștințe extern',
externalKnowledgeAPI: 'API de cunoștințe externe',
retrievalSettings: 'Setări de recuperare',
indexMethodChangeToEconomyDisabledTip: 'Nu este disponibil pentru retrogradarea de la HQ la ECO',
upgradeHighQualityTip: 'După ce faceți upgrade la modul Înaltă calitate, revenirea la modul Economic nu este disponibilă',
helpText: 'Aflați cum să scrieți o descriere bună a setului de date.',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
mixtureInternalAndExternalTip: 'Modelul Rerank este necesar pentru amestecul de cunoștințe interne și externe.',
externalAPIPanelDescription: 'API-ul de cunoștințe externe este utilizat pentru a se conecta la o bază de cunoștințe din afara Dify și pentru a prelua cunoștințe din acea bază de cunoștințe.',
createNewExternalAPI: 'Creați un nou API de cunoștințe externe',
chunkingMode: {
general: 'General',
parentChild: 'Părinte-copil',
},
parentMode: {
paragraph: 'Paragraf',
fullDoc: 'Documentar complet',
},
batchAction: {
enable: 'Activa',
cancel: 'Anula',
delete: 'Șterge',
disable: 'Dezactiva',
selected: 'Selectat',
archive: 'Arhivă',
},
documentsDisabled: '{{num}} documente dezactivate - inactive de peste 30 de zile',
preprocessDocument: '{{num}} Procesarea prealabilă a documentelor',
enable: 'Activa',
localDocs: 'Documente locale',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
zoomOut: 'Уменьшение масштаба',
openInNewTab: 'Открыть в новой вкладке',
copyImage: 'Скопировать изображение',
close: 'Закрывать',
regenerate: 'Регенерировать',
view: 'Вид',
viewMore: 'ПОДРОБНЕЕ',
saveAndRegenerate: 'Сохранение и повторное создание дочерних блоков',
},
errorMsg: {
fieldRequired: '{{field}} обязательно',
@ -478,6 +483,7 @@ const translation = {
emptyTip: 'Знания не были связаны, пожалуйста, перейдите в приложение или плагин, чтобы завершить связывание.',
viewDoc: 'Просмотреть документацию',
relatedApp: 'связанные приложения',
noRelatedApp: 'Нет связанных приложений',
},
voiceInput: {
speaking: 'Говорите сейчас...',

View File

@ -87,6 +87,7 @@ const translation = {
jinaReaderTitle: 'Конвертируйте весь сайт в Markdown',
useSitemapTooltip: 'Следуйте карте сайта, чтобы просканировать сайт. Если нет, Jina Reader будет сканировать итеративно в зависимости от релевантности страницы, выдавая меньшее количество страниц, но более высокого качества.',
},
cancel: 'Отмена',
},
stepTwo: {
segmentation: 'Настройки фрагментации',
@ -148,6 +149,28 @@ const translation = {
datasetSettingLink: 'настройки базы знаний.',
separatorTip: 'Разделитель — это символ, используемый для разделения текста. \\n\\n и \\n — это часто используемые разделители для разделения абзацев и строк. В сочетании с запятыми (\\n\\n,\\n) абзацы будут сегментированы по строкам, если максимальная длина блока превышает их. Вы также можете использовать специальные разделители, определенные вами (например, ***).',
maxLengthCheck: 'Максимальная длина блока должна быть меньше {{limit}}',
switch: 'Выключатель',
parentChunkForContext: 'Родительский блок для контекста',
previewChunkTip: 'Нажмите кнопку «Предварительный просмотр фрагмента» слева, чтобы загрузить предварительный просмотр',
notAvailableForParentChild: 'Недоступно для индекса типа "родитель-потомок"',
parentChildChunkDelimiterTip: 'Разделитель — это символ, используемый для разделения текста. \\n рекомендуется для разбиения родительских блоков на небольшие дочерние блоки. Вы также можете использовать специальные разделители, определенные самостоятельно.',
previewChunk: 'Предварительный просмотр фрагмента',
previewChunkCount: '{{Количество}} Предполагаемые куски',
generalTip: 'Общий режим фрагментации текста, извлекаемые и вызываемые фрагменты одинаковы.',
general: 'Общее',
useQALanguage: 'Фрагмент с использованием формата Q&A в',
notAvailableForQA: 'Недоступно для индекса Q&A',
paragraph: 'Параграф',
parentChild: 'Родитель-дочерний',
fullDoc: 'Полный документальный фильм',
qaSwitchHighQualityTipTitle: 'Формат вопросов и ответов требует высококачественного метода индексации',
parentChildDelimiterTip: 'Разделитель — это символ, используемый для разделения текста. \\n\\n рекомендуется для разделения исходного документа на большие родительские части. Вы также можете использовать специальные разделители, определенные самостоятельно.',
parentChildTip: 'При использовании режима «родитель-потомок» дочерний блок используется для извлечения, а родительский блок — для вызова в качестве контекста.',
paragraphTip: 'В этом режиме текст разбивается на абзацы на основе разделителей и максимальной длины блока, используя разделенный текст в качестве родительского блока для извлечения.',
highQualityTip: 'После завершения встраивания в режиме «Высокое качество» возврат к экономичному режиму невозможен.',
childChunkForRetrieval: 'Детский фрагмент для извлечения',
qaSwitchHighQualityTipContent: 'В настоящее время только высококачественный метод индекса поддерживает фрагментацию формата Q&A. Хотели бы вы перейти в режим высокого качества?',
fullDocTip: 'Весь документ используется в качестве родительского блока и извлекается напрямую. Обратите внимание, что по причинам производительности текст, превышающий 10000 токенов, будет автоматически обрезан.',
},
stepThree: {
creationTitle: '🎉 База знаний создана',
@ -171,6 +194,11 @@ const translation = {
configJinaReader: 'Настройка Jina Reader',
apiKeyPlaceholder: 'Ключ API от jina.ai',
},
otherDataSource: {
learnMore: 'Подробнее',
title: 'Подключаться к другим источникам данных?',
description: 'В настоящее время база знаний Dify имеет лишь ограниченные источники данных. Добавление источника данных в базу знаний Dify — это отличный способ повысить гибкость и возможности платформы для всех пользователей. Наше руководство по вкладу поможет вам легко начать работу. Пожалуйста, нажмите на ссылку ниже, чтобы узнать больше.',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'ВРЕМЯ ЗАГРУЗКИ',
status: 'СТАТУС',
action: 'ДЕЙСТВИЕ',
chunkingMode: 'РЕЖИМ ДРОБЛЕНИЯ',
},
rename: 'Переименовать',
name: 'Название',
@ -77,6 +78,7 @@ const translation = {
error: 'Ошибка импорта',
ok: 'ОК',
},
learnMore: 'Подробнее',
},
metadata: {
title: 'Метаданные',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Автоматически',
custom: 'Пользовательский',
previewTip: 'Предварительный просмотр абзацев будет доступен после завершения расчета эмбеддингов',
parentMaxTokens: 'Родитель',
childMaxTokens: 'Ребёнок',
hierarchical: 'Родитель-дочерний',
pause: 'Пауза',
},
segment: {
paragraphs: 'Абзацы',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Новый текстовый сегмент',
newQaSegment: 'Новый сегмент вопрос-ответ',
delete: 'Удалить этот фрагмент?',
chunks_other: 'КУСКИ',
searchResults_one: 'РЕЗУЛЬТАТ',
parentChunk: 'Родительский блок',
characters_other: 'письмена',
edited: 'ОТРЕДАКТИРОВАНЫ',
regenerationSuccessMessage: 'Вы можете закрыть это окно.',
searchResults_other: 'РЕЗУЛЬТАТЫ',
regeneratingTitle: 'Регенерация дочерних блоков',
parentChunks_one: 'РОДИТЕЛЬСКИЙ БЛОК',
childChunk: 'Чайлд-Чанк',
editedAt: 'Отредактировано в',
editChildChunk: 'Редактирование дочернего фрагмента',
parentChunks_other: 'РОДИТЕЛЬСКИЕ БЛОКИ',
regenerationSuccessTitle: 'Регенерация завершена',
childChunks_one: 'ДОЧЕРНИЙ ЧАНК',
newChunk: 'Новый чанк',
addAnother: 'Добавить еще один',
clearFilter: 'Очистить фильтр',
addChunk: 'Добавить чанк',
editParentChunk: 'Редактирование родительского блока',
chunkDetail: 'Деталь Чанка',
regenerationConfirmMessage: 'При повторном создании дочерних блоков текущие дочерние блоки будут перезаписаны, включая отредактированные и вновь добавленные блоки. Регенерацию нельзя отменить.',
collapseChunks: 'Сворачивание кусков',
regenerationConfirmTitle: 'Вы хотите регенерировать дочерние куски?',
searchResults_zero: 'РЕЗУЛЬТАТ',
childChunks_other: 'ДЕТСКИЕ КУСОЧКИ',
childChunkAdded: 'Добавлен 1 дочерний чанк',
editChunk: 'Редактировать фрагмент',
empty: 'Чанк не найден',
chunks_one: 'ЛОМОТЬ',
regeneratingMessage: 'Это может занять некоторое время, пожалуйста, подождите...',
chunkAdded: 'Добавлен 1 блок',
chunk: 'Ломоть',
expandChunks: 'Развернуть чанки',
characters_one: 'характер',
addChildChunk: 'Добавить дочерний чанк',
newChildChunk: 'Новый дочерний чанк',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
viewChart: 'Посмотреть ВЕКТОРНУЮ ДИАГРАММУ',
viewDetail: 'Подробнее',
settingTitle: 'Настройка извлечения',
records: 'Записи',
hitChunks: 'Попадание {{num}} дочерних чанков',
chunkDetail: 'Деталь Чанка',
open: 'Открытый',
keyword: 'Ключевые слова',
}
export default translation

View File

@ -32,6 +32,9 @@ const translation = {
externalKnowledgeAPI: 'API внешних знаний',
retrievalSettings: 'Настройки извлечения',
externalKnowledgeID: 'Внешний идентификатор базы знаний',
helpText: 'Узнайте, как написать хорошее описание набора данных.',
upgradeHighQualityTip: 'После обновления до режима «Высокое качество» возврат к экономичному режиму невозможен',
indexMethodChangeToEconomyDisabledTip: 'Недоступно для понижения уровня с HQ до ECO',
},
}

View File

@ -146,6 +146,26 @@ const translation = {
allExternalTip: 'При использовании только внешних знаний пользователь может выбрать, следует ли включать модель повторного ранжирования. Если этот параметр не включен, полученные фрагменты будут сортироваться на основе баллов. Когда стратегии извлечения из разных баз знаний несовместимы, они будут неточными.',
externalAPIPanelDocumentation: 'Узнайте, как создать API внешних знаний',
externalAPIPanelDescription: 'Внешний API базы знаний используется для подключения к базе знаний за пределами Dify и извлечения знаний из этой базы знаний.',
chunkingMode: {
general: 'Общее',
parentChild: 'Родитель-дочерний',
},
parentMode: {
fullDoc: 'Полный документ',
paragraph: 'Параграф',
},
batchAction: {
enable: 'Давать возможность',
delete: 'Удалить',
selected: 'Выбранный',
disable: 'Отключить',
cancel: 'Отмена',
archive: 'Архив',
},
preprocessDocument: '{{число}} Предварительная обработка документов',
documentsDisabled: 'Документы {{num}} отключены - неактивны более 30 дней',
localDocs: 'Местная документация',
enable: 'Давать возможность',
}
export default translation

View File

@ -42,6 +42,11 @@ const translation = {
openInNewTab: 'Odpri v novem zavihku',
zoomOut: 'Pomanjšanje',
zoomIn: 'Povečava',
saveAndRegenerate: 'Shranite in regenerirajte otroške koščke',
close: 'Blizu',
view: 'Pogled',
regenerate: 'Regeneracijo',
viewMore: 'POGLEJ VEČ',
},
errorMsg: {
fieldRequired: '{{field}} je obvezno',
@ -677,6 +682,7 @@ const translation = {
emptyTip: 'Znanje ni bilo povezano, prosimo, pojdite na aplikacijo ali vtičnik, da dokončate združenje.',
viewDoc: 'Oglejte si dokumentacijo',
relatedApp: 'Povezane aplikacije',
noRelatedApp: 'Brez povezanih aplikacij',
},
voiceInput: {
notAllow: 'Mikrofon ni pooblaščen',

View File

@ -92,6 +92,7 @@ const translation = {
preview: 'Predogled',
maxDepthTooltip: 'Največja globina iskanja glede na vneseni URL. Globina 0 bo iskala le stran z vnesenim URL-jem, globina 1 bo iskala URL in vse za tem, dodano z enim /, in tako naprej.',
},
cancel: 'Odpovedati',
},
stepTwo: {
segmentation: 'Nastavitve razdeljevanja',
@ -153,6 +154,28 @@ const translation = {
retrievalSettingTip: 'Če želite spremeniti nastavitve iskanja, pojdite na ',
datasetSettingLink: 'nastavitve Znanja.',
maxLengthCheck: 'Največja dolžina kosa mora biti manjša od {{limit}}',
fullDoc: 'Celoten dokument',
parentChildChunkDelimiterTip: 'Ločilo je znak, ki se uporablja za ločevanje besedila. \\n je priporočljivo za razdelitev starševskih kosov na majhne otroške koščke. Uporabite lahko tudi posebne ločila, ki ste jih določili sami.',
highQualityTip: 'Ko končate vdelavo v načinu visoke kakovosti, vrnitev v ekonomični način ni na voljo.',
parentChildTip: 'Ko uporabljate način nadreje-podrejenega, se podrejeni kos uporablja za pridobivanje, nadrejeni kos pa se uporablja za odpoklic kot kontekst.',
paragraph: 'Odstavek',
qaSwitchHighQualityTipTitle: 'Oblika zapisa vprašanj in odgovorov zahteva visokokakovostno metodo indeksiranja',
paragraphTip: 'Ta način razdeli besedilo na odstavke na podlagi ločil in največje dolžine kosa, pri čemer se razdeljeno besedilo uporabi kot nadrejeni kos za pridobivanje.',
parentChildDelimiterTip: 'Ločilo je znak, ki se uporablja za ločevanje besedila. \\n\\n je priporočljivo za razdelitev izvirnega dokumenta na velike nadrejene dele. Uporabite lahko tudi posebne ločila, ki ste jih določili sami.',
notAvailableForQA: 'Ni na voljo za indeks vprašanj in odgovorov',
parentChild: 'Starš-otrok',
parentChunkForContext: 'Nadrejeni kos za kontekst',
notAvailableForParentChild: 'Ni na voljo za indeks nadrejenega in podrejenega',
previewChunk: 'Predogled kosa',
previewChunkCount: '{{štetje}} Ocenjeni kosi',
previewChunkTip: 'Kliknite gumb »Predogled kosa« na levi, da naložite predogled',
fullDocTip: 'Celoten dokument je uporabljen kot nadrejeni kos in pridobljen neposredno. Upoštevajte, da bo zaradi uspešnosti besedilo, ki presega 10000 žetonov, samodejno prikrajšano.',
childChunkForRetrieval: 'Otroški kos za pridobivanje',
qaSwitchHighQualityTipContent: 'Trenutno samo visokokakovostna metoda indeksa podpira deljenje v obliki vprašanj in odgovorov. Želite preklopiti na kakovosten način?',
generalTip: 'Splošni način deljenja besedila, pridobljeni in odpoklicani kosi so enaki.',
useQALanguage: 'Delček z obliko zapisa vprašanj in odgovorov v',
general: 'Splošno',
switch: 'Stikalo',
},
stepThree: {
creationTitle: '🎉 Znanje ustvarjeno',
@ -171,6 +194,11 @@ const translation = {
modelButtonConfirm: 'Potrdi',
modelButtonCancel: 'Prekliči',
},
otherDataSource: {
learnMore: 'Izvedi več',
title: 'Vzpostavite povezavo z drugimi viri podatkov?',
description: 'Trenutno ima baza znanja Dify le omejene vire podatkov. Prispevanje vira podatkov v bazo znanja Dify je fantastičen način za izboljšanje prilagodljivosti in moči platforme za vse uporabnike. Naš vodnik za prispevke olajša začetek. Če želite izvedeti več, kliknite spodnjo povezavo.',
},
}
export default translation

View File

@ -13,6 +13,7 @@ const translation = {
uploadTime: 'ČAS NALAGANJA',
status: 'STATUS',
action: 'DEJANJE',
chunkingMode: 'NAČIN KOŠČENJA',
},
rename: 'Preimenuj',
name: 'Ime',
@ -77,6 +78,7 @@ const translation = {
error: 'Napaka pri uvozu',
ok: 'V redu',
},
learnMore: 'Izvedi več',
},
metadata: {
title: 'Metapodatki',
@ -328,6 +330,10 @@ const translation = {
automatic: 'Samodejno',
custom: 'Po meri',
previewTip: 'Predogled odstavkov bo na voljo po zaključku vdelave',
hierarchical: 'Starš-otrok',
childMaxTokens: 'Otrok',
pause: 'Pavza',
parentMaxTokens: 'Starš',
},
segment: {
paragraphs: 'Odstavki',
@ -346,6 +352,43 @@ const translation = {
newTextSegment: 'Nov besedilni segment',
newQaSegment: 'Nov Q&A segment',
delete: 'Izbriši ta del?',
regenerationSuccessTitle: 'Regeneracija končana',
expandChunks: 'Razširitev kosov',
childChunk: 'Otroški kos',
editedAt: 'Urejeno na',
edited: 'UREJATI',
addAnother: 'Dodajanje še enega',
childChunks_one: 'OTROŠKI KOS',
chunkDetail: 'Detajl koščka',
chunkAdded: 'Dodan 1 kos',
editChildChunk: 'Urejanje podrejenega kosa',
regenerationConfirmTitle: 'Ali želite regenerirati otroške koščke?',
empty: 'Ni najdenega koščka',
searchResults_other: 'REZULTATI',
childChunks_other: 'OTROŠKI KOŠČKI',
addChildChunk: 'Dodajanje podrejenega kosa',
editParentChunk: 'Urejanje nadrejenega kosa',
regenerationConfirmMessage: 'Obnavljanje podrejenih kosov bo prepisalo trenutne podrejene koščke, vključno z urejenimi koščki in na novo dodanimi kosi. Regeneracije ni mogoče razveljaviti.',
editChunk: 'Uredi kos',
chunks_one: 'KOS',
searchResults_one: 'REZULTAT',
parentChunks_one: 'STARŠEVSKI KOS',
characters_other: 'Znakov',
chunks_other: 'KOSE',
clearFilter: 'Počisti filter',
newChildChunk: 'Nov podzakonski kos',
characters_one: 'znak',
regeneratingTitle: 'Regeneracija otroških kosov',
regeneratingMessage: 'To lahko traja trenutek, prosim počakajte ...',
parentChunks_other: 'STARŠEVSKI KOSI',
collapseChunks: 'Strniti koščke',
parentChunk: 'Starševski kos',
regenerationSuccessMessage: 'To okno lahko zaprete.',
newChunk: 'Nov kos',
searchResults_zero: 'REZULTAT',
chunk: 'Kos',
addChunk: 'Dodajanje kosa',
childChunkAdded: 'Dodan je 1 kos otroka',
},
}

View File

@ -25,6 +25,11 @@ const translation = {
noRecentTip: 'Tukaj ni nedavnih rezultatov poizvedb',
viewChart: 'Prikaži VEKTORSKI GRAF',
viewDetail: 'Prikaži podrobnosti',
records: 'Zapisov',
keyword: 'Ključne besede',
chunkDetail: 'Detajl koščka',
open: 'Odprt',
hitChunks: 'Zadenite {{num}} podrejene koščke',
}
export default translation

Some files were not shown because too many files have changed in this diff Show More