foliko 1.0.80 → 1.0.81
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/agents/code-assistant.json +14 -0
- package/.agent/agents/email-assistant.json +14 -0
- package/.agent/agents/file-assistant.json +15 -0
- package/.agent/agents/system-assistant.json +15 -0
- package/.agent/agents/web-assistant.json +12 -0
- package/.agent/data/ambient/goals.json +50 -0
- package/.agent/data/ambient/memories.json +7 -0
- package/.agent/data/default.json +15 -31894
- package/.agent/data/plugins-state.json +146 -181
- package/.agent/data/scheduler/tasks.json +1 -0
- package/.agent/mcp_config.json +1 -0
- package/.agent/package.json +8 -0
- package/.agent/plugins/__pycache__/test_plugin.cpython-312.pyc +0 -0
- package/.agent/plugins/system-info/index.js +387 -0
- package/.agent/plugins/system-info/package.json +4 -0
- package/.agent/plugins/system-info/test.js +40 -0
- package/.agent/plugins/test_plugin.py +304 -0
- package/.agent/plugins.json +14 -5
- package/.agent/python-scripts/test_sample.py +24 -0
- package/.agent/skills/sysinfo/SKILL.md +38 -0
- package/.agent/skills/sysinfo/system-info.sh +130 -0
- package/.agent/skills/workflow/SKILL.md +324 -0
- package/.agent/workflows/email-digest.json +50 -0
- package/.agent/workflows/file-backup.json +21 -0
- package/.agent/workflows/get-ip-notify.json +32 -0
- package/.agent/workflows/news-aggregator.json +93 -0
- package/.agent/workflows/news-dashboard-v2.json +94 -0
- package/.agent/workflows/notification-batch.json +32 -0
- package/.claude/settings.local.json +171 -171
- package/.env.example +56 -56
- 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 +83 -83
- 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 +548 -548
- 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/extension-executor-plugin.js +326 -326
- package/plugins/feishu-plugin.js +481 -481
- package/plugins/file-system-plugin.js +920 -877
- package/plugins/gate-trading.js +747 -747
- package/plugins/install-plugin.js +199 -199
- package/plugins/python-executor-plugin.js +367 -367
- package/plugins/python-plugin-loader.js +651 -651
- package/plugins/rules-plugin.js +294 -294
- package/plugins/scheduler-plugin.js +691 -691
- package/plugins/session-plugin.js +494 -494
- package/plugins/shell-executor-plugin.js +197 -197
- package/plugins/storage-plugin.js +263 -263
- 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 +637 -637
- package/plugins/weixin-plugin.js +545 -545
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/skills/foliko-dev/SKILL.md +563 -583
- package/skills/python-plugin-dev/SKILL.md +238 -238
- 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 +141 -134
- package/src/core/agent.js +958 -958
- package/src/core/framework.js +465 -465
- package/src/core/index.js +19 -19
- package/src/core/plugin-base.js +262 -262
- 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 +845 -845
- 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/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
- 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 +0 -258
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
- package/.agent/ARCHITECTURE.md +0 -288
- package/.agent/agents/ambient-agent.md +0 -57
- package/.agent/agents/debugger.md +0 -55
- package/.agent/agents/email-assistant.md +0 -49
- package/.agent/agents/file-manager.md +0 -42
- package/.agent/agents/python-developer.md +0 -60
- package/.agent/agents/scheduler.md +0 -59
- package/.agent/agents/web-developer.md +0 -45
- package/.agent/mcp_config_updated.json +0 -12
- package/.agent/rules/GEMINI.md +0 -273
- package/.agent/rules/allow-rule.md +0 -77
- package/.agent/rules/log-rule.md +0 -83
- package/.agent/rules/security-rule.md +0 -93
- package/.agent/scripts/auto_preview.py +0 -148
- package/.agent/scripts/checklist.py +0 -217
- package/.agent/scripts/session_manager.py +0 -120
- package/.agent/scripts/verify_all.py +0 -327
- package/.agent/skills/api-patterns/SKILL.md +0 -81
- package/.agent/skills/api-patterns/api-style.md +0 -42
- package/.agent/skills/api-patterns/auth.md +0 -24
- package/.agent/skills/api-patterns/documentation.md +0 -26
- package/.agent/skills/api-patterns/graphql.md +0 -41
- package/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/.agent/skills/api-patterns/response.md +0 -37
- package/.agent/skills/api-patterns/rest.md +0 -40
- package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
- package/.agent/skills/api-patterns/security-testing.md +0 -122
- package/.agent/skills/api-patterns/trpc.md +0 -41
- package/.agent/skills/api-patterns/versioning.md +0 -22
- package/.agent/skills/app-builder/SKILL.md +0 -75
- package/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/.agent/skills/app-builder/feature-building.md +0 -53
- package/.agent/skills/app-builder/project-detection.md +0 -34
- package/.agent/skills/app-builder/scaffolding.md +0 -118
- package/.agent/skills/app-builder/tech-stack.md +0 -40
- package/.agent/skills/app-builder/templates/SKILL.md +0 -39
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -122
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -122
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -169
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -134
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -119
- package/.agent/skills/architecture/SKILL.md +0 -55
- package/.agent/skills/architecture/context-discovery.md +0 -43
- package/.agent/skills/architecture/examples.md +0 -94
- package/.agent/skills/architecture/pattern-selection.md +0 -68
- package/.agent/skills/architecture/patterns-reference.md +0 -50
- package/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/.agent/skills/clean-code/SKILL.md +0 -201
- package/.agent/skills/doc.md +0 -177
- package/.agent/skills/frontend-design/SKILL.md +0 -418
- package/.agent/skills/frontend-design/animation-guide.md +0 -331
- package/.agent/skills/frontend-design/color-system.md +0 -311
- package/.agent/skills/frontend-design/decision-trees.md +0 -418
- package/.agent/skills/frontend-design/motion-graphics.md +0 -306
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
- package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
- package/.agent/skills/frontend-design/typography-system.md +0 -345
- package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
- package/.agent/skills/frontend-design/visual-effects.md +0 -383
- package/.agent/skills/i18n-localization/SKILL.md +0 -154
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
- package/.agent/skills/mcp-builder/SKILL.md +0 -176
- package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
- package/.agent/workflows/brainstorm.md +0 -113
- package/.agent/workflows/create.md +0 -59
- package/.agent/workflows/debug.md +0 -103
- package/.agent/workflows/deploy.md +0 -176
- package/.agent/workflows/enhance.md +0 -63
- package/.agent/workflows/orchestrate.md +0 -237
- package/.agent/workflows/plan.md +0 -89
- package/.agent/workflows/preview.md +0 -81
- package/.agent/workflows/simple-test.md +0 -42
- package/.agent/workflows/status.md +0 -86
- package/.agent/workflows/structured-orchestrate.md +0 -180
- package/.agent/workflows/test.md +0 -144
- package/.agent/workflows/ui-ux-pro-max.md +0 -296
package/src/core/agent-chat.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { EventEmitter } = require('../utils/event-emitter');
|
|
7
7
|
const { logger } = require('../utils/logger');
|
|
8
|
-
const { generateText, pruneMessages } = require('ai');
|
|
8
|
+
const { generateText, pruneMessages, stepCountIs, convertToModelMessages } = require('ai');
|
|
9
9
|
|
|
10
10
|
// 模型上下文限制表(留 15-20% 余量给 system prompt 和输出)
|
|
11
11
|
const MODEL_CONTEXT_LIMITS = {
|
|
@@ -97,7 +97,7 @@ class AgentChatHandler extends EventEmitter {
|
|
|
97
97
|
this._systemPrompt = config.systemPrompt || 'You are a helpful assistant.';
|
|
98
98
|
this._messages = [];
|
|
99
99
|
this._tools = new Map();
|
|
100
|
-
this._maxSteps =
|
|
100
|
+
this._maxSteps = 20; // 降低默认步骤数,减少上下文消耗
|
|
101
101
|
|
|
102
102
|
// 上下文压缩配置:根据模型自动设置限制
|
|
103
103
|
const modelKey = Object.keys(MODEL_CONTEXT_LIMITS).find((k) =>
|
|
@@ -163,7 +163,7 @@ class AgentChatHandler extends EventEmitter {
|
|
|
163
163
|
const existingCount = existingHistory.length;
|
|
164
164
|
|
|
165
165
|
// 只添加新消息(避免重复添加已加载的历史)
|
|
166
|
-
const simpleMessages = messages
|
|
166
|
+
const simpleMessages = messages;
|
|
167
167
|
|
|
168
168
|
const newMessages = simpleMessages.slice(existingCount);
|
|
169
169
|
for (const msg of newMessages) {
|
|
@@ -366,13 +366,14 @@ class AgentChatHandler extends EventEmitter {
|
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
const summary = {
|
|
369
|
-
role: '
|
|
369
|
+
role: 'assistant',
|
|
370
370
|
content: summaryContent,
|
|
371
371
|
};
|
|
372
372
|
|
|
373
|
-
this._messages = [...systemMessages, summary, ...recentMessages]
|
|
373
|
+
this._messages = [...systemMessages, summary, ...recentMessages].filter(
|
|
374
|
+
(item) => item.role !== 'tool'
|
|
375
|
+
);
|
|
374
376
|
this._compressionCount++;
|
|
375
|
-
|
|
376
377
|
const totalTokens = this._countMessagesTokens(this._messages);
|
|
377
378
|
logger.info(
|
|
378
379
|
`Context compressed (${this._compressionCount} times). Messages: ${this._messages.length}, Est. tokens: ${totalTokens}`
|
|
@@ -639,80 +640,77 @@ ${truncatedContent}${truncatedNote}
|
|
|
639
640
|
const context = { sessionId, isStream: false };
|
|
640
641
|
const framework = this.agent.framework;
|
|
641
642
|
const self = this; // 保存引用用于回调
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
643
|
+
try {
|
|
644
|
+
// 从 session 加载聊天历史
|
|
645
|
+
if (sessionId) {
|
|
646
|
+
const savedMessages = this._loadHistoryFromSession(sessionId);
|
|
647
|
+
if (savedMessages.length > 0) {
|
|
648
|
+
this._messages = savedMessages;
|
|
649
|
+
logger.info(`Loaded ${savedMessages.length} messages from session ${sessionId}`);
|
|
650
|
+
}
|
|
649
651
|
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
// 关键:每次 chat 调用时刷新系统提示词,确保包含最新的工具/技能描述
|
|
653
|
-
// 解决上下文过长时 LLM 不调用工具的问题
|
|
654
|
-
this._systemPrompt = this.agent._buildSystemPrompt();
|
|
655
|
-
// 动态导入 AI SDK
|
|
656
|
-
const { tool, ToolLoopAgent } = await this._importAI();
|
|
657
|
-
|
|
658
|
-
const userMessage = typeof message === 'string' ? { role: 'user', content: message } : message;
|
|
659
|
-
|
|
660
|
-
this._messages.push(userMessage);
|
|
661
|
-
|
|
662
|
-
// 检查是否需要压缩上下文(包括工具定义)
|
|
663
|
-
const messagesTokens = this._countMessagesTokens(this._messages);
|
|
664
|
-
const toolsTokens = this._countToolsTokens();
|
|
665
|
-
const systemPromptTokens = this._countTokens(this._systemPrompt);
|
|
666
|
-
const totalTokens = messagesTokens + toolsTokens + systemPromptTokens;
|
|
667
|
-
const limit = this._maxContextTokens * 0.7; // 降低到 70%,更早压缩
|
|
668
|
-
|
|
669
|
-
if (totalTokens > limit) {
|
|
670
|
-
logger.info(
|
|
671
|
-
`Context large (${totalTokens}/${this._maxContextTokens} tokens = msgs:${messagesTokens} + tools:${toolsTokens} + sys:${systemPromptTokens}), compressing...`
|
|
672
|
-
);
|
|
673
|
-
// 使用带超时控制的压缩
|
|
674
|
-
await this._compressContext();
|
|
675
|
-
} else {
|
|
676
|
-
logger.info(`Context OK: ${totalTokens}/${this._maxContextTokens} tokens`);
|
|
677
|
-
}
|
|
678
652
|
|
|
679
|
-
|
|
680
|
-
|
|
653
|
+
// 关键:每次 chat 调用时刷新系统提示词,确保包含最新的工具/技能描述
|
|
654
|
+
// 解决上下文过长时 LLM 不调用工具的问题
|
|
655
|
+
this._systemPrompt = this.agent._buildSystemPrompt();
|
|
656
|
+
// 动态导入 AI SDK
|
|
657
|
+
const { tool, ToolLoopAgent } = await this._importAI();
|
|
658
|
+
|
|
659
|
+
const userMessage =
|
|
660
|
+
typeof message === 'string' ? { role: 'user', content: message } : message;
|
|
661
|
+
//console.log('System Prompt:', this._systemPrompt);
|
|
662
|
+
this._messages.push(userMessage);
|
|
663
|
+
|
|
664
|
+
// 检查是否需要压缩上下文(包括工具定义)
|
|
665
|
+
const messagesTokens = this._countMessagesTokens(this._messages);
|
|
666
|
+
const toolsTokens = this._countToolsTokens();
|
|
667
|
+
const systemPromptTokens = this._countTokens(this._systemPrompt);
|
|
668
|
+
const totalTokens = messagesTokens + toolsTokens + systemPromptTokens;
|
|
669
|
+
const limit = this._maxContextTokens * 0.7; // 降低到 70%,更早压缩
|
|
670
|
+
|
|
671
|
+
if (totalTokens > limit) {
|
|
672
|
+
logger.info(
|
|
673
|
+
`Context large (${totalTokens}/${this._maxContextTokens} tokens = msgs:${messagesTokens} + tools:${toolsTokens} + sys:${systemPromptTokens}), compressing...`
|
|
674
|
+
);
|
|
675
|
+
// 使用带超时控制的压缩
|
|
676
|
+
await this._compressContext();
|
|
677
|
+
} else {
|
|
678
|
+
logger.info(`Context OK: ${totalTokens}/${this._maxContextTokens} tokens`);
|
|
679
|
+
}
|
|
681
680
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
681
|
+
const maxSteps = options.maxSteps || this._maxSteps;
|
|
682
|
+
const tools = this._getAITools(tool);
|
|
685
683
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
684
|
+
if (!this._aiClient) {
|
|
685
|
+
throw new Error('AI client not configured.');
|
|
686
|
+
}
|
|
687
|
+
// const prunedMessages = pruneMessages({
|
|
688
|
+
// messages: this._messages,
|
|
689
|
+
// reasoning: 'all', // Remove all reasoning parts
|
|
690
|
+
// toolCalls: 'before-last-6-messages', // Remove tool calls except those in the last message
|
|
691
|
+
// });
|
|
692
|
+
const agent = new ToolLoopAgent({
|
|
693
|
+
model: this._aiClient,
|
|
694
|
+
instructions: this._systemPrompt,
|
|
695
|
+
tools: tools,
|
|
696
|
+
stopWhen: stepCountIs(maxSteps),
|
|
697
|
+
prepareStep: async ({ stepNumber, steps, messages }) => {
|
|
698
|
+
if (messages.length > 20) {
|
|
699
|
+
return {
|
|
700
|
+
messages: messages.slice(-10),
|
|
701
|
+
};
|
|
702
|
+
}
|
|
692
703
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
reasoning: 'all', // Remove all reasoning parts
|
|
697
|
-
toolCalls: 'before-last-2-messages', // Remove tool calls except those in the last message
|
|
698
|
-
});
|
|
704
|
+
return {};
|
|
705
|
+
},
|
|
706
|
+
});
|
|
699
707
|
|
|
700
|
-
try {
|
|
701
708
|
// 使用 runWithContext 让工具执行时能获取 sessionId
|
|
702
709
|
const result = await framework.runWithContext(context, async () => {
|
|
703
|
-
return agent.generate({ messages:
|
|
710
|
+
return agent.generate({ messages: this._messages, ...this.providerOptions });
|
|
704
711
|
});
|
|
705
712
|
|
|
706
|
-
|
|
707
|
-
if (result.messages && Array.isArray(result.messages)) {
|
|
708
|
-
// 只保留 user 和 assistant 消息,SDK 会自动维护 tool 消息
|
|
709
|
-
this._messages = result.messages.filter((m) => m.role === 'user' || m.role === 'assistant');
|
|
710
|
-
} else if (result.text) {
|
|
711
|
-
this._messages.push({
|
|
712
|
-
role: 'assistant',
|
|
713
|
-
content: result.text,
|
|
714
|
-
});
|
|
715
|
-
}
|
|
713
|
+
this._messages.push(...result.response.messages);
|
|
716
714
|
|
|
717
715
|
// 生成后检查:如果消息太长,下次需要压缩
|
|
718
716
|
const afterTokens = this._countMessagesTokens(this._messages);
|
|
@@ -746,66 +744,77 @@ ${truncatedContent}${truncatedNote}
|
|
|
746
744
|
const sessionId = options.sessionId || null;
|
|
747
745
|
const context = { sessionId, isStream: true };
|
|
748
746
|
const framework = this.agent.framework;
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
747
|
+
try {
|
|
748
|
+
//从 session 加载聊天历史
|
|
749
|
+
if (sessionId) {
|
|
750
|
+
const savedMessages = this._loadHistoryFromSession(sessionId);
|
|
751
|
+
if (savedMessages.length > 0) {
|
|
752
|
+
this._messages = savedMessages;
|
|
753
|
+
logger.info(`Loaded ${savedMessages.length} messages from session ${sessionId}`);
|
|
754
|
+
}
|
|
756
755
|
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
// 关键:每次 chat 调用时刷新系统提示词,确保包含最新的工具/技能描述
|
|
760
|
-
// 解决上下文过长时 LLM 不调用工具的问题
|
|
761
|
-
this._systemPrompt = this.agent._buildSystemPrompt();
|
|
762
|
-
// 动态导入 AI SDK
|
|
763
|
-
const { tool, ToolLoopAgent } = await this._importAI();
|
|
764
|
-
|
|
765
|
-
const userMessage = typeof message === 'string' ? { role: 'user', content: message } : message;
|
|
766
|
-
//console.log('System Prompt:', this._systemPrompt);
|
|
767
|
-
this._messages.push(userMessage);
|
|
768
|
-
// 检查是否需要压缩上下文(包括工具定义)
|
|
769
|
-
const messagesTokens = this._countMessagesTokens(this._messages);
|
|
770
|
-
const toolsTokens = this._countToolsTokens();
|
|
771
|
-
const systemPromptTokens = this._countTokens(this._systemPrompt);
|
|
772
|
-
const totalTokens = messagesTokens + toolsTokens + systemPromptTokens;
|
|
773
|
-
const limit = this._maxContextTokens * 0.7; // 降低到 70%
|
|
774
|
-
|
|
775
|
-
// 对于流式调用,如果上下文太大,先压缩再开始
|
|
776
|
-
if (totalTokens > limit) {
|
|
777
|
-
logger.info(
|
|
778
|
-
`Context large (${totalTokens}/${this._maxContextTokens} tokens), compressing...`
|
|
779
|
-
);
|
|
780
|
-
// 流式调用时等待压缩完成(使用带超时控制的压缩)
|
|
781
|
-
await this._compressContext();
|
|
782
|
-
}
|
|
783
756
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
757
|
+
// 关键:每次 chat 调用时刷新系统提示词,确保包含最新的工具/技能描述
|
|
758
|
+
// 解决上下文过长时 LLM 不调用工具的问题
|
|
759
|
+
this._systemPrompt = this.agent._buildSystemPrompt();
|
|
760
|
+
// 动态导入 AI SDK
|
|
761
|
+
const { tool, ToolLoopAgent } = await this._importAI();
|
|
762
|
+
|
|
763
|
+
const userMessage =
|
|
764
|
+
typeof message === 'string' ? { role: 'user', content: message } : message;
|
|
765
|
+
//console.log('System Prompt:', this._systemPrompt);
|
|
766
|
+
this._messages.push(userMessage);
|
|
767
|
+
|
|
768
|
+
// 检查是否需要压缩上下文(包括工具定义)
|
|
769
|
+
const messagesTokens = this._countMessagesTokens(this._messages);
|
|
770
|
+
const toolsTokens = this._countToolsTokens();
|
|
771
|
+
const systemPromptTokens = this._countTokens(this._systemPrompt);
|
|
772
|
+
const totalTokens = messagesTokens + toolsTokens + systemPromptTokens;
|
|
773
|
+
const limit = this._maxContextTokens * 0.7; // 降低到 70%
|
|
774
|
+
// 对于流式调用,如果上下文太大,先压缩再开始
|
|
775
|
+
if (totalTokens > limit) {
|
|
776
|
+
logger.info(
|
|
777
|
+
`Context large (${totalTokens}/${this._maxContextTokens} tokens), compressing...`
|
|
778
|
+
);
|
|
779
|
+
// 流式调用时等待压缩完成(使用带超时控制的压缩)
|
|
780
|
+
await this._compressContext();
|
|
781
|
+
}
|
|
787
782
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
783
|
+
const maxSteps = options.maxSteps || this._maxSteps;
|
|
784
|
+
const tools = this._getAITools(tool);
|
|
785
|
+
const self = this; // 保存引用用于回调
|
|
786
|
+
if (!this._aiClient) {
|
|
787
|
+
throw new Error('AI client not configured.');
|
|
788
|
+
}
|
|
789
|
+
console.log(JSON.stringify(this._messages, null, 2));
|
|
790
|
+
// const prunedMessages = pruneMessages({
|
|
791
|
+
// messages: this._messages,
|
|
792
|
+
// reasoning: 'all', // Remove all reasoning parts
|
|
793
|
+
// toolCalls: 'before-last-6-messages', // Remove tool calls except those in the last message
|
|
794
|
+
// });
|
|
795
|
+
|
|
796
|
+
const agent = new ToolLoopAgent({
|
|
797
|
+
model: this._aiClient,
|
|
798
|
+
instructions: this._systemPrompt,
|
|
799
|
+
tools: tools,
|
|
800
|
+
stopWhen: stepCountIs(maxSteps),
|
|
801
|
+
prepareStep: async ({ stepNumber, steps, messages }) => {
|
|
802
|
+
if (messages.length > 20) {
|
|
803
|
+
return {
|
|
804
|
+
messages: messages.slice(-10),
|
|
805
|
+
};
|
|
806
|
+
}
|
|
791
807
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
tools: tools,
|
|
796
|
-
stopWhen: (step) => step.stepCount >= maxSteps,
|
|
797
|
-
});
|
|
808
|
+
return {};
|
|
809
|
+
},
|
|
810
|
+
});
|
|
798
811
|
|
|
799
|
-
const messages = this._cleanMessages(this._messages);
|
|
800
|
-
const prunedMessages = pruneMessages({
|
|
801
|
-
messages,
|
|
802
|
-
reasoning: 'all', // Remove all reasoning parts
|
|
803
|
-
toolCalls: 'before-last-2-messages', // Remove tool calls except those in the last message
|
|
804
|
-
});
|
|
805
|
-
try {
|
|
806
812
|
// 使用 runWithContext 让工具执行时能获取 sessionId(支持并行)
|
|
807
813
|
const result = await framework.runWithContext(context, async () => {
|
|
808
|
-
return agent.stream({
|
|
814
|
+
return agent.stream({
|
|
815
|
+
messages: this._messages,
|
|
816
|
+
...this.providerOptions,
|
|
817
|
+
});
|
|
809
818
|
});
|
|
810
819
|
|
|
811
820
|
const stream = result.fullStream;
|
|
@@ -813,7 +822,6 @@ ${truncatedContent}${truncatedNote}
|
|
|
813
822
|
|
|
814
823
|
// 流式迭代器
|
|
815
824
|
const iterator = stream[Symbol.asyncIterator] ? stream : stream.fullStream;
|
|
816
|
-
const finalMessages = [];
|
|
817
825
|
|
|
818
826
|
for await (const part of iterator || stream) {
|
|
819
827
|
if (part.type === 'text-delta') {
|
|
@@ -821,25 +829,24 @@ ${truncatedContent}${truncatedNote}
|
|
|
821
829
|
fullText += text;
|
|
822
830
|
yield { type: 'text', text };
|
|
823
831
|
} else if (part.type === 'reasoning') {
|
|
824
|
-
finalMessages.push(part);
|
|
825
832
|
this.emit('thinking', { content: part.text });
|
|
826
833
|
} else if (part.type === 'tool-call') {
|
|
827
|
-
|
|
828
|
-
yield { type: 'tool-call', toolName: part.toolName, args: part.input };
|
|
834
|
+
yield { type: 'tool-call', toolName: part.toolName, input: part.input };
|
|
829
835
|
} else if (part.type === 'tool-result') {
|
|
830
|
-
// AI SDK 6.x 要求 tool 消息格式为:
|
|
831
|
-
// { role: 'tool', content: [{ type: 'tool-result', toolCallId, toolName, output }] }
|
|
832
|
-
finalMessages.push(part); // 先保存到 finalMessages,等生成结束后统一添加到历史
|
|
833
836
|
yield { type: 'tool-result', toolName: part.toolName, result: part.output };
|
|
834
837
|
} else if (part.type === 'error') {
|
|
835
838
|
yield { type: 'error', error: part.error };
|
|
836
839
|
}
|
|
837
840
|
}
|
|
838
841
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
842
|
+
const finish_messages = (await result.response).messages;
|
|
843
|
+
this._messages.push(...finish_messages);
|
|
844
|
+
// console.log(JSON.stringify(this._messages, null, 2));
|
|
845
|
+
// 生成后检查:如果消息太长,下次需要压缩
|
|
846
|
+
const afterTokens = this._countMessagesTokens(this._messages);
|
|
847
|
+
if (afterTokens > this._maxContextTokens * 0.8) {
|
|
848
|
+
logger.info(`After generation: ${afterTokens} tokens, will compress on next turn`);
|
|
849
|
+
}
|
|
843
850
|
|
|
844
851
|
// 保存聊天历史到 session
|
|
845
852
|
if (sessionId) {
|