YYP0502 commited on
Commit
9ec9071
·
verified ·
1 Parent(s): 3a0502a

Upload 10 files

Browse files
Files changed (10) hide show
  1. .dockerignore +6 -0
  2. .env.example +16 -0
  3. .gitignore +7 -0
  4. DEPLOY.md +24 -0
  5. Dockerfile +17 -105
  6. README.md +12 -13
  7. nginx.conf +29 -0
  8. package-lock.json +592 -0
  9. package.json +9 -0
  10. tsconfig.json +8 -0
.dockerignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ node_modules
2
+ dist
3
+ data
4
+ workspace
5
+ .env
6
+ .git
.env.example ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Space Settings: Secrets
2
+ QQBOT_APP_ID=
3
+ QQBOT_APP_SECRET=
4
+ CODEX_API_KEY=
5
+ JUPYTER_TOKEN=long-random-secret
6
+ # Space Settings: Variables
7
+ QQ_ALLOWED_OPENIDS=
8
+ CODEX_BASE_URL=https://provider.example/v1
9
+ CODEX_MODEL=your-model
10
+ # Optional
11
+ CODEX_REASONING_EFFORT=high
12
+ CODEX_SANDBOX=workspace-write
13
+ CODEX_TIMEOUT_MS=300000
14
+ MAX_REPLY_CHARS=3500
15
+ HISTORY_TURNS=8
16
+ MAX_INPUT_FILE_BYTES=20971520
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ node_modules/
2
+ dist/
3
+ data/
4
+ workspace/
5
+ .env
6
+ *.log
7
+ __pycache__/
DEPLOY.md ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 部署说明
2
+
3
+ ## 平台资格
4
+ Hugging Face 当前文档规定:新建 Docker SDK Space 需要付费计划(个人 PRO,组织 Team/Enterprise);CPU Basic 运行硬件本身不计时费。若你的账号只有免费计划,无法保证创建此 Docker Space。已有符合资格的 Docker Space 可以直接部署。
5
+ 免费 CPU Basic 仍可能因闲置休眠;外部轮询不是官方常驻运行保障。
6
+
7
+ ## 部署
8
+ 1. 创建 Docker SDK Space,将本目录所有非忽略文件提交到 Space 仓库根目录;README.md 中 app_port 为 7860。
9
+ 2. 在 Space Settings 添加 Secrets:QQBOT_APP_ID、QQBOT_APP_SECRET、CODEX_API_KEY、JUPYTER_TOKEN(长随机值)。添加 Variables:QQ_ALLOWED_OPENIDS、CODEX_BASE_URL、CODEX_MODEL。密钥不要提交到仓库。
10
+ 3. CODEX_BASE_URL 应是兼容 OpenAI Responses API 的供应商地址;CODEX_MODEL 是该供应商真实模型 ID。当前 Codex 不支持将 wire_api 设为 chat;仅 Chat Completions 的供应商不可直接使用。
11
+ 4. 构建完成后访问 Space 的 .hf.space 地址,输入 JUPYTER_TOKEN 登录 JupyterLab。QQ 机器人在同一容器自动启动;私聊发送 /status 验证。
12
+ 5. 会话写入 data/history.json 并在每次启动时重新置空;容器文件层及 workspace 在重建时可能丢失,不要存放长期需要的文件。
13
+
14
+ ## UptimeRobot
15
+ Space 上线并取得真实公开域名后,在 UptimeRobot 选择 HTTP(s) monitor,URL 填 https://你的实际子域名.hf.space/health,免费计划通常每 5 分钟检查一次。该端点仅在 QQ 进程与 JupyterLab 均存活时返回 HTTP 200 和 ok。
16
+ 不要选 Heartbeat/Cron 类型:它要求应用向 UptimeRobot 主动发送请求,而这里是外部服务请求 Space。
17
+ 需要实际 Space URL 及 UptimeRobot 登录/授权才能创建远程监控;这里只提供可部署的端点和配置说明。外部心跳不能保证避免平台强制休眠或重启。
18
+
19
+ ## 安全
20
+ 公网 /health 不暴露令牌或聊天内容。JupyterLab 本身必须用 JUPYTER_TOKEN 保护;有访问权者可读取容器内运行时环境变量,请勿分享令牌。不要上传原项目的 .env、data 或 node_modules。原 qq-codex-bridge 未修改。
21
+
22
+ ## Codex CLI 与 JupyterLab
23
+ 容器内全局安装 Codex CLI,JupyterLab 的 Terminal 中可直接执行 codex、codex --help 或 codex exec。QQ 机器人调用的也是同一份 CLI 和同一容器用户环境。CODEX_WORKDIR 默认是 /home/node/app/workspace,JupyterLab 根目录与它一致。
24
+ 每次容器启动会清空 workspace 顶层内容、data/history.json、日志和临时 Codex 输出文件;因此重启后聊天上下文与工作文件都会丢弃并重新创建。不要将 CODEX_WORKDIR 指向挂载卷或持久化目录。
Dockerfile CHANGED
@@ -1,105 +1,17 @@
1
- FROM nvidia/cuda:12.5.1-cudnn-devel-ubuntu20.04
2
-
3
- ENV DEBIAN_FRONTEND=noninteractive \
4
- TZ=Europe/Paris
5
-
6
- # Remove any third-party apt sources to avoid issues with expiring keys.
7
- # Install some basic utilities
8
- RUN rm -f /etc/apt/sources.list.d/*.list && \
9
- apt-get update && apt-get install -y --no-install-recommends \
10
- curl \
11
- ca-certificates \
12
- sudo \
13
- git \
14
- wget \
15
- procps \
16
- git-lfs \
17
- zip \
18
- unzip \
19
- htop \
20
- vim \
21
- nano \
22
- bzip2 \
23
- libx11-6 \
24
- build-essential \
25
- libsndfile-dev \
26
- software-properties-common \
27
- && rm -rf /var/lib/apt/lists/*
28
-
29
- RUN add-apt-repository ppa:flexiondotorg/nvtop && \
30
- apt-get upgrade -y && \
31
- apt-get install -y --no-install-recommends nvtop
32
-
33
- RUN curl -sL https://deb.nodesource.com/setup_21.x | bash - && \
34
- apt-get install -y nodejs && \
35
- npm install -g configurable-http-proxy
36
-
37
- # Create a working directory
38
- WORKDIR /app
39
-
40
- # Create a non-root user and switch to it
41
- RUN adduser --disabled-password --gecos '' --shell /bin/bash user \
42
- && chown -R user:user /app
43
- RUN echo "user ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-user
44
- USER user
45
-
46
- # All users can use /home/user as their home directory
47
- ENV HOME=/home/user
48
- RUN mkdir $HOME/.cache $HOME/.config \
49
- && chmod -R 777 $HOME
50
-
51
- # Set up the Conda environment
52
- ENV CONDA_AUTO_UPDATE_CONDA=false \
53
- PATH=$HOME/miniconda/bin:$PATH
54
- RUN curl -sLo ~/miniconda.sh https://repo.continuum.io/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh \
55
- && chmod +x ~/miniconda.sh \
56
- && ~/miniconda.sh -b -p ~/miniconda \
57
- && rm ~/miniconda.sh \
58
- && conda clean -ya
59
-
60
- WORKDIR $HOME/app
61
-
62
- #######################################
63
- # Start root user section
64
- #######################################
65
-
66
- USER root
67
-
68
- # User Debian packages
69
- ## Security warning : Potential user code executed as root (build time)
70
- RUN --mount=target=/root/packages.txt,source=packages.txt \
71
- apt-get update && \
72
- xargs -r -a /root/packages.txt apt-get install -y --no-install-recommends \
73
- && rm -rf /var/lib/apt/lists/*
74
-
75
- RUN --mount=target=/root/on_startup.sh,source=on_startup.sh,readwrite \
76
- bash /root/on_startup.sh
77
-
78
- RUN mkdir /data && chown user:user /data
79
-
80
- #######################################
81
- # End root user section
82
- #######################################
83
-
84
- USER user
85
-
86
- # Python packages
87
- RUN --mount=target=requirements.txt,source=requirements.txt \
88
- pip install --no-cache-dir --upgrade -r requirements.txt
89
-
90
- # Copy the current directory contents into the container at $HOME/app setting the owner to the user
91
- COPY --chown=user . $HOME/app
92
-
93
- RUN chmod +x start_server.sh
94
-
95
- COPY --chown=user login.html /home/user/miniconda/lib/python3.9/site-packages/jupyter_server/templates/login.html
96
-
97
- ENV PYTHONUNBUFFERED=1 \
98
- GRADIO_ALLOW_FLAGGING=never \
99
- GRADIO_NUM_PORTS=1 \
100
- GRADIO_SERVER_NAME=0.0.0.0 \
101
- GRADIO_THEME=huggingface \
102
- SYSTEM=spaces \
103
- SHELL=/bin/bash
104
-
105
- CMD ["./start_server.sh"]
 
1
+ FROM node:22-bookworm-slim
2
+ ENV DEBIAN_FRONTEND=noninteractive HOME=/home/node CODEX_COMMAND=codex CODEX_WORKDIR=/home/node/app/workspace CODEX_SANDBOX=workspace-write
3
+ ENV PATH=/home/node/.npm-global/bin:/home/node/venv/bin:$PATH
4
+ RUN apt-get update && apt-get install -y --no-install-recommends python3 python3-venv nginx ca-certificates tini bash && rm -rf /var/lib/apt/lists/* && mkdir -p /home/node/app /home/node/.npm-global /tmp/nginx && chown -R node:node /home/node /tmp/nginx
5
+ WORKDIR /home/node/app
6
+ COPY package.json package-lock.json ./
7
+ RUN npm ci && npm install -g --prefix /home/node/.npm-global @openai/codex && python3 -m venv /home/node/venv && /home/node/venv/bin/pip install --no-cache-dir jupyterlab
8
+ COPY tsconfig.json ./
9
+ COPY src ./src
10
+ RUN npm run build && chown -R node:node /home/node/app
11
+ COPY --chown=node:node nginx.conf ./nginx.conf
12
+ COPY --chown=node:node scripts/ ./scripts/
13
+ RUN chmod +x scripts/start.sh
14
+ USER node
15
+ EXPOSE 7860
16
+ ENTRYPOINT ["/usr/bin/tini", "--"]
17
+ CMD ["./scripts/start.sh"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,13 +1,12 @@
1
- ---
2
- title: Bot
3
- emoji: 💻🐳
4
- colorFrom: gray
5
- colorTo: green
6
- sdk: docker
7
- pinned: false
8
- tags:
9
- - jupyterlab
10
- suggested_storage: small
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: QQ Codex Jupyter Bridge
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: gray
6
+ sdk: docker
7
+ app_port: 7860
8
+ ---
9
+
10
+ # QQ Codex Bridge + JupyterLab
11
+
12
+ The Space serves JupyterLab and starts the QQ bot. See DEPLOY.md.
 
nginx.conf ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ worker_processes 1;
2
+ pid /tmp/nginx/nginx.pid;
3
+ error_log /dev/stderr warn;
4
+ events { worker_connections 1024; }
5
+ http {
6
+ access_log /dev/stdout;
7
+ client_body_temp_path /tmp/nginx/client_body;
8
+ proxy_temp_path /tmp/nginx/proxy;
9
+ fastcgi_temp_path /tmp/nginx/fastcgi;
10
+ uwsgi_temp_path /tmp/nginx/uwsgi;
11
+ scgi_temp_path /tmp/nginx/scgi;
12
+ server {
13
+ listen 7860;
14
+ server_name _;
15
+ location = /health { proxy_pass http://127.0.0.1:7861/health; access_log off; }
16
+ location / {
17
+ proxy_pass http://127.0.0.1:8888;
18
+ proxy_http_version 1.1;
19
+ proxy_set_header Host $host;
20
+ proxy_set_header X-Forwarded-Proto https;
21
+ proxy_set_header X-Forwarded-Host $host;
22
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23
+ proxy_set_header Upgrade $http_upgrade;
24
+ proxy_set_header Connection upgrade;
25
+ proxy_read_timeout 3600;
26
+ proxy_buffering off;
27
+ }
28
+ }
29
+ }
package-lock.json ADDED
@@ -0,0 +1,592 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "qq-codex-bridge",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "qq-codex-bridge",
9
+ "version": "1.0.0",
10
+ "dependencies": {
11
+ "@tencent-connect/qqbot-nodejs": "^1.0.4",
12
+ "dotenv": "^16.4.7"
13
+ },
14
+ "devDependencies": {
15
+ "@types/node": "^22.10.2",
16
+ "tsx": "^4.19.2",
17
+ "typescript": "^5.7.2"
18
+ }
19
+ },
20
+ "node_modules/@esbuild/aix-ppc64": {
21
+ "version": "0.28.2",
22
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
23
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
24
+ "cpu": [
25
+ "ppc64"
26
+ ],
27
+ "dev": true,
28
+ "optional": true,
29
+ "os": [
30
+ "aix"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18"
34
+ }
35
+ },
36
+ "node_modules/@esbuild/android-arm": {
37
+ "version": "0.28.2",
38
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
39
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
40
+ "cpu": [
41
+ "arm"
42
+ ],
43
+ "dev": true,
44
+ "optional": true,
45
+ "os": [
46
+ "android"
47
+ ],
48
+ "engines": {
49
+ "node": ">=18"
50
+ }
51
+ },
52
+ "node_modules/@esbuild/android-arm64": {
53
+ "version": "0.28.2",
54
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
55
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
56
+ "cpu": [
57
+ "arm64"
58
+ ],
59
+ "dev": true,
60
+ "optional": true,
61
+ "os": [
62
+ "android"
63
+ ],
64
+ "engines": {
65
+ "node": ">=18"
66
+ }
67
+ },
68
+ "node_modules/@esbuild/android-x64": {
69
+ "version": "0.28.2",
70
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
71
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
72
+ "cpu": [
73
+ "x64"
74
+ ],
75
+ "dev": true,
76
+ "optional": true,
77
+ "os": [
78
+ "android"
79
+ ],
80
+ "engines": {
81
+ "node": ">=18"
82
+ }
83
+ },
84
+ "node_modules/@esbuild/darwin-arm64": {
85
+ "version": "0.28.2",
86
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
87
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
88
+ "cpu": [
89
+ "arm64"
90
+ ],
91
+ "dev": true,
92
+ "optional": true,
93
+ "os": [
94
+ "darwin"
95
+ ],
96
+ "engines": {
97
+ "node": ">=18"
98
+ }
99
+ },
100
+ "node_modules/@esbuild/darwin-x64": {
101
+ "version": "0.28.2",
102
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
103
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
104
+ "cpu": [
105
+ "x64"
106
+ ],
107
+ "dev": true,
108
+ "optional": true,
109
+ "os": [
110
+ "darwin"
111
+ ],
112
+ "engines": {
113
+ "node": ">=18"
114
+ }
115
+ },
116
+ "node_modules/@esbuild/freebsd-arm64": {
117
+ "version": "0.28.2",
118
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
119
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
120
+ "cpu": [
121
+ "arm64"
122
+ ],
123
+ "dev": true,
124
+ "optional": true,
125
+ "os": [
126
+ "freebsd"
127
+ ],
128
+ "engines": {
129
+ "node": ">=18"
130
+ }
131
+ },
132
+ "node_modules/@esbuild/freebsd-x64": {
133
+ "version": "0.28.2",
134
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
135
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
136
+ "cpu": [
137
+ "x64"
138
+ ],
139
+ "dev": true,
140
+ "optional": true,
141
+ "os": [
142
+ "freebsd"
143
+ ],
144
+ "engines": {
145
+ "node": ">=18"
146
+ }
147
+ },
148
+ "node_modules/@esbuild/linux-arm": {
149
+ "version": "0.28.2",
150
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
151
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
152
+ "cpu": [
153
+ "arm"
154
+ ],
155
+ "dev": true,
156
+ "optional": true,
157
+ "os": [
158
+ "linux"
159
+ ],
160
+ "engines": {
161
+ "node": ">=18"
162
+ }
163
+ },
164
+ "node_modules/@esbuild/linux-arm64": {
165
+ "version": "0.28.2",
166
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
167
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
168
+ "cpu": [
169
+ "arm64"
170
+ ],
171
+ "dev": true,
172
+ "optional": true,
173
+ "os": [
174
+ "linux"
175
+ ],
176
+ "engines": {
177
+ "node": ">=18"
178
+ }
179
+ },
180
+ "node_modules/@esbuild/linux-ia32": {
181
+ "version": "0.28.2",
182
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
183
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
184
+ "cpu": [
185
+ "ia32"
186
+ ],
187
+ "dev": true,
188
+ "optional": true,
189
+ "os": [
190
+ "linux"
191
+ ],
192
+ "engines": {
193
+ "node": ">=18"
194
+ }
195
+ },
196
+ "node_modules/@esbuild/linux-loong64": {
197
+ "version": "0.28.2",
198
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
199
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
200
+ "cpu": [
201
+ "loong64"
202
+ ],
203
+ "dev": true,
204
+ "optional": true,
205
+ "os": [
206
+ "linux"
207
+ ],
208
+ "engines": {
209
+ "node": ">=18"
210
+ }
211
+ },
212
+ "node_modules/@esbuild/linux-mips64el": {
213
+ "version": "0.28.2",
214
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
215
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
216
+ "cpu": [
217
+ "mips64el"
218
+ ],
219
+ "dev": true,
220
+ "optional": true,
221
+ "os": [
222
+ "linux"
223
+ ],
224
+ "engines": {
225
+ "node": ">=18"
226
+ }
227
+ },
228
+ "node_modules/@esbuild/linux-ppc64": {
229
+ "version": "0.28.2",
230
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
231
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
232
+ "cpu": [
233
+ "ppc64"
234
+ ],
235
+ "dev": true,
236
+ "optional": true,
237
+ "os": [
238
+ "linux"
239
+ ],
240
+ "engines": {
241
+ "node": ">=18"
242
+ }
243
+ },
244
+ "node_modules/@esbuild/linux-riscv64": {
245
+ "version": "0.28.2",
246
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
247
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
248
+ "cpu": [
249
+ "riscv64"
250
+ ],
251
+ "dev": true,
252
+ "optional": true,
253
+ "os": [
254
+ "linux"
255
+ ],
256
+ "engines": {
257
+ "node": ">=18"
258
+ }
259
+ },
260
+ "node_modules/@esbuild/linux-s390x": {
261
+ "version": "0.28.2",
262
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
263
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
264
+ "cpu": [
265
+ "s390x"
266
+ ],
267
+ "dev": true,
268
+ "optional": true,
269
+ "os": [
270
+ "linux"
271
+ ],
272
+ "engines": {
273
+ "node": ">=18"
274
+ }
275
+ },
276
+ "node_modules/@esbuild/linux-x64": {
277
+ "version": "0.28.2",
278
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
279
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
280
+ "cpu": [
281
+ "x64"
282
+ ],
283
+ "dev": true,
284
+ "optional": true,
285
+ "os": [
286
+ "linux"
287
+ ],
288
+ "engines": {
289
+ "node": ">=18"
290
+ }
291
+ },
292
+ "node_modules/@esbuild/netbsd-arm64": {
293
+ "version": "0.28.2",
294
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
295
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
296
+ "cpu": [
297
+ "arm64"
298
+ ],
299
+ "dev": true,
300
+ "optional": true,
301
+ "os": [
302
+ "netbsd"
303
+ ],
304
+ "engines": {
305
+ "node": ">=18"
306
+ }
307
+ },
308
+ "node_modules/@esbuild/netbsd-x64": {
309
+ "version": "0.28.2",
310
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
311
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
312
+ "cpu": [
313
+ "x64"
314
+ ],
315
+ "dev": true,
316
+ "optional": true,
317
+ "os": [
318
+ "netbsd"
319
+ ],
320
+ "engines": {
321
+ "node": ">=18"
322
+ }
323
+ },
324
+ "node_modules/@esbuild/openbsd-arm64": {
325
+ "version": "0.28.2",
326
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
327
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
328
+ "cpu": [
329
+ "arm64"
330
+ ],
331
+ "dev": true,
332
+ "optional": true,
333
+ "os": [
334
+ "openbsd"
335
+ ],
336
+ "engines": {
337
+ "node": ">=18"
338
+ }
339
+ },
340
+ "node_modules/@esbuild/openbsd-x64": {
341
+ "version": "0.28.2",
342
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
343
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
344
+ "cpu": [
345
+ "x64"
346
+ ],
347
+ "dev": true,
348
+ "optional": true,
349
+ "os": [
350
+ "openbsd"
351
+ ],
352
+ "engines": {
353
+ "node": ">=18"
354
+ }
355
+ },
356
+ "node_modules/@esbuild/openharmony-arm64": {
357
+ "version": "0.28.2",
358
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
359
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
360
+ "cpu": [
361
+ "arm64"
362
+ ],
363
+ "dev": true,
364
+ "optional": true,
365
+ "os": [
366
+ "openharmony"
367
+ ],
368
+ "engines": {
369
+ "node": ">=18"
370
+ }
371
+ },
372
+ "node_modules/@esbuild/sunos-x64": {
373
+ "version": "0.28.2",
374
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
375
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
376
+ "cpu": [
377
+ "x64"
378
+ ],
379
+ "dev": true,
380
+ "optional": true,
381
+ "os": [
382
+ "sunos"
383
+ ],
384
+ "engines": {
385
+ "node": ">=18"
386
+ }
387
+ },
388
+ "node_modules/@esbuild/win32-arm64": {
389
+ "version": "0.28.2",
390
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
391
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
392
+ "cpu": [
393
+ "arm64"
394
+ ],
395
+ "dev": true,
396
+ "optional": true,
397
+ "os": [
398
+ "win32"
399
+ ],
400
+ "engines": {
401
+ "node": ">=18"
402
+ }
403
+ },
404
+ "node_modules/@esbuild/win32-ia32": {
405
+ "version": "0.28.2",
406
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
407
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
408
+ "cpu": [
409
+ "ia32"
410
+ ],
411
+ "dev": true,
412
+ "optional": true,
413
+ "os": [
414
+ "win32"
415
+ ],
416
+ "engines": {
417
+ "node": ">=18"
418
+ }
419
+ },
420
+ "node_modules/@esbuild/win32-x64": {
421
+ "version": "0.28.2",
422
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
423
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
424
+ "cpu": [
425
+ "x64"
426
+ ],
427
+ "dev": true,
428
+ "optional": true,
429
+ "os": [
430
+ "win32"
431
+ ],
432
+ "engines": {
433
+ "node": ">=18"
434
+ }
435
+ },
436
+ "node_modules/@tencent-connect/qqbot-nodejs": {
437
+ "version": "1.0.4",
438
+ "resolved": "https://registry.npmjs.org/@tencent-connect/qqbot-nodejs/-/qqbot-nodejs-1.0.4.tgz",
439
+ "integrity": "sha512-gU5HySLplczZXMUjM7NtiUACY7YfX9YlI/R9PKzCLMgLmHvwsX9L2sitsrYPMentGUr9b8NLfSaSTsndF77NBA==",
440
+ "dependencies": {
441
+ "ws": "^8.21.0"
442
+ },
443
+ "engines": {
444
+ "node": ">=18"
445
+ },
446
+ "peerDependencies": {
447
+ "mpg123-decoder": "^1.0.3",
448
+ "silk-wasm": "^3.7.1"
449
+ },
450
+ "peerDependenciesMeta": {
451
+ "mpg123-decoder": {
452
+ "optional": true
453
+ },
454
+ "silk-wasm": {
455
+ "optional": true
456
+ }
457
+ }
458
+ },
459
+ "node_modules/@types/node": {
460
+ "version": "22.20.4",
461
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.4.tgz",
462
+ "integrity": "sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==",
463
+ "dev": true,
464
+ "dependencies": {
465
+ "undici-types": "~6.21.0"
466
+ }
467
+ },
468
+ "node_modules/dotenv": {
469
+ "version": "16.6.1",
470
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
471
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
472
+ "engines": {
473
+ "node": ">=12"
474
+ },
475
+ "funding": {
476
+ "url": "https://dotenvx.com"
477
+ }
478
+ },
479
+ "node_modules/esbuild": {
480
+ "version": "0.28.2",
481
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
482
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
483
+ "dev": true,
484
+ "hasInstallScript": true,
485
+ "bin": {
486
+ "esbuild": "bin/esbuild"
487
+ },
488
+ "engines": {
489
+ "node": ">=18"
490
+ },
491
+ "optionalDependencies": {
492
+ "@esbuild/aix-ppc64": "0.28.2",
493
+ "@esbuild/android-arm": "0.28.2",
494
+ "@esbuild/android-arm64": "0.28.2",
495
+ "@esbuild/android-x64": "0.28.2",
496
+ "@esbuild/darwin-arm64": "0.28.2",
497
+ "@esbuild/darwin-x64": "0.28.2",
498
+ "@esbuild/freebsd-arm64": "0.28.2",
499
+ "@esbuild/freebsd-x64": "0.28.2",
500
+ "@esbuild/linux-arm": "0.28.2",
501
+ "@esbuild/linux-arm64": "0.28.2",
502
+ "@esbuild/linux-ia32": "0.28.2",
503
+ "@esbuild/linux-loong64": "0.28.2",
504
+ "@esbuild/linux-mips64el": "0.28.2",
505
+ "@esbuild/linux-ppc64": "0.28.2",
506
+ "@esbuild/linux-riscv64": "0.28.2",
507
+ "@esbuild/linux-s390x": "0.28.2",
508
+ "@esbuild/linux-x64": "0.28.2",
509
+ "@esbuild/netbsd-arm64": "0.28.2",
510
+ "@esbuild/netbsd-x64": "0.28.2",
511
+ "@esbuild/openbsd-arm64": "0.28.2",
512
+ "@esbuild/openbsd-x64": "0.28.2",
513
+ "@esbuild/openharmony-arm64": "0.28.2",
514
+ "@esbuild/sunos-x64": "0.28.2",
515
+ "@esbuild/win32-arm64": "0.28.2",
516
+ "@esbuild/win32-ia32": "0.28.2",
517
+ "@esbuild/win32-x64": "0.28.2"
518
+ }
519
+ },
520
+ "node_modules/fsevents": {
521
+ "version": "2.3.3",
522
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
523
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
524
+ "dev": true,
525
+ "hasInstallScript": true,
526
+ "optional": true,
527
+ "os": [
528
+ "darwin"
529
+ ],
530
+ "engines": {
531
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
532
+ }
533
+ },
534
+ "node_modules/tsx": {
535
+ "version": "4.23.15",
536
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz",
537
+ "integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==",
538
+ "dev": true,
539
+ "dependencies": {
540
+ "esbuild": "~0.28.0"
541
+ },
542
+ "bin": {
543
+ "tsx": "dist/cli.mjs"
544
+ },
545
+ "engines": {
546
+ "node": ">=18.0.0"
547
+ },
548
+ "optionalDependencies": {
549
+ "fsevents": "~2.3.3"
550
+ }
551
+ },
552
+ "node_modules/typescript": {
553
+ "version": "5.9.3",
554
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
555
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
556
+ "dev": true,
557
+ "bin": {
558
+ "tsc": "bin/tsc",
559
+ "tsserver": "bin/tsserver"
560
+ },
561
+ "engines": {
562
+ "node": ">=14.17"
563
+ }
564
+ },
565
+ "node_modules/undici-types": {
566
+ "version": "6.21.0",
567
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
568
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
569
+ "dev": true
570
+ },
571
+ "node_modules/ws": {
572
+ "version": "8.21.3",
573
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
574
+ "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
575
+ "engines": {
576
+ "node": ">=10.0.0"
577
+ },
578
+ "peerDependencies": {
579
+ "bufferutil": "^4.0.1",
580
+ "utf-8-validate": ">=5.0.2"
581
+ },
582
+ "peerDependenciesMeta": {
583
+ "bufferutil": {
584
+ "optional": true
585
+ },
586
+ "utf-8-validate": {
587
+ "optional": true
588
+ }
589
+ }
590
+ }
591
+ }
592
+ }
package.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "qq-codex-bridge",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": { "dev": "tsx src/index.ts", "build": "tsc", "start": "node dist/index.js", "doctor": "tsx src/doctor.ts" },
7
+ "dependencies": { "@tencent-connect/qqbot-nodejs": "^1.0.4", "dotenv": "^16.4.7" },
8
+ "devDependencies": { "@types/node": "^22.10.2", "tsx": "^4.19.2", "typescript": "^5.7.2" }
9
+ }
tsconfig.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext",
4
+ "strict": true, "esModuleInterop": true, "skipLibCheck": true,
5
+ "outDir": "dist", "rootDir": "src", "types": ["node"]
6
+ },
7
+ "include": ["src/**/*.ts"]
8
+ }