anthropic_provider.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import json
  2. import logging
  3. from typing import Optional, Union
  4. import anthropic
  5. from langchain.chat_models import ChatAnthropic
  6. from langchain.schema import HumanMessage
  7. from core import hosted_llm_credentials
  8. from core.llm.error import ProviderTokenNotInitError
  9. from core.llm.provider.base import BaseProvider
  10. from core.llm.provider.errors import ValidateFailedError
  11. from models.provider import ProviderName, ProviderType
  12. class AnthropicProvider(BaseProvider):
  13. def get_models(self, model_id: Optional[str] = None) -> list[dict]:
  14. return [
  15. {
  16. 'id': 'claude-instant-1',
  17. 'name': 'claude-instant-1',
  18. },
  19. {
  20. 'id': 'claude-2',
  21. 'name': 'claude-2',
  22. },
  23. ]
  24. def get_credentials(self, model_id: Optional[str] = None) -> dict:
  25. return self.get_provider_api_key(model_id=model_id)
  26. def get_provider_name(self):
  27. return ProviderName.ANTHROPIC
  28. def get_provider_configs(self, obfuscated: bool = False, only_custom: bool = False) -> Union[str | dict]:
  29. """
  30. Returns the provider configs.
  31. """
  32. try:
  33. config = self.get_provider_api_key(only_custom=only_custom)
  34. except:
  35. config = {
  36. 'anthropic_api_key': ''
  37. }
  38. if obfuscated:
  39. if not config.get('anthropic_api_key'):
  40. config = {
  41. 'anthropic_api_key': ''
  42. }
  43. config['anthropic_api_key'] = self.obfuscated_token(config.get('anthropic_api_key'))
  44. return config
  45. return config
  46. def get_encrypted_token(self, config: Union[dict | str]):
  47. """
  48. Returns the encrypted token.
  49. """
  50. return json.dumps({
  51. 'anthropic_api_key': self.encrypt_token(config['anthropic_api_key'])
  52. })
  53. def get_decrypted_token(self, token: str):
  54. """
  55. Returns the decrypted token.
  56. """
  57. config = json.loads(token)
  58. config['anthropic_api_key'] = self.decrypt_token(config['anthropic_api_key'])
  59. return config
  60. def get_token_type(self):
  61. return dict
  62. def config_validate(self, config: Union[dict | str]):
  63. """
  64. Validates the given config.
  65. """
  66. # check OpenAI / Azure OpenAI credential is valid
  67. openai_provider = BaseProvider.get_valid_provider(self.tenant_id, ProviderName.OPENAI.value)
  68. azure_openai_provider = BaseProvider.get_valid_provider(self.tenant_id, ProviderName.AZURE_OPENAI.value)
  69. provider = None
  70. if openai_provider:
  71. provider = openai_provider
  72. elif azure_openai_provider:
  73. provider = azure_openai_provider
  74. if not provider:
  75. raise ValidateFailedError(f"OpenAI or Azure OpenAI provider must be configured first.")
  76. if provider.provider_type == ProviderType.SYSTEM.value:
  77. quota_used = provider.quota_used if provider.quota_used is not None else 0
  78. quota_limit = provider.quota_limit if provider.quota_limit is not None else 0
  79. if quota_used >= quota_limit:
  80. raise ValidateFailedError(f"Your quota for Dify Hosted OpenAI has been exhausted, "
  81. f"please configure OpenAI or Azure OpenAI provider first.")
  82. try:
  83. if not isinstance(config, dict):
  84. raise ValueError('Config must be a object.')
  85. if 'anthropic_api_key' not in config:
  86. raise ValueError('anthropic_api_key must be provided.')
  87. chat_llm = ChatAnthropic(
  88. model='claude-instant-1',
  89. anthropic_api_key=config['anthropic_api_key'],
  90. max_tokens_to_sample=10,
  91. temperature=0,
  92. default_request_timeout=60
  93. )
  94. messages = [
  95. HumanMessage(
  96. content="ping"
  97. )
  98. ]
  99. chat_llm(messages)
  100. except anthropic.APIConnectionError as ex:
  101. raise ValidateFailedError(f"Anthropic: Connection error, cause: {ex.__cause__}")
  102. except (anthropic.APIStatusError, anthropic.RateLimitError) as ex:
  103. raise ValidateFailedError(f"Anthropic: Error code: {ex.status_code} - "
  104. f"{ex.body['error']['type']}: {ex.body['error']['message']}")
  105. except Exception as ex:
  106. logging.exception('Anthropic config validation failed')
  107. raise ex
  108. def get_hosted_credentials(self) -> Union[str | dict]:
  109. if not hosted_llm_credentials.anthropic or not hosted_llm_credentials.anthropic.api_key:
  110. raise ProviderTokenNotInitError(
  111. f"No valid {self.get_provider_name().value} model provider credentials found. "
  112. f"Please go to Settings -> Model Provider to complete your provider credentials."
  113. )
  114. return {'anthropic_api_key': hosted_llm_credentials.anthropic.api_key}