Przeglądaj źródła

Fix/2969 add model provider ollama not work (#2973)

crazywoola 1 rok temu
rodzic
commit
eeaa3c1643

+ 3 - 3
web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx

@@ -161,7 +161,7 @@ const Form: FC<FormProps> = ({
                     flex justify-center items-center mr-2 w-4 h-4 border border-gray-300 rounded-full
                     ${value[variable] === option.value && 'border-[5px] border-primary-600'}
                   `} />
-                  <div className='text-sm text-gray-900'>{option.label[language]}</div>
+                  <div className='text-sm text-gray-900'>{option.label[language] || option.label.en_US}</div>
                 </div>
               ))
             }
@@ -206,9 +206,9 @@ const Form: FC<FormProps> = ({
                 return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)
 
               return true
-            }).map(option => ({ value: option.value, name: option.label[language] }))}
+            }).map(option => ({ value: option.value, name: option.label[language] || option.label.en_US }))}
             onSelect={item => handleFormChange(variable, item.value as string)}
-            placeholder={placeholder?.[language]}
+            placeholder={placeholder?.[language] || placeholder?.en_US}
           />
           {fieldMoreInfo?.(formSchema)}
           {validating && changeKey === variable && <ValidatingTip />}

+ 1 - 1
web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx

@@ -219,7 +219,7 @@ const ModelModal: FC<ModelModalProps> = ({
   const renderTitlePrefix = () => {
     const prefix = configurateMethod === ConfigurateMethodEnum.customizableModel ? t('common.operation.add') : t('common.operation.setup')
 
-    return `${prefix} ${provider.label[language]}`
+    return `${prefix} ${provider.label[language] || provider.label.en_US}`
   }
 
   return (

+ 3 - 3
web/app/components/header/account-setting/model-provider-page/provider-card/index.tsx

@@ -116,11 +116,11 @@ const ProviderCard: FC<ProviderCardProps> = ({
                 return (
                   <Button
                     key={method}
-                    className='h-7 bg-white text-xs text-gray-700'
+                    className={'h-7 bg-white text-xs text-gray-700 shrink-0'}
                     onClick={() => onOpenModal(method)}
                   >
-                    <Settings01 className='mr-[5px] w-3.5 h-3.5' />
-                    {t('common.operation.setup')}
+                    <Settings01 className={`mr-[5px] w-3.5 h-3.5 ${s.icon}`} />
+                    <span className='text-xs inline-flex items-center justify-center overflow-ellipsis shrink-0'>{t('common.operation.setup')}</span>
                   </Button>
                 )
               }

+ 1 - 1
web/app/components/header/account-setting/model-provider-page/provider-icon/index.tsx

@@ -25,7 +25,7 @@ const ProviderIcon: FC<ProviderIconProps> = ({
   return (
     <div className={`inline-flex items-center ${className}`}>
       <div className='text-xs font-semibold text-black'>
-        {provider.label[language]}
+        {provider.label[language] || provider.label.en_US}
       </div>
     </div>
   )

+ 256 - 96
web/i18n/pt-BR/common.ts

@@ -1,39 +1,210 @@
 const translation = {
-  you: '(Você)',
+  api: {
+    success: 'Sucesso',
+    actionSuccess: 'Ação bem-sucedida',
+    saved: 'Salvo',
+    create: 'Criado',
+    remove: 'Removido',
+  },
+  operation: {
+    create: 'Criar',
+    confirm: 'Confirmar',
+    cancel: 'Cancelar',
+    clear: 'Limpar',
+    save: 'Salvar',
+    edit: 'Editar',
+    add: 'Adicionar',
+    added: 'Adicionado',
+    refresh: 'Reiniciar',
+    reset: 'Redefinir',
+    search: 'Buscar',
+    change: 'Alterar',
+    remove: 'Remover',
+    send: 'Enviar',
+    copy: 'Copiar',
+    lineBreak: 'Quebra de linha',
+    sure: 'Tenho certeza',
+    download: 'Baixar',
+    delete: 'Excluir',
+    settings: 'Configurações',
+    setup: 'Configuração',
+    getForFree: 'Obter gratuitamente',
+    reload: 'Recarregar',
+    ok: 'OK',
+    log: 'Log',
+    learnMore: 'Saiba Mais',
+    params: 'Parâmetros',
+  },
+  placeholder: {
+    input: 'Por favor, insira',
+    select: 'Por favor, selecione',
+  },
+  voice: {
+    language: {
+      zhHans: 'Chinês',
+      enUS: 'Inglês',
+      deDE: 'Alemão',
+      frFR: 'Francês',
+      esES: 'Espanhol',
+      itIT: 'Italiano',
+      thTH: 'Tailandês',
+      idID: 'Indonésio',
+      jaJP: 'Japonês',
+      koKR: 'Coreano',
+      ptBR: 'Português',
+      ruRU: 'Russo',
+      ukUA: 'Ucraniano',
+    },
+  },
+  unit: {
+    char: 'caracteres',
+  },
+  actionMsg: {
+    noModification: 'Sem modificações no momento.',
+    modifiedSuccessfully: 'Modificado com sucesso',
+    modifiedUnsuccessfully: 'Modificado sem sucesso',
+    copySuccessfully: 'Copiado com sucesso',
+    paySucceeded: 'Pagamento realizado com sucesso',
+    payCancelled: 'Pagamento cancelado',
+    generatedSuccessfully: 'Gerado com sucesso',
+    generatedUnsuccessfully: 'Geração sem sucesso',
+  },
+  model: {
+    params: {
+      temperature: 'Temperatura',
+      temperatureTip:
+        'Controla a aleatoriedade: Diminuir resulta em conclusões menos aleatórias. À medida que a temperatura se aproxima de zero, o modelo se tornará determinístico e repetitivo.',
+      top_p: 'Top P',
+      top_pTip:
+        'Controla a diversidade via amostragem de núcleo: 0.5 significa que metade de todas as opções ponderadas por probabilidade são consideradas.',
+      presence_penalty: 'Penalidade de presença',
+      presence_penaltyTip:
+        'Quanto penalizar novos tokens com base em se eles aparecem no texto até agora.\nAumenta a probabilidade do modelo de falar sobre novos tópicos.',
+      frequency_penalty: 'Penalidade de frequência',
+      frequency_penaltyTip:
+        'Quanto penalizar novos tokens com base em sua frequência existente no texto até agora.\nDiminui a probabilidade do modelo de repetir a mesma linha textualmente.',
+      max_tokens: 'Máximo de tokens',
+      max_tokensTip:
+        'Usado para limitar o comprimento máximo da resposta, em tokens. \nValores maiores podem limitar o espaço restante para palavras de prompt, registros de bate-papo e Conhecimento. \nRecomenda-se defini-lo abaixo de dois terços\ngpt-4-1106-preview, gpt-4-vision-preview max token (entrada 128k saída 4k)',
+      maxTokenSettingTip: 'Sua configuração máxima de token é alta, limitando potencialmente o espaço para palavras de prompt, consultas e dados. Considere definir abaixo de 2/3.',
+      setToCurrentModelMaxTokenTip: 'O máximo de tokens é atualizado para 80% do máximo de token do modelo atual {{maxToken}}.',
+      stop_sequences: 'Sequências de parada',
+      stop_sequencesTip: 'Até quatro sequências onde a API irá parar de gerar mais tokens. O texto retornado não conterá a sequência de parada.',
+      stop_sequencesPlaceholder: 'Digite a sequência e pressione Tab',
+    },
+    tone: {
+      Creative: 'Criativo',
+      Balanced: 'Equilibrado',
+      Precise: 'Preciso',
+      Custom: 'Personalizado',
+    },
+    addMoreModel: 'Vá para configurações para adicionar mais modelos',
+  },
+  menus: {
+    status: 'beta',
+    explore: 'Explorar',
+    apps: 'Estúdio',
+    plugins: 'Plugins',
+    pluginsTips: 'Integre plugins de terceiros ou crie plugins de IA compatíveis com o ChatGPT.',
+    datasets: 'Conhecimento',
+    datasetsTips: 'EM BREVE: Importe seus próprios dados de texto ou escreva dados em tempo real via Webhook para aprimoramento do contexto LLM.',
+    newApp: 'Novo App',
+    newDataset: 'Criar Conhecimento',
+    tools: 'Ferramentas',
+  },
+  userProfile: {
+    settings: 'Configurações',
+    workspace: 'Espaço de trabalho',
+    createWorkspace: 'Criar Espaço de Trabalho',
+    helpCenter: 'Ajuda',
+    roadmapAndFeedback: 'Roadmap e Feedback',
+    community: 'Comunidade',
+    about: 'Sobre',
+    logout: 'Sair',
+  },
+  settings: {
+    accountGroup: 'CONTA',
+    workplaceGroup: 'ESPAÇO DE TRABALHO',
+    account: 'Minha conta',
+    members: 'Membros',
+    billing: 'Faturamento',
+    integrations: 'Integrações',
+    language: 'Idioma',
+    provider: 'Fornecedor de modelo',
+    dataSource: 'Fonte de dados',
+    plugin: 'Plugins',
+    apiBasedExtension: 'Extensão baseada em API',
+  },
+  account: {
+    avatar: 'Avatar',
+    name: 'Nome',
+    email: 'E-mail',
+    password: 'Senha',
+    passwordTip: 'Você pode definir uma senha permanente se não quiser usar códigos de login temporários',
+    setPassword: 'Definir uma senha',
+    resetPassword: 'Redefinir senha',
+    currentPassword: 'Senha atual',
+    newPassword: 'Nova senha',
+    confirmPassword: 'Confirmar senha',
+    notEqual: 'As duas senhas são diferentes.',
+    langGeniusAccount: 'Conta Dify',
+    langGeniusAccountTip: 'Sua conta Dify e dados de usuário associados.',
+    editName: 'Editar Nome',
+    showAppLength: 'Mostrar {{length}} apps',
+  },
+  members: {
+    team: 'Equipe',
+    invite: 'Adicionar',
+    name: 'NOME',
+    lastActive: 'ÚLTIMA ATIVIDADE',
+    role: 'FUNÇÕES',
+    pending: 'Pendente...',
+    owner: 'Proprietário',
+    admin: 'Admin',
+    adminTip: 'Pode criar aplicativos e gerenciar configurações da equipe',
+    normal: 'Normal',
+    normalTip: 'Só pode usar aplicativos, não pode criar aplicativos',
+    inviteTeamMember: 'Adicionar membro da equipe',
+    inviteTeamMemberTip: 'Eles podem acessar os dados da sua equipe diretamente após fazer login.',
+    email: 'E-mail',
+    emailInvalid: 'Formato de e-mail inválido',
+    emailPlaceholder: 'Por favor, insira e-mails',
+    sendInvite: 'Enviar Convite',
+    invitedAsRole: 'Convidado como usuário {{role}}',
+    invitationSent: 'Convite enviado',
+    invitationSentTip: 'Convite enviado e eles podem fazer login no Dify para acessar os dados da sua equipe.',
+    invitationLink: 'Link do Convite',
+    failedinvitationEmails: 'Os seguintes usuários não foram convidados com sucesso',
+    ok: 'OK',
+    removeFromTeam: 'Remover da equipe',
+    removeFromTeamTip: 'Removerá o acesso da equipe',
+    setAdmin: 'Definir como administrador',
+    setMember: 'Definir como membro comum',
+    disinvite: 'Cancelar o convite',
+    deleteMember: 'Excluir Membro',
+    you: '(Você)',
+  },
   integrations: {
     connected: 'Conectado',
     google: 'Google',
-    googleAccount: 'Entrar com conta do Google',
+    googleAccount: 'Faça login com a conta do Google',
     github: 'GitHub',
-    githubAccount: 'Entrar com conta do GitHub',
+    githubAccount: 'Faça login com a conta do GitHub',
     connect: 'Conectar',
   },
   language: {
     displayLanguage: 'Idioma de exibição',
     timezone: 'Fuso horário',
   },
-  voice: {
-    language: {
-      zhHans: 'chinês',
-      enUS: 'inglês',
-      deDE: 'alemão',
-      frFR: 'francês',
-      esES: 'espanhol',
-      itIT: 'italiano',
-      thTH: 'tailandês',
-      idID: 'indonésio',
-      ukUA: 'ucraniana',
-    },
-  },
   provider: {
     apiKey: 'Chave da API',
     enterYourKey: 'Insira sua chave da API aqui',
-    invalidKey: 'Chave da API inválida',
+    invalidKey: 'Chave da API OpenAI inválida',
     validatedError: 'Falha na validação: ',
     validating: 'Validando chave...',
     saveFailed: 'Falha ao salvar a chave da API',
-    apiKeyExceedBill: 'Esta chave da API não possui cota disponível, por favor leia',
-    addKey: 'Adicionar chave',
+    apiKeyExceedBill: 'Esta CHAVE DE API não tem quota disponível, por favor, leia',
+    addKey: 'Adicionar Chave',
     comingSoon: 'Em breve',
     editKey: 'Editar',
     invalidApiKey: 'Chave da API inválida',
@@ -42,49 +213,33 @@ const translation = {
       apiBasePlaceholder: 'A URL base da API do seu ponto de extremidade Azure OpenAI.',
       apiKey: 'Chave da API',
       apiKeyPlaceholder: 'Insira sua chave da API aqui',
-      helpTip: 'Aprenda sobre o Serviço Azure OpenAI',
+      helpTip: 'Saiba mais sobre o Serviço Azure OpenAI',
     },
     openaiHosted: {
       openaiHosted: 'OpenAI Hospedado',
       onTrial: 'EM TESTE',
       exhausted: 'COTA ESGOTADA',
-      desc: 'O serviço de hospedagem OpenAI fornecido pela Dify permite que você use modelos como o GPT-3.5. Antes que sua cota de teste seja esgotada, você precisa configurar outros provedores de modelo.',
-      callTimes: 'Número de chamadas',
-      usedUp: 'Cota de teste esgotada. Adicione seu próprio provedor de modelo.',
-      useYourModel: 'Atualmente usando seu próprio provedor de modelo.',
+      desc: 'O serviço de hospedagem OpenAI fornecido pela Dify permite que você use modelos como GPT-3.5. Antes que sua cota de teste seja esgotada, você precisa configurar outros fornecedores de modelos.',
+      callTimes: 'Chamadas',
+      usedUp: 'Cota de teste esgotada. Adicione seu próprio Fornecedor de Modelo.',
+      useYourModel: 'Atualmente usando seu próprio Fornecedor de Modelo.',
       close: 'Fechar',
     },
-    voice: {
-      language: {
-        zhHans: 'chinês',
-        enUS: 'inglês',
-        deDE: 'alemão',
-        frFR: 'francês',
-        esES: 'espanhol',
-        itIT: 'italiano',
-        thTH: 'tailandês',
-        idID: 'indonésio',
-        jaJP: 'japonês',
-        koKR: 'coreano',
-        ptBR: 'português',
-        ruRU: 'russo',
-      },
-    },
     anthropicHosted: {
       anthropicHosted: 'Anthropic Claude',
       onTrial: 'EM TESTE',
       exhausted: 'COTA ESGOTADA',
       desc: 'Modelo poderoso, que se destaca em uma ampla gama de tarefas, desde diálogos sofisticados e geração de conteúdo criativo até instruções detalhadas.',
-      callTimes: 'Número de chamadas',
-      usedUp: 'Cota de teste esgotada. Adicione seu próprio provedor de modelo.',
-      useYourModel: 'Atualmente usando seu próprio provedor de modelo.',
+      callTimes: 'Chamadas',
+      usedUp: 'Cota de teste esgotada. Adicione seu próprio Fornecedor de Modelo.',
+      useYourModel: 'Atualmente usando seu próprio Fornecedor de Modelo.',
       close: 'Fechar',
     },
     anthropic: {
-      using: 'A capacidade de incorporação está usando',
-      enableTip: 'Para habilitar o modelo Anthropic, você precisa se vincular ao OpenAI ou ao Azure OpenAI Service primeiro.',
+      using: 'A capacidade de incorporação está sendo utilizada',
+      enableTip: 'Para habilitar o modelo da Anthropic, você precisa vincular ao OpenAI ou ao Azure OpenAI Service primeiro.',
       notEnabled: 'Não habilitado',
-      keyFrom: 'Obtenha sua chave da API do Anthropic',
+      keyFrom: 'Obtenha sua chave da API da Anthropic',
     },
     encrypted: {
       front: 'Sua CHAVE DA API será criptografada e armazenada usando',
@@ -92,29 +247,33 @@ const translation = {
     },
   },
   modelProvider: {
-    notConfigured: 'O modelo do sistema ainda não foi totalmente configurado e algumas funções podem não estar disponíveis.',
-    systemModelSettings: 'Configurações do modelo do sistema',
+    notConfigured: 'O modelo do sistema ainda não foi totalmente configurado e algumas funções podem estar indisponíveis.',
+    systemModelSettings: 'Configurações do Modelo do Sistema',
     systemModelSettingsLink: 'Por que é necessário configurar um modelo do sistema?',
     selectModel: 'Selecione seu modelo',
     setupModelFirst: 'Por favor, configure seu modelo primeiro',
     systemReasoningModel: {
-      key: 'Modelo de raciocínio do sistema',
-      tip: 'Defina o modelo de inferência padrão a ser usado para criar aplicativos, bem como recursos como geração de nome de diálogo e sugestão de próxima pergunta também usarão o modelo de inferência padrão.',
+      key: 'Modelo de Raciocínio do Sistema',
+      tip: 'Defina o modelo de inferência padrão a ser usado para criar aplicativos, bem como recursos como geração de nomes de diálogo e sugestão de próxima pergunta também usarão o modelo de inferência padrão.',
     },
     embeddingModel: {
-      key: 'Modelo de incorporação',
-      tip: 'Defina o modelo padrão para o processamento de incorporação de documentos do Conhecimento, tanto a recuperação quanto a importação do Conhecimento usam este modelo de Incorporação para o processamento de vetorização. A troca causará inconsistência na dimensão do vetor entre o Conhecimento importado e a pergunta, resultando em falha na recuperação. Para evitar falhas na recuperação, não altere este modelo indiscriminadamente.',
-      required: 'O modelo de incorporação é obrigatório',
+      key: 'Modelo de Incorporação',
+      tip: 'Defina o modelo padrão para o processamento de incorporação de documentos do Conhecimento, tanto a recuperação quanto a importação do Conhecimento usam este modelo de Incorporação para processamento de vetorização. Alterar causará inconsistência na dimensão do vetor entre o Conhecimento importado e a pergunta, resultando em falha na recuperação. Para evitar falhas na recuperação, não altere este modelo indiscriminadamente.',
+      required: 'O modelo de Incorporação é obrigatório',
     },
     speechToTextModel: {
-      key: 'Modelo de fala para texto',
-      tip: 'Defina o modelo padrão para entrada de fala para texto em conversa.',
+      key: 'Modelo de Fala para Texto',
+      tip: 'Defina o modelo padrão para entrada de fala para texto na conversa.',
+    },
+    ttsModel: {
+      key: 'Modelo de Texto para Fala',
+      tip: 'Defina o modelo padrão para entrada de texto para fala na conversa.',
     },
     rerankModel: {
-      key: 'Modelo de reclassificação',
-      tip: 'O modelo de reclassificação reordenará a lista de documentos candidatos com base na correspondência semântica com a consulta do usuário, melhorando os resultados da classificação semântica',
+      key: 'Modelo de Reordenação',
+      tip: 'O modelo de reordenaenação reorganizará a lista de documentos candidatos com base na correspondência semântica com a consulta do usuário, melhorando os resultados da classificação semântica',
     },
-    quota: 'Cota',
+    quota: 'Quota',
     searchModel: 'Modelo de pesquisa',
     noModelFound: 'Nenhum modelo encontrado para {{model}}',
     models: 'Modelos',
@@ -122,24 +281,24 @@ const translation = {
     selector: {
       tip: 'Este modelo foi removido. Adicione um modelo ou selecione outro modelo.',
       emptyTip: 'Nenhum modelo disponível',
-      emptySetting: 'Por favor, vá para as configurações para configurar',
-      rerankTip: 'Por favor, configure o modelo de reclassificação',
+      emptySetting: 'Por favor, vá para configurações para configurar',
+      rerankTip: 'Por favor, configure o modelo de reordenação',
     },
     card: {
-      quota: 'COTA',
+      quota: 'QUOTA',
       onTrial: 'Em Teste',
       paid: 'Pago',
-      quotaExhausted: 'Cota esgotada',
-      callTimes: 'Número de chamadas',
+      quotaExhausted: 'Quota esgotada',
+      callTimes: 'Chamadas',
       tokens: 'Tokens',
-      buyQuota: 'Comprar Cota',
+      buyQuota: 'Comprar Quota',
       priorityUse: 'Uso prioritário',
       removeKey: 'Remover Chave da API',
-      tip: 'A cota paga terá prioridade. A cota de teste será usada após a cota paga ser esgotada.',
+      tip: 'A prioridade será dada à quota paga. A quota de teste será usada após a quota paga ser esgotada.',
     },
     item: {
       deleteDesc: '{{modelName}} está sendo usado como modelos de raciocínio do sistema. Algumas funções não estarão disponíveis após a remoção. Por favor, confirme.',
-      freeQuota: 'COTA GRATUITA',
+      freeQuota: 'QUOTA GRATUITA',
     },
     addApiKey: 'Adicionar sua chave da API',
     invalidApiKey: 'Chave da API inválida',
@@ -150,24 +309,25 @@ const translation = {
     freeQuota: {
       howToEarn: 'Como ganhar',
     },
-    addMoreModelProvider: 'ADICIONAR MAIS PROVEDOR DE MODELO',
+    addMoreModelProvider: 'ADICIONAR MAIS FORNECEDOR DE MODELO',
     addModel: 'Adicionar Modelo',
     modelsNum: '{{num}} Modelos',
     showModels: 'Mostrar Modelos',
     showModelsNum: 'Mostrar {{num}} Modelos',
     collapse: 'Recolher',
-    config: 'Configurar',
+    config: 'Configuração',
     modelAndParameters: 'Modelo e Parâmetros',
     model: 'Modelo',
     featureSupported: '{{feature}} suportado',
-    callTimes: 'Número de chamadas',
-    buyQuota: 'Comprar Cota',
-    getFreeTokens: 'Obter Tokens gratuitos',
+    callTimes: 'Chamadas',
+    credits: 'Créditos de Mensagem',
+    buyQuota: 'Comprar Quota',
+    getFreeTokens: 'Obter Tokens Gratuitos',
     priorityUsing: 'Uso prioritário',
-    deprecated: 'Descontinuado',
+    deprecated: 'Obsoleto',
     confirmDelete: 'confirmar exclusão?',
     quotaTip: 'Tokens gratuitos disponíveis restantes',
-    loadPresets: 'Carregar presentes',
+    loadPresets: 'Carregar Predefinições',
     parameters: 'PARÂMETROS',
   },
   dataSource: {
@@ -197,11 +357,11 @@ const translation = {
     serpapi: {
       apiKey: 'Chave da API',
       apiKeyPlaceholder: 'Insira sua chave da API',
-      keyFrom: 'Obtenha sua chave SerpAPI na página da conta SerpAPI',
+      keyFrom: 'Obtenha sua chave da SerpAPI na página da conta da SerpAPI',
     },
   },
   apiBasedExtension: {
-    title: 'As extensões de API fornecem gerenciamento centralizado de API, simplificando a configuração para uso fácil em aplicativos da Dify.',
+    title: 'As extensões de API fornecem gerenciamento centralizado de API, simplificando a configuração para uso fácil em todos os aplicativos da Dify.',
     link: 'Saiba como desenvolver sua própria Extensão de API.',
     linkUrl: 'https://docs.dify.ai/features/extension/api_based_extension',
     add: 'Adicionar Extensão de API',
@@ -230,13 +390,13 @@ const translation = {
     type: 'Tipo',
   },
   about: {
-    changeLog: 'Registro de alterações',
+    changeLog: 'Registro de Alterações',
     updateNow: 'Atualizar agora',
-    nowAvailable: 'Dify {{version}} está disponível agora.',
-    latestAvailable: 'Dify {{version}} é a versão mais recente disponível.',
+    nowAvailable: 'Dify {{version}} está disponível.',
+    latestAvailable: 'Dify {{version}} é a última versão disponível.',
   },
   appMenus: {
-    overview: 'Visão geral',
+    overview: 'Visão Geral',
     promptEng: 'Orquestrar',
     apiAccess: 'Acesso à API',
     logAndAnn: 'Logs e Anúncios',
@@ -247,7 +407,7 @@ const translation = {
   },
   appModes: {
     completionApp: 'Gerador de Texto',
-    chatApp: 'Aplicativo de Chat',
+    chatApp: 'Aplicativo de Bate-papo',
   },
   datasetMenus: {
     documents: 'Documentos',
@@ -255,7 +415,7 @@ const translation = {
     settings: 'Configurações',
     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 vinculados',
+    relatedApp: 'aplicativos relacionados',
   },
   voiceInput: {
     speaking: 'Fale agora...',
@@ -267,10 +427,10 @@ const translation = {
     'gpt-3.5-turbo-16k': 'GPT-3.5-Turbo-16K',
     'gpt-4': 'GPT-4',
     'gpt-4-32k': 'GPT-4-32K',
-    'text-davinci-003': 'Text-Davinci-003',
-    'text-embedding-ada-002': 'Text-Embedding-Ada-002',
-    'whisper-1': 'Whisper-1',
-    'claude-instant-1': 'Claude-Instant',
+    'text-davinci-003': 'Texto-Davinci-003',
+    'text-embedding-ada-002': 'Texto-Embutimento-Ada-002',
+    'whisper-1': 'Sussurro-1',
+    'claude-instant-1': 'Claude-Instantâneo',
     'claude-2': 'Claude-2',
   },
   chat: {
@@ -280,29 +440,29 @@ const translation = {
     conversationNameCanNotEmpty: 'Nome da conversa obrigatório',
     citation: {
       title: 'CITAÇÕES',
-      linkToDataset: 'Link para o Conhecimento',
+      linkToDataset: 'Link para Conhecimento',
       characters: 'Personagens:',
       hitCount: 'Contagem de recuperação:',
-      vectorHash: 'Hash do vetor:',
+      vectorHash: 'Hash de vetor:',
       hitScore: 'Pontuação de recuperação:',
     },
   },
   promptEditor: {
-    placeholder: 'Escreva sua palavra de estímulo aqui, digite \'{\' para inserir uma variável, digite \'/\' para inserir um bloco de conteúdo de estímulo',
+    placeholder: 'Escreva sua palavra de incentivo aqui, digite \'{\' para inserir uma variável, digite \'/\' para inserir um bloco de conteúdo de incentivo',
     context: {
       item: {
         title: 'Contexto',
         desc: 'Inserir modelo de contexto',
       },
       modal: {
-        title: '{{num}} Conhecimento em Contexto',
+        title: '{{num}} Conhecimentos no Contexto',
         add: 'Adicionar Contexto',
-        footer: 'Você pode gerenciar os contextos na seção de Contexto abaixo.',
+        footer: 'Você pode gerenciar contextos na seção Contexto abaixo.',
       },
     },
     history: {
       item: {
-        title: 'Histórico da Conversa',
+        title: 'Histórico de Conversas',
         desc: 'Inserir modelo de mensagem histórica',
       },
       modal: {
@@ -328,17 +488,17 @@ const translation = {
         desc: 'Inserir modelo de consulta do usuário',
       },
     },
-    existed: 'Já existe no estímulo',
+    existed: 'Já existe no incentivo',
   },
   imageUploader: {
-    uploadFromComputer: 'Enviar do computador',
-    uploadFromComputerReadError: 'Falha na leitura da imagem, por favor, tente novamente.',
-    uploadFromComputerUploadError: 'Falha no envio da imagem, por favor, envie novamente.',
+    uploadFromComputer: 'Enviar do Computador',
+    uploadFromComputerReadError: 'Falha ao ler a imagem, por favor, tente novamente.',
+    uploadFromComputerUploadError: 'Falha ao enviar a imagem, por favor, envie novamente.',
     uploadFromComputerLimit: 'As imagens enviadas não podem exceder {{size}} MB',
     pasteImageLink: 'Colar link da imagem',
     pasteImageLinkInputPlaceholder: 'Cole o link da imagem aqui',
     pasteImageLinkInvalid: 'Link da imagem inválido',
-    imageUpload: 'Envio de Imagem',
+    imageUpload: 'Enviar Imagem',
   },
 }
 

+ 18 - 18
web/i18n/pt-BR/custom.ts

@@ -1,29 +1,29 @@
 const translation = {
-  custom: 'Customization',
+  custom: 'Personalização',
   upgradeTip: {
-    prefix: 'Upgrade your plan to',
-    suffix: 'customize your brand.',
+    prefix: 'Atualize seu plano para',
+    suffix: 'personalizar sua marca.',
   },
   webapp: {
-    title: 'Customize WebApp brand',
-    removeBrand: 'Remove Powered by Dify',
-    changeLogo: 'Change Powered by Brand Image',
-    changeLogoTip: 'SVG or PNG format with a minimum size of 40x40px',
+    title: 'Personalizar marca do WebApp',
+    removeBrand: 'Remover Powered by Dify',
+    changeLogo: 'Alterar Imagem da Marca Powered by',
+    changeLogoTip: 'Formato SVG ou PNG com tamanho mínimo de 40x40px',
   },
   app: {
-    title: 'Customize app header brand',
-    changeLogoTip: 'SVG or PNG format with a minimum size of 80x80px',
+    title: 'Personalizar cabeçalho do aplicativo',
+    changeLogoTip: 'Formato SVG ou PNG com tamanho mínimo de 80x80px',
   },
-  upload: 'Upload',
-  uploading: 'Uploading',
-  uploadedFail: 'Image upload failed, please re-upload.',
-  change: 'Change',
-  apply: 'Apply',
-  restore: 'Restore Defaults',
+  upload: 'Enviar',
+  uploading: 'Enviando',
+  uploadedFail: 'Falha no envio da imagem, por favor, envie novamente.',
+  change: 'Alterar',
+  apply: 'Aplicar',
+  restore: 'Restaurar Padrões',
   customize: {
-    contactUs: ' contact us ',
-    prefix: 'To customize the brand logo within the app, please',
-    suffix: 'to upgrade to the Enterprise edition.',
+    contactUs: ' entre em contato conosco ',
+    prefix: 'Para personalizar o logotipo da marca dentro do aplicativo, por favor',
+    suffix: 'para fazer upgrade para a edição Enterprise.',
   },
 }
 

+ 13 - 8
web/i18n/pt-BR/tools.ts

@@ -4,7 +4,7 @@ const translation = {
   type: {
     all: 'Todas',
     builtIn: 'Integradas',
-    custom: 'Personal...',
+    custom: 'Personalizadas',
   },
   contribute: {
     line1: 'Estou interessado em ',
@@ -13,7 +13,7 @@ const translation = {
   },
   author: 'Por',
   auth: {
-    unauthorized: 'Não autorizado',
+    unauthorized: 'Para Autorizar',
     authorized: 'Autorizado',
     setup: 'Configurar autorização para usar',
     setupModalTitle: 'Configurar Autorização',
@@ -35,8 +35,8 @@ const translation = {
     urlError: 'Digite uma URL válida',
     examples: 'Exemplos',
     exampleOptions: {
-      json: 'Clima (JSON)',
-      yaml: 'Pet Store (YAML)',
+      json: 'Clima(JSON)',
+      yaml: 'Pet Store(YAML)',
       blankTemplate: 'Modelo em Branco',
     },
     availableTools: {
@@ -51,18 +51,22 @@ const translation = {
     authMethod: {
       title: 'Método de Autorização',
       type: 'Tipo de Autorização',
+      keyTooltip: 'Chave do Cabeçalho HTTP, você pode deixar como "Authorization" se não tiver ideia do que é ou definir um valor personalizado',
       types: {
         none: 'Nenhum',
         api_key: 'Chave de API',
+        apiKeyPlaceholder: 'Nome do cabeçalho HTTP para a Chave de API',
+        apiValuePlaceholder: 'Digite a Chave de API',
       },
       key: 'Chave',
       value: 'Valor',
     },
     authHeaderPrefix: {
+      title: 'Tipo de Autenticação',
       types: {
-        basic: 'Basic',
+        basic: 'Básica',
         bearer: 'Bearer',
-        custom: 'Custom',
+        custom: 'Personalizada',
       },
     },
     privacyPolicy: 'Política de Privacidade',
@@ -94,7 +98,7 @@ const translation = {
   },
   noCustomTool: {
     title: 'Nenhuma ferramenta personalizada!',
-    content: 'Você não possui ferramentas personalizadas. ',
+    content: 'Adicione e gerencie suas ferramentas personalizadas aqui para construir aplicativos de IA.',
     createTool: 'Criar Ferramenta',
   },
   noSearchRes: {
@@ -104,7 +108,8 @@ const translation = {
   },
   builtInPromptTitle: 'Prompt',
   toolRemoved: 'Ferramenta removida',
-  howToGet: 'Como conseguir',
+  notAuthorized: 'Ferramenta não autorizada',
+  howToGet: 'Como obter',
 }
 
 export default translation

+ 6 - 3
web/i18n/uk-UA/tools.ts

@@ -49,11 +49,14 @@ const translation = {
       test: 'Перевірка',
     },
     authMethod: {
-      title: 'Спосіб авторизації',
+      title: 'Метод авторизації',
       type: 'Тип авторизації',
+      keyTooltip: 'Ключ HTTP-заголовка. Якщо ви не знаєте, залиште його як "Authorization" або встановіть власне значення',
       types: {
-        none: 'Немає',
-        api_key: 'API ключі',
+        none: 'Відсутня',
+        api_key: 'API-ключ',
+        apiKeyPlaceholder: 'Назва HTTP-заголовка для API-ключа',
+        apiValuePlaceholder: 'Введіть API-ключ',
       },
       key: 'Ключ',
       value: 'Значення',

+ 8 - 0
web/i18n/zh-Hans/tools.ts

@@ -72,6 +72,14 @@ const translation = {
     privacyPolicy: '隐私协议',
     privacyPolicyPlaceholder: '请输入隐私协议',
   },
+  test: {
+    title: '测试',
+    parametersValue: '参数和值',
+    parameters: '参数',
+    value: '值',
+    testResult: '测试结果',
+    testResultPlaceholder: '测试结果将显示在这里',
+  },
   thought: {
     using: '正在使用',
     used: '已使用',