Skip to content

Commit

Permalink
Merge pull request #340 from LlmKira/github-bot
Browse files Browse the repository at this point in the history
Pydantic 2.0 / Fix Bug
  • Loading branch information
sudoskys authored Nov 12, 2023
2 parents d785885 + 27a1d14 commit 9874567
Show file tree
Hide file tree
Showing 56 changed files with 748 additions and 651 deletions.
42 changes: 27 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
FROM python:3.10-slim AS builder
# 第一个阶段
FROM python:3.11-buster as builder

RUN apt update && \
apt install build-essential -y
RUN apt update && apt install -y build-essential \
&& pip install poetry==1.6.1

ENV POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=1 \
POETRY_VIRTUALENVS_CREATE=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache

COPY ./requirements.txt .
COPY pm2.json .
COPY start.sh .
# 将 config_dir 的设置文件映射到宿主机
COPY ./config_dir /config_dir
WORKDIR /app

COPY poetry.lock pyproject.toml ./
VOLUME ["/redis", "/rabbitmq", "/mongodb", "run.log", "/config_dir"]

RUN pip install --upgrade --no-cache-dir pip && pip install --no-cache-dir -r requirements.txt
RUN poetry config virtualenvs.in-project true && \
poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR

FROM python:3.10-slim
RUN apt-get update && \
# 第二个阶段
FROM python:3.11-slim-buster as runtime

RUN apt update && \
apt install -y npm && \
npm install pm2 -g

ENV WORKDIR /app
WORKDIR $WORKDIR
ADD . $WORKDIR
COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
ENV VIRTUAL_ENV=/app/.venv \
PATH="/app/.venv/bin:$PATH"

WORKDIR /app

COPY --from=builder /app/.venv /app/.venv

COPY pm2.json ./
COPY config_dir ./config_dir

CMD [ "pm2-runtime", "pm2.json" ]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ docker-compose -f docker-compose.yml up -d

```shell
git clone https://github.com/LlmKira/Openaibot.git
pip install poetry
cd Openaibot
pip install -r requirements.txt
# poetry config virtualenvs.in-project true
poetry install
cp .env.exp .env&&nano .env
apt install npm -y && npm install pm2 && pm2 start pm2.json
pm2 monit
Expand Down
4 changes: 3 additions & 1 deletion README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ curl -sSL https://raw.githubusercontent.com/LLMKira/Openaibot/main/deploy.sh | b
```shell
git clone https://github.com/LlmKira/Openaibot.git
cd Openaibot
pip install -r requirements.txt
pip install poetry
# poetry config virtualenvs.in-project true
poetry install
docker-compose -f docker-compose.yml up -d

```
Expand Down
4 changes: 3 additions & 1 deletion deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ cd Openaibot || echo "DO NOT Exist Openaibot Dir" && exit

# Install project dependencies
echo "$(tput setaf 6)Installing project dependencies...$(tput sgr0)"
python3 -m pip install -r requirements.txt
python3 -m pip install poetry
poetry config virtualenvs.in-project true &&
poetry install
python3 -m pip install rich loguru && python3 start_tutorial.py
echo "$(tput setaf 2)Project dependencies installation complete.$(tput sgr0)"

Expand Down
2 changes: 1 addition & 1 deletion docs/test_script/funtion.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ def add_property(self, property_name: str,
required=True
)
# print(Function.schema_json(indent=4))
print(json.dumps(f.dict(), indent=4))
print(json.dumps(f.model_dump(), indent=4))
2 changes: 1 addition & 1 deletion docs/test_script/note_pydantic_alias_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ class Child(Test):
env_required = ["test"]


_r = Child().dict()
_r = Child().model_dump()
_s = Child().env_help_docs
print(_r)
23 changes: 23 additions & 0 deletions docs/test_script/pydantic_feat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# @Time : 2023/11/12 下午9:12
# @Author : sudoskys
# @File : pydantic_feat.py
# @Software: PyCharm
from pydantic import field_validator, BaseModel, ValidationError


class UserModel(BaseModel):
id: int
name: str

@field_validator('name')
def name_must_contain_space(cls, v: str) -> str:
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()


try:
UserModel(id=0, name='JohnDoe')
except ValidationError as e:
print(e)
8 changes: 5 additions & 3 deletions docs/test_script/survey_arg_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
# @Author : sudoskys
# @File : arg.py.py
# @Software: PyCharm
from typing import Optional

from pydantic import BaseModel, Field


class Search(BaseModel):
"""
测试搜索类型
"""
keywords: str = Field(None, description="关键词")
text: str = Field(None, description="文本")
keywords: Optional[str] = Field(None, description="关键词")
text: Optional[str] = Field(None, description="文本")

def run(self):
return self.keywords + self.text


print(Search.schema())
print(Search.model_json_schema())
8 changes: 4 additions & 4 deletions docs/test_script/web_craw_note/note_unstructured.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# @Author : sudoskys
# @File : note_unstructured.py
# @Software: PyCharm
from typing import List
from typing import List, Optional

from pydantic import BaseModel, Field
from rich import print
Expand All @@ -20,13 +20,13 @@
class UnstructuredElement(BaseModel):
class Meta(BaseModel):
url: str
title: str = Field(None, alias="title")
filetype: str = Field(None, alias="filetype")
title: Optional[str] = Field(None, alias="title")
filetype: Optional[str] = Field(None, alias="filetype")
page_number: int = Field(None, alias="page_number")
languages: List[str] = Field(None, alias="languages")
category_depth: int = Field(None, alias="category_depth")
link_urls: List[str] = Field(None, alias="link_urls")
link_texts: str = Field(None, alias="link_text")
link_texts: Optional[str] = Field(None, alias="link_text")

text: str
metadata: Meta
Expand Down
6 changes: 5 additions & 1 deletion llmkira/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
# @File : error.py
# @Software: PyCharm


class ReplyNeededError(Exception):
"""
Raised a error that need reply
"""
pass

def __init__(self, message: str = None, *args):
# 拦截 url 信息
super().__init__(message, *args)


# 更安全的 format
Expand Down
8 changes: 4 additions & 4 deletions llmkira/extra/plugins/_finish.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pydantic import ConfigDict

__package__name__ = "llmkira.extra.plugins.finish"
__plugin_name__ = "finish_conversation"
__openapi_version__ = "20231111"
Expand Down Expand Up @@ -31,9 +33,7 @@

class Finish(BaseModel):
comment: str = Field(default=":)", description="end with a question or a comment.(__language: $context)")

class Config:
extra = "allow"
model_config = ConfigDict(extra="allow")


class FinishTool(BaseTool):
Expand Down Expand Up @@ -99,7 +99,7 @@ async def run(self,
"""
处理message,返回message
"""
_set = Finish.parse_obj(arg)
_set = Finish.model_validate(arg)
# META
_meta = task.task_meta.reply_message(
plugin_name=__plugin_name__,
Expand Down
8 changes: 4 additions & 4 deletions llmkira/extra/plugins/_translate_doc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pydantic import ConfigDict

__package__name__ = "llmkira.extra.plugins.translate_file"
__plugin_name__ = "translate_file"
__openapi_version__ = "20231027"
Expand Down Expand Up @@ -44,9 +46,7 @@
class Translate(BaseModel):
language: str
file_id: str

class Config:
extra = "allow"
model_config = ConfigDict(extra="allow")


class TranslateTool(BaseTool):
Expand Down Expand Up @@ -179,7 +179,7 @@ async def run(self,
for i in item.file:
_translate_file.append(i)
try:
translate_arg = Translate.parse_obj(arg)
translate_arg = Translate.model_validate(arg)
except Exception:
raise ValueError("Please specify the following parameters clearly\n file_id=xxx,language=xxx")
_file_obj = [await i.raw_file()
Expand Down
34 changes: 15 additions & 19 deletions llmkira/extra/plugins/alarm/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pydantic import field_validator, ConfigDict

__package__name__ = "llmkira.extra.plugins.alarm"
__plugin_name__ = "set_alarm_reminder"
__openapi_version__ = "20231111"
Expand All @@ -10,18 +12,17 @@

import datetime
import re
import time

from loguru import logger
from pydantic import validator, BaseModel
from pydantic import BaseModel

from llmkira.receiver.aps import SCHEDULER
from llmkira.schema import RawMessage
from llmkira.sdk.func_calling import PluginMetadata, BaseTool
from llmkira.sdk.func_calling.schema import FuncPair
from llmkira.task import Task, TaskHeader

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
from llmkira.sdk.schema import TaskBatch
Expand All @@ -44,11 +45,9 @@
class Alarm(BaseModel):
delay: int
content: str
model_config = ConfigDict(extra="allow")

class Config:
extra = "allow"

@validator("delay")
@field_validator("delay")
def delay_validator(cls, v):
if v < 0:
raise ValueError("delay must be greater than 0")
Expand All @@ -58,9 +57,9 @@ def delay_validator(cls, v):
async def send_notify(_platform, _meta, _sender: dict, _receiver: dict, _user, _chat, _content: str):
await Task(queue=_platform).send_task(
task=TaskHeader(
sender=TaskHeader.Location.parse_obj(_sender), # 继承发送者
receiver=TaskHeader.Location.parse_obj(_receiver), # 因为可能有转发,所以可以单配
task_meta=TaskHeader.Meta.parse_obj(_meta),
sender=TaskHeader.Location.model_validate(_sender), # 继承发送者
receiver=TaskHeader.Location.model_validate(_receiver), # 因为可能有转发,所以可以单配
task_meta=TaskHeader.Meta.model_validate(_meta),
message=[
RawMessage(
user_id=_user,
Expand All @@ -79,7 +78,7 @@ class AlarmTool(BaseTool):
silent: bool = False
function: Function = alarm
keywords: list = ["闹钟", "提醒", "定时", "到点", '分钟']
pattern = re.compile(r"(\d+)(分钟|小时|天|周|月|年)后提醒我(.*)")
pattern: Optional[re.Pattern] = re.compile(r"(\d+)(分钟|小时|天|周|月|年)后提醒我(.*)")
require_auth: bool = True

# env_required: list = ["SCHEDULER", "TIMEZONE"]
Expand Down Expand Up @@ -148,7 +147,7 @@ async def run(self,
"""
处理message,返回message
"""
_set = Alarm.parse_obj(arg)
_set = Alarm.model_validate(arg)
_meta = task.task_meta.reply_message(
plugin_name=__plugin_name__,
callback=[
Expand All @@ -163,22 +162,19 @@ async def run(self,
logger.debug("Plugin:set alarm {} minutes later".format(_set.delay))
SCHEDULER.add_job(
func=send_notify,
id=str(time.time()),
id=str(receiver.user_id),
trigger="date",
replace_existing=True,
misfire_grace_time=1000,
run_date=datetime.datetime.now() + datetime.timedelta(minutes=_set.delay),
args=[
task.receiver.platform,
_meta.dict(),
task.sender.dict(), receiver.dict(),
_meta.model_dump(),
task.sender.model_dump(), receiver.model_dump(),
receiver.user_id, receiver.chat_id,
_set.content
]
)
try:
SCHEDULER.start()
except Exception as e:
print(f"[155035]{e}")
await Task(queue=receiver.platform).send_task(
task=TaskHeader(
sender=task.sender, # 继承发送者
Expand Down
12 changes: 8 additions & 4 deletions llmkira/extra/plugins/search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pydantic import ConfigDict

__package__name__ = "llmkira.extra.plugins.search"
__plugin_name__ = "search_in_google"
__openapi_version__ = "20231111"
Expand All @@ -25,6 +27,10 @@
search = Function(
name=__plugin_name__,
description="Search/validate on google.com.[ONLY IF NECESSARY]",
).update_config(
config=Function.FunctionExtra(
system_prompt='Search only if necessary',
)
)
search.add_property(
property_name="keywords",
Expand Down Expand Up @@ -70,9 +76,7 @@ def search_on_duckduckgo(search_sentence: str, key_words: str = None):

class Search(BaseModel):
keywords: str

class Config:
extra = "allow"
model_config = ConfigDict(extra="allow")


class SearchTool(BaseTool):
Expand Down Expand Up @@ -196,7 +200,7 @@ async def run(self,
处理message,返回message
"""

_set = Search.parse_obj(arg)
_set = Search.model_validate(arg)
_search_result = search_on_duckduckgo(_set.keywords)
# META
_meta = task.task_meta.reply_raw(
Expand Down
Loading

0 comments on commit 9874567

Please sign in to comment.