foliko 1.0.75 → 1.0.76
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/.claude/settings.local.json +159 -157
- package/cli/bin/foliko.js +12 -12
- package/cli/src/commands/chat.js +143 -143
- package/cli/src/commands/list.js +93 -93
- package/cli/src/index.js +75 -75
- package/cli/src/ui/chat-ui.js +201 -201
- package/cli/src/utils/ansi.js +40 -40
- package/cli/src/utils/markdown.js +292 -292
- package/examples/ambient-example.js +194 -194
- package/examples/basic.js +115 -115
- package/examples/bootstrap.js +121 -121
- package/examples/mcp-example.js +56 -56
- package/examples/skill-example.js +49 -49
- package/examples/test-chat.js +137 -137
- package/examples/test-mcp.js +85 -85
- package/examples/test-reload.js +59 -59
- package/examples/test-telegram.js +50 -50
- package/examples/test-tg-bot.js +45 -45
- package/examples/test-tg-simple.js +47 -47
- package/examples/test-tg.js +62 -62
- package/examples/test-think.js +43 -43
- package/examples/test-web-plugin.js +103 -103
- package/examples/test-weixin-feishu.js +103 -103
- package/examples/workflow.js +158 -158
- package/package.json +1 -1
- package/plugins/ai-plugin.js +102 -102
- package/plugins/ambient-agent/EventWatcher.js +113 -113
- package/plugins/ambient-agent/ExplorerLoop.js +640 -640
- package/plugins/ambient-agent/GoalManager.js +197 -197
- package/plugins/ambient-agent/Reflector.js +95 -95
- package/plugins/ambient-agent/StateStore.js +90 -90
- package/plugins/ambient-agent/constants.js +101 -101
- package/plugins/ambient-agent/index.js +579 -579
- package/plugins/audit-plugin.js +187 -187
- package/plugins/default-plugins.js +662 -662
- package/plugins/email/constants.js +64 -64
- package/plugins/email/handlers.js +461 -461
- package/plugins/email/index.js +278 -278
- package/plugins/email/monitor.js +269 -269
- package/plugins/email/parser.js +138 -138
- package/plugins/email/reply.js +151 -151
- package/plugins/email/utils.js +124 -124
- package/plugins/feishu-plugin.js +481 -481
- package/plugins/file-system-plugin.js +826 -826
- package/plugins/install-plugin.js +199 -199
- package/plugins/python-executor-plugin.js +367 -367
- package/plugins/python-plugin-loader.js +481 -481
- package/plugins/rules-plugin.js +294 -294
- package/plugins/scheduler-plugin.js +691 -691
- package/plugins/session-plugin.js +369 -369
- package/plugins/shell-executor-plugin.js +197 -197
- package/plugins/storage-plugin.js +240 -240
- package/plugins/subagent-plugin.js +845 -845
- package/plugins/telegram-plugin.js +482 -482
- package/plugins/think-plugin.js +345 -345
- package/plugins/tools-plugin.js +196 -196
- package/plugins/web-plugin.js +606 -606
- package/plugins/weixin-plugin.js +545 -545
- package/src/capabilities/index.js +11 -11
- package/src/capabilities/skill-manager.js +609 -609
- package/src/capabilities/workflow-engine.js +1109 -1109
- package/src/core/agent-chat.js +882 -882
- package/src/core/agent.js +892 -892
- package/src/core/framework.js +465 -465
- package/src/core/index.js +19 -19
- package/src/core/plugin-base.js +219 -219
- package/src/core/plugin-manager.js +863 -863
- package/src/core/provider.js +114 -114
- package/src/core/sub-agent-config.js +264 -264
- package/src/core/system-prompt-builder.js +120 -120
- package/src/core/tool-registry.js +517 -517
- package/src/core/tool-router.js +297 -297
- package/src/executors/executor-base.js +58 -58
- package/src/executors/mcp-executor.js +741 -741
- package/src/index.js +25 -25
- package/src/utils/circuit-breaker.js +301 -301
- package/src/utils/error-boundary.js +363 -363
- package/src/utils/error.js +374 -374
- package/src/utils/event-emitter.js +97 -97
- package/src/utils/id.js +133 -133
- package/src/utils/index.js +217 -217
- package/src/utils/logger.js +181 -181
- package/src/utils/plugin-helpers.js +90 -90
- package/src/utils/retry.js +122 -122
- package/src/utils/sandbox.js +292 -292
- package/test/tool-registry-validation.test.js +218 -218
- package/website/script.js +136 -136
- package/foliko-1.0.75.tgz +0 -0
package/plugins/email/utils.js
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Email 插件 - 工具函数
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const https = require('https')
|
|
6
|
-
const http = require('http')
|
|
7
|
-
const fs = require('fs')
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 验证邮箱地址格式
|
|
11
|
-
* @param {string} email - 邮箱地址
|
|
12
|
-
* @returns {boolean}
|
|
13
|
-
*/
|
|
14
|
-
function isValidEmail(email) {
|
|
15
|
-
if (!email) return false
|
|
16
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
17
|
-
return emailRegex.test(email)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 从邮件地址提取显示名称和邮箱
|
|
22
|
-
* @param {string} from - 邮件地址文本
|
|
23
|
-
* @returns {{name: string, email: string}}
|
|
24
|
-
*/
|
|
25
|
-
function parseEmailAddress(from) {
|
|
26
|
-
if (!from) return { name: '', email: '' }
|
|
27
|
-
|
|
28
|
-
// 格式: "Display Name <email@example.com>"
|
|
29
|
-
const match = from.match(/^(.+?)\s*<(.+)>$/)
|
|
30
|
-
if (match) {
|
|
31
|
-
return { name: match[1].trim(), email: match[2].trim() }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 格式: email@example.com
|
|
35
|
-
return { name: '', email: from.trim() }
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 获取环境变量配置
|
|
40
|
-
* @param {Object} args - 参数对象
|
|
41
|
-
* @returns {Object} 合并后的配置
|
|
42
|
-
*/
|
|
43
|
-
function getConfig(args) {
|
|
44
|
-
return {
|
|
45
|
-
host: args.host || process.env.IMAP_HOST,
|
|
46
|
-
port: args.port || parseInt(process.env.IMAP_PORT) || 993,
|
|
47
|
-
user: args.user || process.env.IMAP_USER,
|
|
48
|
-
password: args.password || process.env.IMAP_PASS
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* 从 URL 获取内容
|
|
54
|
-
* @param {string} url - 文件 URL
|
|
55
|
-
* @returns {Promise<Buffer>}
|
|
56
|
-
*/
|
|
57
|
-
function fetchUrl(url) {
|
|
58
|
-
return new Promise((resolve, reject) => {
|
|
59
|
-
const lib = url.startsWith('https') ? https : http
|
|
60
|
-
|
|
61
|
-
const request = lib.get(url, (response) => {
|
|
62
|
-
// 处理重定向
|
|
63
|
-
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
64
|
-
fetchUrl(response.headers.location).then(resolve).catch(reject)
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const chunks = []
|
|
69
|
-
response.on('data', (chunk) => chunks.push(chunk))
|
|
70
|
-
response.on('end', () => resolve(Buffer.concat(chunks)))
|
|
71
|
-
response.on('error', reject)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
request.on('error', reject)
|
|
75
|
-
request.setTimeout(10000, () => {
|
|
76
|
-
request.destroy()
|
|
77
|
-
reject(new Error('下载超时'))
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 处理附件
|
|
84
|
-
* @param {Object} att - 附件定义
|
|
85
|
-
* @returns {Promise<Object>} 处理后的附件
|
|
86
|
-
*/
|
|
87
|
-
async function processAttachment(att) {
|
|
88
|
-
const attachment = { filename: att.filename }
|
|
89
|
-
|
|
90
|
-
if (att.path) {
|
|
91
|
-
// 本地文件
|
|
92
|
-
attachment.content = fs.createReadStream(att.path)
|
|
93
|
-
} else if (att.url) {
|
|
94
|
-
// 远程 URL
|
|
95
|
-
attachment.content = await fetchUrl(att.url)
|
|
96
|
-
} else if (att.content) {
|
|
97
|
-
// Base64 内容
|
|
98
|
-
const base64Data = att.content.replace(/^data:[^;]+;base64,/, '')
|
|
99
|
-
attachment.content = Buffer.from(base64Data, 'base64')
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (att.cid) {
|
|
103
|
-
attachment.cid = att.cid
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return attachment
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 生成唯一调用 ID
|
|
111
|
-
* @returns {string}
|
|
112
|
-
*/
|
|
113
|
-
function generateCallId() {
|
|
114
|
-
return `${Date.now()}_${Math.random().toString(36).substr(2, 5)}`
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
module.exports = {
|
|
118
|
-
isValidEmail,
|
|
119
|
-
parseEmailAddress,
|
|
120
|
-
getConfig,
|
|
121
|
-
fetchUrl,
|
|
122
|
-
processAttachment,
|
|
123
|
-
generateCallId
|
|
124
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Email 插件 - 工具函数
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const https = require('https')
|
|
6
|
+
const http = require('http')
|
|
7
|
+
const fs = require('fs')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 验证邮箱地址格式
|
|
11
|
+
* @param {string} email - 邮箱地址
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
function isValidEmail(email) {
|
|
15
|
+
if (!email) return false
|
|
16
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
17
|
+
return emailRegex.test(email)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 从邮件地址提取显示名称和邮箱
|
|
22
|
+
* @param {string} from - 邮件地址文本
|
|
23
|
+
* @returns {{name: string, email: string}}
|
|
24
|
+
*/
|
|
25
|
+
function parseEmailAddress(from) {
|
|
26
|
+
if (!from) return { name: '', email: '' }
|
|
27
|
+
|
|
28
|
+
// 格式: "Display Name <email@example.com>"
|
|
29
|
+
const match = from.match(/^(.+?)\s*<(.+)>$/)
|
|
30
|
+
if (match) {
|
|
31
|
+
return { name: match[1].trim(), email: match[2].trim() }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 格式: email@example.com
|
|
35
|
+
return { name: '', email: from.trim() }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 获取环境变量配置
|
|
40
|
+
* @param {Object} args - 参数对象
|
|
41
|
+
* @returns {Object} 合并后的配置
|
|
42
|
+
*/
|
|
43
|
+
function getConfig(args) {
|
|
44
|
+
return {
|
|
45
|
+
host: args.host || process.env.IMAP_HOST,
|
|
46
|
+
port: args.port || parseInt(process.env.IMAP_PORT) || 993,
|
|
47
|
+
user: args.user || process.env.IMAP_USER,
|
|
48
|
+
password: args.password || process.env.IMAP_PASS
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 从 URL 获取内容
|
|
54
|
+
* @param {string} url - 文件 URL
|
|
55
|
+
* @returns {Promise<Buffer>}
|
|
56
|
+
*/
|
|
57
|
+
function fetchUrl(url) {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const lib = url.startsWith('https') ? https : http
|
|
60
|
+
|
|
61
|
+
const request = lib.get(url, (response) => {
|
|
62
|
+
// 处理重定向
|
|
63
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
64
|
+
fetchUrl(response.headers.location).then(resolve).catch(reject)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const chunks = []
|
|
69
|
+
response.on('data', (chunk) => chunks.push(chunk))
|
|
70
|
+
response.on('end', () => resolve(Buffer.concat(chunks)))
|
|
71
|
+
response.on('error', reject)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
request.on('error', reject)
|
|
75
|
+
request.setTimeout(10000, () => {
|
|
76
|
+
request.destroy()
|
|
77
|
+
reject(new Error('下载超时'))
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 处理附件
|
|
84
|
+
* @param {Object} att - 附件定义
|
|
85
|
+
* @returns {Promise<Object>} 处理后的附件
|
|
86
|
+
*/
|
|
87
|
+
async function processAttachment(att) {
|
|
88
|
+
const attachment = { filename: att.filename }
|
|
89
|
+
|
|
90
|
+
if (att.path) {
|
|
91
|
+
// 本地文件
|
|
92
|
+
attachment.content = fs.createReadStream(att.path)
|
|
93
|
+
} else if (att.url) {
|
|
94
|
+
// 远程 URL
|
|
95
|
+
attachment.content = await fetchUrl(att.url)
|
|
96
|
+
} else if (att.content) {
|
|
97
|
+
// Base64 内容
|
|
98
|
+
const base64Data = att.content.replace(/^data:[^;]+;base64,/, '')
|
|
99
|
+
attachment.content = Buffer.from(base64Data, 'base64')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (att.cid) {
|
|
103
|
+
attachment.cid = att.cid
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return attachment
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 生成唯一调用 ID
|
|
111
|
+
* @returns {string}
|
|
112
|
+
*/
|
|
113
|
+
function generateCallId() {
|
|
114
|
+
return `${Date.now()}_${Math.random().toString(36).substr(2, 5)}`
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
isValidEmail,
|
|
119
|
+
parseEmailAddress,
|
|
120
|
+
getConfig,
|
|
121
|
+
fetchUrl,
|
|
122
|
+
processAttachment,
|
|
123
|
+
generateCallId
|
|
124
|
+
}
|