grok-cli-to-openai-compatible 1.2.5 → 1.3.1
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.
- package/.env.example +25 -3
- package/README-ZH.md +189 -56
- package/README.md +195 -62
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +199 -12
- package/dist/app.js.map +1 -1
- package/dist/cli/commands/admin-panel.d.ts +13 -0
- package/dist/cli/commands/admin-panel.d.ts.map +1 -0
- package/dist/cli/commands/admin-panel.js +98 -0
- package/dist/cli/commands/admin-panel.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +74 -8
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/key.d.ts +18 -0
- package/dist/cli/commands/key.d.ts.map +1 -0
- package/dist/cli/commands/key.js +81 -0
- package/dist/cli/commands/key.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +10 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +83 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/open.d.ts +1 -0
- package/dist/cli/commands/open.d.ts.map +1 -1
- package/dist/cli/commands/open.js +1 -1
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/restart.d.ts +1 -0
- package/dist/cli/commands/restart.d.ts.map +1 -1
- package/dist/cli/commands/restart.js +17 -1
- package/dist/cli/commands/restart.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +12 -0
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/start.d.ts +2 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +50 -8
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +44 -16
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/stop.d.ts +1 -0
- package/dist/cli/commands/stop.d.ts.map +1 -1
- package/dist/cli/commands/stop.js +30 -5
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/commands/update.d.ts +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +156 -33
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +112 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/db-keys.d.ts +33 -0
- package/dist/cli/lib/db-keys.d.ts.map +1 -0
- package/dist/cli/lib/db-keys.js +103 -0
- package/dist/cli/lib/db-keys.js.map +1 -0
- package/dist/cli/lib/env-file.d.ts +7 -0
- package/dist/cli/lib/env-file.d.ts.map +1 -1
- package/dist/cli/lib/env-file.js +62 -17
- package/dist/cli/lib/env-file.js.map +1 -1
- package/dist/cli/lib/pm2-runner.d.ts +14 -0
- package/dist/cli/lib/pm2-runner.d.ts.map +1 -0
- package/dist/cli/lib/pm2-runner.js +179 -0
- package/dist/cli/lib/pm2-runner.js.map +1 -0
- package/dist/cli/lib/process-mgr.d.ts +15 -0
- package/dist/cli/lib/process-mgr.d.ts.map +1 -1
- package/dist/cli/lib/process-mgr.js +122 -20
- package/dist/cli/lib/process-mgr.js.map +1 -1
- package/dist/cli/lib/runner-info.d.ts +20 -0
- package/dist/cli/lib/runner-info.d.ts.map +1 -0
- package/dist/cli/lib/runner-info.js +120 -0
- package/dist/cli/lib/runner-info.js.map +1 -0
- package/dist/cli/lib/seed-admin.d.ts.map +1 -1
- package/dist/cli/lib/seed-admin.js +2 -1
- package/dist/cli/lib/seed-admin.js.map +1 -1
- package/dist/cli/lib/spinner.d.ts +20 -0
- package/dist/cli/lib/spinner.d.ts.map +1 -0
- package/dist/cli/lib/spinner.js +72 -0
- package/dist/cli/lib/spinner.js.map +1 -0
- package/dist/config/constants.d.ts +31 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +103 -2
- package/dist/config/constants.js.map +1 -1
- package/dist/config/cors.js +1 -1
- package/dist/config/cors.js.map +1 -1
- package/dist/config/env.d.ts +11 -1
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +43 -3
- package/dist/config/env.js.map +1 -1
- package/dist/controllers/admin.controller.d.ts +35 -0
- package/dist/controllers/admin.controller.d.ts.map +1 -1
- package/dist/controllers/admin.controller.js +599 -18
- package/dist/controllers/admin.controller.js.map +1 -1
- package/dist/controllers/api-key.controller.d.ts.map +1 -1
- package/dist/controllers/api-key.controller.js +4 -3
- package/dist/controllers/api-key.controller.js.map +1 -1
- package/dist/controllers/chat.controller.d.ts.map +1 -1
- package/dist/controllers/chat.controller.js +2 -1
- package/dist/controllers/chat.controller.js.map +1 -1
- package/dist/controllers/document.controller.d.ts.map +1 -1
- package/dist/controllers/document.controller.js +3 -2
- package/dist/controllers/document.controller.js.map +1 -1
- package/dist/dto/admin.dto.d.ts +36 -1
- package/dist/dto/admin.dto.d.ts.map +1 -1
- package/dist/dto/admin.dto.js +23 -1
- package/dist/dto/admin.dto.js.map +1 -1
- package/dist/dto/chat.dto.d.ts +73 -0
- package/dist/dto/chat.dto.d.ts.map +1 -1
- package/dist/dto/chat.dto.js +5 -1
- package/dist/dto/chat.dto.js.map +1 -1
- package/dist/dto/conversation.dto.d.ts +286 -0
- package/dist/dto/conversation.dto.d.ts.map +1 -0
- package/dist/dto/conversation.dto.js +62 -0
- package/dist/dto/conversation.dto.js.map +1 -0
- package/dist/dto/ddos.dto.d.ts +191 -0
- package/dist/dto/ddos.dto.d.ts.map +1 -0
- package/dist/dto/ddos.dto.js +57 -0
- package/dist/dto/ddos.dto.js.map +1 -0
- package/dist/entities/api-key.entity.d.ts +2 -0
- package/dist/entities/api-key.entity.d.ts.map +1 -1
- package/dist/interfaces/auth.interface.d.ts +1 -0
- package/dist/interfaces/auth.interface.d.ts.map +1 -1
- package/dist/interfaces/express.interface.d.ts +2 -0
- package/dist/interfaces/express.interface.d.ts.map +1 -1
- package/dist/middlewares/auth.middleware.d.ts.map +1 -1
- package/dist/middlewares/auth.middleware.js +30 -3
- package/dist/middlewares/auth.middleware.js.map +1 -1
- package/dist/middlewares/client-ip.middleware.d.ts +11 -0
- package/dist/middlewares/client-ip.middleware.d.ts.map +1 -0
- package/dist/middlewares/client-ip.middleware.js +19 -0
- package/dist/middlewares/client-ip.middleware.js.map +1 -0
- package/dist/middlewares/connection-tracker.d.ts +47 -0
- package/dist/middlewares/connection-tracker.d.ts.map +1 -0
- package/dist/middlewares/connection-tracker.js +99 -0
- package/dist/middlewares/connection-tracker.js.map +1 -0
- package/dist/middlewares/rate-limit.middleware.d.ts +9 -2
- package/dist/middlewares/rate-limit.middleware.d.ts.map +1 -1
- package/dist/middlewares/rate-limit.middleware.js +116 -32
- package/dist/middlewares/rate-limit.middleware.js.map +1 -1
- package/dist/routes/admin.routes.d.ts.map +1 -1
- package/dist/routes/admin.routes.js +38 -0
- package/dist/routes/admin.routes.js.map +1 -1
- package/dist/routes/v1/chat.routes.d.ts.map +1 -1
- package/dist/routes/v1/chat.routes.js +1 -1
- package/dist/routes/v1/chat.routes.js.map +1 -1
- package/dist/server.js +53 -0
- package/dist/server.js.map +1 -1
- package/dist/services/abuse-guard.service.d.ts +27 -0
- package/dist/services/abuse-guard.service.d.ts.map +1 -0
- package/dist/services/abuse-guard.service.js +243 -0
- package/dist/services/abuse-guard.service.js.map +1 -0
- package/dist/services/api-key.service.d.ts +18 -1
- package/dist/services/api-key.service.d.ts.map +1 -1
- package/dist/services/api-key.service.js +79 -11
- package/dist/services/api-key.service.js.map +1 -1
- package/dist/services/chat-admin.service.d.ts +11 -0
- package/dist/services/chat-admin.service.d.ts.map +1 -1
- package/dist/services/chat-admin.service.js +61 -9
- package/dist/services/chat-admin.service.js.map +1 -1
- package/dist/services/conversation.service.d.ts +104 -0
- package/dist/services/conversation.service.d.ts.map +1 -0
- package/dist/services/conversation.service.js +232 -0
- package/dist/services/conversation.service.js.map +1 -0
- package/dist/services/ddos-policy.service.d.ts +40 -0
- package/dist/services/ddos-policy.service.d.ts.map +1 -0
- package/dist/services/ddos-policy.service.js +257 -0
- package/dist/services/ddos-policy.service.js.map +1 -0
- package/dist/services/document.service.d.ts.map +1 -1
- package/dist/services/document.service.js +21 -11
- package/dist/services/document.service.js.map +1 -1
- package/dist/services/ip-blacklist.service.d.ts +40 -0
- package/dist/services/ip-blacklist.service.d.ts.map +1 -0
- package/dist/services/ip-blacklist.service.js +126 -0
- package/dist/services/ip-blacklist.service.js.map +1 -0
- package/dist/services/models.service.d.ts +8 -1
- package/dist/services/models.service.d.ts.map +1 -1
- package/dist/services/models.service.js +18 -3
- package/dist/services/models.service.js.map +1 -1
- package/dist/services/pm2-config.d.ts +34 -0
- package/dist/services/pm2-config.d.ts.map +1 -0
- package/dist/services/pm2-config.js +156 -0
- package/dist/services/pm2-config.js.map +1 -0
- package/dist/services/pm2.service.d.ts +197 -0
- package/dist/services/pm2.service.d.ts.map +1 -0
- package/dist/services/pm2.service.js +776 -0
- package/dist/services/pm2.service.js.map +1 -0
- package/dist/services/stats.service.d.ts +36 -0
- package/dist/services/stats.service.d.ts.map +1 -1
- package/dist/services/stats.service.js +67 -2
- package/dist/services/stats.service.js.map +1 -1
- package/dist/services/system-health.service.d.ts +30 -0
- package/dist/services/system-health.service.d.ts.map +1 -0
- package/dist/services/system-health.service.js +234 -0
- package/dist/services/system-health.service.js.map +1 -0
- package/dist/services/update.service.d.ts +32 -0
- package/dist/services/update.service.d.ts.map +1 -1
- package/dist/services/update.service.js +176 -41
- package/dist/services/update.service.js.map +1 -1
- package/dist/services/usage.service.d.ts +43 -0
- package/dist/services/usage.service.d.ts.map +1 -0
- package/dist/services/usage.service.js +163 -0
- package/dist/services/usage.service.js.map +1 -0
- package/dist/utils/client-ip.d.ts +41 -0
- package/dist/utils/client-ip.d.ts.map +1 -0
- package/dist/utils/client-ip.js +172 -0
- package/dist/utils/client-ip.js.map +1 -0
- package/dist/utils/file-sniff.d.ts +16 -0
- package/dist/utils/file-sniff.d.ts.map +1 -0
- package/dist/utils/file-sniff.js +151 -0
- package/dist/utils/file-sniff.js.map +1 -0
- package/dist/utils/ip-match.d.ts +15 -0
- package/dist/utils/ip-match.d.ts.map +1 -0
- package/dist/utils/ip-match.js +133 -0
- package/dist/utils/ip-match.js.map +1 -0
- package/dist/utils/stream.d.ts.map +1 -1
- package/dist/utils/stream.js +40 -1
- package/dist/utils/stream.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260714120000_ip_whitelist_blacklist/migration.sql +19 -0
- package/prisma/migrations/20260714220000_chat_conversations/migration.sql +22 -0
- package/prisma/migrations/20260714230000_conversation_context/migration.sql +6 -0
- package/prisma/schema.prisma +52 -3
- package/public/admin/app.js +5696 -375
- package/public/admin/assets/logo.svg +37 -0
- package/public/admin/disabled.html +131 -0
- package/public/admin/i18n.js +1567 -0
- package/public/admin/index.html +19 -3
- package/public/admin/styles.css +3507 -190
- package/public/admin/vendor/marked.min.js +6 -0
- package/public/admin/vendor/purify.min.js +3 -0
- package/scripts/install.sh +8 -27
- package/scripts/prepare.cjs +11 -8
package/.env.example
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# development = pretty logs; production recommended for long-running service
|
|
2
|
+
NODE_ENV=production
|
|
3
|
+
# Unique default port for this project (override anytime; Admin PM2 page can change it)
|
|
3
4
|
PORT=3847
|
|
4
5
|
HOST=0.0.0.0
|
|
5
6
|
|
|
@@ -28,14 +29,35 @@ GROK_SAFE_MODE=false
|
|
|
28
29
|
GROK_SAFE_MAX_TURNS=4
|
|
29
30
|
GROK_SAFE_TIMEOUT_MS=120000
|
|
30
31
|
ADMIN_PANEL_ENABLED=true
|
|
32
|
+
# Allow Admin UI to control PM2 (start/stop/restart for grok-openai-gateway only)
|
|
33
|
+
PM2_ADMIN_ENABLED=true
|
|
31
34
|
|
|
32
35
|
CORS_ORIGINS=http://localhost:3847,http://127.0.0.1:3847
|
|
36
|
+
# --- DDoS / rate limits: initial defaults only ---
|
|
37
|
+
# After first boot, Admin → DDoS Center policy is authoritative (stored in DB).
|
|
38
|
+
# Reset to these env values via Admin → DDoS → "Reset to env defaults".
|
|
33
39
|
RATE_LIMIT_WINDOW_MS=60000
|
|
34
40
|
RATE_LIMIT_MAX=120
|
|
41
|
+
# Unauthenticated / IP-only cap (stricter than RATE_LIMIT_MAX)
|
|
42
|
+
RATE_LIMIT_IP_MAX=60
|
|
43
|
+
# Short burst window for chat (10s) — window also editable in Admin policy
|
|
44
|
+
CHAT_BURST_MAX=20
|
|
45
|
+
# Temporary IP block after repeated failed auth (auto-auth rule defaults)
|
|
46
|
+
BLOCK_FAILED_AUTH_THRESHOLD=20
|
|
47
|
+
BLOCK_FAILED_AUTH_WINDOW_MS=300000
|
|
48
|
+
BLOCK_DURATION_MS=600000
|
|
35
49
|
BODY_LIMIT=1mb
|
|
50
|
+
# Max single upload size (bytes). Larger uploads are rejected before processing.
|
|
36
51
|
UPLOAD_MAX_BYTES=10485760
|
|
52
|
+
# Below this size → encrypted in SQLite; above → encrypted file under STORAGE_DIR
|
|
37
53
|
DOCUMENT_DB_MAX_BYTES=1048576
|
|
54
|
+
# Absolute or relative path for encrypted large documents (*.enc)
|
|
38
55
|
STORAGE_DIR=./storage
|
|
39
56
|
|
|
40
57
|
LOG_LEVEL=info
|
|
41
|
-
|
|
58
|
+
# Reverse proxy / CDN client IP (nginx, Cloudflare, load balancer)
|
|
59
|
+
# TRUST_PROXY hops: 0=off (socket only), 1=nginx or CF→app (default), 2=CF→nginx→app
|
|
60
|
+
# Legacy: true→1, false→0. Can also be set in Admin → DDoS → Reverse proxy (runtime).
|
|
61
|
+
TRUST_PROXY=1
|
|
62
|
+
# auto | cloudflare | nginx | x-forwarded-for | socket
|
|
63
|
+
PROXY_IP_SOURCE=auto
|
package/README-ZH.md
CHANGED
|
@@ -15,15 +15,17 @@
|
|
|
15
15
|
| **npm** | [`grok-cli-to-openai-compatible`](https://www.npmjs.com/package/grok-cli-to-openai-compatible) |
|
|
16
16
|
| **CLI** | `gctoac` · 短名 `gcoa` |
|
|
17
17
|
| **預設 port** | **`3847`** |
|
|
18
|
+
| **NODE_ENV 預設** | **`production`**(本機開發才設 `development`) |
|
|
18
19
|
|
|
19
20
|
**主要能力**
|
|
20
21
|
|
|
21
22
|
- OpenAI 相容 `POST /v1/chat/completions`(stream / 非 stream)
|
|
22
23
|
- Thinking / `reasoning_content`(DeepSeek 風格 + Grok `thought`)
|
|
23
|
-
- 每把 key 的 **safe** / **agent** 政策
|
|
24
|
+
- 每把 key 的 **safe** / **agent** 政策 + 全域安全覆寫
|
|
24
25
|
- AES-256-GCM 加密 + 完整 chat 稽核
|
|
25
|
-
- Admin Panel
|
|
26
|
-
-
|
|
26
|
+
- **Admin Panel** — 儀表板、對話、金鑰、文件、稽核、用量、**DDoS 中心**、PM2、系統更新
|
|
27
|
+
- **DDoS/防濫用** — 可配置限流、多規則自動封鎖、反向代理真實客戶端 IP(nginx / Cloudflare)
|
|
28
|
+
- 控制 CLI:setup、start/stop/restart、status、doctor、logs、update、keys、admin on/off
|
|
27
29
|
|
|
28
30
|
```text
|
|
29
31
|
Client (OpenAI SDK / curl / Open WebUI)
|
|
@@ -31,6 +33,7 @@ Client (OpenAI SDK / curl / Open WebUI)
|
|
|
31
33
|
▼
|
|
32
34
|
Express Gateway :3847
|
|
33
35
|
· 認證 · 限流 · safe/agent
|
|
36
|
+
· 代理感知 Client IP · 自動封鎖
|
|
34
37
|
· 加密稽核 · Admin /admin
|
|
35
38
|
· gctoac start | stop | status | update
|
|
36
39
|
│
|
|
@@ -58,18 +61,25 @@ grok --version
|
|
|
58
61
|
```bash
|
|
59
62
|
npm install -g grok-cli-to-openai-compatible
|
|
60
63
|
|
|
61
|
-
gctoac doctor # 檢查 Node / Grok / 環境
|
|
62
|
-
gctoac setup #
|
|
64
|
+
gctoac doctor # 檢查 Node / Grok / 環境 / runner / 代理
|
|
65
|
+
gctoac setup # 資料目錄、.env(NODE_ENV=production)、資料庫、admin API key
|
|
63
66
|
gctoac start # http://127.0.0.1:3847
|
|
64
|
-
gctoac status
|
|
67
|
+
gctoac status # runner、port、proxy、health
|
|
65
68
|
```
|
|
66
69
|
|
|
67
|
-
開啟 Admin(貼上
|
|
70
|
+
開啟 Admin(貼上 **admin API key**):
|
|
68
71
|
|
|
69
72
|
```text
|
|
70
73
|
http://127.0.0.1:3847/admin/
|
|
71
74
|
```
|
|
72
75
|
|
|
76
|
+
若遺失 setup 時的 key:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
gctoac key create # 明文只顯示一次
|
|
80
|
+
gctoac key list # 只顯示 prefix(明文不會存庫)
|
|
81
|
+
```
|
|
82
|
+
|
|
73
83
|
**資料目錄:** `~/.gctoac/`
|
|
74
84
|
可用 `GCTOAC_HOME` 或 `gctoac --home /path` 覆蓋。
|
|
75
85
|
|
|
@@ -89,14 +99,20 @@ curl -s http://127.0.0.1:3847/v1/chat/completions \
|
|
|
89
99
|
|
|
90
100
|
---
|
|
91
101
|
|
|
92
|
-
##
|
|
102
|
+
## 安裝
|
|
93
103
|
|
|
94
|
-
|
|
104
|
+
**支援方式:** 只從 **npm registry** 安裝。
|
|
95
105
|
|
|
96
106
|
```bash
|
|
97
107
|
npm install -g grok-cli-to-openai-compatible
|
|
98
108
|
```
|
|
99
109
|
|
|
110
|
+
可選輔助腳本(等同上面指令):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -fsSL https://raw.githubusercontent.com/yanshekki/Grok-Cli-to-OpenAI-compatible/main/scripts/install.sh | bash
|
|
114
|
+
```
|
|
115
|
+
|
|
100
116
|
### 專案依賴
|
|
101
117
|
|
|
102
118
|
```bash
|
|
@@ -105,7 +121,9 @@ npx gctoac setup
|
|
|
105
121
|
npx gctoac start --foreground
|
|
106
122
|
```
|
|
107
123
|
|
|
108
|
-
###
|
|
124
|
+
### 由原始碼開發(貢獻者)
|
|
125
|
+
|
|
126
|
+
`dist/` **不會** commit 到 git。clone 後請自行 build:
|
|
109
127
|
|
|
110
128
|
```bash
|
|
111
129
|
git clone https://github.com/yanshekki/Grok-Cli-to-OpenAI-compatible.git
|
|
@@ -113,25 +131,18 @@ cd Grok-Cli-to-OpenAI-compatible
|
|
|
113
131
|
npm install
|
|
114
132
|
npm run build
|
|
115
133
|
npm link # 可選:把 gctoac 掛到 PATH
|
|
116
|
-
gctoac setup
|
|
117
|
-
gctoac start
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
一鍵腳本(clone 到 `~/.gctoac/src` 再 `npm link`):
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
curl -fsSL https://raw.githubusercontent.com/yanshekki/Grok-Cli-to-OpenAI-compatible/main/scripts/install.sh | bash
|
|
124
134
|
```
|
|
125
135
|
|
|
126
|
-
>
|
|
127
|
-
> 不建議 `npm install -g github:yanshekki/...`(部分 npm 版本會失敗)。
|
|
136
|
+
> **不要** 使用 `npm install -g github:…`(不支援)。
|
|
128
137
|
|
|
129
138
|
### 更新
|
|
130
139
|
|
|
131
140
|
```bash
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
gctoac update
|
|
141
|
+
npm install -g grok-cli-to-openai-compatible@latest
|
|
142
|
+
# 或
|
|
143
|
+
gctoac update # 自我更新並排程重啟
|
|
144
|
+
gctoac update --check # 只檢查
|
|
145
|
+
gctoac update --no-restart
|
|
135
146
|
```
|
|
136
147
|
|
|
137
148
|
亦可在 Admin → **系統狀態** → 一鍵更新。
|
|
@@ -146,27 +157,45 @@ gctoac update --no-restart # 更新但不重啟
|
|
|
146
157
|
| `http://127.0.0.1:3847/admin/` | Admin 控制台 |
|
|
147
158
|
| `http://127.0.0.1:3847/health` | 健康檢查 |
|
|
148
159
|
|
|
149
|
-
|
|
160
|
+
更改監聽連接埠(會寫入 `.env`;Admin 儲存時會重啟 runner):
|
|
150
161
|
|
|
151
162
|
```bash
|
|
152
|
-
|
|
163
|
+
# CLI — 寫入 PORT 到 .env 並啟動
|
|
164
|
+
gctoac --port 4000 start
|
|
165
|
+
gctoac --port 4000 start --pm2
|
|
166
|
+
|
|
167
|
+
# 或編輯 .env
|
|
168
|
+
PORT=4000
|
|
153
169
|
```
|
|
154
170
|
|
|
171
|
+
**Admin → PM2 → 監聽連接埠** — 預設 **3847**,儲存並重啟。改完請用**新 port** 開啟 Admin(例如 `http://127.0.0.1:4000/admin/`)。
|
|
172
|
+
|
|
155
173
|
---
|
|
156
174
|
|
|
157
175
|
## CLI(`gctoac` / `gcoa`)
|
|
158
176
|
|
|
177
|
+
全域選項:`--home <path>`、`--port <n>`(預設 **3847**)。
|
|
178
|
+
|
|
159
179
|
| 指令 | 說明 |
|
|
160
180
|
|------|------|
|
|
161
|
-
| `gctoac setup` | 建目錄、`.env`、migrate、seed admin key |
|
|
162
|
-
| `gctoac start` | 背景啟動 gateway |
|
|
181
|
+
| `gctoac setup` | 建目錄、`.env`、migrate、seed admin key,盡量安裝 pm2 |
|
|
182
|
+
| `gctoac start` | 背景啟動 gateway(detached gctoac) |
|
|
163
183
|
| `gctoac start -f` | 前景啟動 |
|
|
164
|
-
| `gctoac
|
|
165
|
-
| `gctoac
|
|
166
|
-
| `gctoac
|
|
167
|
-
| `gctoac
|
|
168
|
-
| `gctoac
|
|
169
|
-
| `gctoac doctor` |
|
|
184
|
+
| `gctoac start --pm2` | 用 PM2 啟動 |
|
|
185
|
+
| `gctoac stop` | 停止 gctoac + PM2 app + 清 port 佔用 |
|
|
186
|
+
| `gctoac restart` | 重啟;跟從 **preferred runner**(上次用 PM2 則用 PM2) |
|
|
187
|
+
| `gctoac restart --pm2` | 強制用 PM2 重啟 |
|
|
188
|
+
| `gctoac status` | Runner、NODE_ENV、port、trust proxy/IP 來源、health |
|
|
189
|
+
| `gctoac doctor` | 全面檢查(代理、雙 runner、port 衝突、log 大小) |
|
|
190
|
+
| `gctoac logs` / `logs show` | 查看 pm2 + gctoac 日誌 |
|
|
191
|
+
| `gctoac logs clear` | 清空日誌(與 Admin 清除一致) |
|
|
192
|
+
| `gctoac admin status` | Admin 面板開關狀態 |
|
|
193
|
+
| `gctoac admin on` / `off` | 開關 Admin(DB;**只能用 CLI `on` 重開**) |
|
|
194
|
+
| `gctoac migrate` | Prisma migrate deploy |
|
|
195
|
+
| `gctoac seed` | 產生 admin API key(若未有) |
|
|
196
|
+
| `gctoac key` / `key create` | 建立 API key(明文只顯示一次) |
|
|
197
|
+
| `gctoac key list` | 列出 keys(只有 prefix) |
|
|
198
|
+
| `gctoac key revoke <id>` | 撤銷 key |
|
|
170
199
|
| `gctoac update` | 自我更新後重啟 |
|
|
171
200
|
| `gctoac update --check` | 只檢查有無新版本 |
|
|
172
201
|
| `gctoac update --no-restart` | 更新但不重啟 |
|
|
@@ -176,6 +205,8 @@ gctoac --port 3847 start
|
|
|
176
205
|
```bash
|
|
177
206
|
gctoac --home ~/.gctoac-alt setup
|
|
178
207
|
gctoac --port 3847 start
|
|
208
|
+
gctoac status
|
|
209
|
+
gctoac logs clear
|
|
179
210
|
```
|
|
180
211
|
|
|
181
212
|
---
|
|
@@ -186,12 +217,15 @@ gctoac --port 3847 start
|
|
|
186
217
|
|------|------|
|
|
187
218
|
| OpenAI API | `POST /v1/chat/completions`(stream / 非 stream)、`GET /v1/models` |
|
|
188
219
|
| Thinking | `reasoning_content` + Grok `thought` + `grok.*` |
|
|
189
|
-
| 文件 |
|
|
220
|
+
| 文件 | 類型嗅探上傳、加密儲存(DB 或檔案系統)、下載 |
|
|
190
221
|
| Safe / Agent | 每 key 政策;可全域強制 safe |
|
|
191
222
|
| 加密 | AES-256-GCM 加密 prompt、response、檔案 |
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
223
|
+
| 對話歷史 | 多輪對話、上下文模式(full / summary / recent) |
|
|
224
|
+
| Admin Panel | 儀表板、對話、金鑰、文件、稽核、用量、DDoS、PM2、系統 |
|
|
225
|
+
| DDoS 中心 | 即時連線、黑名單、自動封鎖、可配置策略與預設檔 |
|
|
226
|
+
| 反向代理 | 信任層數 + CF / nginx / X-Forwarded-For 真實 IP |
|
|
227
|
+
| CLI | 生命週期、preferred runner、日誌、自我更新 |
|
|
228
|
+
| 運維 | SQLite、PM2、日誌自動裁剪(>5 MB)、GitHub Actions CI |
|
|
195
229
|
|
|
196
230
|
---
|
|
197
231
|
|
|
@@ -274,6 +308,7 @@ console.log(res.choices[0].message.content);
|
|
|
274
308
|
| POST | `/v1/documents` | 上傳(欄位 `file`) |
|
|
275
309
|
| GET/DELETE | `/v1/documents`… | 列表 / 軟刪除 |
|
|
276
310
|
| POST/GET/DELETE | `/v1/api-keys`… | Admin 管理 key |
|
|
311
|
+
| * | `/admin/api/*` | Admin JSON API(需 `role=admin`) |
|
|
277
312
|
|
|
278
313
|
---
|
|
279
314
|
|
|
@@ -284,7 +319,7 @@ console.log(res.choices[0].message.content);
|
|
|
284
319
|
| **`safe`**(client 預設) | 對外應用 | Sandbox cwd、不 always-approve、限制 tools、較短 timeout |
|
|
285
320
|
| **`agent`** | 受信 / 內網 | 完整 CLI tools(可 always-approve);cwd 仍受 allowlist 限制 |
|
|
286
321
|
|
|
287
|
-
- 全域強制 safe:`GROK_SAFE_MODE=true` 或 Admin →
|
|
322
|
+
- 全域強制 safe:`GROK_SAFE_MODE=true` 或 Admin → **安全設定**
|
|
288
323
|
- Client **無法** 靠 request body 提權
|
|
289
324
|
- **不要** 將 `agent` key 暴露於公網
|
|
290
325
|
|
|
@@ -298,25 +333,67 @@ http://127.0.0.1:3847/admin/
|
|
|
298
333
|
|
|
299
334
|
| 頁面 | 功能 |
|
|
300
335
|
|------|------|
|
|
301
|
-
|
|
|
302
|
-
|
|
|
303
|
-
|
|
|
304
|
-
|
|
|
305
|
-
|
|
|
306
|
-
|
|
|
307
|
-
|
|
|
336
|
+
| **儀表板** | 24h KPI、成功率、防護摘要、模型用量、運行狀態(port/加密) |
|
|
337
|
+
| **對話** | 多輪 playground、歷史、上下文模式、附件 |
|
|
338
|
+
| **對話記錄** | 搜尋/篩選/分頁;**完整解密** prompt/reasoning/response |
|
|
339
|
+
| **API 金鑰** | 建立/編輯 mode/role/限流/IP 白名單;撤銷 |
|
|
340
|
+
| **文件** | 搜尋/篩選/分頁;預覽、下載、刪除;DB 與檔案系統儲存 |
|
|
341
|
+
| **稽核日誌** | 搜尋/篩選/分頁;可讀動作標籤 |
|
|
342
|
+
| **用量與防護** | 24h 統計、按模型/按金鑰分 tab、限流摘要 |
|
|
343
|
+
| **DDoS 中心** | 即時連線、黑名單、自動封鎖事件、**可配置防護策略**(寬鬆/均衡/嚴格/自訂)、反向代理 IP |
|
|
344
|
+
| **安全設定** | 全域 safe、tools、timeout |
|
|
345
|
+
| **PM2** | Runner 切換(gctoac ↔ PM2)、**監聽連接埠**(預設 3847)、設定、**清除日誌** + 自動裁剪 |
|
|
346
|
+
| **系統狀態** | 健康、軟體檢查、一鍵更新並重啟 |
|
|
308
347
|
|
|
309
348
|
Admin API 前綴:`/admin/api/*`(需要 `role=admin`)。
|
|
310
349
|
|
|
350
|
+
### DDoS/防濫用(運行時)
|
|
351
|
+
|
|
352
|
+
策略存於資料庫(Admin → DDoS)。環境變數只是**初始預設**;儲存後以 Admin 為準。可用「重設為環境預設」還原。
|
|
353
|
+
|
|
354
|
+
| 能力 | 說明 |
|
|
355
|
+
|------|------|
|
|
356
|
+
| 限流 | 視窗、每 key 上限、每 IP 上限、chat burst |
|
|
357
|
+
| 自動封鎖 | 失敗認證、重複 429、並發洪水、請求速率、累犯升級 |
|
|
358
|
+
| 預設檔 | 寬鬆/均衡/嚴格/自訂(自動判定) |
|
|
359
|
+
| 白名單 | 永不被自動封鎖(例如 `127.0.0.1`) |
|
|
360
|
+
| 手動封鎖 | TTL 或永久 |
|
|
361
|
+
|
|
362
|
+
### 反向代理/CDN(客戶端 IP)
|
|
363
|
+
|
|
364
|
+
經 **nginx** 或 **Cloudflare** 時,請設定信任層數,令封鎖、限流、稽核使用**真實用戶 IP**:
|
|
365
|
+
|
|
366
|
+
| 設定 | 常見值 |
|
|
367
|
+
|------|--------|
|
|
368
|
+
| 信任代理層數 | `1` = nginx 或 CF→應用;`2` = CF→nginx→應用;`0` = 僅直連 |
|
|
369
|
+
| IP 來源 | `auto`(建議)、`cloudflare`、`nginx`、`x-forwarded-for`、`socket` |
|
|
370
|
+
|
|
371
|
+
在 **Admin → DDoS → 反向代理** 設定,或 env:
|
|
372
|
+
|
|
373
|
+
```env
|
|
374
|
+
TRUST_PROXY=1
|
|
375
|
+
PROXY_IP_SOURCE=auto
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
nginx 示例:
|
|
379
|
+
|
|
380
|
+
```nginx
|
|
381
|
+
proxy_set_header Host $host;
|
|
382
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
383
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
384
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
385
|
+
```
|
|
386
|
+
|
|
311
387
|
---
|
|
312
388
|
|
|
313
389
|
## 環境變數
|
|
314
390
|
|
|
315
|
-
詳見 [`.env.example`](./.env.example)
|
|
391
|
+
詳見 [`.env.example`](./.env.example)。`gctoac setup` 新建時預設 **`NODE_ENV=production`**。
|
|
316
392
|
|
|
317
393
|
| 變數 | 說明 |
|
|
318
394
|
|------|------|
|
|
319
|
-
| `
|
|
395
|
+
| `NODE_ENV` | 預設 **`production`**。本機開發才設 `development`(美化日誌) |
|
|
396
|
+
| `PORT` | 預設 **`3847`**(亦可在 Admin → PM2 修改) |
|
|
320
397
|
| `DATABASE_URL` | SQLite,例如 `file:../data/gateway.db`(相對 `prisma/`) |
|
|
321
398
|
| `ENCRYPTION_KEY` | 32-byte key:`openssl rand -base64 32` |
|
|
322
399
|
| `GROK_BIN` | 預設 `grok` |
|
|
@@ -325,16 +402,35 @@ Admin API 前綴:`/admin/api/*`(需要 `role=admin`)。
|
|
|
325
402
|
| `GROK_ALWAYS_APPROVE` | 只對 agent;safe 一律關閉 |
|
|
326
403
|
| `GROK_SAFE_MODE` | 強制全部 key 用 safe |
|
|
327
404
|
| `GROK_MAX_CONCURRENT` | 最多並行 Grok 進程 |
|
|
328
|
-
| `ADMIN_PANEL_ENABLED` |
|
|
329
|
-
| `
|
|
405
|
+
| `ADMIN_PANEL_ENABLED` | 硬關 `/admin`(env,需重啟)。運行時:`gctoac admin on\|off` |
|
|
406
|
+
| `PM2_ADMIN_ENABLED` | 允許 Admin 控制 PM2 |
|
|
407
|
+
| `CORS_ORIGINS` | 逗號分隔 origins(改 `PORT` 時請一併更新) |
|
|
408
|
+
| `RATE_LIMIT_*` / `CHAT_BURST_MAX` / `BLOCK_*` | 限流/自動認證初始值(DDoS 策略儲存後會覆寫) |
|
|
409
|
+
| `TRUST_PROXY` | 代理層數:`0`/`1`/`2`…(`true`→1,`false`→0) |
|
|
410
|
+
| `PROXY_IP_SOURCE` | `auto` \| `cloudflare` \| `nginx` \| `x-forwarded-for` \| `socket` |
|
|
330
411
|
| `GCTOAC_HOME` | CLI 資料目錄(預設 `~/.gctoac`) |
|
|
331
|
-
| `STORAGE_DIR` |
|
|
412
|
+
| `STORAGE_DIR` | 加密大檔 + sandbox |
|
|
413
|
+
| `UPLOAD_MAX_BYTES` / `DOCUMENT_DB_MAX_BYTES` | 上傳上限/DB 與檔案系統分界 |
|
|
332
414
|
|
|
333
415
|
**請備份 `ENCRYPTION_KEY`。** 遺失後歷史資料無法解密。
|
|
334
416
|
|
|
335
417
|
---
|
|
336
418
|
|
|
337
|
-
##
|
|
419
|
+
## 生產環境
|
|
420
|
+
|
|
421
|
+
### 建議:CLI
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
gctoac setup
|
|
425
|
+
gctoac start # detached gctoac
|
|
426
|
+
# 或
|
|
427
|
+
gctoac start --pm2 # 使用 PM2
|
|
428
|
+
gctoac status
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
`gctoac restart` 會跟從上次的 **preferred runner**(gctoac 或 PM2)。
|
|
432
|
+
|
|
433
|
+
### PM2 ecosystem
|
|
338
434
|
|
|
339
435
|
```bash
|
|
340
436
|
npm run build
|
|
@@ -342,7 +438,21 @@ pm2 start ecosystem.config.cjs
|
|
|
342
438
|
pm2 logs grok-openai-gateway
|
|
343
439
|
```
|
|
344
440
|
|
|
345
|
-
|
|
441
|
+
### 日誌
|
|
442
|
+
|
|
443
|
+
- 檔案位於 `logs/`(或資料目錄):`pm2-error.log`、`pm2-out.log`、`gctoac.*.log`
|
|
444
|
+
- **Admin → PM2 → 清除日誌**,或 `gctoac logs clear`
|
|
445
|
+
- **自動裁剪:** 每次讀取日誌時,單檔 **> 5 MB** 只保留最後約 512 KB
|
|
446
|
+
|
|
447
|
+
### 避免 EADDRINUSE
|
|
448
|
+
|
|
449
|
+
同一 port 只應有一個 runner。若 gctoac 與 PM2 搶 port:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
gctoac stop
|
|
453
|
+
gctoac start # 或:gctoac start --pm2
|
|
454
|
+
gctoac doctor # 會標示 mixed runners
|
|
455
|
+
```
|
|
346
456
|
|
|
347
457
|
---
|
|
348
458
|
|
|
@@ -352,7 +462,7 @@ pm2 logs grok-openai-gateway
|
|
|
352
462
|
src/ TypeScript 原始碼(app、routes、services、cli)
|
|
353
463
|
public/admin/ Admin SPA
|
|
354
464
|
prisma/ Schema、migrations、seed
|
|
355
|
-
dist/ 編譯後 JS
|
|
465
|
+
dist/ 編譯後 JS(gitignore;npm run build / prepublishOnly 產生)
|
|
356
466
|
scripts/ prepare、install.sh
|
|
357
467
|
tests/ Vitest
|
|
358
468
|
```
|
|
@@ -363,18 +473,19 @@ tests/ Vitest
|
|
|
363
473
|
|
|
364
474
|
```bash
|
|
365
475
|
npm run dev # 開發
|
|
366
|
-
npm run build #
|
|
476
|
+
npm run build # prisma generate + tsc
|
|
367
477
|
npm start # node dist/server.js
|
|
368
478
|
npm test # 單元 + 整合測試
|
|
369
479
|
npm run db:setup # migrate + seed
|
|
370
|
-
gctoac setup|start|status|stop|doctor|update
|
|
480
|
+
gctoac setup|start|status|stop|doctor|logs|update
|
|
371
481
|
```
|
|
372
482
|
|
|
373
483
|
### 發佈到 npm(維護者)
|
|
374
484
|
|
|
485
|
+
`prepublishOnly` 會跑 `npm run build`,tarball 一定包含 `dist/`。
|
|
486
|
+
|
|
375
487
|
```bash
|
|
376
488
|
npm login
|
|
377
|
-
npm run build
|
|
378
489
|
npm publish --access public --otp=<2FA六位碼>
|
|
379
490
|
```
|
|
380
491
|
|
|
@@ -385,7 +496,29 @@ npm publish --access public --otp=<2FA六位碼>
|
|
|
385
496
|
- API key 只存 **SHA-256 hash**
|
|
386
497
|
- Chat prompt/response 與文件以 **AES-256-GCM** 靜態加密
|
|
387
498
|
- 對外 client 請用 **`safe`** mode
|
|
499
|
+
- **客戶端 IP:** 只有 **可信代理列表** 內的 TCP peer(預設 `127.0.0.1`)先會採信 `CF-Connecting-IP`/`X-Real-IP`/`XFF`。直連客戶**無法偽造 header** 繞過限流或 ban 他人。遠端 nginx 請把其 IP 加進 Admin → DDoS → 可信代理。
|
|
500
|
+
- Admin 只應開喺本機/VPN;admin key 存 `sessionStorage`(XSS = 完全接管)
|
|
388
501
|
- 不要 commit `.env`,不要外洩 admin key
|
|
502
|
+
- 可完全關閉 Admin:`gctoac admin off`(只能用 `gctoac admin on` 重開)
|
|
503
|
+
- 一鍵更新/PM2/改 port 需 admin(視 admin key 為 root)
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## 👤 作者
|
|
508
|
+
|
|
509
|
+
**Ki (yanshekki)** — 全端工程師、量化交易者,[YSK Limited](https://ysk.hk/) 創辦人。
|
|
510
|
+
|
|
511
|
+
🌐 [linktr.ee/yanshekki](https://linktr.ee/yanshekki) · 🏢 [ysk.hk](https://ysk.hk/)
|
|
512
|
+
|
|
513
|
+
### ☕ 支持 / 打賞
|
|
514
|
+
|
|
515
|
+
如果呢個 Grok → OpenAI Gateway 對你有幫助,歡迎請我飲杯咖啡!
|
|
516
|
+
|
|
517
|
+
| 網路 | 地址 |
|
|
518
|
+
| --- | --- |
|
|
519
|
+
| **EVM** (ETH/BSC/AVAX) | `yanshekki.eth` |
|
|
520
|
+
| **NEAR** | `yanshekki.near` |
|
|
521
|
+
| **ADA** (Cardano) | `$yanshekki` |
|
|
389
522
|
|
|
390
523
|
---
|
|
391
524
|
|