foliko 1.1.34 → 1.1.35
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/sessions/cli_default.json +112 -1756
- package/.agent/skills/fk-poster/SKILL.md +441 -255
- package/package.json +1 -1
- package/src/core/agent-chat.js +59 -2
- package/src/core/context-compressor.js +2 -0
- package/src/core/provider.js +37 -3
package/package.json
CHANGED
package/src/core/agent-chat.js
CHANGED
|
@@ -22,6 +22,7 @@ const {
|
|
|
22
22
|
const { prepareMessagesForAPI, cleanResponse } = require('../utils');
|
|
23
23
|
const { ChatQueueManager } = require('../utils/chat-queue');
|
|
24
24
|
const { countTokens } = require('@anthropic-ai/tokenizer');
|
|
25
|
+
const { isThinkingModel } = require('./provider');
|
|
25
26
|
const fs = require('fs/promises');
|
|
26
27
|
// 新模块
|
|
27
28
|
const { ChatSession } = require('./chat-session');
|
|
@@ -46,7 +47,18 @@ class AgentChatHandler extends EventEmitter {
|
|
|
46
47
|
this.baseURL = config.baseURL;
|
|
47
48
|
this.providerOptions = config.providerOptions || {};
|
|
48
49
|
this.providerOptions.maxOutputTokens = config.providerOptions?.maxOutputTokens || 8192;
|
|
49
|
-
|
|
50
|
+
// DeepSeek thinking mode 模型不支持 temperature 参数
|
|
51
|
+
if (isThinkingModel(this.model)) {
|
|
52
|
+
this.providerOptions.temperature = undefined;
|
|
53
|
+
// DeepSeek 需要通过 extra_body 启用 thinking mode
|
|
54
|
+
// AI SDK 会将 providerOptions.deepseek 映射到请求体的 extra_body
|
|
55
|
+
if (!this.providerOptions.deepseek) {
|
|
56
|
+
this.providerOptions.deepseek = {};
|
|
57
|
+
}
|
|
58
|
+
this.providerOptions.deepseek.thinking = { type: 'enabled' };
|
|
59
|
+
} else {
|
|
60
|
+
this.providerOptions.temperature = config.providerOptions?.temperature || 0.3;
|
|
61
|
+
}
|
|
50
62
|
|
|
51
63
|
this._systemPrompt = config.systemPrompt || 'You are a helpful assistant.';
|
|
52
64
|
this._maxSteps = config.maxSteps || 20;
|
|
@@ -452,6 +464,10 @@ class AgentChatHandler extends EventEmitter {
|
|
|
452
464
|
logger.debug(`[AgentChat] SDK onError: ${error?.message}`);
|
|
453
465
|
};
|
|
454
466
|
|
|
467
|
+
// DeepSeek thinking mode: 收集 reasoning_content
|
|
468
|
+
const isThinking = isThinkingModel(this.model);
|
|
469
|
+
let reasoningContent = '';
|
|
470
|
+
|
|
455
471
|
const result = await framework.runInSession(sessionId, {}, async () => {
|
|
456
472
|
return agent.stream({ messages, ...this.providerOptions, onError: handleSDKError });
|
|
457
473
|
});
|
|
@@ -466,6 +482,7 @@ class AgentChatHandler extends EventEmitter {
|
|
|
466
482
|
fullText += text;
|
|
467
483
|
yield { type: 'text', text };
|
|
468
484
|
} else if (part.type === 'reasoning') {
|
|
485
|
+
reasoningContent += part.text || '';
|
|
469
486
|
yield { type: 'thinking', text: part.text };
|
|
470
487
|
} else if (part.type === 'tool-call') {
|
|
471
488
|
yield { type: 'tool-call', toolName: part.toolName, input: part.input };
|
|
@@ -478,7 +495,24 @@ class AgentChatHandler extends EventEmitter {
|
|
|
478
495
|
}
|
|
479
496
|
}
|
|
480
497
|
|
|
498
|
+
// DeepSeek thinking mode: 标记 reasoning_content 已处理
|
|
499
|
+
// 在 finishMessages 中标记,避免重复添加
|
|
481
500
|
const finishMessages = (await result.response).messages;
|
|
501
|
+
if (isThinking && reasoningContent) {
|
|
502
|
+
// DeepSeek 要求:当有 tool_calls 时,必须将 reasoning_content 添加到消息中
|
|
503
|
+
// AI SDK 的 finishMessage 不会包含 reasoning_content,需要手动添加
|
|
504
|
+
for (const msg of finishMessages) {
|
|
505
|
+
if (msg.role === 'assistant') {
|
|
506
|
+
// 检查是否有 tool_calls
|
|
507
|
+
const hasToolCalls = msg.tool_calls?.length > 0 ||
|
|
508
|
+
(Array.isArray(msg.content) && msg.content.some(c => c.type === 'tool-call' || c.type === 'tool-use'));
|
|
509
|
+
if (hasToolCalls) {
|
|
510
|
+
// DeepSeek API 要求:带 tool_calls 时必须传递 reasoning_content
|
|
511
|
+
msg.reasoning_content = reasoningContent;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
482
516
|
messages.push(...finishMessages);
|
|
483
517
|
const usage = await result.totalUsage;
|
|
484
518
|
if (usage) {
|
|
@@ -542,6 +576,13 @@ class AgentChatHandler extends EventEmitter {
|
|
|
542
576
|
}
|
|
543
577
|
const systemPrompt = framework._mainAgent._buildSystemPrompt();
|
|
544
578
|
const tools = this._getAITools(aiTool);
|
|
579
|
+
|
|
580
|
+
// DeepSeek thinking mode: 处理参数
|
|
581
|
+
const apiOptions = { ...this.providerOptions };
|
|
582
|
+
if (isThinkingModel(this.model)) {
|
|
583
|
+
delete apiOptions.temperature;
|
|
584
|
+
}
|
|
585
|
+
|
|
545
586
|
const agent = new ToolLoopAgent({
|
|
546
587
|
model: this._aiClient,
|
|
547
588
|
instructions: systemPrompt,
|
|
@@ -551,13 +592,29 @@ class AgentChatHandler extends EventEmitter {
|
|
|
551
592
|
});
|
|
552
593
|
|
|
553
594
|
const result = await framework.runInSession(sessionId, {}, async () => {
|
|
554
|
-
return agent.generate({ messages, ...
|
|
595
|
+
return agent.generate({ messages, ...apiOptions });
|
|
555
596
|
});
|
|
556
597
|
|
|
557
598
|
if (result.usage) {
|
|
558
599
|
this._updateMessageStoreUsage(messageStore, result.usage);
|
|
559
600
|
}
|
|
560
601
|
|
|
602
|
+
// DeepSeek thinking mode: 处理 reasoning_content
|
|
603
|
+
const isThinking = isThinkingModel(this.model);
|
|
604
|
+
if (isThinking && result.reasoningText) {
|
|
605
|
+
// 有 reasoning_text 需要添加到消息中(当有 tool_calls 时)
|
|
606
|
+
const finishMessages = result.response.messages;
|
|
607
|
+
for (const msg of finishMessages) {
|
|
608
|
+
if (msg.role === 'assistant') {
|
|
609
|
+
const hasToolCalls = msg.tool_calls?.length > 0 ||
|
|
610
|
+
(Array.isArray(msg.content) && msg.content.some(c => c.type === 'tool-call' || c.type === 'tool-use'));
|
|
611
|
+
if (hasToolCalls) {
|
|
612
|
+
msg.reasoning_content = result.reasoningText;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
561
618
|
messages.push(...result.response.messages);
|
|
562
619
|
const userMsg = messages[messages.length - result.response.messages.length - 1];
|
|
563
620
|
this.emit('message', { content: result.text, sessionId: sessionId, userMessage: userMsg });
|
|
@@ -15,6 +15,8 @@ const { Subagent } = require('./subagent');
|
|
|
15
15
|
const MODEL_CONTEXT_LIMITS = {
|
|
16
16
|
'deepseek-chat': 100000,
|
|
17
17
|
'deepseek-coder': 100000,
|
|
18
|
+
'deepseek-v4-pro': 800000,
|
|
19
|
+
'deepseek-v4-flash': 800000,
|
|
18
20
|
'deepseek-reasoner': 100000,
|
|
19
21
|
'MiniMax-M2.7': 100000,
|
|
20
22
|
'gpt-4': 100000,
|
package/src/core/provider.js
CHANGED
|
@@ -37,6 +37,28 @@ const DEFAULT_PROVIDERS = {
|
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* 需要禁用 temperature 的模型(thinking mode 模型)
|
|
42
|
+
*/
|
|
43
|
+
const THINKING_MODELS = [
|
|
44
|
+
'deepseek-v4-pro',
|
|
45
|
+
'deepseek-v4-flash',
|
|
46
|
+
'deepseek-reasoner',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 检查是否是 thinking mode 模型
|
|
51
|
+
* @param {string} model - 模型名称
|
|
52
|
+
* @returns {boolean}
|
|
53
|
+
*/
|
|
54
|
+
function isThinkingModel(model) {
|
|
55
|
+
if (!model) return false;
|
|
56
|
+
const lowerModel = model.toLowerCase();
|
|
57
|
+
return THINKING_MODELS.some(
|
|
58
|
+
(tm) => lowerModel.includes(tm) || lowerModel === tm
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
/**
|
|
41
63
|
* 创建 AI 客户端
|
|
42
64
|
* @param {Object} config - 配置
|
|
@@ -48,9 +70,22 @@ const DEFAULT_PROVIDERS = {
|
|
|
48
70
|
function createAI(config) {
|
|
49
71
|
const { provider, model, apiKey, baseURL } = config;
|
|
50
72
|
const providerName = (provider || 'deepseek').toLowerCase();
|
|
73
|
+
const isThinking = isThinkingModel(model);
|
|
74
|
+
|
|
51
75
|
// 检查是否是预定义提供商
|
|
52
76
|
if (DEFAULT_PROVIDERS[providerName]) {
|
|
53
77
|
const providerConfig = DEFAULT_PROVIDERS[providerName];
|
|
78
|
+
|
|
79
|
+
// 为 DeepSeek thinking mode 模型添加特殊配置
|
|
80
|
+
const streamOptions = {
|
|
81
|
+
includeUsage: true,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// DeepSeek 模型添加 reasoning_content 输出
|
|
85
|
+
if (providerName === 'deepseek') {
|
|
86
|
+
streamOptions.includeReasoningContent = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
54
89
|
return createOpenAICompatible({
|
|
55
90
|
name: providerConfig.name,
|
|
56
91
|
baseURL: baseURL || providerConfig.baseURL,
|
|
@@ -65,9 +100,7 @@ function createAI(config) {
|
|
|
65
100
|
models: {
|
|
66
101
|
default: {
|
|
67
102
|
id: model || 'deepseek-chat',
|
|
68
|
-
streamOptions
|
|
69
|
-
includeUsage: true,
|
|
70
|
-
},
|
|
103
|
+
streamOptions,
|
|
71
104
|
},
|
|
72
105
|
},
|
|
73
106
|
});
|
|
@@ -111,4 +144,5 @@ module.exports = {
|
|
|
111
144
|
createModel,
|
|
112
145
|
getAvailableProviders,
|
|
113
146
|
DEFAULT_PROVIDERS,
|
|
147
|
+
isThinkingModel,
|
|
114
148
|
};
|