Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DashScope model wrapper into AgentScope #54

Merged
merged 21 commits into from
Mar 14, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 65 additions & 18 deletions src/agentscope/models/tongyi_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
"""Model wrapper for Tongyi models"""
from http import HTTPStatus
from typing import Any

try:
Expand All @@ -13,9 +14,13 @@

from ..utils.monitor import MonitorFactory
from ..utils.monitor import get_full_name
from ..utils import QuotaExceededError
from ..constants import _DEFAULT_API_BUDGET

# The models in this list require that the roles of messages must alternate
# between "user" and "assistant".
# TODO: add more models
SPECIAL_MODEL_LIST = ["qwen-turbo", "qwen-plus", "qwen1.5-72b-chat"]
pan-x-c marked this conversation as resolved.
Show resolved Hide resolved


class TongyiWrapper(ModelWrapperBase):
qbc2016 marked this conversation as resolved.
Show resolved Hide resolved
"""The model wrapper for Tongyi API."""
Expand Down Expand Up @@ -176,12 +181,9 @@ def __call__(
"and 'content' key for Tongyi API.",
)

# For Tongyi model, the "role" value of the first and the last message
# must be "user"
if len(messages) > 0:
messages[0]["role"] = "user"
messages[-1]["role"] = "user"
messages = self._preprocess_role(messages)

# TODO: if user input nothing, will be an error
# step3: forward to generate response
response = dashscope.Generation.call(
model=self.model,
Expand All @@ -200,18 +202,63 @@ def __call__(
json_response=response,
)

# TODO: Add monitor for Tongyi?
# step5: update monitor accordingly
try:
self.monitor.update(
response.usage,
prefix=self.model,
)
except QuotaExceededError as e:
# TODO: optimize quota exceeded error handling process
logger.error(e.message)
# try:
# self.monitor.update(
# response.usage,
qbc2016 marked this conversation as resolved.
Show resolved Hide resolved
# prefix=self.model,
# )
# except QuotaExceededError as e:
# logger.error(e.message)

# step6: return response
return ModelResponse(
text=response.output["choices"][0]["message"]["content"],
raw=response,
)
if response.status_code == HTTPStatus.OK:
return ModelResponse(
text=response.output["choices"][0]["message"]["content"],
raw=response,
)
else:
error_msg = (
f"Request id: {response.request_id},"
f" Status code: {response.status_code},"
f" error code: {response.code},"
f" error message: {response.message}."
)

raise RuntimeError(error_msg)

def _preprocess_role(self, messages: list) -> list:
qbc2016 marked this conversation as resolved.
Show resolved Hide resolved
"""preprocess role rules for Tongyi"""
if self.model in SPECIAL_MODEL_LIST:
# The models in this list require that the roles of messages must
# alternate between "user" and "assistant".
message_length = len(messages)
if message_length % 2 == 1:
# If the length of the message list is odd, roles will
# alternate, starting with "user"
roles = [
"user" if i % 2 == 0 else "assistant"
for i in range(message_length)
]
else:
# If the length of the message list is even, the first role
# will be "system", followed by alternating "user" and
# "assistant"
roles = ["system"] + [
"user" if i % 2 == 1 else "assistant"
for i in range(1, message_length)
]

# Assign the roles list to the "role" key for each message in
# the messages list
for message, role in zip(messages, roles):
message["role"] = role
else:
# For other Tongyi models, the "role" value of the first and the
# last messages must be "user"
if len(messages) > 0:
messages[0]["role"] = "user"
messages[-1]["role"] = "user"

return messages