mirror of https://github.com/hwchase17/langchain
Add Tencent Hunyuan chat model (#12022)
### Description: The Tencent Hunyuan model, developed by Tencent, is a large language model by robust Chinese text generation capabilities, adeptness in logical reasoning within complex contexts, and reliable task execution proficiency.For more information, see [https://cloud.tencent.com/document/product/1729](https://cloud.tencent.com/document/product/1729)pull/12047/head
parent
68599d98c2
commit
4188f046ec
@ -0,0 +1,160 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Tencent Hunyuan\n",
|
||||
"\n",
|
||||
"Hunyuan chat model API by Tencent. For more information, see [https://cloud.tencent.com/document/product/1729](https://cloud.tencent.com/document/product/1729)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-10-19T10:20:38.718834Z",
|
||||
"start_time": "2023-10-19T10:20:38.264050Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.chat_models import ChatHunyuan\n",
|
||||
"from langchain.schema import HumanMessage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-10-19T10:19:53.529876Z",
|
||||
"start_time": "2023-10-19T10:19:53.526210Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"chat = ChatHunyuan(\n",
|
||||
" hunyuan_app_id='YOUR_APP_ID',\n",
|
||||
" hunyuan_secret_id='YOUR_SECRET_ID',\n",
|
||||
" hunyuan_secret_key='YOUR_SECRET_KEY',\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-10-19T10:19:56.054289Z",
|
||||
"start_time": "2023-10-19T10:19:53.531078Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": "AIMessage(content=\"J'aime programmer.\")"
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chat([\n",
|
||||
" HumanMessage(content='You are a helpful assistant that translates English to French.Translate this sentence from English to French. I love programming.')\n",
|
||||
"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## For ChatHunyuan with Streaming"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"chat = ChatHunyuan(\n",
|
||||
" hunyuan_app_id='YOUR_APP_ID',\n",
|
||||
" hunyuan_secret_id='YOUR_SECRET_ID',\n",
|
||||
" hunyuan_secret_key='YOUR_SECRET_KEY',\n",
|
||||
" streaming=True,\n",
|
||||
")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-10-19T10:20:41.507720Z",
|
||||
"start_time": "2023-10-19T10:20:41.496456Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": "AIMessageChunk(content=\"J'aime programmer.\")"
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chat([\n",
|
||||
" HumanMessage(content='You are a helpful assistant that translates English to French.Translate this sentence from English to French. I love programming.')\n",
|
||||
"])"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-10-19T10:20:46.275673Z",
|
||||
"start_time": "2023-10-19T10:20:44.241097Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"start_time": "2023-10-19T10:19:56.233477Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.4"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
@ -0,0 +1,325 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Any, Dict, Iterator, List, Mapping, Optional, Type, Union
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
|
||||
from langchain.callbacks.manager import CallbackManagerForLLMRun
|
||||
from langchain.chat_models.base import BaseChatModel, _generate_from_stream
|
||||
from langchain.pydantic_v1 import Field, SecretStr, root_validator
|
||||
from langchain.schema import (
|
||||
AIMessage,
|
||||
BaseMessage,
|
||||
ChatGeneration,
|
||||
ChatMessage,
|
||||
ChatResult,
|
||||
HumanMessage,
|
||||
)
|
||||
from langchain.schema.messages import (
|
||||
AIMessageChunk,
|
||||
BaseMessageChunk,
|
||||
ChatMessageChunk,
|
||||
HumanMessageChunk,
|
||||
)
|
||||
from langchain.schema.output import ChatGenerationChunk
|
||||
from langchain.utils import get_from_dict_or_env, get_pydantic_field_names
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_HUNYUAN_API_BASE = "https://hunyuan.cloud.tencent.com"
|
||||
DEFAULT_HUNYUAN_PATH = "/hyllm/v1/chat/completions"
|
||||
|
||||
|
||||
def _convert_message_to_dict(message: BaseMessage) -> dict:
|
||||
message_dict: Dict[str, Any]
|
||||
if isinstance(message, ChatMessage):
|
||||
message_dict = {"role": message.role, "content": message.content}
|
||||
elif isinstance(message, HumanMessage):
|
||||
message_dict = {"role": "user", "content": message.content}
|
||||
elif isinstance(message, AIMessage):
|
||||
message_dict = {"role": "assistant", "content": message.content}
|
||||
else:
|
||||
raise TypeError(f"Got unknown type {message}")
|
||||
|
||||
return message_dict
|
||||
|
||||
|
||||
def _convert_dict_to_message(_dict: Mapping[str, Any]) -> BaseMessage:
|
||||
role = _dict["role"]
|
||||
if role == "user":
|
||||
return HumanMessage(content=_dict["content"])
|
||||
elif role == "assistant":
|
||||
return AIMessage(content=_dict.get("content", "") or "")
|
||||
else:
|
||||
return ChatMessage(content=_dict["content"], role=role)
|
||||
|
||||
|
||||
def _convert_delta_to_message_chunk(
|
||||
_dict: Mapping[str, Any], default_class: Type[BaseMessageChunk]
|
||||
) -> BaseMessageChunk:
|
||||
role = _dict.get("role")
|
||||
content = _dict.get("content") or ""
|
||||
|
||||
if role == "user" or default_class == HumanMessageChunk:
|
||||
return HumanMessageChunk(content=content)
|
||||
elif role == "assistant" or default_class == AIMessageChunk:
|
||||
return AIMessageChunk(content=content)
|
||||
elif role or default_class == ChatMessageChunk:
|
||||
return ChatMessageChunk(content=content, role=role)
|
||||
else:
|
||||
return default_class(content=content)
|
||||
|
||||
|
||||
# signature generation
|
||||
# https://cloud.tencent.com/document/product/1729/97732#532252ce-e960-48a7-8821-940a9ce2ccf3
|
||||
def _signature(secret_key: SecretStr, url: str, payload: Dict[str, Any]) -> str:
|
||||
sorted_keys = sorted(payload.keys())
|
||||
|
||||
url_info = urlparse(url)
|
||||
|
||||
sign_str = url_info.netloc + url_info.path + "?"
|
||||
|
||||
for key in sorted_keys:
|
||||
value = payload[key]
|
||||
|
||||
if isinstance(value, list) or isinstance(value, dict):
|
||||
value = json.dumps(value, separators=(",", ":"))
|
||||
elif isinstance(value, float):
|
||||
value = "%g" % value
|
||||
|
||||
sign_str = sign_str + key + "=" + str(value) + "&"
|
||||
|
||||
sign_str = sign_str[:-1]
|
||||
|
||||
hmacstr = hmac.new(
|
||||
key=secret_key.get_secret_value().encode("utf-8"),
|
||||
msg=sign_str.encode("utf-8"),
|
||||
digestmod=hashlib.sha1,
|
||||
).digest()
|
||||
|
||||
return base64.b64encode(hmacstr).decode("utf-8")
|
||||
|
||||
|
||||
def _create_chat_result(response: Mapping[str, Any]) -> ChatResult:
|
||||
generations = []
|
||||
for choice in response["choices"]:
|
||||
message = _convert_dict_to_message(choice["messages"])
|
||||
generations.append(ChatGeneration(message=message))
|
||||
|
||||
token_usage = response["usage"]
|
||||
llm_output = {"token_usage": token_usage}
|
||||
return ChatResult(generations=generations, llm_output=llm_output)
|
||||
|
||||
|
||||
def _to_secret(value: Union[SecretStr, str]) -> SecretStr:
|
||||
"""Convert a string to a SecretStr if needed."""
|
||||
if isinstance(value, SecretStr):
|
||||
return value
|
||||
return SecretStr(value)
|
||||
|
||||
|
||||
class ChatHunyuan(BaseChatModel):
|
||||
"""Tencent Hunyuan chat models API by Tencent.
|
||||
|
||||
For more information, see https://cloud.tencent.com/document/product/1729
|
||||
"""
|
||||
|
||||
@property
|
||||
def lc_secrets(self) -> Dict[str, str]:
|
||||
return {
|
||||
"hunyuan_app_id": "HUNYUAN_APP_ID",
|
||||
"hunyuan_secret_id": "HUNYUAN_SECRET_ID",
|
||||
"hunyuan_secret_key": "HUNYUAN_SECRET_KEY",
|
||||
}
|
||||
|
||||
@property
|
||||
def lc_serializable(self) -> bool:
|
||||
return True
|
||||
|
||||
hunyuan_api_base: str = "https://hunyuan.cloud.tencent.com"
|
||||
"""Hunyuan custom endpoints"""
|
||||
hunyuan_app_id: Optional[str] = None
|
||||
"""Hunyuan App ID"""
|
||||
hunyuan_secret_id: Optional[str] = None
|
||||
"""Hunyuan Secret ID"""
|
||||
hunyuan_secret_key: Optional[SecretStr] = None
|
||||
"""Hunyuan Secret Key"""
|
||||
streaming: bool = False
|
||||
"""Whether to stream the results or not."""
|
||||
request_timeout: int = 60
|
||||
"""Timeout for requests to Hunyuan API. Default is 60 seconds."""
|
||||
|
||||
query_id: Optional[str] = None
|
||||
"""Query id for troubleshooting"""
|
||||
temperature: float = 1.0
|
||||
"""What sampling temperature to use."""
|
||||
top_p: float = 1.0
|
||||
"""What probability mass to use."""
|
||||
|
||||
model_kwargs: Dict[str, Any] = Field(default_factory=dict)
|
||||
"""Holds any model parameters valid for API call not explicitly specified."""
|
||||
|
||||
class Config:
|
||||
"""Configuration for this pydantic object."""
|
||||
|
||||
allow_population_by_field_name = True
|
||||
|
||||
@root_validator(pre=True)
|
||||
def build_extra(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Build extra kwargs from additional params that were passed in."""
|
||||
all_required_field_names = get_pydantic_field_names(cls)
|
||||
extra = values.get("model_kwargs", {})
|
||||
for field_name in list(values):
|
||||
if field_name in extra:
|
||||
raise ValueError(f"Found {field_name} supplied twice.")
|
||||
if field_name not in all_required_field_names:
|
||||
logger.warning(
|
||||
f"""WARNING! {field_name} is not default parameter.
|
||||
{field_name} was transferred to model_kwargs.
|
||||
Please confirm that {field_name} is what you intended."""
|
||||
)
|
||||
extra[field_name] = values.pop(field_name)
|
||||
|
||||
invalid_model_kwargs = all_required_field_names.intersection(extra.keys())
|
||||
if invalid_model_kwargs:
|
||||
raise ValueError(
|
||||
f"Parameters {invalid_model_kwargs} should be specified explicitly. "
|
||||
f"Instead they were passed in as part of `model_kwargs` parameter."
|
||||
)
|
||||
|
||||
values["model_kwargs"] = extra
|
||||
return values
|
||||
|
||||
@root_validator()
|
||||
def validate_environment(cls, values: Dict) -> Dict:
|
||||
values["hunyuan_api_base"] = get_from_dict_or_env(
|
||||
values,
|
||||
"hunyuan_api_base",
|
||||
"HUNYUAN_API_BASE",
|
||||
)
|
||||
values["hunyuan_app_id"] = get_from_dict_or_env(
|
||||
values,
|
||||
"hunyuan_app_id",
|
||||
"HUNYUAN_APP_ID",
|
||||
)
|
||||
values["hunyuan_secret_id"] = get_from_dict_or_env(
|
||||
values,
|
||||
"hunyuan_secret_id",
|
||||
"HUNYUAN_SECRET_ID",
|
||||
)
|
||||
values["hunyuan_secret_key"] = _to_secret(
|
||||
get_from_dict_or_env(
|
||||
values,
|
||||
"hunyuan_secret_key",
|
||||
"HUNYUAN_SECRET_KEY",
|
||||
)
|
||||
)
|
||||
|
||||
return values
|
||||
|
||||
@property
|
||||
def _default_params(self) -> Dict[str, Any]:
|
||||
"""Get the default parameters for calling Hunyuan API."""
|
||||
normal_params = {
|
||||
"app_id": self.hunyuan_app_id,
|
||||
"secret_id": self.hunyuan_secret_id,
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
}
|
||||
|
||||
if self.query_id is not None:
|
||||
normal_params["query_id"] = self.query_id
|
||||
|
||||
return {**normal_params, **self.model_kwargs}
|
||||
|
||||
def _generate(
|
||||
self,
|
||||
messages: List[BaseMessage],
|
||||
stop: Optional[List[str]] = None,
|
||||
run_manager: Optional[CallbackManagerForLLMRun] = None,
|
||||
**kwargs: Any,
|
||||
) -> ChatResult:
|
||||
if self.streaming:
|
||||
stream_iter = self._stream(
|
||||
messages=messages, stop=stop, run_manager=run_manager, **kwargs
|
||||
)
|
||||
return _generate_from_stream(stream_iter)
|
||||
|
||||
res = self._chat(messages, **kwargs)
|
||||
|
||||
response = res.json()
|
||||
|
||||
if "error" in response:
|
||||
raise ValueError(f"Error from Hunyuan api response: {response}")
|
||||
|
||||
return _create_chat_result(response)
|
||||
|
||||
def _stream(
|
||||
self,
|
||||
messages: List[BaseMessage],
|
||||
stop: Optional[List[str]] = None,
|
||||
run_manager: Optional[CallbackManagerForLLMRun] = None,
|
||||
**kwargs: Any,
|
||||
) -> Iterator[ChatGenerationChunk]:
|
||||
res = self._chat(messages, **kwargs)
|
||||
|
||||
default_chunk_class = AIMessageChunk
|
||||
for chunk in res.iter_lines():
|
||||
response = json.loads(chunk)
|
||||
if "error" in response:
|
||||
raise ValueError(f"Error from Hunyuan api response: {response}")
|
||||
|
||||
for choice in response["choices"]:
|
||||
chunk = _convert_delta_to_message_chunk(
|
||||
choice["delta"], default_chunk_class
|
||||
)
|
||||
default_chunk_class = chunk.__class__
|
||||
yield ChatGenerationChunk(message=chunk)
|
||||
if run_manager:
|
||||
run_manager.on_llm_new_token(chunk.content)
|
||||
|
||||
def _chat(self, messages: List[BaseMessage], **kwargs: Any) -> requests.Response:
|
||||
if self.hunyuan_secret_key is None:
|
||||
raise ValueError("Hunyuan secret key is not set.")
|
||||
|
||||
parameters = {**self._default_params, **kwargs}
|
||||
|
||||
headers = parameters.pop("headers", {})
|
||||
timestamp = parameters.pop("timestamp", int(time.time()))
|
||||
expired = parameters.pop("expired", timestamp + 24 * 60 * 60)
|
||||
|
||||
payload = {
|
||||
"timestamp": timestamp,
|
||||
"expired": expired,
|
||||
"messages": [_convert_message_to_dict(m) for m in messages],
|
||||
**parameters,
|
||||
}
|
||||
|
||||
if self.streaming:
|
||||
payload["stream"] = 1
|
||||
|
||||
url = self.hunyuan_api_base + DEFAULT_HUNYUAN_PATH
|
||||
|
||||
res = requests.post(
|
||||
url=url,
|
||||
timeout=self.request_timeout,
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": _signature(
|
||||
secret_key=self.hunyuan_secret_key, url=url, payload=payload
|
||||
),
|
||||
**headers,
|
||||
},
|
||||
json=payload,
|
||||
stream=self.streaming,
|
||||
)
|
||||
return res
|
||||
|
||||
@property
|
||||
def _llm_type(self) -> str:
|
||||
return "hunyuan-chat"
|
@ -0,0 +1,24 @@
|
||||
from langchain.chat_models.hunyuan import ChatHunyuan
|
||||
from langchain.schema.messages import AIMessage, HumanMessage
|
||||
|
||||
|
||||
def test_chat_hunyuan() -> None:
|
||||
chat = ChatHunyuan()
|
||||
message = HumanMessage(content="Hello")
|
||||
response = chat([message])
|
||||
assert isinstance(response, AIMessage)
|
||||
assert isinstance(response.content, str)
|
||||
|
||||
|
||||
def test_chat_hunyuan_with_temperature() -> None:
|
||||
chat = ChatHunyuan(temperature=0.6)
|
||||
message = HumanMessage(content="Hello")
|
||||
response = chat([message])
|
||||
assert isinstance(response, AIMessage)
|
||||
assert isinstance(response.content, str)
|
||||
|
||||
|
||||
def test_extra_kwargs() -> None:
|
||||
chat = ChatHunyuan(temperature=0.88, top_p=0.7)
|
||||
assert chat.temperature == 0.88
|
||||
assert chat.top_p == 0.7
|
@ -0,0 +1,114 @@
|
||||
import pytest
|
||||
|
||||
from langchain.chat_models.hunyuan import (
|
||||
_convert_delta_to_message_chunk,
|
||||
_convert_dict_to_message,
|
||||
_convert_message_to_dict,
|
||||
_signature,
|
||||
)
|
||||
from langchain.pydantic_v1 import SecretStr
|
||||
from langchain.schema.messages import (
|
||||
AIMessage,
|
||||
AIMessageChunk,
|
||||
ChatMessage,
|
||||
FunctionMessage,
|
||||
HumanMessage,
|
||||
HumanMessageChunk,
|
||||
SystemMessage,
|
||||
)
|
||||
|
||||
|
||||
def test__convert_message_to_dict_human() -> None:
|
||||
message = HumanMessage(content="foo")
|
||||
result = _convert_message_to_dict(message)
|
||||
expected_output = {"role": "user", "content": "foo"}
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_message_to_dict_ai() -> None:
|
||||
message = AIMessage(content="foo")
|
||||
result = _convert_message_to_dict(message)
|
||||
expected_output = {"role": "assistant", "content": "foo"}
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_message_to_dict_system() -> None:
|
||||
message = SystemMessage(content="foo")
|
||||
with pytest.raises(TypeError) as e:
|
||||
_convert_message_to_dict(message)
|
||||
assert "Got unknown type" in str(e)
|
||||
|
||||
|
||||
def test__convert_message_to_dict_function() -> None:
|
||||
message = FunctionMessage(name="foo", content="bar")
|
||||
with pytest.raises(TypeError) as e:
|
||||
_convert_message_to_dict(message)
|
||||
assert "Got unknown type" in str(e)
|
||||
|
||||
|
||||
def test__convert_dict_to_message_human() -> None:
|
||||
message_dict = {"role": "user", "content": "foo"}
|
||||
result = _convert_dict_to_message(message_dict)
|
||||
expected_output = HumanMessage(content="foo")
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_dict_to_message_ai() -> None:
|
||||
message_dict = {"role": "assistant", "content": "foo"}
|
||||
result = _convert_dict_to_message(message_dict)
|
||||
expected_output = AIMessage(content="foo")
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_dict_to_message_other_role() -> None:
|
||||
message_dict = {"role": "system", "content": "foo"}
|
||||
result = _convert_dict_to_message(message_dict)
|
||||
expected_output = ChatMessage(role="system", content="foo")
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_delta_to_message_assistant() -> None:
|
||||
delta = {"role": "assistant", "content": "foo"}
|
||||
result = _convert_delta_to_message_chunk(delta, AIMessageChunk)
|
||||
expected_output = AIMessageChunk(content="foo")
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__convert_delta_to_message_human() -> None:
|
||||
delta = {"role": "user", "content": "foo"}
|
||||
result = _convert_delta_to_message_chunk(delta, HumanMessageChunk)
|
||||
expected_output = HumanMessageChunk(content="foo")
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
def test__signature() -> None:
|
||||
secret_key = SecretStr("YOUR_SECRET_KEY")
|
||||
url = "https://hunyuan.cloud.tencent.com/hyllm/v1/chat/completions"
|
||||
|
||||
result = _signature(
|
||||
secret_key=secret_key,
|
||||
url=url,
|
||||
payload={
|
||||
"app_id": "YOUR_APP_ID",
|
||||
"secret_id": "YOUR_SECRET_ID",
|
||||
"query_id": "test_query_id_cb5d8156-0ce2-45af-86b4-d02f5c26a142",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "You are a helpful assistant that translates English"
|
||||
" to French.Translate this sentence from English to"
|
||||
" French. I love programming.",
|
||||
}
|
||||
],
|
||||
"temperature": 0.0,
|
||||
"top_p": 0.8,
|
||||
"stream": 1,
|
||||
"timestamp": 1697738378,
|
||||
"expired": 1697824778,
|
||||
},
|
||||
)
|
||||
|
||||
# The signature was generated by the demo provided by Huanyuan.
|
||||
# https://hunyuan-sdk-1256237915.cos.ap-guangzhou.myqcloud.com/python.zip
|
||||
expected_output = "MXBvqNCXyxJWfEyBwk1pYBVnxzo="
|
||||
assert result == expected_output
|
Loading…
Reference in New Issue