foliko 1.0.43 → 1.0.44

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/.dockerignore ADDED
@@ -0,0 +1,45 @@
1
+ # 依赖
2
+ node_modules
3
+ .agent/node_modules
4
+
5
+ # 日志
6
+ *.log
7
+ npm-debug.log*
8
+
9
+ # 环境变量(包含敏感信息)
10
+ .env
11
+ .env.local
12
+
13
+ # Git
14
+ .git
15
+ .gitignore
16
+
17
+ # IDE
18
+ .idea
19
+ .vscode
20
+ *.swp
21
+ *.swo
22
+
23
+ # 文档(可选保留)
24
+ *.md
25
+ !README.md
26
+
27
+ # 测试
28
+ test
29
+ tests
30
+ coverage
31
+
32
+ # 临时文件
33
+ tmp
34
+ temp
35
+ *.tmp
36
+
37
+ # Docker 相关(避免递归)
38
+ Dockerfile*
39
+ docker-compose*
40
+ .dockerignore
41
+
42
+ # CI/CD
43
+ .github
44
+ .gitlab-ci.yml
45
+ .travis.yml
package/.env.example CHANGED
@@ -38,3 +38,13 @@ FROM_EMAIL=your-email@gmail.com
38
38
 
39
39
  # ========== Telegram Bot (optional) ==========
40
40
  TELEGRAM_BOT_TOKEN=your-telegram-bot-token
41
+
42
+ # ========== Web Server (optional) ==========
43
+ # Web 服务端口,默认 8088
44
+ WEB_PORT=8088
45
+
46
+ # Web 服务主机,默认 127.0.0.1
47
+ WEB_HOST=127.0.0.1
48
+
49
+ # 公网访问的 base URL(用于生成 webhook URL 等),不设置则使用 host:port
50
+ WEB_BASE_URL=https://your-domain.com
package/Dockerfile ADDED
@@ -0,0 +1,35 @@
1
+ # ========== Foliko - 插件化 Agent 框架 ==========
2
+ # 基于 Node.js 20 LTS
3
+
4
+ FROM node:20-slim
5
+
6
+ # 安装 Python 和构建工具(部分 npm 包需要编译)
7
+ RUN apt-get update && apt-get install -y --no-install-recommends \
8
+ build-essential \
9
+ python3 \
10
+ python3-pip \
11
+ curl \
12
+ git \
13
+ && rm -rf /var/lib/apt/lists/* \
14
+ && ln -sf /usr/bin/python3 /usr/bin/python
15
+
16
+ # 安装 uv(快速的 Python 包管理器)
17
+ RUN pip3 install uv
18
+
19
+ # 设置工作目录
20
+ WORKDIR /app
21
+
22
+ # 全局安装 foliko CLI
23
+ RUN npm install -g foliko
24
+
25
+ # 暴露端口
26
+ # 8088: Web 服务端口
27
+ EXPOSE 8088
28
+
29
+ # 环境变量(可以在 docker-compose 或运行时覆盖)
30
+ ENV NODE_ENV=production
31
+ ENV WEB_PORT=8088
32
+ ENV WEB_HOST=127.0.0.1
33
+
34
+ # 默认命令:运行聊天界面
35
+ CMD ["foliko", "chat"]
@@ -0,0 +1,33 @@
1
+ # ========== Foliko Docker Compose ==========
2
+ # 使用方式: docker-compose up -d
3
+
4
+ services:
5
+ foliko:
6
+ build: .
7
+ container_name: foliko-agent
8
+ restart: unless-stopped
9
+ ports:
10
+ - "8088:8088"
11
+ environment:
12
+ # AI 配置
13
+ - FOLIKO_PROVIDER=${FOLIKO_PROVIDER:-minimax}
14
+ - FOLIKO_MODEL=${FOLIKO_MODEL:-}
15
+ - FOLIKO_BASE_URL=${FOLIKO_BASE_URL:-}
16
+ - FOLIKO_API_KEY=${FOLIKO_API_KEY:-}
17
+ # Web 服务配置
18
+ - WEB_PORT=8088
19
+ - WEB_HOST=0.0.0.0
20
+ - WEB_BASE_URL=${WEB_BASE_URL:-}
21
+ # Telegram 配置(可选)
22
+ - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-}
23
+ # 飞书配置(可选)
24
+ - FEISHU_APP_ID=${FEISHU_APP_ID:-}
25
+ - FEISHU_APP_SECRET=${FEISHU_APP_SECRET:-}
26
+ volumes:
27
+ # 持久化数据
28
+ - foliko-data:/app/.agent/data
29
+ tty: true
30
+ stdin_open: true
31
+
32
+ volumes:
33
+ foliko-data:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foliko",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
4
4
  "description": "简约的插件化 Agent 框架",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -105,6 +105,11 @@ class FeishuPlugin extends Plugin {
105
105
  this._framework.on('scheduler:reminder', async (data) => {
106
106
  await this._handleScheduledReminder(data)
107
107
  })
108
+
109
+ // 监听 webhook 事件
110
+ this._framework.on('webhook:received', async (data) => {
111
+ await this._handleWebhookNotification(data)
112
+ })
108
113
  }
109
114
 
110
115
  console.log('[Feishu] WebSocket client started')
@@ -245,6 +250,27 @@ class FeishuPlugin extends Plugin {
245
250
  }
246
251
  }
247
252
 
253
+ /**
254
+ * 处理 webhook 通知
255
+ */
256
+ async _handleWebhookNotification(data) {
257
+ const { data: webhookData, response, sessionId } = data
258
+
259
+ if (!sessionId || !sessionId.startsWith('feishu_')) {
260
+ return
261
+ }
262
+
263
+ const openId = sessionId.replace('feishu_', '')
264
+ const notificationText = `📥 [Webhook 接收]\n\n路径: ${webhookData.path}\n方法: ${webhookData.method}\n\n处理结果: ${response || '处理中...'}`
265
+
266
+ try {
267
+ await this._sendTextMessage(openId, notificationText)
268
+ console.log(`[Feishu] Webhook notification sent to ${openId}`)
269
+ } catch (err) {
270
+ console.error(`[Feishu] Failed to send webhook notification:`, err.message)
271
+ }
272
+ }
273
+
248
274
  async _processChat(openId, text, originalMsg) {
249
275
  const sessionInfo = this._getSessionAgent(openId)
250
276
  if (!sessionInfo) return
@@ -102,6 +102,11 @@ class TelegramPlugin extends Plugin {
102
102
  this._framework.on('scheduler:reminder', async (data) => {
103
103
  await this._handleScheduledReminder(data)
104
104
  })
105
+
106
+ // 监听 webhook 事件
107
+ this._framework.on('webhook:received', async (data) => {
108
+ await this._handleWebhookNotification(data)
109
+ })
105
110
  }
106
111
  } catch (err) {
107
112
  console.error('[Telegram] Failed to initialize bot:', err.message)
@@ -140,6 +145,27 @@ class TelegramPlugin extends Plugin {
140
145
  }
141
146
  }
142
147
 
148
+ /**
149
+ * 处理 webhook 通知
150
+ */
151
+ async _handleWebhookNotification(data) {
152
+ const { data: webhookData, response, sessionId } = data
153
+
154
+ if (!sessionId || !sessionId.startsWith('telegram_')) {
155
+ return
156
+ }
157
+
158
+ const chatId = sessionId.replace('telegram_', '')
159
+ const notificationText = `📥 [Webhook 接收]\n\n路径: ${webhookData.path}\n方法: ${webhookData.method}\n\n处理结果: ${response || '处理中...'}`
160
+
161
+ try {
162
+ await this._bot.sendMessage(chatId, notificationText)
163
+ console.log(`[Telegram] Webhook notification sent to chat ${chatId}`)
164
+ } catch (err) {
165
+ console.error(`[Telegram] Failed to send webhook notification:`, err.message)
166
+ }
167
+ }
168
+
143
169
  _getMainAgent() {
144
170
  if (this._framework._mainAgent) return this._framework._mainAgent
145
171
  const agents = this._framework._agents || []
@@ -202,7 +202,22 @@ class WebPlugin extends Plugin {
202
202
 
203
203
  // 1. 静态文件
204
204
  const staticResult = this._serveStatic(pathname)
205
- if (staticResult) return staticResult
205
+ if (staticResult) {
206
+ if (staticResult.type === 'file') {
207
+ return c.newResponse(staticResult.content, {
208
+ headers: { 'Content-Type': staticResult.contentType }
209
+ })
210
+ }
211
+ if (staticResult.type === 'notFound') {
212
+ return c.json({ error: 'Not Found' }, 404)
213
+ }
214
+ if (staticResult.type === 'forbidden') {
215
+ return c.json({ error: 'Forbidden' }, 403)
216
+ }
217
+ if (staticResult.type === 'error') {
218
+ return c.json({ error: staticResult.message }, 500)
219
+ }
220
+ }
206
221
 
207
222
  // 2. Webhook(精确匹配)
208
223
  const webhook = this._webhooks.get(pathname)
@@ -261,7 +276,7 @@ class WebPlugin extends Plugin {
261
276
  const finalSessionId = sessionId || `web_${Date.now()}`
262
277
 
263
278
  // 触发 webhook 接收事件
264
- this._framework.emit('webhook:received', { webhook, data: webhookData })
279
+ this._framework.emit('webhook:received', { webhook, data: webhookData, sessionId: finalSessionId })
265
280
 
266
281
  if (!webhook.awaitResponse) {
267
282
  // 不等待,立即返回
@@ -281,7 +296,7 @@ class WebPlugin extends Plugin {
281
296
  }
282
297
 
283
298
  // 触发 webhook 处理完成事件
284
- this._framework.emit('webhook:received', { webhook, data: webhookData, response: responseText })
299
+ this._framework.emit('webhook:received', { webhook, data: webhookData, response: responseText, sessionId: finalSessionId })
285
300
  }).catch(err => {
286
301
  console.error('[Web] Webhook error:', err.message)
287
302
  })
@@ -307,7 +322,7 @@ class WebPlugin extends Plugin {
307
322
  }
308
323
 
309
324
  // 触发 webhook 处理完成事件
310
- this._framework.emit('webhook:received', { webhook, data: webhookData, response: responseText })
325
+ this._framework.emit('webhook:received', { webhook, data: webhookData, response: responseText, sessionId: finalSessionId })
311
326
 
312
327
  return { success: true, message: 'Webhook processed', response: responseText }
313
328
  } catch (err) {
@@ -74,6 +74,12 @@ class WeixinPlugin extends Plugin {
74
74
  console.log('[WeChat] Received scheduler reminder:', data)
75
75
  await this._handleScheduledReminder(data)
76
76
  })
77
+
78
+ // 监听 webhook 事件
79
+ this._framework.on('webhook:received', async (data) => {
80
+ console.log('[WeChat] Received webhook event:', data)
81
+ await this._handleWebhookNotification(data)
82
+ })
77
83
  }
78
84
 
79
85
  // 异步初始化 Bot
@@ -334,6 +340,33 @@ class WeixinPlugin extends Plugin {
334
340
  }
335
341
  }
336
342
 
343
+ /**
344
+ * 处理 webhook 通知
345
+ */
346
+ async _handleWebhookNotification(data) {
347
+ const { data: webhookData, response, sessionId } = data
348
+
349
+ if (!this._bot) {
350
+ console.warn('[WeChat] Bot not ready, cannot send webhook notification')
351
+ return
352
+ }
353
+
354
+ // 只处理 weixin 相关的 session
355
+ if (!sessionId || !sessionId.startsWith('weixin_')) {
356
+ return
357
+ }
358
+
359
+ const userId = sessionId.replace('weixin_', '')
360
+ const notificationText = `📥 [Webhook 接收]\n\n路径: ${webhookData.path}\n方法: ${webhookData.method}\n\n处理结果: ${response || '处理中...'}`
361
+
362
+ try {
363
+ await this._bot.sendText(userId, notificationText)
364
+ console.log(`[WeChat] Webhook notification sent to user ${userId}`)
365
+ } catch (err) {
366
+ console.error(`[WeChat] Failed to send webhook notification:`, err.message)
367
+ }
368
+ }
369
+
337
370
  /**
338
371
  * 获取插件状态
339
372
  */
package/test.txt ADDED
@@ -0,0 +1,3 @@
1
+ Hello from static resource test!
2
+ This is a test file for verifying static resource serving.
3
+ Timestamp: 2026-03-24