foliko 1.1.6 → 1.1.8
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/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +288 -0
- package/.agent/agents/ambient-agent.md +57 -0
- package/.agent/agents/debugger.md +55 -0
- package/.agent/agents/email-assistant.md +49 -0
- package/.agent/agents/file-manager.md +42 -0
- package/.agent/agents/python-developer.md +60 -0
- package/.agent/agents/scheduler.md +59 -0
- package/.agent/agents/web-developer.md +45 -0
- package/.agent/data/default.json +412 -3
- package/.agent/data/plugins-state.json +177 -174
- package/.agent/data/puppeteer-sessions/undefined.json +6 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
- package/.agent/mcp_config.json +11 -3
- package/.agent/memory/feedback/mnrdvj5i-ca3dkd.md +9 -0
- package/.agent/memory/feedback/mnre365e-7s4zax.md +9 -0
- package/.agent/memory/feedback/mnre36jn-nkfgmp.md +9 -0
- package/.agent/memory/feedback/mnre3805-kjiq6h.md +9 -0
- package/.agent/memory/feedback/mnsf66kp-b10rcd.md +9 -0
- package/.agent/memory/feedback/mnsi3sz8-p5g2cw.md +9 -0
- package/.agent/memory/feedback/mnsibe47-sv2ni1.md +9 -0
- package/.agent/memory/feedback/mnsic89w-nn228o.md +9 -0
- package/.agent/memory/feedback/mnsj1xe9-x83ba0.md +9 -0
- package/.agent/memory/feedback/mnsj21iv-wnwelx.md +9 -0
- package/.agent/memory/feedback/mnsj2g4a-cog7a2.md +9 -0
- package/.agent/memory/feedback/mnsj4js7-lktjp6.md +9 -0
- package/.agent/memory/feedback/mnsj5d4y-uglwvp.md +9 -0
- package/.agent/memory/feedback/mnslkuo9-uous66.md +24 -0
- package/.agent/memory/feedback/mnsm3vq0-megoil.md +9 -0
- package/.agent/memory/feedback/mnsnn5x2-sxcihd.md +9 -0
- package/.agent/memory/feedback/mnsnq17s-nabrn9.md +9 -0
- package/.agent/memory/feedback/mnsnybet-wz7rn3.md +9 -0
- package/.agent/memory/feedback/mnsrw0s7-7s9e30.md +9 -0
- package/.agent/memory/feedback/mnu5hpnd-tlm16q.md +9 -0
- package/.agent/memory/feedback/mnu60uqe-xuoxp4.md +9 -0
- package/.agent/memory/project/mnqx54u5-loqtoe.md +9 -0
- package/.agent/memory/project/mnqx84cv-mx6dmd.md +9 -0
- package/.agent/memory/project/mnsacuyr-hgtk5n.md +20 -0
- package/.agent/memory/project/mnu5hy2x-bjsg7u.md +9 -0
- package/.agent/memory/reference/mnre3cww-penbo1.md +9 -0
- package/.agent/memory/reference/mns9wn48-luerua.md +14 -0
- package/.agent/memory/reference/mns9yz5c-thc2s0.md +16 -0
- package/.agent/memory/reference/mnsfy4um-910f1o.md +23 -0
- package/.agent/memory/reference/mnsg37dp-lmfj18.md +32 -0
- package/.agent/memory/reference/mnsll60q-0j911u.md +36 -0
- package/.agent/memory/reference/mnsmlb5y-nej31u.md +16 -0
- package/.agent/memory/reference/mnssle72-yrot96.md +9 -0
- package/.agent/memory/user/mnsfuon6-l416q1.md +21 -0
- package/.agent/memory/user/mnsg9kut-95m7rf.md +20 -0
- package/.agent/memory/user/mnu2eo1v-yy6fhe.md +9 -0
- package/.agent/memory/user/mnu2etuo-8u8jk8.md +9 -0
- package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
- package/.agent/plugins/poster-plugin/fonts/Symbola_hint.ttf +0 -0
- package/.agent/plugins/poster-plugin/package.json +3 -3
- package/.agent/plugins/poster-plugin/src/canvas.js +8 -0
- package/.agent/plugins/poster-plugin/src/components/barcode.js +5 -2
- package/.agent/plugins/poster-plugin/src/components/bubble.js +3 -2
- package/.agent/plugins/poster-plugin/src/components/button.js +74 -30
- package/.agent/plugins/poster-plugin/src/components/columns.js +97 -83
- package/.agent/plugins/poster-plugin/src/components/grid.js +104 -92
- package/.agent/plugins/poster-plugin/src/components/highlightText.js +2 -1
- package/.agent/plugins/poster-plugin/src/components/imageFrame.js +143 -93
- package/.agent/plugins/poster-plugin/src/components/quote.js +85 -13
- package/.agent/plugins/poster-plugin/src/components/ribbon.js +13 -9
- package/.agent/plugins/poster-plugin/src/components/seal.js +5 -3
- package/.agent/plugins/poster-plugin/src/components/star.js +3 -3
- package/.agent/plugins/poster-plugin/src/components/table.js +1 -1
- package/.agent/plugins/poster-plugin/src/components/watermark.js +4 -2
- package/.agent/plugins/poster-plugin/src/composer.js +181 -13
- package/.agent/plugins/poster-plugin/src/elements/artText.js +16 -7
- package/.agent/plugins/poster-plugin/src/elements/background.js +20 -5
- package/.agent/plugins/poster-plugin/src/elements/richText.js +160 -107
- package/.agent/plugins/poster-plugin/src/elements/text.js +48 -45
- package/.agent/plugins/poster-plugin/src/fonts.js +556 -125
- package/.agent/plugins/poster-plugin/src/index.js +46 -1
- package/.agent/plugins/poster-plugin/yarn.lock +186 -356
- package/.agent/plugins/puppeteer-plugin/README.md +147 -0
- package/.agent/plugins/puppeteer-plugin/index.js +1422 -0
- package/.agent/plugins/puppeteer-plugin/package.json +9 -0
- package/.agent/plugins.json +5 -11
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/rules/allow-rule.md +77 -0
- package/.agent/rules/log-rule.md +83 -0
- package/.agent/rules/security-rule.md +93 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/sessions/cli_default.json +128 -5479
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/poster-design/SKILL.md +385 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +81 -0
- package/.agent/workflows/simple-test.md +42 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/structured-orchestrate.md +180 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/.env.example +56 -56
- package/README.md +441 -441
- package/SPEC.md +735 -696
- package/output/foliko-poster.png +0 -0
- package/outputs/emoji-font-showcase.png +0 -0
- package/outputs/foliko-muji-style.png +0 -0
- package/package.json +3 -2
- package/plugins/ambient-agent/EventWatcher.js +33 -37
- package/plugins/ambient-agent/ExplorerLoop.js +338 -36
- package/plugins/ambient-agent/GoalManager.js +7 -3
- package/plugins/ambient-agent/StateStore.js +30 -1
- package/plugins/ambient-agent/constants.js +15 -1
- package/plugins/ambient-agent/index.js +26 -33
- package/plugins/coordinator-plugin.js +3 -3
- package/plugins/default-plugins.js +4 -3
- package/plugins/email/index.js +150 -36
- package/plugins/email/monitor.js +79 -5
- package/plugins/email/reply.js +15 -25
- package/plugins/extension-executor-plugin.js +184 -32
- package/plugins/feishu-plugin.js +2 -2
- package/plugins/file-system-plugin.js +57 -24
- package/plugins/memory-plugin.js +176 -64
- package/plugins/python-plugin-loader.js +79 -9
- package/plugins/scheduler-plugin.js +64 -24
- package/plugins/telegram-plugin.js +2 -2
- package/plugins/think-plugin.js +7 -2
- package/plugins/web-plugin.js +263 -4
- package/plugins/weixin-plugin.js +2 -2
- package/skills/ambient-agent/SKILL.md +342 -314
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/src/core/agent-chat.js +64 -9
- package/src/core/agent.js +216 -69
- package/src/core/tool-registry.js +5 -5
- package/src/executors/mcp-executor.js +453 -35
- package/src/utils/id.js +5 -0
- package/system.md +3629 -0
- package/.agent/agents/code-assistant.json +0 -17
- package/.agent/agents/email-assistant.json +0 -14
- package/.agent/agents/file-assistant.json +0 -18
- package/.agent/agents/orchestrator-demo.md +0 -53
- package/.agent/agents/orchestrator.json +0 -7
- package/.agent/agents/system-assistant.json +0 -15
- package/.agent/agents/web-assistant.json +0 -12
- package/.agent/data/ambient/goals.json +0 -50
- package/.agent/data/ambient/memories.json +0 -7
- package/.agent/data/scheduler/tasks.json +0 -1
- package/.agent/memory/core.md +0 -1
- package/.agent/memory/feedback/mnrsiuoc-e1ru74.md +0 -9
- package/.agent/memory/feedback/mnrt2mmz-98az6n.md +0 -9
- package/.agent/memory/feedback/mnrtqrhm-kxsicz.md +0 -9
- package/.agent/memory/feedback/mnrts8vg-i0ngzp.md +0 -15
- package/.agent/memory/feedback/mnrtt7jt-c0trb2.md +0 -9
- package/.agent/memory/feedback/mnruc2f0-5s52la.md +0 -16
- package/.agent/memory/feedback/mnrumbmx-63sa0v.md +0 -9
- package/.agent/memory/project/mnn93ogy-ypjn27.md +0 -9
- package/.agent/memory/project/mnn98fqy-5nhc1u.md +0 -25
- package/.agent/memory/project/mnrp7p5n-8enm2a.md +0 -31
- package/.agent/memory/project/mnrp9ifb-yynks0.md +0 -40
- package/.agent/memory/project/mnrpb3b8-f617s4.md +0 -25
- package/.agent/memory/project/mnrrmqgg-focprv.md +0 -9
- package/.agent/memory/project/mnrtykbh-6atsor.md +0 -9
- package/.agent/memory/project/mnru9jiu-kgau16.md +0 -35
- package/.agent/memory/reference/mnq3oenw-46haj6.md +0 -63
- package/.agent/memory/reference/mnq5qxm2-mjoooh.md +0 -116
- package/.agent/memory/reference/mnrnvpwo-rcqv9m.md +0 -52
- package/.agent/memory/reference/mnrovxvz-zy9xqm.md +0 -25
- package/.agent/memory/reference/mnroxabj-1b3930.md +0 -68
- package/.agent/memory/reference/mnrpjtlp-mnb9od.md +0 -35
- package/.agent/memory/reference/mnrps1x3-6b8xfm.md +0 -28
- package/.agent/memory/reference/mnrpt9ov-15er5w.md +0 -22
- package/.agent/memory/reference/mnrq82dn-y9tv9e.md +0 -50
- package/.agent/memory/reference/mnrqnr5v-v75drf.md +0 -34
- package/.agent/memory/reference/mnrrfzys-urudaf.md +0 -31
- package/.agent/memory/reference/mnrrocha-t0027n.md +0 -21
- package/.agent/memory/reference/mnrukklc-bxndsb.md +0 -35
- package/.agent/memory/user/mnm67t9m-x8rekk.md +0 -9
- package/.agent/memory/user/mnn5mmqh-w6aktx.md +0 -11
- package/.agent/memory/user/mnnbfhhn-dk1bd1.md +0 -22
- package/.agent/memory/user/mnrt39t8-8eosy0.md +0 -9
- package/.agent/package.json +0 -8
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +0 -89
- package/.agent/plugins/daytona/index.js +0 -377
- package/.agent/plugins/daytona/package.json +0 -12
- package/.agent/plugins/marknative/README.md +0 -134
- package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/marknative/fonts.zip +0 -0
- package/.agent/plugins/marknative/index.js +0 -256
- package/.agent/plugins/marknative/package.json +0 -12
- package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
- package/.agent/plugins/poster-plugin/test-background.svg +0 -1
- package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
- package/.agent/plugins/poster-plugin/test-image.png +0 -0
- package/.agent/plugins/system-info/index.js +0 -387
- package/.agent/plugins/system-info/package.json +0 -4
- package/.agent/plugins/system-info/test.js +0 -40
- package/.agent/python-scripts/test_sample.py +0 -24
- package/.agent/skills/agent-browser/SKILL.md +0 -311
- package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
- package/.agent/skills/sysinfo/SKILL.md +0 -38
- package/.agent/skills/sysinfo/system-info.sh +0 -130
- package/.agent/skills/workflow/SKILL.md +0 -324
- package/.agent/test-agent.js +0 -35
- package/.agent/weixin.json +0 -6
- package/.agent/workflows/email-digest.json +0 -50
- package/.agent/workflows/file-backup.json +0 -21
- package/.agent/workflows/get-ip-notify.json +0 -32
- package/.agent/workflows/news-aggregator.json +0 -93
- package/.agent/workflows/news-dashboard-v2.json +0 -94
- package/.agent/workflows/notification-batch.json +0 -32
- package/foliko-cloud-rising.png +0 -0
- package/foliko-dawn-of-ai.png +0 -0
- package/foliko-mindful-observation.png +0 -0
- package/foliko-stellar-dreams.png +0 -0
- package/foliko-zen-jing.png +0 -0
- package/foliko-zen-kong.png +0 -0
- package/foliko-zen-wu.png +0 -0
- package/zen_karesansui.png +0 -0
|
@@ -34,7 +34,36 @@ class StateStore {
|
|
|
34
34
|
*/
|
|
35
35
|
saveGoals(goals) {
|
|
36
36
|
try {
|
|
37
|
-
|
|
37
|
+
// 过滤掉循环引用的运行时数据,只保留可序列化的字段
|
|
38
|
+
const filtered = goals.map(g => ({
|
|
39
|
+
id: g.id,
|
|
40
|
+
title: g.title,
|
|
41
|
+
description: g.description,
|
|
42
|
+
priority: g.priority,
|
|
43
|
+
state: g.state,
|
|
44
|
+
actions: g.actions?.map(a => ({
|
|
45
|
+
id: a.id,
|
|
46
|
+
type: a.type,
|
|
47
|
+
name: a.name,
|
|
48
|
+
args: a.args,
|
|
49
|
+
content: a.content,
|
|
50
|
+
topic: a.topic,
|
|
51
|
+
mode: a.mode,
|
|
52
|
+
completed: a.completed,
|
|
53
|
+
order: a.order
|
|
54
|
+
})),
|
|
55
|
+
conditions: g.conditions,
|
|
56
|
+
persistent: g.persistent,
|
|
57
|
+
createdAt: g.createdAt,
|
|
58
|
+
updatedAt: g.updatedAt,
|
|
59
|
+
activatedAt: g.activatedAt,
|
|
60
|
+
completedAt: g.completedAt,
|
|
61
|
+
failedAt: g.failedAt,
|
|
62
|
+
attempts: g.attempts,
|
|
63
|
+
maxAttempts: g.maxAttempts,
|
|
64
|
+
eventsReceived: [] // 不保存运行时事件
|
|
65
|
+
}))
|
|
66
|
+
fs.writeFileSync(this._getGoalsPath(), JSON.stringify(filtered, null, 2))
|
|
38
67
|
} catch (err) {
|
|
39
68
|
log.error('保存目标失败:', err.message)
|
|
40
69
|
}
|
|
@@ -24,12 +24,26 @@ const EventDescriptions = {
|
|
|
24
24
|
|
|
25
25
|
// 监听的事件类型列表
|
|
26
26
|
const DefaultEvents = [
|
|
27
|
+
// 工具事件
|
|
28
|
+
'tool:call',
|
|
27
29
|
'tool:result',
|
|
30
|
+
'tool:error',
|
|
31
|
+
// Scheduler 事件
|
|
32
|
+
'scheduler:task_created',
|
|
28
33
|
'scheduler:reminder',
|
|
34
|
+
'scheduler:task_completed',
|
|
35
|
+
'scheduler:task_failed',
|
|
36
|
+
// Agent/Think 事件
|
|
29
37
|
'agent:message',
|
|
30
38
|
'think:thought_completed',
|
|
39
|
+
// Email/Webhook 事件
|
|
31
40
|
'email:received',
|
|
32
|
-
'webhook:received'
|
|
41
|
+
'webhook:received',
|
|
42
|
+
'webhook:processed',
|
|
43
|
+
// Worker/Subagent 事件
|
|
44
|
+
'worker:completed',
|
|
45
|
+
'worker:error',
|
|
46
|
+
'subagent:chat:end'
|
|
33
47
|
]
|
|
34
48
|
|
|
35
49
|
// 系统提示词模板
|
|
@@ -22,23 +22,12 @@ class AmbientAgentPlugin extends Plugin {
|
|
|
22
22
|
super()
|
|
23
23
|
this.name = 'ambient'
|
|
24
24
|
this.version = '1.0.0'
|
|
25
|
-
this.description = `Ambient Agent -
|
|
26
|
-
|
|
27
|
-
## 支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):
|
|
28
|
-
- email:received - 收到新邮件(参数:from, subject, text, messageId)
|
|
29
|
-
- tool:result - 工具执行完成(参数:name, args, result)
|
|
30
|
-
- scheduler:reminder - 定时提醒(参数:taskId, message, time)
|
|
31
|
-
- scheduler:task_completed - 任务完成(参数:taskId, result)
|
|
32
|
-
- scheduler:task_failed - 任务失败(参数:taskId, error)
|
|
33
|
-
- agent:message - 代理消息(参数:content, sessionId)
|
|
34
|
-
- think:thought_completed - 思考完成(参数:mode, topic, thought)
|
|
35
|
-
- webhook:received - Webhook接收(参数:headers, body, query, path)
|
|
36
|
-
|
|
37
|
-
## 在 action 参数中引用事件数据:
|
|
38
|
-
使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}`
|
|
39
|
-
this.priority = 18
|
|
25
|
+
this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控事件并执行操作`
|
|
26
|
+
this.priority = 50
|
|
40
27
|
this.system = true
|
|
41
28
|
|
|
29
|
+
this.tools={}
|
|
30
|
+
|
|
42
31
|
this.config = {
|
|
43
32
|
enabled: config.enabled !== false,
|
|
44
33
|
tickInterval: config.tickInterval || 5000, // tick间隔(毫秒)
|
|
@@ -165,10 +154,10 @@ class AmbientAgentPlugin extends Plugin {
|
|
|
165
154
|
const eventList = defaultEvents.map(e => ` - ${e.type} - ${e.desc}`).join('\n')
|
|
166
155
|
this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控和执行操作
|
|
167
156
|
|
|
168
|
-
|
|
157
|
+
**支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):**
|
|
169
158
|
${eventList}
|
|
170
159
|
|
|
171
|
-
|
|
160
|
+
**在 action 参数中引用事件数据:**
|
|
172
161
|
使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}`
|
|
173
162
|
return
|
|
174
163
|
}
|
|
@@ -183,14 +172,14 @@ ${eventList}
|
|
|
183
172
|
|
|
184
173
|
this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控和执行操作
|
|
185
174
|
|
|
186
|
-
|
|
175
|
+
*支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):*
|
|
187
176
|
${eventList}
|
|
188
177
|
|
|
189
|
-
|
|
178
|
+
*在 action 参数中引用事件数据:*
|
|
190
179
|
使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}
|
|
191
180
|
|
|
192
181
|
---
|
|
193
|
-
💡
|
|
182
|
+
💡 提示:事件描述由触发事件的插件动态注册。\n`
|
|
194
183
|
}
|
|
195
184
|
|
|
196
185
|
// ============================================================================
|
|
@@ -199,7 +188,7 @@ ${eventList}
|
|
|
199
188
|
|
|
200
189
|
_registerTools(framework) {
|
|
201
190
|
// ambient_goals - 列出/创建/更新/删除目标
|
|
202
|
-
|
|
191
|
+
this.tools.ambient_goals={
|
|
203
192
|
name: 'ambient_goals',
|
|
204
193
|
description: '管理Ambient Agent目标 - 列出、创建、更新、删除、激活目标',
|
|
205
194
|
inputSchema: z.object({
|
|
@@ -208,9 +197,11 @@ ${eventList}
|
|
|
208
197
|
title: z.string().optional().describe('目标标题(创建/更新时使用)'),
|
|
209
198
|
description: z.string().optional().describe('目标描述(创建/更新时使用)'),
|
|
210
199
|
priority: z.number().optional().describe('优先级1-10,数值越高越重要(创建/更新时使用)'),
|
|
200
|
+
persistent: z.boolean().optional().describe('是否持久化(创建时使用)。true=事件驱动目标,执行完等待下一事件;false=一次性目标,执行完自动完成。默认true'),
|
|
211
201
|
actions: z.array(z.object({
|
|
212
202
|
id: z.string().optional().describe('操作标识符'),
|
|
213
203
|
type: z.enum(['tool', 'message', 'think']).describe('操作类型'),
|
|
204
|
+
plugin: z.string().optional().describe('插件名称(tool类型时使用,如 email, gate-trading)'),
|
|
214
205
|
name: z.string().optional().describe('工具名称(tool类型时使用)'),
|
|
215
206
|
args: z.record(z.any()).optional().describe('工具参数(tool类型时使用)'),
|
|
216
207
|
content: z.string().optional().describe('消息内容(message类型时使用)'),
|
|
@@ -219,26 +210,26 @@ ${eventList}
|
|
|
219
210
|
})).optional().describe('要执行的操作列表(创建/更新时使用)'),
|
|
220
211
|
conditions: z.object({
|
|
221
212
|
events: z.union([z.string(), z.array(z.string())]).optional().describe('要监听的事件类型'),
|
|
222
|
-
toolNames: z.union([z.string(), z.array(z.string())]).optional().describe('
|
|
213
|
+
toolNames: z.union([z.string(), z.array(z.string())]).optional().describe('按工具名称过滤(支持 gate_get_market_info 或 gate:get_market_info 格式)')
|
|
223
214
|
}).optional().describe('激活条件(创建/更新时使用)')
|
|
224
215
|
}),
|
|
225
216
|
execute: async (args) => {
|
|
226
217
|
return this._handleGoalsTool(args)
|
|
227
218
|
}
|
|
228
|
-
}
|
|
219
|
+
}
|
|
229
220
|
|
|
230
221
|
// ambient_status - 获取当前循环状态
|
|
231
|
-
|
|
222
|
+
this.tools.ambient_status={
|
|
232
223
|
name: 'ambient_status',
|
|
233
224
|
description: '获取当前Ambient Agent状态 - 循环状态、进行中的目标、最近活动',
|
|
234
225
|
inputSchema: z.object({}),
|
|
235
226
|
execute: async () => {
|
|
236
227
|
return this._handleStatusTool()
|
|
237
228
|
}
|
|
238
|
-
}
|
|
229
|
+
}
|
|
239
230
|
|
|
240
231
|
// ambient_think - 触发主动LLM思考
|
|
241
|
-
|
|
232
|
+
this.tools.ambient_think={
|
|
242
233
|
name: 'ambient_think',
|
|
243
234
|
description: '为某个目标触发主动LLM思考 - 模式:reflect(反思)、brainstorm(头脑风暴)、plan(计划)、analyze(分析)',
|
|
244
235
|
inputSchema: z.object({
|
|
@@ -250,10 +241,10 @@ ${eventList}
|
|
|
250
241
|
execute: async (args) => {
|
|
251
242
|
return this._handleThinkTool(args)
|
|
252
243
|
}
|
|
253
|
-
}
|
|
244
|
+
}
|
|
254
245
|
|
|
255
246
|
// ambient_remember - 存储/检索/搜索持久化记忆
|
|
256
|
-
|
|
247
|
+
this.tools.ambient_remember={
|
|
257
248
|
name: 'ambient_remember',
|
|
258
249
|
description: '为Ambient Agent存储或检索持久化记忆',
|
|
259
250
|
inputSchema: z.object({
|
|
@@ -266,10 +257,10 @@ ${eventList}
|
|
|
266
257
|
execute: async (args) => {
|
|
267
258
|
return this._handleRememberTool(args)
|
|
268
259
|
}
|
|
269
|
-
}
|
|
260
|
+
}
|
|
270
261
|
|
|
271
262
|
// ambient_control - 暂停/恢复/调整探索循环
|
|
272
|
-
|
|
263
|
+
this.tools.ambient_control={
|
|
273
264
|
name: 'ambient_control',
|
|
274
265
|
description: '控制Ambient Agent探索循环 - 暂停、恢复或调整设置',
|
|
275
266
|
inputSchema: z.object({
|
|
@@ -280,7 +271,7 @@ ${eventList}
|
|
|
280
271
|
execute: async (args) => {
|
|
281
272
|
return this._handleControlTool(args)
|
|
282
273
|
}
|
|
283
|
-
}
|
|
274
|
+
}
|
|
284
275
|
}
|
|
285
276
|
|
|
286
277
|
// ============================================================================
|
|
@@ -288,7 +279,7 @@ ${eventList}
|
|
|
288
279
|
// ============================================================================
|
|
289
280
|
|
|
290
281
|
_handleGoalsTool(args) {
|
|
291
|
-
const { action, goalId, title, description, priority, actions, conditions } = args
|
|
282
|
+
const { action, goalId, title, description, priority, persistent, actions, conditions } = args
|
|
292
283
|
|
|
293
284
|
switch (action) {
|
|
294
285
|
case 'list': {
|
|
@@ -300,6 +291,7 @@ ${eventList}
|
|
|
300
291
|
title: g.title,
|
|
301
292
|
state: g.state,
|
|
302
293
|
priority: g.priority,
|
|
294
|
+
persistent: g.persistent,
|
|
303
295
|
actionsCount: g.actions ? g.actions.length : 0,
|
|
304
296
|
attempts: g.attempts,
|
|
305
297
|
createdAt: g.createdAt,
|
|
@@ -317,7 +309,7 @@ ${eventList}
|
|
|
317
309
|
if (!title) {
|
|
318
310
|
return { success: false, error: '创建目标需要提供标题' }
|
|
319
311
|
}
|
|
320
|
-
const goal = this._goalManager.createGoal({ title, description, priority, actions, conditions })
|
|
312
|
+
const goal = this._goalManager.createGoal({ title, description, priority, persistent, actions, conditions })
|
|
321
313
|
return { success: true, goal }
|
|
322
314
|
}
|
|
323
315
|
|
|
@@ -329,6 +321,7 @@ ${eventList}
|
|
|
329
321
|
if (title !== undefined) updates.title = title
|
|
330
322
|
if (description !== undefined) updates.description = description
|
|
331
323
|
if (priority !== undefined) updates.priority = priority
|
|
324
|
+
if (persistent !== undefined) updates.persistent = persistent
|
|
332
325
|
if (actions !== undefined) updates.actions = actions
|
|
333
326
|
if (conditions !== undefined) updates.conditions = conditions
|
|
334
327
|
const goal = this._goalManager.updateGoal(goalId, updates)
|
|
@@ -69,7 +69,7 @@ class CoordinatorPlugin extends Plugin {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
agent.registerPromptPart('coordinator-mode', 650, () => `
|
|
72
|
-
【并行任务处理 - Coordinator 模式】
|
|
72
|
+
### 【并行任务处理 - Coordinator 模式】
|
|
73
73
|
当遇到可并行处理的任务时(如多主题搜索、多文件处理、多计算任务),使用以下工具:
|
|
74
74
|
|
|
75
75
|
- spawn_worker: 创建独立Worker并行执行任务
|
|
@@ -78,12 +78,12 @@ class CoordinatorPlugin extends Plugin {
|
|
|
78
78
|
- list_workers: 查看所有Worker状态
|
|
79
79
|
- get_worker: 查看单个Worker详情
|
|
80
80
|
|
|
81
|
-
【使用场景】
|
|
81
|
+
#### 【使用场景】
|
|
82
82
|
- "帮我搜索X、Y、Z" → 使用 spawn_worker 并行执行
|
|
83
83
|
- "帮我同时处理这几个文件" → 使用 spawn_worker 并行执行
|
|
84
84
|
- 需要主动查询Worker结果时 → 使用 get_worker / list_workers
|
|
85
85
|
|
|
86
|
-
【重要】
|
|
86
|
+
#### 【重要】
|
|
87
87
|
- spawn_worker 创建后立即返回,Worker在后台执行
|
|
88
88
|
- 可同时创建多个Worker并行处理不同任务
|
|
89
89
|
- Worker完成后生成 <task-notification> JSON 通知
|
|
@@ -229,7 +229,7 @@ async function bootstrapDefaults(framework, config = {}) {
|
|
|
229
229
|
// 核心插件列表(不能禁用,必须加载)
|
|
230
230
|
const CORE_PLUGINS = new Set([
|
|
231
231
|
'install', 'ai', 'storage', 'tools', 'workflow', 'skill-manager',
|
|
232
|
-
'mcp
|
|
232
|
+
'mcp', 'extension-executor', 'shell-executor', 'python-executor', 'session', 'web',
|
|
233
233
|
'audit', 'rules', 'scheduler', 'file-system', 'think', 'ambient',
|
|
234
234
|
'python-plugin-loader', 'telegram', 'weixin', 'subagent-manager',
|
|
235
235
|
'memory', 'coordinator'
|
|
@@ -316,7 +316,7 @@ async function bootstrapDefaults(framework, config = {}) {
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
// 3. MCP 执行器插件(需要转换 mcpServers 格式)
|
|
319
|
-
if (shouldLoad('mcp
|
|
319
|
+
if (shouldLoad('mcp')) {
|
|
320
320
|
const mcpServers = Object.entries(agentConfig.mcpServers || {})
|
|
321
321
|
const servers = mcpServers.map(([name, cfg]) => ({
|
|
322
322
|
...cfg,
|
|
@@ -325,7 +325,8 @@ async function bootstrapDefaults(framework, config = {}) {
|
|
|
325
325
|
args: cfg.args || [],
|
|
326
326
|
env: cfg.env || {},
|
|
327
327
|
url: cfg.url,
|
|
328
|
-
headers: cfg.headers
|
|
328
|
+
headers: cfg.headers,
|
|
329
|
+
enabled: cfg.enabled !== false // 默认为 true
|
|
329
330
|
}))
|
|
330
331
|
const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
|
|
331
332
|
await framework.loadPlugin(new MCPExecutorPlugin({ servers }))
|
package/plugins/email/index.js
CHANGED
|
@@ -7,6 +7,8 @@ const { Plugin } = require('../../src/core/plugin-base')
|
|
|
7
7
|
const { logger } = require('../../src/utils/logger')
|
|
8
8
|
const log = logger.child('Email')
|
|
9
9
|
const { z } = require('zod')
|
|
10
|
+
const fs = require('fs')
|
|
11
|
+
const path = require('path')
|
|
10
12
|
|
|
11
13
|
// 导入子模块
|
|
12
14
|
const { sendEmail, readEmails, getUnreadCount, markAsRead, deleteEmail, getEmailConfig } = require('./handlers')
|
|
@@ -14,6 +16,49 @@ const { handleEmailWatch } = require('./monitor')
|
|
|
14
16
|
const { handleAutoReply } = require('./reply')
|
|
15
17
|
const { EMAIL_DEFAULTS } = require('./constants')
|
|
16
18
|
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// ProcessedEmailStore - 持久化已处理邮件 ID
|
|
21
|
+
// ============================================================================
|
|
22
|
+
class ProcessedEmailStore {
|
|
23
|
+
constructor(persistencePath) {
|
|
24
|
+
this._persistencePath = persistencePath
|
|
25
|
+
this._ensureDir()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_ensureDir() {
|
|
29
|
+
const dir = path.dirname(this._persistencePath)
|
|
30
|
+
if (!fs.existsSync(dir)) {
|
|
31
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
_getFilePath() {
|
|
36
|
+
return this._persistencePath
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
save(processedEmails) {
|
|
40
|
+
try {
|
|
41
|
+
const data = Array.from(processedEmails)
|
|
42
|
+
fs.writeFileSync(this._getFilePath(), JSON.stringify(data))
|
|
43
|
+
} catch (err) {
|
|
44
|
+
log.error(' 保存已处理邮件失败:', err.message)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
load() {
|
|
49
|
+
try {
|
|
50
|
+
const filePath = this._getFilePath()
|
|
51
|
+
if (fs.existsSync(filePath)) {
|
|
52
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
|
|
53
|
+
return new Set(Array.isArray(data) ? data : [])
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
log.error(' 加载已处理邮件失败:', err.message)
|
|
57
|
+
}
|
|
58
|
+
return new Set()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
17
62
|
class EmailPlugin extends Plugin {
|
|
18
63
|
constructor(config = {}) {
|
|
19
64
|
super()
|
|
@@ -29,9 +74,11 @@ class EmailPlugin extends Plugin {
|
|
|
29
74
|
- attachments.url: 远程图片/文件URL(自动下载)
|
|
30
75
|
- attachments.content: Base64内容
|
|
31
76
|
- attachments.cid: 嵌入式图片CID(HTML中用 <img src="cid:xxx"> 引用)`
|
|
32
|
-
this.priority =
|
|
77
|
+
this.priority = 50
|
|
33
78
|
this.enabled = false
|
|
34
79
|
|
|
80
|
+
this.tools={}
|
|
81
|
+
|
|
35
82
|
// 邮件监控状态
|
|
36
83
|
this._watchInterval = null
|
|
37
84
|
this._lastSeenUid = null
|
|
@@ -45,6 +92,14 @@ class EmailPlugin extends Plugin {
|
|
|
45
92
|
this._processedEmails = new Set()
|
|
46
93
|
this._maxSetSize = MAX_SET_SIZE
|
|
47
94
|
|
|
95
|
+
// 持久化存储
|
|
96
|
+
this._emailStore = null
|
|
97
|
+
this._persistencePath = config.persistencePath || '.agent/data/email/processed-emails.json'
|
|
98
|
+
|
|
99
|
+
// 防抖相关
|
|
100
|
+
this._emailDebounceMap = new Map() // msgId -> timer
|
|
101
|
+
this._emailDebounceDelay = 2000 // 2秒防抖延迟
|
|
102
|
+
|
|
48
103
|
// 日志器
|
|
49
104
|
this._log = log
|
|
50
105
|
}
|
|
@@ -52,6 +107,27 @@ class EmailPlugin extends Plugin {
|
|
|
52
107
|
install(framework) {
|
|
53
108
|
this._framework = framework
|
|
54
109
|
this._registerTools()
|
|
110
|
+
|
|
111
|
+
// 注册所有工具到 framework(供直接调用)
|
|
112
|
+
// for (const toolDef of Object.values(this.tools)) {
|
|
113
|
+
// if (toolDef && toolDef.name) {
|
|
114
|
+
// framework.registerTool({
|
|
115
|
+
// name: toolDef.name,
|
|
116
|
+
// description: toolDef.description || '',
|
|
117
|
+
// inputSchema: toolDef.inputSchema,
|
|
118
|
+
// execute: toolDef.execute
|
|
119
|
+
// })
|
|
120
|
+
// }
|
|
121
|
+
// }
|
|
122
|
+
|
|
123
|
+
// 初始化持久化存储并加载已处理的邮件
|
|
124
|
+
this._emailStore = new ProcessedEmailStore(this._persistencePath)
|
|
125
|
+
this._processedEmails = this._emailStore.load()
|
|
126
|
+
this._log.info(` 加载了 ${this._processedEmails.size} 个已处理邮件记录`)
|
|
127
|
+
if (this._processedEmails.size > 0 && this._processedEmails.size <= 10) {
|
|
128
|
+
this._log.info(`[Email] 已处理的邮件ID: ${Array.from(this._processedEmails).join(', ')}`)
|
|
129
|
+
}
|
|
130
|
+
|
|
55
131
|
return this
|
|
56
132
|
}
|
|
57
133
|
|
|
@@ -75,45 +151,80 @@ class EmailPlugin extends Plugin {
|
|
|
75
151
|
}
|
|
76
152
|
|
|
77
153
|
/**
|
|
78
|
-
*
|
|
154
|
+
* 保存已处理邮件到持久化存储
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
_saveProcessedEmails() {
|
|
158
|
+
if (this._emailStore) {
|
|
159
|
+
this._emailStore.save(this._processedEmails)
|
|
160
|
+
this._log.debug(`[Email] 已保存 ${this._processedEmails.size} 个已处理邮件到文件`)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 发送邮件事件(带防抖)
|
|
79
166
|
*/
|
|
80
167
|
_emitEmailReceived(email) {
|
|
81
168
|
if (!this._framework) return
|
|
82
169
|
|
|
83
170
|
const msgId = email.messageId || email.uid
|
|
171
|
+
// 规范化 messageId(去掉 < > 括号,避免格式不一致)
|
|
172
|
+
const normalizedMsgId = msgId ? msgId.replace(/^<|>$/g, '') : null
|
|
173
|
+
this._log.debug(`[Email] 检查邮件: ${email.subject}, msgId=${msgId}, normalized=${normalizedMsgId}`)
|
|
84
174
|
|
|
85
|
-
//
|
|
86
|
-
if (
|
|
87
|
-
this._log.info(`跳过已处理的邮件: ${email.subject} (
|
|
175
|
+
// 优先检查是否已处理过
|
|
176
|
+
if (normalizedMsgId && this._processedEmails.has(normalizedMsgId)) {
|
|
177
|
+
this._log.info(`跳过已处理的邮件: ${email.subject} (msgId=${msgId})`)
|
|
88
178
|
return
|
|
89
179
|
}
|
|
90
180
|
|
|
91
|
-
//
|
|
92
|
-
if (
|
|
181
|
+
// 检查是否有待处理的相同邮件(防抖)
|
|
182
|
+
if (normalizedMsgId && this._emailDebounceMap.has(normalizedMsgId)) {
|
|
183
|
+
this._log.debug(`[Email] 防抖跳过: ${email.subject} (${normalizedMsgId}) 等待中...`)
|
|
93
184
|
return
|
|
94
185
|
}
|
|
95
186
|
|
|
96
|
-
//
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
187
|
+
// 设置防抖定时器,延迟发送事件
|
|
188
|
+
if (normalizedMsgId) {
|
|
189
|
+
this._emailDebounceMap.set(normalizedMsgId, setTimeout(() => {
|
|
190
|
+
this._emailDebounceMap.delete(normalizedMsgId)
|
|
191
|
+
}, this._emailDebounceDelay))
|
|
192
|
+
|
|
193
|
+
// 标记为已处理(立即标记,防止重复添加)
|
|
194
|
+
this._addToBoundedSet(this._recentlyEmailed, normalizedMsgId)
|
|
195
|
+
this._addToBoundedSet(this._processedEmails, normalizedMsgId)
|
|
196
|
+
this._saveProcessedEmails()
|
|
197
|
+
this._log.info(`[Email] 邮件已标记处理: ${email.subject} (msgId=${normalizedMsgId})`)
|
|
103
198
|
|
|
104
|
-
//
|
|
105
|
-
this.
|
|
199
|
+
// 发送事件,整理数据结构让所有字段在同一层级
|
|
200
|
+
this._framework.emit('email:received', {
|
|
201
|
+
uid: email.uid,
|
|
202
|
+
messageId: email.messageId,
|
|
203
|
+
from: email.from,
|
|
204
|
+
to: email.to,
|
|
205
|
+
subject: email.subject,
|
|
206
|
+
text: email.text,
|
|
207
|
+
body: email.text,
|
|
208
|
+
html: email.html,
|
|
209
|
+
attachments: email.attachments || [],
|
|
210
|
+
timestamp: new Date()
|
|
211
|
+
})
|
|
106
212
|
}
|
|
213
|
+
}
|
|
107
214
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
215
|
+
/**
|
|
216
|
+
* 清除所有待处理的防抖定时器
|
|
217
|
+
*/
|
|
218
|
+
_clearAllDebounceTimers() {
|
|
219
|
+
for (const [msgId, timer] of this._emailDebounceMap) {
|
|
220
|
+
clearTimeout(timer)
|
|
221
|
+
this._emailDebounceMap.delete(msgId)
|
|
222
|
+
}
|
|
112
223
|
}
|
|
113
224
|
|
|
114
225
|
_registerTools() {
|
|
115
226
|
// 发送邮件工具
|
|
116
|
-
this.
|
|
227
|
+
this.tools.email_send={
|
|
117
228
|
name: 'email_send',
|
|
118
229
|
description: '发送电子邮件,无须用户确认',
|
|
119
230
|
inputSchema: z.object({
|
|
@@ -134,10 +245,10 @@ class EmailPlugin extends Plugin {
|
|
|
134
245
|
execute: async (args) => {
|
|
135
246
|
return sendEmail(this, args)
|
|
136
247
|
}
|
|
137
|
-
}
|
|
248
|
+
}
|
|
138
249
|
|
|
139
250
|
// 读取邮件工具
|
|
140
|
-
this.
|
|
251
|
+
this.tools.email_read={
|
|
141
252
|
name: 'email_read',
|
|
142
253
|
description: '读取电子邮件(支持IMAP协议)',
|
|
143
254
|
inputSchema: z.object({
|
|
@@ -149,10 +260,10 @@ class EmailPlugin extends Plugin {
|
|
|
149
260
|
execute: async (args) => {
|
|
150
261
|
return readEmails(this, args)
|
|
151
262
|
}
|
|
152
|
-
}
|
|
263
|
+
}
|
|
153
264
|
|
|
154
265
|
// 获取未读邮件数量
|
|
155
|
-
this.
|
|
266
|
+
this.tools.email_unread_count={
|
|
156
267
|
name: 'email_unread_count',
|
|
157
268
|
description: '获取邮箱未读邮件数量',
|
|
158
269
|
inputSchema: z.object({
|
|
@@ -161,10 +272,10 @@ class EmailPlugin extends Plugin {
|
|
|
161
272
|
execute: async (args) => {
|
|
162
273
|
return getUnreadCount(this, args)
|
|
163
274
|
}
|
|
164
|
-
}
|
|
275
|
+
}
|
|
165
276
|
|
|
166
277
|
// 标记邮件为已读
|
|
167
|
-
this.
|
|
278
|
+
this.tools.email_mark_read={
|
|
168
279
|
name: 'email_mark_read',
|
|
169
280
|
description: '标记邮件为已读',
|
|
170
281
|
inputSchema: z.object({
|
|
@@ -173,10 +284,10 @@ class EmailPlugin extends Plugin {
|
|
|
173
284
|
execute: async (args) => {
|
|
174
285
|
return markAsRead(this, args)
|
|
175
286
|
}
|
|
176
|
-
}
|
|
287
|
+
}
|
|
177
288
|
|
|
178
289
|
// 删除邮件
|
|
179
|
-
this.
|
|
290
|
+
this.tools.email_delete={
|
|
180
291
|
name: 'email_delete',
|
|
181
292
|
description: '删除邮件(标记为已删除,然后永久删除)',
|
|
182
293
|
inputSchema: z.object({
|
|
@@ -186,20 +297,20 @@ class EmailPlugin extends Plugin {
|
|
|
186
297
|
execute: async (args) => {
|
|
187
298
|
return deleteEmail(this, args)
|
|
188
299
|
}
|
|
189
|
-
}
|
|
300
|
+
}
|
|
190
301
|
|
|
191
302
|
// 配置邮箱连接
|
|
192
|
-
this.
|
|
303
|
+
this.tools.email_configure={
|
|
193
304
|
name: 'email_configure',
|
|
194
305
|
description: '查看邮箱配置(实际配置通过环境变量设置)',
|
|
195
306
|
inputSchema: z.object({}),
|
|
196
307
|
execute: async () => {
|
|
197
308
|
return getEmailConfig()
|
|
198
309
|
}
|
|
199
|
-
}
|
|
310
|
+
}
|
|
200
311
|
|
|
201
312
|
// 监控新邮件
|
|
202
|
-
this.
|
|
313
|
+
this.tools.email_watch={
|
|
203
314
|
name: 'email_watch',
|
|
204
315
|
description: '启动/停止邮件监控,检测新邮件并发送事件通知',
|
|
205
316
|
inputSchema: z.object({
|
|
@@ -210,10 +321,10 @@ class EmailPlugin extends Plugin {
|
|
|
210
321
|
execute: async (args) => {
|
|
211
322
|
return handleEmailWatch(this, args)
|
|
212
323
|
}
|
|
213
|
-
}
|
|
324
|
+
}
|
|
214
325
|
|
|
215
326
|
// 自动回复邮件
|
|
216
|
-
this.
|
|
327
|
+
this.tools.email_auto_reply={
|
|
217
328
|
name: 'email_auto_reply',
|
|
218
329
|
description: '自动分析邮件内容并发送回复(无需用户确认)',
|
|
219
330
|
inputSchema: z.object({
|
|
@@ -228,7 +339,7 @@ class EmailPlugin extends Plugin {
|
|
|
228
339
|
execute: async (args) => {
|
|
229
340
|
return handleAutoReply(this, args)
|
|
230
341
|
}
|
|
231
|
-
}
|
|
342
|
+
}
|
|
232
343
|
}
|
|
233
344
|
|
|
234
345
|
/**
|
|
@@ -269,6 +380,9 @@ class EmailPlugin extends Plugin {
|
|
|
269
380
|
clearInterval(this._watchInterval)
|
|
270
381
|
this._watchInterval = null
|
|
271
382
|
}
|
|
383
|
+
// 清除所有防抖定时器
|
|
384
|
+
this._clearAllDebounceTimers()
|
|
385
|
+
this.tools=null
|
|
272
386
|
this._watchEnabled = false
|
|
273
387
|
this._watchConfig = null
|
|
274
388
|
this._framework = null
|