Skip to content

Commit

Permalink
Merge pull request #169 from barrierye/master
Browse files Browse the repository at this point in the history
一系列更新
  • Loading branch information
MrChengmo authored Mar 13, 2024
2 parents fad4cd4 + 070677c commit b422f53
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 30 deletions.
15 changes: 8 additions & 7 deletions appbuilder/core/_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,16 @@ class TypeNotSupportedException(BaseRPCException):
class AppBuilderServerException(BaseRPCException):
r"""AppBuilderServerException represent backend server failed response.
"""
description: str = "Interal Server Error"
code: int = 500

def __init__(self, request_id="", code="", message="", service_err_code="", service_err_message=""):
r"""__init__ a AppBuilderServerException instance.
:param request_id: str, request unique id.
:param code: str, backend .
:rtype:
"""
super().__init__("request_id={}, code={}, message={}, service_err_code={}, service_err_message={} ".format(
request_id, code, message, service_err_code, service_err_message))
self.description = "request_id={}, code={}, message={}, service_err_code={}, service_err_message={} ".format(
request_id, code, message, service_err_code, service_err_message)
self.code = code if code else self.code

def __str__(self):
return self.description


class InvalidRequestArgumentError(BaseRPCException):
Expand Down
30 changes: 15 additions & 15 deletions appbuilder/core/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import copy
import os
import logging
import uuid
Expand Down Expand Up @@ -246,7 +247,11 @@ def warp():
app_builder_token = request.headers["X-Appbuilder-Token"]
self.component.set_secret_key_and_gateway(secret_key=app_builder_token)
except appbuilder.core._exception.BaseRPCException as e:
logging.error(f"failed to verify. err={e}", exc_info=True)
raise BadRequest("X-Appbuilder-Token invalid")
except Exception as e:
logging.error(f"failed to verify. err={e}", exc_info=True)
raise e
else:
pass

Expand Down Expand Up @@ -276,34 +281,29 @@ def warp():
def gen_sse_resp(stream_message):
with app.app_context():
try:
iterator = iter(stream_message.content)
prev_result = {
"content": next(iterator),
"extra": stream_message.extra if hasattr(stream_message, "extra") else {},
"token_usage": stream_message.token_usage if hasattr(stream_message, "token_usage") else {},
}
for sub_content in iterator:
content_iterator = iter(stream_message.content)
prev_content = next(content_iterator)
prev_result = copy.deepcopy(stream_message)
prev_result.content = prev_content
for sub_content in content_iterator:
logging.info(f"[request_id={request_id}, session_id={session_id}] streaming_result={prev_result}")
yield "data: " + json.dumps({
"code": 0, "message": "",
"result": {
"session_id": session_id,
"is_completion": False,
"answer_message": prev_result
"answer_message": json.loads(prev_result.json(exclude_none=True))
}
}, ensure_ascii=False) + "\n\n"
prev_result = {
"content": sub_content,
"extra": stream_message.extra if hasattr(stream_message, "extra") else {},
"token_usage": stream_message.token_usage if hasattr(stream_message, "token_usage") else {},
}
prev_result = copy.deepcopy(stream_message)
prev_result.content = sub_content
logging.info(f"[request_id={request_id}, session_id={session_id}] streaming_result={prev_result}")
yield "data: " + json.dumps({
"code": 0, "message": "",
"result": {
"session_id": session_id,
"is_completion": True,
"answer_message": prev_result
"answer_message": json.loads(prev_result.json(exclude_none=True))
}
}, ensure_ascii=False) + "\n\n"
self.user_session._post_append()
Expand All @@ -317,7 +317,7 @@ def gen_sse_resp(stream_message):
{'Content-Type': 'text/event-stream; charset=utf-8'},
)
else:
blocking_result = json.loads(answer.json(exclude_none=True))
blocking_result = json.loads(copy.deepcopy(answer).json(exclude_none=True))
logging.info(f"[request_id={request_id}, session_id={session_id}] blocking_result={blocking_result}")
self.user_session._post_append()
return {
Expand Down
5 changes: 3 additions & 2 deletions appbuilder/core/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from pydantic import BaseModel
from typing import Dict, List, Optional, Any

from appbuilder.core.utils import ttl_lru_cache
from appbuilder.core._client import HTTPClient
from appbuilder.core.message import Message

Expand Down Expand Up @@ -81,7 +81,8 @@ def __init__(
self.lazy_certification = lazy_certification
if not self.lazy_certification:
self.set_secret_key_and_gateway(self.secret_key, self.gateway)


@ttl_lru_cache(seconds_to_live=1 * 60 * 60) # 1h
def set_secret_key_and_gateway(self, secret_key: Optional[str] = None, gateway: str = ""):
self.secret_key = secret_key
self.gateway = gateway
Expand Down
8 changes: 5 additions & 3 deletions appbuilder/core/components/excel2figure/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from appbuilder.core._exception import AppBuilderServerException, ModelNotSupportedException
from appbuilder.core.component import Component, ComponentArguments
from appbuilder.core.message import Message
from appbuilder.core.utils import ModelInfo
from appbuilder.core.utils import ModelInfo, ttl_lru_cache


class Excel2FigureArgs(ComponentArguments):
Expand Down Expand Up @@ -74,11 +74,13 @@ def __init__(
self._check_model_and_get_model_url(self.model, self.model_type)
self.server_sub_path = "/v1/ai_engine/copilot_engine/v1/api/agent/excel2figure"

@ttl_lru_cache(seconds_to_live=1 * 60 * 60) # 1h
def set_secret_key_and_gateway(self, secret_key: Optional[str] = None, gateway: str = ""):
super(Excel2Figure, self).set_secret_key_and_gateway(
secret_key=secret_key, gateway=gateway)
self.__class__.model_info = ModelInfo(client=self.http_client)

@ttl_lru_cache(seconds_to_live=1 * 60 * 60) # 1h
def _check_model_and_get_model_url(self, model, model_type):
if model and model in self.excluded_models:
raise ModelNotSupportedException(f"Model {model} not supported")
Expand Down Expand Up @@ -221,8 +223,8 @@ def tool_eval(
'text': [result_msg.content],
}
except Exception as e:
result = f'绘制图表时发生错误:{e}'
logging.error(result, exc_info=True)
raise RuntimeError(f'绘制图表时发生错误:{e}')

if streaming:
yield result
else:
Expand Down
16 changes: 15 additions & 1 deletion appbuilder/core/components/llms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from enum import Enum
import logging
import requests
import copy
import collections.abc
from appbuilder.core.constants import GATEWAY_URL, GATEWAY_INNER_URL
from pydantic import BaseModel, Field, ValidationError, HttpUrl, validator
from pydantic.types import confloat
Expand All @@ -27,7 +29,7 @@
from typing import Dict, List, Optional, Any

from appbuilder.core.component import ComponentArguments
from appbuilder.core.utils import ModelInfo
from appbuilder.core.utils import ModelInfo, ttl_lru_cache
from appbuilder.utils.sse_util import SSEClient
from appbuilder.core._exception import AppBuilderServerException, ModelNotSupportedException

Expand All @@ -40,6 +42,16 @@ class LLMMessage(Message):
def __str__(self):
return f"Message(name={self.name}, content={self.content}, " \
f"mtype={self.mtype}, extra={self.extra}, token_usage={self.token_usage})"

def __deepcopy__(self, memo):
new_instance = self.__class__()
memo[id(self)] = new_instance
for k, v in self.__dict__.items():
if k == "content" and isinstance(v, collections.abc.Iterator):
pass
else:
setattr(new_instance, k, copy.deepcopy(v, memo))
return new_instance


class CompletionRequest(object):
Expand Down Expand Up @@ -270,11 +282,13 @@ def __init__(
if not lazy_certification:
self._check_model_and_get_model_url(self.model_name, self.model_type)

@ttl_lru_cache(seconds_to_live=1 * 60 * 60) # 1h
def set_secret_key_and_gateway(self, secret_key: Optional[str] = None, gateway: str = ""):
super(CompletionBaseComponent, self).set_secret_key_and_gateway(
secret_key=secret_key, gateway=gateway)
self.__class__.model_info = ModelInfo(client=self.http_client)

@ttl_lru_cache(seconds_to_live=1 * 60 * 60) # 1h
def _check_model_and_get_model_url(self, model, model_type):
if model and model in self.excluded_models:
raise ModelNotSupportedException(f"Model {model} not supported")
Expand Down
4 changes: 2 additions & 2 deletions appbuilder/core/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

import uuid

from pydantic import BaseModel
from pydantic import BaseModel, Extra
from typing import Optional, TypeVar, Generic


_T = TypeVar("_T")


class Message(BaseModel, Generic[_T]):
class Message(BaseModel, Generic[_T], extra=Extra.allow):
content: Optional[_T] = {}
name: Optional[str] = "msg"
mtype: Optional[str] = "dict"
Expand Down
16 changes: 16 additions & 0 deletions appbuilder/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import time
import itertools
from typing import List
from urllib.parse import urlparse
from appbuilder.core._client import HTTPClient
from appbuilder.core._exception import TypeNotSupportedException, ModelNotSupportedException
from appbuilder.utils.model_util import GetModelListRequest, Models, RemoteModelCollector
from functools import lru_cache


def utils_get_user_agent():
Expand Down Expand Up @@ -75,6 +77,20 @@ def is_url(string):
return all([result.scheme, result.netloc])


def ttl_lru_cache(seconds_to_live: int, maxsize: int = 128):
"""
Time aware lru caching
"""
def wrapper(func):
@lru_cache(maxsize)
def inner(__ttl, *args, **kwargs):
# Note that __ttl is not passed down to func,
# as it's only used to trigger cache miss after some time
return func(*args, **kwargs)
return lambda *args, **kwargs: inner(time.time() // seconds_to_live, *args, **kwargs)
return wrapper


class ModelInfo:
""" 模型信息类 """

Expand Down

0 comments on commit b422f53

Please sign in to comment.