aidev-wxbot 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ ### Django template
2
+ *.log
3
+ *.pot
4
+ *.pyc
5
+ __pycache__/
6
+ local_settings.py
7
+ db.sqlite3
8
+ db.sqlite3-journal
9
+ media
10
+
11
+ # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
12
+ # in your Git repository. Update and uncomment the following line accordingly.
13
+ # <django-project-name>/staticfiles/
14
+ staticfiles
15
+
16
+ ### Python template
17
+ # Byte-compiled / optimized / DLL files
18
+ __pycache__/
19
+ *.py[cod]
20
+ *$py.class
21
+
22
+ # C extensions
23
+ *.so
24
+
25
+ # Distribution / packaging
26
+ .Python
27
+ build/
28
+ develop-eggs/
29
+ dist/
30
+ downloads/
31
+ eggs/
32
+ .eggs/
33
+ lib64/
34
+ parts/
35
+ sdist/
36
+ var/
37
+ wheels/
38
+ share/python-wheels/
39
+ *.egg-info/
40
+ .installed.cfg
41
+ *.egg
42
+ MANIFEST
43
+
44
+ # PyInstaller
45
+ # Usually these files are written by a python script from a template
46
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
47
+ *.manifest
48
+ *.spec
49
+
50
+ # Installer logs
51
+ pip-log.txt
52
+ pip-delete-this-directory.txt
53
+
54
+ # Unit test / coverage reports
55
+ htmlcov/
56
+ .tox/
57
+ .nox/
58
+ .coverage
59
+ .coverage.*
60
+ .cache
61
+ nosetests.xml
62
+ coverage.xml
63
+ *.cover
64
+ *.py,cover
65
+ .hypothesis/
66
+ .pytest_cache/
67
+ cover/
68
+
69
+ # Translations
70
+ *.mo
71
+ *.pot
72
+
73
+ # Django stuff:
74
+ *.log
75
+ local_settings.py
76
+ db.sqlite3
77
+ db.sqlite3-journal
78
+
79
+ # Flask stuff:
80
+ instance/
81
+ .webassets-cache
82
+
83
+ # Scrapy stuff:
84
+ .scrapy
85
+
86
+ # Sphinx documentation
87
+ docs/_build/
88
+
89
+ # PyBuilder
90
+ .pybuilder/
91
+ target/
92
+
93
+ # Jupyter Notebook
94
+ .ipynb_checkpoints
95
+
96
+ # IPython
97
+ profile_default/
98
+ ipython_config.py
99
+
100
+ # pyenv
101
+ .python-version
102
+
103
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
104
+ __pypackages__/
105
+
106
+ # Celery stuff
107
+ celerybeat-schedule
108
+ celerybeat.pid
109
+
110
+ # SageMath parsed files
111
+ *.sage.py
112
+
113
+ # Environments
114
+ .env
115
+ .envrc
116
+ .venv
117
+ env/
118
+ venv/
119
+ ENV/
120
+ env.bak/
121
+ venv.bak/
122
+
123
+ # Spyder project settings
124
+ .spyderproject
125
+ .spyproject
126
+
127
+ # Rope project settings
128
+ .ropeproject
129
+
130
+ # mkdocs documentation
131
+ /site
132
+
133
+ # mypy
134
+ .mypy_cache/
135
+ .dmypy.json
136
+ dmypy.json
137
+
138
+ # Pyre type checker
139
+ .pyre/
140
+
141
+ # pytype static type analyzer
142
+ .pytype/
143
+
144
+ # Cython debug symbols
145
+ cython_debug/
146
+
147
+ # PyCharm
148
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
149
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
150
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
151
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
152
+ .idea/
153
+ .codecc/
154
+ .pdm-build
155
+
156
+ pre-*-bkcodeai
157
+ *.xml
158
+ local_framework_settings.py
159
+ .DS_Store
160
+ v3logs/
161
+ logs/
162
+
163
+ ### PreCI ###
164
+ .codecc
165
+ build.yml
166
+ # BK CodeAI
167
+ bkcodeai.json
168
+
169
+ # apigw
170
+ src/aidev/support-files/openapi.yaml
171
+ src/aidev/support-files/resources.yaml
172
+ src/aidev/support-files/apidocs/
173
+
174
+ # vitepress
175
+ src/frontend/web/docs/.vitepress/cache/
176
+ src/frontend/web/docs/.vitepress/temp/
177
+ src/frontend/web/docs/.vitepress/dist/
178
+
179
+ # node_modules
180
+ src/frontend/node_modules/
181
+ src/frontend/ai-blueking/node_modules/
182
+ src/frontend/web/node_modules/
183
+ src/frontend/vue2-playground/node_modules/
184
+ src/frontend/publish-template/node_modules/
185
+
186
+ # lesscode dist
187
+ src/frontend/ai-blueking/lesscode-dist/
188
+
189
+ # pnpm-lock.yaml
190
+ pnpm-lock.yaml
191
+
192
+ # pnpm-workspace.yaml
193
+ pnpm-workspace.yaml
194
+ .aider*
195
+ .vscode/
@@ -0,0 +1,42 @@
1
+ # 导入子目录中的 Makefile 文件
2
+ ROOT_DIR?=$(shell git rev-parse --show-toplevel)/src/agent
3
+ pytest = uv run --no-sync pytest -c ${ROOT_DIR}/pyproject.toml
4
+
5
+
6
+ .PHONY: ALL
7
+ ALL: init
8
+
9
+ uv.lock: pyproject.toml
10
+ uv lock
11
+ uv lock --check
12
+
13
+ .PHONY: requirements
14
+ requirements: requirements.txt
15
+
16
+ .PHONY: requirements.txt
17
+ requirements.txt: pyproject.toml
18
+ uv export --no-hashes --no-annotate --no-dev --no-editable --no-header --format requirements-txt | awk 'NR>1' > requirements.txt
19
+
20
+ .PHONY: init-project
21
+ init: uv-install
22
+ @echo "Project initialization complete."
23
+
24
+ .PHONY: uv-install
25
+ uv-install:
26
+ uv --version
27
+ uv sync --inexact
28
+
29
+
30
+ build:
31
+ uv pip install build
32
+ uv run -m build
33
+
34
+ .PHONY: clean
35
+ clean:
36
+ find . -name '*.pyc' -type f -delete
37
+ find . -name "__pycache__" | xargs rm -rf
38
+ find . -name ".mypy_cache" | xargs rm -rf
39
+ find . -name ".cache" | xargs rm -rf
40
+ rm -rf ./dist
41
+ rm -rf .venv
42
+ uv clean
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: aidev-wxbot
3
+ Version: 1.0.0
4
+ Summary: A Django app for WeChat AI bot integration with BK AI Dev platform
5
+ Author: tencentblueking
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: django<5.0,>=4.0
16
+ Requires-Dist: djangorestframework>=3.14.0
17
+ Requires-Dist: pika<2.0,>=1.3.0
18
+ Requires-Dist: pycryptodome>=3.23.0
19
+ Requires-Dist: pydantic>=2.11.7
20
+ Requires-Dist: requests>=2.32.5
21
+ Requires-Dist: stackprinter>=0.2.12
22
+ Description-Content-Type: text/markdown
23
+
24
+ # aidev-wxbot-plugin
25
+
26
+ A WeChat bot plugin for bkaidev platform.
27
+
28
+ ## Description
29
+
30
+ This plugin provides WeChat bot functionality for the bkaidev platform, enabling automated message handling and responses.
31
+
32
+ ## Features
33
+
34
+ - WeChat message callback handling
35
+ - Automated message processing
36
+ - Integration with bkaidev platform
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install aidev_wxbot
42
+ ```
43
+
44
+ ## Usage
45
+
46
+ Configure the plugin in your bkaidev platform and set up the WeChat bot callback URL.
47
+
48
+ ## License
49
+
50
+ MIT License
@@ -0,0 +1,27 @@
1
+ # aidev-wxbot-plugin
2
+
3
+ A WeChat bot plugin for bkaidev platform.
4
+
5
+ ## Description
6
+
7
+ This plugin provides WeChat bot functionality for the bkaidev platform, enabling automated message handling and responses.
8
+
9
+ ## Features
10
+
11
+ - WeChat message callback handling
12
+ - Automated message processing
13
+ - Integration with bkaidev platform
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install aidev_wxbot
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Configure the plugin in your bkaidev platform and set up the WeChat bot callback URL.
24
+
25
+ ## License
26
+
27
+ MIT License
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ aidev_wxbot Django app.
5
+
6
+ A Django app for WeChat AI bot integration with BK AI Dev platform.
7
+ """
8
+
9
+ default_app_config = "aidev_wxbot.apps.AidevWxbotConfig"
10
+
11
+ __version__ = "1.0.0"
12
+ __author__ = "tencentblueking"
@@ -0,0 +1,85 @@
1
+ import json
2
+ from logging import getLogger
3
+
4
+ import requests
5
+ from django.conf import settings
6
+
7
+ logger = getLogger(__name__)
8
+
9
+
10
+ class ActionFailed(Exception):
11
+ """
12
+ Action failed to execute.
13
+ """
14
+
15
+ def __init__(self, code, info=None):
16
+ self.code = code
17
+ self.info = info
18
+
19
+
20
+ class Api(object):
21
+ def __init__(self, base_url):
22
+ self.base_url = base_url
23
+
24
+ def get_auth_header(self, bk_username):
25
+ return {}
26
+
27
+ def call_action(self, action: str, method="POST", bk_username="admin", **params):
28
+ if not bk_username:
29
+ bk_username = (
30
+ params.get("json", {}).get("bk_username", None)
31
+ or params.get("params", {}).get("bk_username", None)
32
+ or "admin"
33
+ )
34
+ auth_header = self.get_auth_header(bk_username)
35
+ url = f"{self.base_url}/{action}"
36
+ if "headers" not in params:
37
+ params["headers"] = auth_header
38
+ else:
39
+ params["headers"].update(auth_header)
40
+ logger.info(
41
+ f"\n-----call action-----\n {method}\n {url}\n"
42
+ f" {json.dumps(params, ensure_ascii=False)} \n-------------------"
43
+ )
44
+ try:
45
+ response = requests.request(method, url, **params)
46
+ logger.info(f"\n-----resp-----\n {response.url} {response.text}")
47
+ if 200 <= response.status_code < 300:
48
+ result = response.json()
49
+ if isinstance(result, dict):
50
+ if (
51
+ result.get("result", False)
52
+ or result.get("code", -1) == 0
53
+ or result.get("status", -1) != -1
54
+ or result.get("errcode", 1) == 0
55
+ ):
56
+ return result.get("data", result)
57
+ logger.error(result)
58
+ raise ActionFailed(code=result.get("code"), info=result)
59
+
60
+ logger.error(response.text)
61
+ except Exception as e:
62
+ logger.error(e)
63
+ raise e
64
+
65
+
66
+ class BkApi(Api):
67
+ BK_APIGW_MANAGER_URL_TMPL = settings.BK_APIGW_MANAGER_URL_TMPL
68
+ BKPAAS_ENVIRONMENT = settings.BKPAAS_ENVIRONMENT
69
+ BKPAAS_APP_SECRET = settings.BKPAAS_APP_SECRET
70
+ BKPAAS_APP_CODE = settings.BKPAAS_APP_CODE
71
+
72
+ def __init__(self, api_name):
73
+ base_url = f"{self.BK_APIGW_MANAGER_URL_TMPL}/{self.BKPAAS_ENVIRONMENT}".format(api_name=api_name)
74
+ super().__init__(base_url)
75
+
76
+ def get_auth_header(self, bk_username):
77
+ return {
78
+ "X-Bkapi-Authorization": json.dumps(
79
+ {
80
+ "bk_app_code": self.BKPAAS_APP_CODE,
81
+ "bk_app_secret": self.BKPAAS_APP_SECRET,
82
+ "bk_username": bk_username,
83
+ }
84
+ )
85
+ }
@@ -0,0 +1,34 @@
1
+ from django.conf import settings
2
+
3
+ from aidev_wxbot.api import BkApi
4
+
5
+
6
+ class BkAiDevApi:
7
+ def __init__(self):
8
+ self.api = BkApi("bkaidev")
9
+
10
+ def retrieve_agent_channel_configs(self, channel_type):
11
+ return self.api.call_action(
12
+ f"openapi/aidev/resource/v1/agent_channel/configs/?channel_type={channel_type}/", "GET"
13
+ )
14
+
15
+ def convert_to_rtx(self, open_id):
16
+ return self.api.call_action("resource/v1/qyweixin/convert_to_userid/", "POST", json={"open_id": open_id})
17
+
18
+
19
+ class AgentBackend:
20
+ def __init__(self):
21
+ self.api = BkApi(settings.BKPAAS_BK_PLUGIN_APIGW_NAME)
22
+
23
+ def invoke(self, content):
24
+ data = {
25
+ "inputs": {
26
+ "command": "chat",
27
+ "input": content,
28
+ "stream": False,
29
+ "chat_history": [{"role": "user", "content": content}],
30
+ "context": [],
31
+ },
32
+ "context": {"executor": "user"},
33
+ }
34
+ return self.api.call_action("invoke/1.0.0assistant", "POST", json=data)
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Django app configuration for aidev_wxbot.
5
+ """
6
+
7
+ from django.apps import AppConfig
8
+
9
+
10
+ class AidevWxbotConfig(AppConfig):
11
+ """Configuration for aidev_wxbot Django app."""
12
+
13
+ default_auto_field = "django.db.models.BigAutoField"
14
+ name = "aidev_wxbot"
15
+ verbose_name = "AI Dev WeChat Bot"
16
+
17
+ def ready(self):
18
+ """Initialize the app when Django starts."""
19
+ # 这里可以添加应用启动时需要执行的代码
@@ -0,0 +1,49 @@
1
+ from typing import Union
2
+
3
+ from pydantic import BaseConfig, BaseModel, ConfigDict, Field
4
+
5
+ from aidev_wxbot.context.message import Message
6
+ from aidev_wxbot.utils import AttrDict
7
+
8
+
9
+ class Context(BaseModel):
10
+ # config类信息:
11
+ model_config = ConfigDict(
12
+ arbitrary_types_allowed=True, json_encoders={BaseConfig: lambda v: v.to_dict(), AttrDict: lambda v: v.to_dict()}
13
+ )
14
+ msg_proxy_config: Union[BaseConfig, AttrDict, None] = Field(default=None, description="msg proxy config")
15
+
16
+ # message相关:
17
+ message: Union[Message, None] = Field(default=None, description="message content")
18
+ # message来源信息:
19
+ from_type: Union[str, None] = Field(default=None, description="whether message is from group or single")
20
+ sender_id: Union[str, None] = Field(default=None, description="sender id")
21
+ sender_code: Union[str, None] = Field(default=None, description="sender code")
22
+ group_id: Union[str, None] = Field(default=None, description="message group id")
23
+ create_time: Union[str, None] = Field(default=None, description="message send time, default str")
24
+ to_me: bool = Field(default=False, description="whether message is send to bot")
25
+
26
+ # api:
27
+ payload: Union[dict, None] = Field(default=None, description="params from api request")
28
+ action: Union[str, None] = Field(default=None, description="api action name")
29
+
30
+ # other param:
31
+ param_value: Union[str, None] = Field(default=None, description="set param value in this attribute")
32
+ param_name: Union[str, None] = Field(default=None, description="set waiting param name in this attribute")
33
+
34
+ def __getitem__(self, item):
35
+ """
36
+ Compatible with older versions using like a dict
37
+ :param item:
38
+ :return:
39
+ """
40
+ return getattr(self, item)
41
+
42
+ def get(self, item, default=None):
43
+ """
44
+ Compatible with older versions using like a dict
45
+ :param default:
46
+ :param item:
47
+ :return:
48
+ """
49
+ return getattr(self, item, default)