foliko 2.0.5 → 2.0.7
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 +4 -1
- package/.cli_default_systemPrompt.md +291 -0
- package/CLAUDE.md +3 -0
- package/README.md +20 -3
- package/docs/architecture.md +34 -2
- package/docs/extensions.md +199 -0
- package/docs/migration.md +100 -0
- package/docs/public-api.md +280 -24
- package/docs/usage.md +122 -30
- package/package.json +1 -1
- package/plugins/core/audit/index.js +1 -1
- package/plugins/core/default/bootstrap.js +44 -19
- package/plugins/core/python-loader/index.js +43 -25
- package/plugins/core/scheduler/index.js +1 -0
- package/plugins/core/skill-manager/PROMPT.md +6 -0
- package/plugins/core/skill-manager/index.js +402 -115
- package/plugins/core/sub-agent/PROMPT.md +10 -0
- package/plugins/core/sub-agent/index.js +36 -3
- package/plugins/core/think/index.js +1 -0
- package/plugins/core/workflow/context.js +941 -0
- package/plugins/core/workflow/engine.js +66 -0
- package/plugins/core/workflow/examples/01-basic.js +42 -0
- package/plugins/core/workflow/examples/01-basic.json +30 -0
- package/plugins/core/workflow/examples/02-choice.js +75 -0
- package/plugins/core/workflow/examples/02-choice.json +59 -0
- package/plugins/core/workflow/examples/03-chain-style.js +114 -0
- package/plugins/core/workflow/examples/03-each.json +41 -0
- package/plugins/core/workflow/examples/04-parallel.js +52 -0
- package/plugins/core/workflow/examples/04-parallel.json +51 -0
- package/plugins/core/workflow/examples/05-chain-style.json +68 -0
- package/plugins/core/workflow/examples/05-each.js +65 -0
- package/plugins/core/workflow/examples/06-script.js +82 -0
- package/plugins/core/workflow/examples/07-module-export.js +43 -0
- package/plugins/core/workflow/examples/08-default-export.js +29 -0
- package/plugins/core/workflow/examples/09-next-with-args.js +50 -0
- package/plugins/core/workflow/examples/10-logger.js +34 -0
- package/plugins/core/workflow/examples/11-storage.js +68 -0
- package/plugins/core/workflow/examples/simple.js +77 -0
- package/plugins/core/workflow/examples/simple.json +75 -0
- package/plugins/core/workflow/index.js +204 -78
- package/plugins/core/workflow/js-runner.js +318 -0
- package/plugins/core/workflow/json-runner.js +323 -0
- package/plugins/core/workflow/stages/action.js +211 -0
- package/plugins/core/workflow/stages/choice.js +74 -0
- package/plugins/core/workflow/stages/delay.js +73 -0
- package/plugins/core/workflow/stages/each.js +123 -0
- package/plugins/core/workflow/stages/parallel.js +69 -0
- package/plugins/core/workflow/stages/try.js +142 -0
- package/plugins/executors/data-splitter/PROMPT.md +13 -0
- package/plugins/executors/data-splitter/index.js +8 -6
- package/plugins/executors/extension/extension-registry.js +145 -0
- package/plugins/executors/extension/index.js +405 -437
- package/plugins/executors/extension/prompt-builder.js +359 -0
- package/plugins/executors/extension/skill-helper.js +143 -0
- package/plugins/messaging/feishu/index.js +5 -3
- package/plugins/messaging/qq/index.js +6 -4
- package/plugins/messaging/telegram/index.js +6 -3
- package/plugins/messaging/weixin/index.js +5 -3
- package/plugins/tools/PROMPT.md +26 -0
- package/plugins/tools/index.js +6 -5
- package/sandbox/check-context.js +5 -0
- package/sandbox/test-context.js +27 -0
- package/sandbox/test-fixes.js +40 -0
- package/sandbox/test-hello-js.js +46 -0
- package/skills/foliko/AGENTS.md +196 -43
- package/skills/foliko/SKILL.md +157 -28
- package/skills/mcp/SKILL.md +77 -118
- package/skills/plugins/SKILL.md +89 -3
- package/skills/python/SKILL.md +57 -39
- package/skills/skill-guide/SKILL.md +42 -34
- package/skills/workflows/SKILL.md +753 -436
- package/src/agent/chat.js +56 -28
- package/src/agent/main.js +39 -14
- package/src/agent/prompt-registry.js +56 -16
- package/src/agent/prompts/PROMPT.md +3 -0
- package/src/agent/sub.js +1 -1
- package/src/cli/ui/chat-ui-old.js +5 -2
- package/src/cli/ui/chat-ui.js +9 -5
- package/src/common/constants.js +12 -0
- package/src/common/error-capture.js +91 -0
- package/src/common/json-safe.js +20 -0
- package/src/common/logger.js +2 -2
- package/src/context/compressor.js +6 -2
- package/src/executors/mcp-executor.js +105 -125
- package/src/framework/framework.js +78 -12
- package/src/index.js +4 -0
- package/src/plugin/base.js +908 -5
- package/src/plugin/manager.js +124 -9
- package/src/tool/schema.js +32 -9
- package/src/utils/sandbox.js +1 -1
- package/website/index.html +821 -0
- package/skills/workflows/workflow-troubleshooting/DEBUGGING.md +0 -197
- package/skills/workflows/workflow-troubleshooting/SKILL.md +0 -391
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Foliko — 简约的插件化 Agent 框架</title>
|
|
7
|
+
<meta name="description" content="Foliko 是一个纯 JavaScript 编写的插件化 Agent 框架,支持多 AI 提供商、流式输出、工具调用、工作流自动化。">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--primary: #2A9D8F;
|
|
13
|
+
--primary-dark: #238B7E;
|
|
14
|
+
--primary-light: #3DB8A8;
|
|
15
|
+
--gold: #E9C46A;
|
|
16
|
+
--sand: #F4F1DE;
|
|
17
|
+
--terracotta: #E76F51;
|
|
18
|
+
--dim: #6B7280;
|
|
19
|
+
--dark: #1a2332;
|
|
20
|
+
--darker: #111827;
|
|
21
|
+
--card-bg: rgba(255,255,255,0.04);
|
|
22
|
+
--card-border: rgba(255,255,255,0.08);
|
|
23
|
+
--text: #F9FAFB;
|
|
24
|
+
--text-secondary: #9CA3AF;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
28
|
+
|
|
29
|
+
body {
|
|
30
|
+
font-family: 'Inter', -apple-system, sans-serif;
|
|
31
|
+
background: var(--darker);
|
|
32
|
+
color: var(--text);
|
|
33
|
+
line-height: 1.6;
|
|
34
|
+
overflow-x: hidden;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
a { color: var(--primary); text-decoration: none; transition: color 0.2s; }
|
|
38
|
+
a:hover { color: var(--primary-light); }
|
|
39
|
+
|
|
40
|
+
/* NAV */
|
|
41
|
+
nav {
|
|
42
|
+
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
|
43
|
+
background: rgba(17,24,39,0.85);
|
|
44
|
+
backdrop-filter: blur(16px);
|
|
45
|
+
border-bottom: 1px solid var(--card-border);
|
|
46
|
+
padding: 0 2rem;
|
|
47
|
+
}
|
|
48
|
+
nav .inner {
|
|
49
|
+
max-width: 1200px; margin: 0 auto;
|
|
50
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
51
|
+
height: 64px;
|
|
52
|
+
}
|
|
53
|
+
nav .logo { font-size: 1.35rem; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
|
|
54
|
+
nav .logo span { color: var(--primary); }
|
|
55
|
+
nav .links { display: flex; gap: 2rem; align-items: center; }
|
|
56
|
+
nav .links a { color: var(--text-secondary); font-size: 0.9rem; font-weight: 500; }
|
|
57
|
+
nav .links a:hover { color: var(--text); }
|
|
58
|
+
nav .cta-btn {
|
|
59
|
+
background: var(--primary); color: #fff !important;
|
|
60
|
+
padding: 0.45rem 1.2rem; border-radius: 8px;
|
|
61
|
+
font-weight: 600 !important; font-size: 0.85rem !important;
|
|
62
|
+
transition: background 0.2s !important;
|
|
63
|
+
}
|
|
64
|
+
nav .cta-btn:hover { background: var(--primary-dark) !important; color: #fff !important; }
|
|
65
|
+
|
|
66
|
+
/* HERO */
|
|
67
|
+
.hero {
|
|
68
|
+
min-height: 100vh;
|
|
69
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
70
|
+
text-align: center; padding: 8rem 2rem 4rem;
|
|
71
|
+
position: relative; overflow: hidden;
|
|
72
|
+
}
|
|
73
|
+
.hero::before {
|
|
74
|
+
content: '';
|
|
75
|
+
position: absolute; inset: 0;
|
|
76
|
+
background:
|
|
77
|
+
radial-gradient(ellipse 80% 60% at 50% 0%, rgba(42,157,143,0.18) 0%, transparent 70%),
|
|
78
|
+
radial-gradient(ellipse 60% 40% at 80% 80%, rgba(231,111,81,0.08) 0%, transparent 60%);
|
|
79
|
+
pointer-events: none;
|
|
80
|
+
}
|
|
81
|
+
.hero-badge {
|
|
82
|
+
display: inline-flex; align-items: center; gap: 0.5rem;
|
|
83
|
+
background: rgba(42,157,143,0.15); border: 1px solid rgba(42,157,143,0.3);
|
|
84
|
+
color: var(--primary-light); font-size: 0.8rem; font-weight: 600;
|
|
85
|
+
padding: 0.35rem 1rem; border-radius: 999px;
|
|
86
|
+
margin-bottom: 2rem; letter-spacing: 0.05em; text-transform: uppercase;
|
|
87
|
+
}
|
|
88
|
+
.hero-badge .dot { width: 6px; height: 6px; background: var(--primary-light); border-radius: 50%; animation: pulse 2s infinite; }
|
|
89
|
+
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
90
|
+
|
|
91
|
+
.hero h1 {
|
|
92
|
+
font-size: clamp(3rem, 8vw, 5.5rem);
|
|
93
|
+
font-weight: 800; letter-spacing: -0.04em; line-height: 1.05;
|
|
94
|
+
margin-bottom: 1.5rem;
|
|
95
|
+
}
|
|
96
|
+
.hero h1 .gradient {
|
|
97
|
+
background: linear-gradient(135deg, #fff 0%, var(--primary-light) 50%, var(--gold) 100%);
|
|
98
|
+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
99
|
+
background-clip: text;
|
|
100
|
+
}
|
|
101
|
+
.hero .subtitle {
|
|
102
|
+
font-size: clamp(1.1rem, 2.5vw, 1.35rem);
|
|
103
|
+
color: var(--text-secondary); max-width: 620px;
|
|
104
|
+
margin-bottom: 3rem; font-weight: 300; line-height: 1.7;
|
|
105
|
+
}
|
|
106
|
+
.hero-actions { display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center; margin-bottom: 3rem; }
|
|
107
|
+
.btn {
|
|
108
|
+
display: inline-flex; align-items: center; gap: 0.5rem;
|
|
109
|
+
padding: 0.75rem 1.75rem; border-radius: 10px;
|
|
110
|
+
font-weight: 600; font-size: 0.95rem; cursor: pointer;
|
|
111
|
+
border: none; transition: all 0.2s;
|
|
112
|
+
}
|
|
113
|
+
.btn-primary { background: var(--primary); color: #fff; }
|
|
114
|
+
.btn-primary:hover { background: var(--primary-dark); transform: translateY(-1px); color: #fff; }
|
|
115
|
+
.btn-ghost {
|
|
116
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
117
|
+
color: var(--text); backdrop-filter: blur(8px);
|
|
118
|
+
}
|
|
119
|
+
.btn-ghost:hover { background: rgba(255,255,255,0.08); transform: translateY(-1px); color: var(--text); }
|
|
120
|
+
|
|
121
|
+
.hero-code {
|
|
122
|
+
background: rgba(0,0,0,0.4); border: 1px solid var(--card-border);
|
|
123
|
+
border-radius: 14px; padding: 1.5rem 2rem;
|
|
124
|
+
font-family: 'JetBrains Mono', monospace;
|
|
125
|
+
font-size: 0.875rem; color: #a8b5c4;
|
|
126
|
+
max-width: 700px; width: 100%;
|
|
127
|
+
text-align: left; position: relative;
|
|
128
|
+
backdrop-filter: blur(8px);
|
|
129
|
+
}
|
|
130
|
+
.hero-code .kw { color: var(--primary-light); }
|
|
131
|
+
.hero-code .str { color: var(--gold); }
|
|
132
|
+
.hero-code .cm { color: #555; font-style: italic; }
|
|
133
|
+
.hero-code .fn { color: var(--terracotta); }
|
|
134
|
+
.hero-code .dot { color: #93c5fd; }
|
|
135
|
+
.hero-code .num { color: #f97316; }
|
|
136
|
+
|
|
137
|
+
.hero-scroll {
|
|
138
|
+
margin-top: 5rem; color: var(--dim); font-size: 0.8rem;
|
|
139
|
+
display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
|
|
140
|
+
animation: bounce 2s infinite;
|
|
141
|
+
}
|
|
142
|
+
@keyframes bounce { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
|
|
143
|
+
|
|
144
|
+
/* SECTIONS */
|
|
145
|
+
.section { padding: 7rem 2rem; }
|
|
146
|
+
.section-inner { max-width: 1200px; margin: 0 auto; }
|
|
147
|
+
.section-label {
|
|
148
|
+
font-size: 0.75rem; font-weight: 700; letter-spacing: 0.12em;
|
|
149
|
+
text-transform: uppercase; color: var(--primary); margin-bottom: 0.75rem;
|
|
150
|
+
}
|
|
151
|
+
.section-title {
|
|
152
|
+
font-size: clamp(1.8rem, 4vw, 2.8rem); font-weight: 800;
|
|
153
|
+
letter-spacing: -0.03em; margin-bottom: 1rem; line-height: 1.15;
|
|
154
|
+
}
|
|
155
|
+
.section-desc { color: var(--text-secondary); font-size: 1.1rem; max-width: 560px; margin-bottom: 4rem; font-weight: 300; }
|
|
156
|
+
|
|
157
|
+
.divider { height: 1px; background: linear-gradient(90deg, transparent, var(--card-border), transparent); max-width: 1200px; margin: 0 auto; }
|
|
158
|
+
|
|
159
|
+
/* FEATURES */
|
|
160
|
+
.features-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.25rem; }
|
|
161
|
+
.feature-card {
|
|
162
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
163
|
+
border-radius: 16px; padding: 1.75rem;
|
|
164
|
+
transition: all 0.25s;
|
|
165
|
+
}
|
|
166
|
+
.feature-card:hover { border-color: rgba(42,157,143,0.4); background: rgba(42,157,143,0.06); transform: translateY(-3px); }
|
|
167
|
+
.feature-icon {
|
|
168
|
+
width: 44px; height: 44px; border-radius: 10px;
|
|
169
|
+
background: rgba(42,157,143,0.15);
|
|
170
|
+
display: flex; align-items: center; justify-content: center;
|
|
171
|
+
font-size: 1.3rem; margin-bottom: 1.1rem;
|
|
172
|
+
}
|
|
173
|
+
.feature-card h3 { font-size: 1rem; font-weight: 700; margin-bottom: 0.5rem; }
|
|
174
|
+
.feature-card p { font-size: 0.875rem; color: var(--text-secondary); line-height: 1.65; }
|
|
175
|
+
|
|
176
|
+
/* ARCH DIAGRAM */
|
|
177
|
+
.arch-diagram {
|
|
178
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
179
|
+
border-radius: 20px; padding: 2rem 2.5rem; margin-top: 2rem;
|
|
180
|
+
font-family: 'JetBrains Mono', monospace; font-size: 0.8rem;
|
|
181
|
+
}
|
|
182
|
+
.layer { margin-bottom: 1rem; }
|
|
183
|
+
.layer-label {
|
|
184
|
+
font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.1em;
|
|
185
|
+
color: var(--primary); font-weight: 700; margin-bottom: 0.5rem;
|
|
186
|
+
}
|
|
187
|
+
.layer-items { display: flex; gap: 0.5rem; flex-wrap: wrap; }
|
|
188
|
+
.arch-item {
|
|
189
|
+
background: rgba(42,157,143,0.1); border: 1px solid rgba(42,157,143,0.25);
|
|
190
|
+
border-radius: 6px; padding: 0.35rem 0.7rem;
|
|
191
|
+
color: var(--primary-light); font-size: 0.75rem;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* CODE BLOCK */
|
|
195
|
+
.code-block {
|
|
196
|
+
background: rgba(0,0,0,0.5); border: 1px solid var(--card-border);
|
|
197
|
+
border-radius: 14px; padding: 1.25rem 1.75rem;
|
|
198
|
+
font-family: 'JetBrains Mono', monospace; font-size: 0.82rem;
|
|
199
|
+
overflow-x: auto; position: relative;
|
|
200
|
+
}
|
|
201
|
+
.code-block .copy-btn {
|
|
202
|
+
position: absolute; top: 0.6rem; right: 0.6rem;
|
|
203
|
+
background: rgba(255,255,255,0.08); border: 1px solid var(--card-border);
|
|
204
|
+
border-radius: 6px; padding: 0.2rem 0.55rem;
|
|
205
|
+
font-size: 0.68rem; color: var(--text-secondary); cursor: pointer;
|
|
206
|
+
transition: all 0.2s; font-family: 'Inter', sans-serif;
|
|
207
|
+
}
|
|
208
|
+
.code-block .copy-btn:hover { background: rgba(255,255,255,0.14); color: var(--text); }
|
|
209
|
+
.code-block .kw { color: var(--primary-light); }
|
|
210
|
+
.code-block .str { color: var(--gold); }
|
|
211
|
+
.code-block .cm { color: #555; font-style: italic; }
|
|
212
|
+
.code-block .fn { color: var(--terracotta); }
|
|
213
|
+
.code-block .dot { color: #93c5fd; }
|
|
214
|
+
.code-block .num { color: #f97316; }
|
|
215
|
+
.code-block .tag { color: #f472b6; }
|
|
216
|
+
|
|
217
|
+
/* PLUGINS */
|
|
218
|
+
.plugin-tabs { display: flex; gap: 0.5rem; margin-bottom: 2rem; flex-wrap: wrap; }
|
|
219
|
+
.plugin-tab {
|
|
220
|
+
padding: 0.5rem 1.25rem; border-radius: 8px; font-size: 0.85rem;
|
|
221
|
+
font-weight: 500; cursor: pointer; border: 1px solid var(--card-border);
|
|
222
|
+
background: var(--card-bg); color: var(--text-secondary);
|
|
223
|
+
transition: all 0.2s; font-family: 'Inter', sans-serif;
|
|
224
|
+
}
|
|
225
|
+
.plugin-tab.active { background: var(--primary); color: #fff; border-color: var(--primary); }
|
|
226
|
+
.plugin-tab:hover:not(.active) { color: var(--text); }
|
|
227
|
+
.plugin-list { display: grid; gap: 0.75rem; }
|
|
228
|
+
.plugin-item {
|
|
229
|
+
display: flex; align-items: center; gap: 1rem;
|
|
230
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
231
|
+
border-radius: 12px; padding: 0.9rem 1.25rem;
|
|
232
|
+
}
|
|
233
|
+
.plugin-item .p-name { font-weight: 600; font-size: 0.875rem; min-width: 160px; }
|
|
234
|
+
.plugin-item .p-desc { font-size: 0.8rem; color: var(--text-secondary); }
|
|
235
|
+
|
|
236
|
+
/* SKILLS */
|
|
237
|
+
.skill-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.25rem; }
|
|
238
|
+
.skill-card {
|
|
239
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
240
|
+
border-radius: 16px; padding: 1.5rem; transition: all 0.25s;
|
|
241
|
+
}
|
|
242
|
+
.skill-card:hover { border-color: rgba(42,157,143,0.4); transform: translateY(-2px); }
|
|
243
|
+
.skill-card .skill-tag {
|
|
244
|
+
font-size: 0.68rem; font-weight: 600; letter-spacing: 0.05em;
|
|
245
|
+
background: rgba(42,157,143,0.15); border: 1px solid rgba(42,157,143,0.25);
|
|
246
|
+
color: var(--primary-light); padding: 0.2rem 0.65rem;
|
|
247
|
+
border-radius: 999px; display: inline-block; margin-bottom: 0.75rem;
|
|
248
|
+
}
|
|
249
|
+
.skill-card h3 { font-size: 1rem; font-weight: 700; margin-bottom: 0.4rem; }
|
|
250
|
+
.skill-card p { font-size: 0.8rem; color: var(--text-secondary); line-height: 1.6; }
|
|
251
|
+
|
|
252
|
+
/* TWO COLUMN LAYOUT */
|
|
253
|
+
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 2rem; }
|
|
254
|
+
.info-card {
|
|
255
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
256
|
+
border-radius: 16px; padding: 1.5rem;
|
|
257
|
+
}
|
|
258
|
+
.info-card h3 { font-size: 0.95rem; font-weight: 700; margin-bottom: 1rem; }
|
|
259
|
+
.info-card .item { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.9; }
|
|
260
|
+
.info-card .item .dot { color: var(--primary); margin-right: 0.4rem; }
|
|
261
|
+
|
|
262
|
+
/* INSTALL CARDS */
|
|
263
|
+
.install-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 2rem; }
|
|
264
|
+
.install-card {
|
|
265
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
266
|
+
border-radius: 14px; padding: 1.5rem;
|
|
267
|
+
}
|
|
268
|
+
.install-card h4 {
|
|
269
|
+
font-size: 0.78rem; font-weight: 700; margin-bottom: 0.75rem;
|
|
270
|
+
color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.06em;
|
|
271
|
+
}
|
|
272
|
+
.install-card pre {
|
|
273
|
+
background: rgba(0,0,0,0.35); border-radius: 8px;
|
|
274
|
+
padding: 0.75rem 1rem; font-size: 0.78rem; color: #a8b5c4;
|
|
275
|
+
border: 1px solid rgba(255,255,255,0.05); font-family: 'JetBrains Mono', monospace;
|
|
276
|
+
overflow-x: auto;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* API TABLE */
|
|
280
|
+
.api-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 1rem; margin-top: 2rem; }
|
|
281
|
+
.api-card {
|
|
282
|
+
background: var(--card-bg); border: 1px solid var(--card-border);
|
|
283
|
+
border-radius: 12px; padding: 1.1rem 1.3rem;
|
|
284
|
+
}
|
|
285
|
+
.api-card .api-name { font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; color: var(--primary-light); font-weight: 600; }
|
|
286
|
+
.api-card .api-desc { font-size: 0.78rem; color: var(--text-secondary); margin-top: 0.4rem; line-height: 1.6; }
|
|
287
|
+
|
|
288
|
+
/* FOOTER */
|
|
289
|
+
footer {
|
|
290
|
+
border-top: 1px solid var(--card-border);
|
|
291
|
+
padding: 3rem 2rem; text-align: center;
|
|
292
|
+
color: var(--dim); font-size: 0.8rem;
|
|
293
|
+
}
|
|
294
|
+
footer a { color: var(--dim); }
|
|
295
|
+
footer a:hover { color: var(--primary); }
|
|
296
|
+
|
|
297
|
+
/* ANIMATIONS */
|
|
298
|
+
.fade-in { opacity: 0; transform: translateY(24px); transition: all 0.7s cubic-bezier(0.16,1,0.3,1); }
|
|
299
|
+
.fade-in.visible { opacity: 1; transform: translateY(0); }
|
|
300
|
+
.delay-1 { transition-delay: 0.1s; }
|
|
301
|
+
.delay-2 { transition-delay: 0.2s; }
|
|
302
|
+
.delay-3 { transition-delay: 0.3s; }
|
|
303
|
+
|
|
304
|
+
/* MOBILE */
|
|
305
|
+
@media (max-width: 768px) {
|
|
306
|
+
nav .links { display: none; }
|
|
307
|
+
.hero { padding: 7rem 1.5rem 3rem; }
|
|
308
|
+
.install-grid, .two-col { grid-template-columns: 1fr; }
|
|
309
|
+
.features-grid { grid-template-columns: 1fr; }
|
|
310
|
+
.section { padding: 4rem 1.5rem; }
|
|
311
|
+
}
|
|
312
|
+
</style>
|
|
313
|
+
</head>
|
|
314
|
+
<body>
|
|
315
|
+
|
|
316
|
+
<!-- NAV -->
|
|
317
|
+
<nav>
|
|
318
|
+
<div class="inner">
|
|
319
|
+
<div class="logo">folio<span>ko</span></div>
|
|
320
|
+
<div class="links">
|
|
321
|
+
<a href="#features">特性</a>
|
|
322
|
+
<a href="#architecture">架构</a>
|
|
323
|
+
<a href="#plugins">插件</a>
|
|
324
|
+
<a href="#skills">技能</a>
|
|
325
|
+
<a href="#api">API</a>
|
|
326
|
+
<a href="#quickstart">快速开始</a>
|
|
327
|
+
<a href="https://github.com/folikoai/foliko" class="cta-btn" target="_blank">GitHub</a>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
</nav>
|
|
331
|
+
|
|
332
|
+
<!-- HERO -->
|
|
333
|
+
<section class="hero">
|
|
334
|
+
<div class="hero-badge"><span class="dot"></span> v2.0 · 纯 JavaScript · 无 TypeScript 依赖</div>
|
|
335
|
+
<h1>Foliko</h1>
|
|
336
|
+
<p class="subtitle">
|
|
337
|
+
简约的插件化 Agent 框架。纯 JavaScript 编写,支持多 AI 提供商、流式输出、工具调用、工作流自动化与统一扩展调度。
|
|
338
|
+
</p>
|
|
339
|
+
<div class="hero-actions">
|
|
340
|
+
<a href="#quickstart" class="btn btn-primary">▶ 快速开始</a>
|
|
341
|
+
<a href="#architecture" class="btn btn-ghost">◎ 了解架构</a>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="hero-code">
|
|
344
|
+
<span class="cm">// 安装</span><br>
|
|
345
|
+
<span class="kw">npm</span> install foliko<br><br>
|
|
346
|
+
<span class="cm">// 创建 Framework,链式加载插件</span><br>
|
|
347
|
+
<span class="kw">const</span> { createApp, withAI, bootstrap } = <span class="kw">require</span>(<span class="str">'foliko'</span>);<br><br>
|
|
348
|
+
<span class="kw">const</span> app = createApp({ debug: <span class="kw">true</span> });<br>
|
|
349
|
+
<span class="kw">await</span> app.<span class="dot">use</span>(withAI({<br>
|
|
350
|
+
provider: <span class="str">'deepseek'</span>,<br>
|
|
351
|
+
model: <span class="str">'deepseek-chat'</span>,<br>
|
|
352
|
+
apiKey: process.env.<span class="str">DEEPSEEK_API_KEY</span><br>
|
|
353
|
+
}));<br>
|
|
354
|
+
<span class="kw">await</span> bootstrap(app, { _config: { ai: {} } });<br><br>
|
|
355
|
+
<span class="cm">// 创建 Agent 并对话</span><br>
|
|
356
|
+
<span class="kw">const</span> agent = createAgent(app, { systemPrompt: <span class="str">'你是智能助手'</span> });<br>
|
|
357
|
+
<span class="kw">const</span> reply = <span class="kw">await</span> agent.<span class="dot">chat</span>(<span class="str">'解释量子计算'</span>);<br>
|
|
358
|
+
<span class="cm">// → 流式输出,实时响应</span>
|
|
359
|
+
</div>
|
|
360
|
+
<div class="hero-scroll">
|
|
361
|
+
<div>向下滚动了解更多</div><span>↓</span>
|
|
362
|
+
</div>
|
|
363
|
+
</section>
|
|
364
|
+
|
|
365
|
+
<!-- FEATURES -->
|
|
366
|
+
<section class="section" id="features">
|
|
367
|
+
<div class="section-inner">
|
|
368
|
+
<div class="section-label">核心特性</div>
|
|
369
|
+
<h2 class="section-title">为什么选择 Foliko?</h2>
|
|
370
|
+
<p class="section-desc">轻量、灵活、可扩展。Foliko 帮你快速构建 AI 应用,无需复杂的工程化配置。</p>
|
|
371
|
+
<div class="features-grid">
|
|
372
|
+
<div class="feature-card fade-in">
|
|
373
|
+
<div class="feature-icon">🔌</div>
|
|
374
|
+
<h3>插件化架构</h3>
|
|
375
|
+
<p>核心保持简单,功能通过插件扩展。支持热重载,按需加载,开箱即用的插件生态。</p>
|
|
376
|
+
</div>
|
|
377
|
+
<div class="feature-card fade-in delay-1">
|
|
378
|
+
<div class="feature-icon">⚡</div>
|
|
379
|
+
<h3>流式输出</h3>
|
|
380
|
+
<p>实时流式响应,无需等待完整生成。支持 Markdown 渲染和代码高亮。</p>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="feature-card fade-in delay-2">
|
|
383
|
+
<div class="feature-icon">🤖</div>
|
|
384
|
+
<h3>多 AI 支持</h3>
|
|
385
|
+
<p>统一接口对接 Anthropic、DeepSeek、OpenAI、MiniMax 等多提供商,轻松切换模型。</p>
|
|
386
|
+
</div>
|
|
387
|
+
<div class="feature-card fade-in">
|
|
388
|
+
<div class="feature-icon">🔧</div>
|
|
389
|
+
<h3>工具调用</h3>
|
|
390
|
+
<p>通过 Zod Schema 定义工具参数,自动调用 Shell、Python、文件系统等工具完成任务。</p>
|
|
391
|
+
</div>
|
|
392
|
+
<div class="feature-card fade-in delay-1">
|
|
393
|
+
<div class="feature-icon">🧩</div>
|
|
394
|
+
<h3>子 Agent 系统</h3>
|
|
395
|
+
<p>多 Agent 协作,任务委托。上下文三层隔离(Request / Session / Agent),互不干扰。</p>
|
|
396
|
+
</div>
|
|
397
|
+
<div class="feature-card fade-in delay-2">
|
|
398
|
+
<div class="feature-icon">📅</div>
|
|
399
|
+
<h3>定时调度</h3>
|
|
400
|
+
<p>内置 Cron 调度器,支持自然语言设置提醒:"每天早上 9 点提醒我查邮件"。</p>
|
|
401
|
+
</div>
|
|
402
|
+
<div class="feature-card fade-in">
|
|
403
|
+
<div class="feature-icon">💬</div>
|
|
404
|
+
<h3>多渠道消息推送</h3>
|
|
405
|
+
<p>统一的消息推送,支持 Telegram、QQ、微信、企业微信、飞书、邮件。</p>
|
|
406
|
+
</div>
|
|
407
|
+
<div class="feature-card fade-in delay-1">
|
|
408
|
+
<div class="feature-icon">🔗</div>
|
|
409
|
+
<h3>MCP 协议集成</h3>
|
|
410
|
+
<p>支持 Model Context Protocol,可连接各种 MCP 服务器,扩展 AI 能力边界。</p>
|
|
411
|
+
</div>
|
|
412
|
+
<div class="feature-card fade-in delay-2">
|
|
413
|
+
<div class="feature-icon">🛡️</div>
|
|
414
|
+
<h3>规则引擎</h3>
|
|
415
|
+
<p>细粒度的权限和行为规则,内容过滤、敏感词检测、操作审计,开箱即用。</p>
|
|
416
|
+
</div>
|
|
417
|
+
<div class="feature-card fade-in">
|
|
418
|
+
<div class="feature-icon">🧠</div>
|
|
419
|
+
<h3>上下文压缩</h3>
|
|
420
|
+
<p>自动上下文压缩,控制 token 消耗。支持智能压缩策略,保留关键信息。</p>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="feature-card fade-in delay-1">
|
|
423
|
+
<div class="feature-icon">📦</div>
|
|
424
|
+
<h3>工作流引擎</h3>
|
|
425
|
+
<p>结构化工作流执行,支持顺序、并行、条件分支,满足复杂自动化场景。</p>
|
|
426
|
+
</div>
|
|
427
|
+
<div class="feature-card fade-in delay-2">
|
|
428
|
+
<div class="feature-icon">🌙</div>
|
|
429
|
+
<h3>Ambient Agent</h3>
|
|
430
|
+
<p>后台自主运行,主动监控事件、思考下一步行动,无需人工干预的自动化 Agent。</p>
|
|
431
|
+
</div>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
</section>
|
|
435
|
+
|
|
436
|
+
<div class="divider"></div>
|
|
437
|
+
|
|
438
|
+
<!-- ARCHITECTURE -->
|
|
439
|
+
<section class="section" id="architecture">
|
|
440
|
+
<div class="section-inner">
|
|
441
|
+
<div class="section-label">架构设计</div>
|
|
442
|
+
<h2 class="section-title">三层上下文隔离</h2>
|
|
443
|
+
<p class="section-desc">基于 AsyncLocalStorage 实现请求、会话、Agent 三层完全隔离,安全可靠。</p>
|
|
444
|
+
|
|
445
|
+
<div class="arch-diagram fade-in">
|
|
446
|
+
<div class="layer">
|
|
447
|
+
<div class="layer-label">Agent Context · Layer 3</div>
|
|
448
|
+
<div class="layer-items">
|
|
449
|
+
<span class="arch-item">agentId</span>
|
|
450
|
+
<span class="arch-item">tools</span>
|
|
451
|
+
<span class="arch-item">skills</span>
|
|
452
|
+
<span class="arch-item">systemPrompt</span>
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
<div style="color:#333;font-size:1.1rem;text-align:center;margin:0.3rem 0;">↓</div>
|
|
456
|
+
<div class="layer">
|
|
457
|
+
<div class="layer-label">Session Context · Layer 2</div>
|
|
458
|
+
<div class="layer-items">
|
|
459
|
+
<span class="arch-item">sessionId</span>
|
|
460
|
+
<span class="arch-item">variables</span>
|
|
461
|
+
<span class="arch-item">messageStore</span>
|
|
462
|
+
<span class="arch-item">metadata</span>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
<div style="color:#333;font-size:1.1rem;text-align:center;margin:0.3rem 0;">↓</div>
|
|
466
|
+
<div class="layer">
|
|
467
|
+
<div class="layer-label">Request Context · Layer 1</div>
|
|
468
|
+
<div class="layer-items">
|
|
469
|
+
<span class="arch-item">requestId</span>
|
|
470
|
+
<span class="arch-item">traceId</span>
|
|
471
|
+
<span class="arch-item">timeout</span>
|
|
472
|
+
<span class="arch-item">startTime</span>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
|
|
477
|
+
<div class="two-col fade-in">
|
|
478
|
+
<div class="info-card">
|
|
479
|
+
<h3>Framework 容器层</h3>
|
|
480
|
+
<div class="item"><span class="dot">•</span>pluginManager — 插件生命周期管理</div>
|
|
481
|
+
<div class="item"><span class="dot">•</span>toolRegistry — 工具注册与执行</div>
|
|
482
|
+
<div class="item"><span class="dot">•</span>promptRegistry — 系统提示词注册表</div>
|
|
483
|
+
<div class="item"><span class="dot">•</span>skillManager — 技能加载与命令</div>
|
|
484
|
+
<div class="item"><span class="dot">•</span>eventEmitter — 事件总线</div>
|
|
485
|
+
</div>
|
|
486
|
+
<div class="info-card">
|
|
487
|
+
<h3>Agent 对话层</h3>
|
|
488
|
+
<div class="item"><span class="dot">•</span>chat() / chatStream() — 发送消息</div>
|
|
489
|
+
<div class="item"><span class="dot">•</span>tools — 来自 Framework</div>
|
|
490
|
+
<div class="item"><span class="dot">•</span>events — 消息/工具事件</div>
|
|
491
|
+
<div class="item"><span class="dot">•</span>subAgent — 子 Agent 委托</div>
|
|
492
|
+
<div class="item"><span class="dot">•</span>消息队列自动管理</div>
|
|
493
|
+
</div>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
</section>
|
|
497
|
+
|
|
498
|
+
<div class="divider"></div>
|
|
499
|
+
|
|
500
|
+
<!-- PLUGINS -->
|
|
501
|
+
<section class="section" id="plugins">
|
|
502
|
+
<div class="section-inner">
|
|
503
|
+
<div class="section-label">插件生态</div>
|
|
504
|
+
<h2 class="section-title">开箱即用的插件</h2>
|
|
505
|
+
<p class="section-desc">丰富的内置插件覆盖 AI、工具执行、消息推送、数据存储等场景。</p>
|
|
506
|
+
|
|
507
|
+
<div class="plugin-tabs" id="pluginTabs">
|
|
508
|
+
<button class="plugin-tab active" data-tab="core">核心</button>
|
|
509
|
+
<button class="plugin-tab" data-tab="executor">执行器</button>
|
|
510
|
+
<button class="plugin-tab" data-tab="messaging">消息</button>
|
|
511
|
+
<button class="plugin-tab" data-tab="io">文件/网络</button>
|
|
512
|
+
<button class="plugin-tab" data-tab="other">其他</button>
|
|
513
|
+
</div>
|
|
514
|
+
<div class="plugin-list" id="pluginList"></div>
|
|
515
|
+
</div>
|
|
516
|
+
</section>
|
|
517
|
+
|
|
518
|
+
<div class="divider"></div>
|
|
519
|
+
|
|
520
|
+
<!-- SKILLS -->
|
|
521
|
+
<section class="section" id="skills">
|
|
522
|
+
<div class="section-inner">
|
|
523
|
+
<div class="section-label">技能系统</div>
|
|
524
|
+
<h2 class="section-title">可扩展的 Skill 体系</h2>
|
|
525
|
+
<p class="section-desc">Skill 是可复用的技能模块,包含描述文档和可执行命令。通过 <code style="background:rgba(0,0,0,0.3);padding:0.15rem 0.4rem;border-radius:4px;">ext_call({ plugin: "skill:<name>", tool: "<cmd>", args: {...} })</code> 统一调度。</p>
|
|
526
|
+
|
|
527
|
+
<div class="skill-grid">
|
|
528
|
+
<div class="skill-card fade-in">
|
|
529
|
+
<div class="skill-tag">视频</div>
|
|
530
|
+
<h3>video-creator</h3>
|
|
531
|
+
<p>基于 FFmpeg 的视频生成技能,支持片头/内容页/片尾、TTS 字幕、背景音乐、转场动画。</p>
|
|
532
|
+
</div>
|
|
533
|
+
<div class="skill-card fade-in delay-1">
|
|
534
|
+
<div class="skill-tag">AI 绘画</div>
|
|
535
|
+
<h3>mmx-cli</h3>
|
|
536
|
+
<p>MiniMax AI 绘画命令行工具,支持文生图、图生图、风格迁移。</p>
|
|
537
|
+
</div>
|
|
538
|
+
<div class="skill-card fade-in delay-2">
|
|
539
|
+
<div class="skill-tag">搜索</div>
|
|
540
|
+
<h3>baidu-video-publisher</h3>
|
|
541
|
+
<p>百度视频素材搜索与发布,支持 Cookie 管理、视频下载、批量上传。</p>
|
|
542
|
+
</div>
|
|
543
|
+
<div class="skill-card fade-in">
|
|
544
|
+
<div class="skill-tag">开发</div>
|
|
545
|
+
<h3>skill-guide</h3>
|
|
546
|
+
<p>Foliko Skill 开发指南,教你如何编写自定义 Skill 并注册到框架中。</p>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
</section>
|
|
551
|
+
|
|
552
|
+
<div class="divider"></div>
|
|
553
|
+
|
|
554
|
+
<!-- UNIFIED EXTENSION CALL -->
|
|
555
|
+
<section class="section" id="extensions">
|
|
556
|
+
<div class="section-inner">
|
|
557
|
+
<div class="section-label">扩展调用</div>
|
|
558
|
+
<h2 class="section-title">ext_call 统一扩展调度</h2>
|
|
559
|
+
<p class="section-desc">通过 <code style="background:rgba(0,0,0,0.3);padding:0.15rem 0.4rem;border-radius:4px;">ext_call</code> 一个工具调用所有扩展类型:MCP 服务器、Skill 命令、Python 插件、普通扩展。</p>
|
|
560
|
+
|
|
561
|
+
<div class="code-block fade-in" style="margin-bottom:1rem;">
|
|
562
|
+
<span class="cm">// ext_skill 查询扩展详情(必先调用)</span><br>
|
|
563
|
+
ext_skill({ plugin: <span class="str">"skill:my-skill"</span> })<br>
|
|
564
|
+
ext_skill({ plugin: <span class="str">"mcp:designmd"</span> })<br><br>
|
|
565
|
+
<span class="cm">// ext_call 调用扩展工具(plugin 格式决定类型)</span><br>
|
|
566
|
+
ext_call({<br>
|
|
567
|
+
plugin: <span class="str">"skill:my-skill"</span>, <span class="cm">// skill:<name> → Skill 命令</span><br>
|
|
568
|
+
tool: <span class="str">"greet"</span>,<br>
|
|
569
|
+
args: { command: <span class="str">"-n Alice -l en"</span> }<br>
|
|
570
|
+
})<br><br>
|
|
571
|
+
ext_call({<br>
|
|
572
|
+
plugin: <span class="str">"mcp:designmd"</span>, <span class="cm">// mcp:<server> → MCP 服务器</span><br>
|
|
573
|
+
tool: <span class="str">"search_design_kits"</span>,<br>
|
|
574
|
+
args: { query: <span class="str">"minimal UI"</span> }<br>
|
|
575
|
+
})<br><br>
|
|
576
|
+
ext_call({<br>
|
|
577
|
+
plugin: <span class="str">"gate-trading"</span>, <span class="cm">// 普通扩展</span><br>
|
|
578
|
+
tool: <span class="str">"gate_get_balance"</span>,<br>
|
|
579
|
+
args: { currency: <span class="str">"USDT"</span> }<br>
|
|
580
|
+
})
|
|
581
|
+
</div>
|
|
582
|
+
|
|
583
|
+
<div class="info-card fade-in" style="margin-top:1.5rem;">
|
|
584
|
+
<h3>扩展命名空间</h3>
|
|
585
|
+
<div class="item"><span class="dot">•</span><code style="font-family:'JetBrains Mono',monospace;font-size:0.78rem;">skill:<name></code> — Skill 命令(如 skill:video-creator)</div>
|
|
586
|
+
<div class="item"><span class="dot">•</span><code style="font-family:'JetBrains Mono',monospace;font-size:0.78rem;">mcp:<server></code> — MCP 服务器(如 mcp:designmd)</div>
|
|
587
|
+
<div class="item"><span class="dot">•</span><code style="font-family:'JetBrains Mono',monospace;font-size:0.78rem;">python:<plugin></code> — Python 插件</div>
|
|
588
|
+
<div class="item"><span class="dot">•</span><code style="font-family:'JetBrains Mono',monospace;font-size:0.78rem;"><name></code> — 普通扩展(如 gate-trading)</div>
|
|
589
|
+
</div>
|
|
590
|
+
</div>
|
|
591
|
+
</section>
|
|
592
|
+
|
|
593
|
+
<div class="divider"></div>
|
|
594
|
+
|
|
595
|
+
<!-- API REFERENCE -->
|
|
596
|
+
<section class="section" id="api">
|
|
597
|
+
<div class="section-inner">
|
|
598
|
+
<div class="section-label">API 参考</div>
|
|
599
|
+
<h2 class="section-title">Framework 接口一览</h2>
|
|
600
|
+
<p class="section-desc">Framework 实例上可直接访问 prompts、skills、workflows、storage、mcps、sessions、extensions、rules 等子系统。</p>
|
|
601
|
+
|
|
602
|
+
<div class="api-grid">
|
|
603
|
+
<div class="api-card fade-in">
|
|
604
|
+
<div class="api-name">framework.prompts</div>
|
|
605
|
+
<div class="api-desc">系统提示词注册表。register / registerFile / build() / invalidate() / clearOwner()</div>
|
|
606
|
+
</div>
|
|
607
|
+
<div class="api-card fade-in delay-1">
|
|
608
|
+
<div class="api-name">framework.skills</div>
|
|
609
|
+
<div class="api-desc">技能管理器。list() / get() / register() / remove() / reload() / details()</div>
|
|
610
|
+
</div>
|
|
611
|
+
<div class="api-card fade-in delay-2">
|
|
612
|
+
<div class="api-name">framework.workflows</div>
|
|
613
|
+
<div class="api-desc">工作流引擎。list() / get() / execute() / register() / remove()</div>
|
|
614
|
+
</div>
|
|
615
|
+
<div class="api-card fade-in">
|
|
616
|
+
<div class="api-name">framework.storage</div>
|
|
617
|
+
<div class="api-desc">键值存储。get() / set() / delete() / list() / clear() / stats()</div>
|
|
618
|
+
</div>
|
|
619
|
+
<div class="api-card fade-in delay-1">
|
|
620
|
+
<div class="api-name">framework.mcps</div>
|
|
621
|
+
<div class="api-desc">MCP 服务器。list() / addServer() / removeServer() / call() / setEnabled()</div>
|
|
622
|
+
</div>
|
|
623
|
+
<div class="api-card fade-in delay-2">
|
|
624
|
+
<div class="api-name">framework.sessions</div>
|
|
625
|
+
<div class="api-desc">会话管理。list() / get() / getOrCreate() / destroy() / runIn()</div>
|
|
626
|
+
</div>
|
|
627
|
+
<div class="api-card fade-in">
|
|
628
|
+
<div class="api-name">framework.extensions</div>
|
|
629
|
+
<div class="api-desc">扩展工具。listPlugins() / listTools() / getTool() / execute()</div>
|
|
630
|
+
</div>
|
|
631
|
+
<div class="api-card fade-in delay-1">
|
|
632
|
+
<div class="api-name">framework.rules</div>
|
|
633
|
+
<div class="api-desc">规则引擎。list() / add() / remove() / test() / checkToolCall() / checkMessage()</div>
|
|
634
|
+
</div>
|
|
635
|
+
<div class="api-card fade-in delay-2">
|
|
636
|
+
<div class="api-name">framework.plugins</div>
|
|
637
|
+
<div class="api-desc">插件管理。register() / get() / list() / has() / create()</div>
|
|
638
|
+
</div>
|
|
639
|
+
</div>
|
|
640
|
+
</div>
|
|
641
|
+
</section>
|
|
642
|
+
|
|
643
|
+
<div class="divider"></div>
|
|
644
|
+
|
|
645
|
+
<!-- QUICK START -->
|
|
646
|
+
<section class="section" id="quickstart">
|
|
647
|
+
<div class="section-inner">
|
|
648
|
+
<div class="section-label">快速开始</div>
|
|
649
|
+
<h2 class="section-title">5 分钟上手 Foliko</h2>
|
|
650
|
+
<p class="section-desc">一行命令安装,本地配置 AI Key,马上开始对话。</p>
|
|
651
|
+
|
|
652
|
+
<div class="code-block fade-in">
|
|
653
|
+
<span class="cm"># macOS / Linux</span><br>
|
|
654
|
+
curl -fsSL https://folikoai.com/install.sh | bash<br><br>
|
|
655
|
+
<span class="cm"># Windows</span><br>
|
|
656
|
+
irm https://folikoai.com/install.ps1 | iex<br><br>
|
|
657
|
+
<span class="cm"># npm</span><br>
|
|
658
|
+
npm install -g foliko
|
|
659
|
+
</div>
|
|
660
|
+
|
|
661
|
+
<div class="install-grid">
|
|
662
|
+
<div class="install-card fade-in">
|
|
663
|
+
<h4>配置文件</h4>
|
|
664
|
+
<p style="font-size:0.8rem;color:var(--text-secondary);margin-bottom:0.75rem;">项目根目录创建 <code style="background:rgba(0,0,0,0.3);padding:0.1rem 0.35rem;border-radius:3px;font-family:'JetBrains Mono',monospace;">.foliko/ai.json</code></p>
|
|
665
|
+
<pre>{
|
|
666
|
+
<span class="dot">"provider"</span>: <span class="str">"deepseek"</span>,
|
|
667
|
+
<span class="dot">"apiKey"</span>: <span class="str">"sk-xxx"</span>,
|
|
668
|
+
<span class="dot">"model"</span>: <span class="str">"deepseek-chat"</span>
|
|
669
|
+
}</pre>
|
|
670
|
+
</div>
|
|
671
|
+
<div class="install-card fade-in delay-1">
|
|
672
|
+
<h4>开始对话</h4>
|
|
673
|
+
<pre style="color:#a8b5c4;">$ foliko chat
|
|
674
|
+
|
|
675
|
+
<span class="cm"># 或指定模型</span>
|
|
676
|
+
$ foliko chat --provider deepseek \
|
|
677
|
+
--model deepseek-chat \
|
|
678
|
+
--api-key sk-xxx</pre>
|
|
679
|
+
</div>
|
|
680
|
+
</div>
|
|
681
|
+
|
|
682
|
+
<div style="margin-top:2.5rem;" class="fade-in">
|
|
683
|
+
<h3 style="font-size:1.1rem;font-weight:700;margin-bottom:1.25rem;">完整示例:编程方式</h3>
|
|
684
|
+
<div class="code-block">
|
|
685
|
+
<span class="kw">const</span> { createApp, withAI, withShell, bootstrap, createAgent, destroy } = <span class="kw">require</span>(<span class="str">'foliko'</span>);<br>
|
|
686
|
+
<span class="kw">const</span> { z } = <span class="kw">require</span>(<span class="str">'zod'</span>);<br><br>
|
|
687
|
+
<span class="cm">// 1. 创建 Framework,链式加载插件</span><br>
|
|
688
|
+
<span class="kw">const</span> app = createApp({ debug: <span class="kw">true</span> });<br>
|
|
689
|
+
<span class="kw">await</span> app.<span class="dot">use</span>(withAI({ provider: <span class="str">'deepseek'</span>, model: <span class="str">'deepseek-chat'</span>, apiKey: <span class="str">'sk-xxx'</span> }));<br>
|
|
690
|
+
<span class="kw">await</span> app.<span class="dot">use</span>(withShell());<br>
|
|
691
|
+
<span class="kw">await</span> bootstrap(app, { _config: { ai: {} } });<br><br>
|
|
692
|
+
<span class="cm">// 2. 注册自定义工具(Zod Schema 定义参数)</span><br>
|
|
693
|
+
app.<span class="dot">registerTool</span>({<br>
|
|
694
|
+
name: <span class="str">'calculate'</span>,<br>
|
|
695
|
+
description: <span class="str">'计算数学表达式'</span>,<br>
|
|
696
|
+
inputSchema: z.object({ expression: z.string().describe(<span class="str">'如 2+3*4'</span>) }),<br>
|
|
697
|
+
execute: <span class="kw">async</span> (args) => ({ result: <span class="kw">eval</span>(args.expression) })<br>
|
|
698
|
+
});<br><br>
|
|
699
|
+
<span class="cm">// 3. 创建 Agent</span><br>
|
|
700
|
+
<span class="kw">const</span> agent = createAgent(app, {<br>
|
|
701
|
+
name: <span class="str">'MyAgent'</span>,<br>
|
|
702
|
+
systemPrompt: <span class="str">'你是一个有帮助的助手'</span><br>
|
|
703
|
+
});<br><br>
|
|
704
|
+
<span class="cm">// 4. 流式对话</span><br>
|
|
705
|
+
<span class="kw">for await</span> (<span class="kw">const</span> chunk <span class="kw">of</span> agent.<span class="dot">chatStream</span>(<span class="str">'请用中文介绍一下自己'</span>)) {<br>
|
|
706
|
+
<span class="kw">if</span> (chunk.type === <span class="str">'text'</span>) process.stdout.<span class="dot">write</span>(chunk.text);<br>
|
|
707
|
+
}<br><br>
|
|
708
|
+
<span class="cm">// 5. 清理</span><br>
|
|
709
|
+
<span class="kw">await</span> destroy(app);
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
712
|
+
</div>
|
|
713
|
+
</section>
|
|
714
|
+
|
|
715
|
+
<!-- FOOTER -->
|
|
716
|
+
<footer>
|
|
717
|
+
<p>Foliko · 简约的插件化 Agent 框架 · MIT License</p>
|
|
718
|
+
<p style="margin-top:0.5rem;">
|
|
719
|
+
<a href="https://github.com/folikoai/foliko" target="_blank">GitHub</a> ·
|
|
720
|
+
<a href="https://www.npmjs.com/package/foliko" target="_blank">npm</a> ·
|
|
721
|
+
<a href="https://folikoai.com" target="_blank">官网</a>
|
|
722
|
+
</p>
|
|
723
|
+
</footer>
|
|
724
|
+
|
|
725
|
+
<script>
|
|
726
|
+
// Plugin data
|
|
727
|
+
const pluginData = {
|
|
728
|
+
core: [
|
|
729
|
+
{ name: 'ai', desc: 'AI 对话 · Vercel AI SDK,多 Provider 支持' },
|
|
730
|
+
{ name: 'storage', desc: '键值持久化 · JSONL 格式' },
|
|
731
|
+
{ name: 'session', desc: '多会话管理 · 上下文隔离' },
|
|
732
|
+
{ name: 'sub-agent', desc: '子 Agent 隔离与委托' },
|
|
733
|
+
{ name: 'skill-manager', desc: 'Skill 加载与命令注册' },
|
|
734
|
+
{ name: 'workflow', desc: '结构化工作流引擎' },
|
|
735
|
+
{ name: 'scheduler', desc: 'Cron 定时任务调度' },
|
|
736
|
+
{ name: 'mcp', desc: 'Model Context Protocol 集成' },
|
|
737
|
+
{ name: 'rules', desc: '权限与内容规则引擎' },
|
|
738
|
+
{ name: 'audit', desc: '操作审计日志' },
|
|
739
|
+
{ name: 'coordinator', desc: '多 Agent 协调模式' },
|
|
740
|
+
{ name: 'think', desc: '主动思考 Agent' },
|
|
741
|
+
],
|
|
742
|
+
executor: [
|
|
743
|
+
{ name: 'shell-executor', desc: 'Shell 命令执行' },
|
|
744
|
+
{ name: 'python-executor', desc: 'Python 代码/脚本执行' },
|
|
745
|
+
{ name: 'extension-executor', desc: '外部扩展工具统一调度(ext_call)' },
|
|
746
|
+
{ name: 'data-splitter', desc: '大数据自动分片' },
|
|
747
|
+
{ name: 'python-loader', desc: '动态加载 Python 插件' },
|
|
748
|
+
],
|
|
749
|
+
messaging: [
|
|
750
|
+
{ name: 'telegram', desc: 'Telegram Bot 集成' },
|
|
751
|
+
{ name: 'qq', desc: 'QQ 机器人' },
|
|
752
|
+
{ name: 'weixin', desc: '微信 Bot' },
|
|
753
|
+
{ name: 'feishu', desc: '飞书/Lark 消息推送' },
|
|
754
|
+
{ name: 'email', desc: 'SMTP/IMAP 邮件收发' },
|
|
755
|
+
],
|
|
756
|
+
io: [
|
|
757
|
+
{ name: 'file-system', desc: '文件系统操作工具' },
|
|
758
|
+
{ name: 'web', desc: 'HTTP 服务器与 Webhook' },
|
|
759
|
+
],
|
|
760
|
+
other: [
|
|
761
|
+
{ name: 'ambient', desc: '后台自主 Agent 循环' },
|
|
762
|
+
{ name: 'memory', desc: '四层记忆系统' },
|
|
763
|
+
{ name: 'trading', desc: 'Gate.io 交易接口' },
|
|
764
|
+
{ name: 'install', desc: 'npm 包自动安装' },
|
|
765
|
+
],
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
function renderPlugins(tab) {
|
|
769
|
+
const list = document.getElementById('pluginList');
|
|
770
|
+
list.innerHTML = '';
|
|
771
|
+
(pluginData[tab] || []).forEach(p => {
|
|
772
|
+
const div = document.createElement('div');
|
|
773
|
+
div.className = 'plugin-item';
|
|
774
|
+
div.innerHTML = `<span class="p-name">${p.name}</span><span class="p-desc">${p.desc}</span>`;
|
|
775
|
+
list.appendChild(div);
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
document.querySelectorAll('.plugin-tab').forEach(btn => {
|
|
780
|
+
btn.addEventListener('click', () => {
|
|
781
|
+
document.querySelectorAll('.plugin-tab').forEach(b => b.classList.remove('active'));
|
|
782
|
+
btn.classList.add('active');
|
|
783
|
+
renderPlugins(btn.dataset.tab);
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
renderPlugins('core');
|
|
787
|
+
|
|
788
|
+
// Scroll animations
|
|
789
|
+
const observer = new IntersectionObserver(
|
|
790
|
+
entries => entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); }),
|
|
791
|
+
{ threshold: 0.08, rootMargin: '0px 0px -40px 0px' }
|
|
792
|
+
);
|
|
793
|
+
document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));
|
|
794
|
+
|
|
795
|
+
// Copy buttons
|
|
796
|
+
document.querySelectorAll('.code-block').forEach(block => {
|
|
797
|
+
const btn = document.createElement('button');
|
|
798
|
+
btn.className = 'copy-btn';
|
|
799
|
+
btn.textContent = '复制';
|
|
800
|
+
btn.addEventListener('click', () => {
|
|
801
|
+
const code = block.cloneNode(true);
|
|
802
|
+
code.querySelector('.copy-btn')?.remove();
|
|
803
|
+
navigator.clipboard.writeText(code.textContent).then(() => {
|
|
804
|
+
btn.textContent = '已复制!';
|
|
805
|
+
setTimeout(() => (btn.textContent = '复制'), 2000);
|
|
806
|
+
});
|
|
807
|
+
});
|
|
808
|
+
block.style.position = 'relative';
|
|
809
|
+
block.appendChild(btn);
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
// Smooth scroll
|
|
813
|
+
document.querySelectorAll('a[href^="#"]').forEach(a => {
|
|
814
|
+
a.addEventListener('click', e => {
|
|
815
|
+
e.preventDefault();
|
|
816
|
+
document.querySelector(a.getAttribute('href')).scrollIntoView({ behavior: 'smooth' });
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
</script>
|
|
820
|
+
</body>
|
|
821
|
+
</html>
|