SciPIP / src /utils /api /base_helper.py
lihuigu's picture
change prompt reader & web front
479f67b
raw
history blame
7.2 kB
r"""_summary_
-*- coding: utf-8 -*-
Module : data.utils.api.base_helper
File Name : base_helper.py
Description : API helper automatic registration, using HelperCompany can directly reflect the corresponding helper
Creation Date : 2024-10-29
Author : Frank Kang([email protected])
"""
from typing import Union, List, Optional
from abc import ABCMeta
from typing_extensions import Literal, override
from ..base_company import BaseCompany
from typing import Union
class NotGiven:
"""
Copy from OpenAI
A sentinel singleton class used to distinguish omitted keyword arguments
from those passed in with the value None (which may have different behavior).
For example:
```py
def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response:
...
get(timeout=1) # 1s timeout
get(timeout=None) # No timeout
get() # Default timeout behavior, which may not be statically known at the method definition.
```
"""
def __bool__(self) -> Literal[False]:
return False
@override
def __repr__(self) -> str:
return "NOT_GIVEN"
class HelperCompany(BaseCompany):
"""_summary_
AI helper factory, inheriting BaseCompany
For example:
```
helper_company = HelperCompany.get()
# Of course, you can also obtain the singleton using the following methods
helper_company = HelperCompany()
helper = helper_company[helper_name]
```
@see data.utils.base_company.BaseCompany
"""
@override
def __repr__(self) -> str:
return "HelperCompany"
class register_helper:
"""_summary_
Automatically register helper annotation classes
"""
def __init__(self, helper_type, *args, **kwds):
self.helper_type = helper_type
self.init_args = args
self.init_kwds = kwds
def __call__(self, helper_cls, *args, **kwds):
helper_name = helper_cls.__name__
if HelperCompany.get().register(self.helper_type, helper_cls):
def _method(obj):
return helper_name
helper_cls.name = _method
return helper_cls
else:
raise KeyError()
class BaseHelper:
"""_summary_
Base class for API helper
"""
__metaclass__ = ABCMeta
def __init__(self, api_key, model, base_url) -> None:
super(BaseHelper, self).__init__()
self.api_key = api_key
self.model = model
self.base_url = base_url
self.client = None
def create(
self,
*args,
messages: Union[str, List[str], List[int], object, None],
stream: Optional[Literal[False]] | Literal[True] | NotGiven = None,
temperature: Optional[float] | NotGiven = None,
top_p: Optional[float] | NotGiven = None,
max_tokens: int | NotGiven = None,
seed: int | NotGiven = None,
stop: Optional[Union[str, List[str], None]] | NotGiven = None,
tools: Optional[object] | NotGiven = None,
tool_choice: str | NotGiven = None,
extra_headers: None | NotGiven = None,
extra_body: None | NotGiven = None,
timeout: float | None | NotGiven = None,
**kwargs
):
"""
Creates a model response for the given chat conversation.
Args:
messages: A list of messages comprising the conversation so far.
[Example Python code](https://cookbook.openai.com/examples/how_to_format_inputs_to_chatgpt_models).
stream: If set, partial message deltas will be sent, like in ChatGPT. Tokens will be sent as data-only
[server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
as they become available, with the stream terminated by a `data: [DONE]`
message.
[Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
make the output more random, while lower values like 0.2 will make it more
focused and deterministic.
We generally recommend altering this or `top_p` but not both.
top_p: An alternative to sampling with temperature, called nucleus sampling, where the
model considers the results of the tokens with top_p probability mass. So 0.1
means only the tokens comprising the top 10% probability mass are considered.
We generally recommend altering this or `temperature` but not both.
max_tokens: The maximum number of [tokens](/tokenizer) that can be generated in the chat
completion.
The total length of input tokens and generated tokens is limited by the model's
context length.
[Example Python code](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken)
for counting tokens.
seed: This feature is in Beta. If specified, our system will make a best effort to
sample deterministically, such that repeated requests with the same `seed` and
parameters should return the same result. Determinism is not guaranteed, and you
should refer to the `system_fingerprint` response parameter to monitor changes
in the backend.
stop: Up to 4 sequences where the API will stop generating further tokens.
tools: A list of tools the model may call. Currently, only functions are supported as a
tool. Use this to provide a list of functions the model may generate JSON inputs
for. A max of 128 functions are supported.
tool_choice: Controls which (if any) tool is called by the model. `none` means the model will
not call any tool and instead generates a message. `auto` means the model can
pick between generating a message or calling one or more tools. `required` means
the model must call one or more tools. Specifying a particular tool via
`{"type": "function", "function": {"name": "my_function"}}` forces the model to
call that tool.
`none` is the default when no tools are present. `auto` is the default if tools
are present.
extra_headers: Send extra headers
extra_body: Add additional JSON properties to the request
timeout: Override the client-level default timeout for this request, in seconds
"""
return self.client.chat.completions.create(
*args,
model=self.model,
messages=messages,
stream=stream,
temperature=temperature,
top_p=top_p,
max_tokens=max_tokens,
seed=seed,
stop=stop,
tools=tools,
tool_choice=tool_choice,
extra_headers=extra_headers,
extra_body=extra_body,
timeout=timeout,
**kwargs
)