foliko 2.0.30 → 2.0.32

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.
@@ -1,133 +1,133 @@
1
- ---
2
- name: find-skills
3
- description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
4
- ---
5
-
6
- # Find Skills
7
-
8
- This skill helps you discover and install skills from the open agent skills ecosystem.
9
-
10
- ## When to Use This Skill
11
-
12
- Use this skill when the user:
13
-
14
- - Asks "how do I do X" where X might be a common task with an existing skill
15
- - Says "find a skill for X" or "is there a skill for X"
16
- - Asks "can you do X" where X is a specialized capability
17
- - Expresses interest in extending agent capabilities
18
- - Wants to search for tools, templates, or workflows
19
- - Mentions they wish they had help with a specific domain (design, testing, deployment, etc.)
20
-
21
- ## What is the Skills CLI?
22
-
23
- The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools.
24
-
25
- **Key commands:**
26
-
27
- - `npx skills find [query]` - Search for skills interactively or by keyword
28
- - `npx skills add <package>` - Install a skill from GitHub or other sources
29
- - `npx skills check` - Check for skill updates
30
- - `npx skills update` - Update all installed skills
31
-
32
- **Browse skills at:** https://skills.sh/
33
-
34
- ## How to Help Users Find Skills
35
-
36
- ### Step 1: Understand What They Need
37
-
38
- When a user asks for help with something, identify:
39
-
40
- 1. The domain (e.g., React, testing, design, deployment)
41
- 2. The specific task (e.g., writing tests, creating animations, reviewing PRs)
42
- 3. Whether this is a common enough task that a skill likely exists
43
-
44
- ### Step 2: Search for Skills
45
-
46
- Run the find command with a relevant query:
47
-
48
- ```bash
49
- npx skills find [query]
50
- ```
51
-
52
- For example:
53
-
54
- - User asks "how do I make my React app faster?" → `npx skills find react performance`
55
- - User asks "can you help me with PR reviews?" → `npx skills find pr review`
56
- - User asks "I need to create a changelog" → `npx skills find changelog`
57
-
58
- The command will return results like:
59
-
60
- ```
61
- Install with npx skills add <owner/repo@skill>
62
-
63
- vercel-labs/agent-skills@vercel-react-best-practices
64
- └ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
65
- ```
66
-
67
- ### Step 3: Present Options to the User
68
-
69
- When you find relevant skills, present them to the user with:
70
-
71
- 1. The skill name and what it does
72
- 2. The install command they can run
73
- 3. A link to learn more at skills.sh
74
-
75
- Example response:
76
-
77
- ```
78
- I found a skill that might help! The "vercel-react-best-practices" skill provides
79
- React and Next.js performance optimization guidelines from Vercel Engineering.
80
-
81
- To install it:
82
- npx skills add vercel-labs/agent-skills@vercel-react-best-practices
83
-
84
- Learn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
85
- ```
86
-
87
- ### Step 4: Offer to Install
88
-
89
- If the user wants to proceed, you can install the skill for them:
90
-
91
- ```bash
92
- npx skills add <owner/repo@skill> -g -y
93
- ```
94
-
95
- The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts.
96
-
97
- ## Common Skill Categories
98
-
99
- When searching, consider these common categories:
100
-
101
- | Category | Example Queries |
102
- | --------------- | ---------------------------------------- |
103
- | Web Development | react, nextjs, typescript, css, tailwind |
104
- | Testing | testing, jest, playwright, e2e |
105
- | DevOps | deploy, docker, kubernetes, ci-cd |
106
- | Documentation | docs, readme, changelog, api-docs |
107
- | Code Quality | review, lint, refactor, best-practices |
108
- | Design | ui, ux, design-system, accessibility |
109
- | Productivity | workflow, automation, git |
110
-
111
- ## Tips for Effective Searches
112
-
113
- 1. **Use specific keywords**: "react testing" is better than just "testing"
114
- 2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd"
115
- 3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills`
116
-
117
- ## When No Skills Are Found
118
-
119
- If no relevant skills exist:
120
-
121
- 1. Acknowledge that no existing skill was found
122
- 2. Offer to help with the task directly using your general capabilities
123
- 3. Suggest the user could create their own skill with `npx skills init`
124
-
125
- Example:
126
-
127
- ```
128
- I searched for skills related to "xyz" but didn't find any matches.
129
- I can still help you with this task directly! Would you like me to proceed?
130
-
131
- If this is something you do often, you could create your own skill:
132
- npx skills init my-xyz-skill
133
- ```
1
+ ---
2
+ name: find-skills
3
+ description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
4
+ ---
5
+
6
+ # Find Skills
7
+
8
+ This skill helps you discover and install skills from the open agent skills ecosystem.
9
+
10
+ ## When to Use This Skill
11
+
12
+ Use this skill when the user:
13
+
14
+ - Asks "how do I do X" where X might be a common task with an existing skill
15
+ - Says "find a skill for X" or "is there a skill for X"
16
+ - Asks "can you do X" where X is a specialized capability
17
+ - Expresses interest in extending agent capabilities
18
+ - Wants to search for tools, templates, or workflows
19
+ - Mentions they wish they had help with a specific domain (design, testing, deployment, etc.)
20
+
21
+ ## What is the Skills CLI?
22
+
23
+ The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools.
24
+
25
+ **Key commands:**
26
+
27
+ - `npx skills find [query]` - Search for skills interactively or by keyword
28
+ - `npx skills add <package>` - Install a skill from GitHub or other sources
29
+ - `npx skills check` - Check for skill updates
30
+ - `npx skills update` - Update all installed skills
31
+
32
+ **Browse skills at:** https://skills.sh/
33
+
34
+ ## How to Help Users Find Skills
35
+
36
+ ### Step 1: Understand What They Need
37
+
38
+ When a user asks for help with something, identify:
39
+
40
+ 1. The domain (e.g., React, testing, design, deployment)
41
+ 2. The specific task (e.g., writing tests, creating animations, reviewing PRs)
42
+ 3. Whether this is a common enough task that a skill likely exists
43
+
44
+ ### Step 2: Search for Skills
45
+
46
+ Run the find command with a relevant query:
47
+
48
+ ```bash
49
+ npx skills find [query]
50
+ ```
51
+
52
+ For example:
53
+
54
+ - User asks "how do I make my React app faster?" → `npx skills find react performance`
55
+ - User asks "can you help me with PR reviews?" → `npx skills find pr review`
56
+ - User asks "I need to create a changelog" → `npx skills find changelog`
57
+
58
+ The command will return results like:
59
+
60
+ ```
61
+ Install with npx skills add <owner/repo@skill>
62
+
63
+ vercel-labs/agent-skills@vercel-react-best-practices
64
+ └ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
65
+ ```
66
+
67
+ ### Step 3: Present Options to the User
68
+
69
+ When you find relevant skills, present them to the user with:
70
+
71
+ 1. The skill name and what it does
72
+ 2. The install command they can run
73
+ 3. A link to learn more at skills.sh
74
+
75
+ Example response:
76
+
77
+ ```
78
+ I found a skill that might help! The "vercel-react-best-practices" skill provides
79
+ React and Next.js performance optimization guidelines from Vercel Engineering.
80
+
81
+ To install it:
82
+ npx skills add vercel-labs/agent-skills@vercel-react-best-practices
83
+
84
+ Learn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices
85
+ ```
86
+
87
+ ### Step 4: Offer to Install
88
+
89
+ If the user wants to proceed, you can install the skill for them:
90
+
91
+ ```bash
92
+ npx skills add <owner/repo@skill> -g -y
93
+ ```
94
+
95
+ The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts.
96
+
97
+ ## Common Skill Categories
98
+
99
+ When searching, consider these common categories:
100
+
101
+ | Category | Example Queries |
102
+ | --------------- | ---------------------------------------- |
103
+ | Web Development | react, nextjs, typescript, css, tailwind |
104
+ | Testing | testing, jest, playwright, e2e |
105
+ | DevOps | deploy, docker, kubernetes, ci-cd |
106
+ | Documentation | docs, readme, changelog, api-docs |
107
+ | Code Quality | review, lint, refactor, best-practices |
108
+ | Design | ui, ux, design-system, accessibility |
109
+ | Productivity | workflow, automation, git |
110
+
111
+ ## Tips for Effective Searches
112
+
113
+ 1. **Use specific keywords**: "react testing" is better than just "testing"
114
+ 2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd"
115
+ 3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills`
116
+
117
+ ## When No Skills Are Found
118
+
119
+ If no relevant skills exist:
120
+
121
+ 1. Acknowledge that no existing skill was found
122
+ 2. Offer to help with the task directly using your general capabilities
123
+ 3. Suggest the user could create their own skill with `npx skills init`
124
+
125
+ Example:
126
+
127
+ ```
128
+ I searched for skills related to "xyz" but didn't find any matches.
129
+ I can still help you with this task directly! Would you like me to proceed?
130
+
131
+ If this is something you do often, you could create your own skill:
132
+ npx skills init my-xyz-skill
133
+ ```
package/src/agent/chat.js CHANGED
@@ -116,6 +116,11 @@ class AgentChatHandler extends EventEmitter {
116
116
  this._messageTokenCache = new Map();
117
117
  this._messageTokenCacheMaxSize = 200;
118
118
 
119
+ // ★ 每 session 串行锁:非流式 chat() 不走 queueManager,
120
+ // 同一 session 并发调用会并发 mutate/save 消息数组 → 交错/丢失。
121
+ // 用 promise 链把同 session 的调用串行化;不同 session 仍并行。
122
+ this._sessionLocks = new Map();
123
+
119
124
  // ChatQueueManager: 队列管理
120
125
  this.queueManager = new ChatQueueManager({
121
126
  maxConcurrent: config.maxConcurrent || DEFAULT_MAX_CONCURRENT,
@@ -711,10 +716,29 @@ class AgentChatHandler extends EventEmitter {
711
716
  */
712
717
  async chat(message, options = {}) {
713
718
  const sessionId = options.sessionId || this.getDefaultSessionId();
714
- const result = await this._processMessage(sessionId, message, options);
719
+ const result = await this._withSessionLock(sessionId, () => this._processMessage(sessionId, message, options));
715
720
  return { message: result.text, ...result };
716
721
  }
717
722
 
723
+ /**
724
+ * 按 sessionId 串行执行 fn:同一 session 的调用排队,不同 session 并行。
725
+ * 无论前一个成功或失败都继续(不因一次失败卡死队列)。
726
+ * @private
727
+ */
728
+ _withSessionLock(sessionId, fn) {
729
+ const key = sessionId || '__default__';
730
+ const prev = this._sessionLocks.get(key) || Promise.resolve();
731
+ const run = prev.then(fn, fn); // 前一个 settle(成功/失败)后都执行本次
732
+ // gate 只用于排队,吞掉 run 的结果/异常,避免影响下一个
733
+ const gate = run.then(() => {}, () => {});
734
+ this._sessionLocks.set(key, gate);
735
+ gate.finally(() => {
736
+ // 队尾清理,避免 Map 无限增长
737
+ if (this._sessionLocks.get(key) === gate) this._sessionLocks.delete(key);
738
+ });
739
+ return run;
740
+ }
741
+
718
742
  /**
719
743
  * 流式聊天
720
744
  */
@@ -795,8 +819,9 @@ class AgentChatHandler extends EventEmitter {
795
819
  // yield usage 数据,让 UI 层能直接获取
796
820
  // (usage 已在 stream 循环中 yield,无需重复)
797
821
 
798
- const userMsg = messages.length > 0 ? messages[messages.length - 1] : null;
799
- this.emit('message', { content: fullText, sessionId: sessionId, userMessage: userMsg });
822
+ // _prepareSession 返回的 userMessage,而非 messages 末尾——
823
+ // 末尾现在是刚追加的 assistant 最终答复,不再是 user 消息。
824
+ this.emit('message', { content: fullText, sessionId: sessionId, userMessage });
800
825
 
801
826
  // ★ 修复:成功路径才持久化。AI 失败时若 finally 也 save,
802
827
  // 会把刚 push 的 userMessage 写盘 → 下次请求 loadHistory 再次
@@ -939,12 +964,9 @@ class AgentChatHandler extends EventEmitter {
939
964
  messageStore.usage = { promptTokens: inputTokens, completionTokens: outputTokens };
940
965
  }
941
966
 
942
- // ToolLoop 已经直接在 messages 末尾添加了新消息,不需要再 push
943
- // 计算 original user message
944
- const userMsg = result.text
945
- ? messages.slice(-1)[0]
946
- : messages[messages.length - 1];
947
- this.emit('message', { content: result.text, sessionId: sessionId, userMessage: userMsg });
967
+ // ToolLoop 已经直接在 messages 末尾添加了新消息(含最终 assistant 答复)
968
+ // userMessage _prepareSession 返回值,不能再取 messages 末尾(已是 assistant)
969
+ this.emit('message', { content: result.text, sessionId: sessionId, userMessage });
948
970
 
949
971
  // ★ 修复:AI 调用成功后才持久化(之前 finally 总是 save,
950
972
  // 会把刚 push 的 userMessage 写盘;下次请求 loadHistory 再次 load 到,
package/src/agent/sub.js CHANGED
@@ -9,6 +9,7 @@
9
9
  const { BaseAgent } = require('./base');
10
10
  const { cleanResponse } = require('../utils');
11
11
  const { ToolLoop } = require('./tool-loop');
12
+ const { isThinkingModel } = require('../llm/provider');
12
13
  const { z } = require('zod');
13
14
  const { logger } = require('../common/logger');
14
15
  const { validateAll } = require('../utils/message-validator');
@@ -150,13 +151,26 @@ class SubAgent extends BaseAgent {
150
151
  tools,
151
152
  maxSteps,
152
153
  prepareStep: this._prepareStep ? this._prepareStep.bind(this) : undefined,
154
+ // ★ 子 Agent 同样要感知 thinking 模式,否则缺 reasoning_content 时会 400。
155
+ // 白名单命中或 providerOptions 显式开启即视为思考模式;
156
+ // 即便都没命中,tool-loop 内部还有 _forceReasoning 自愈兜底。
157
+ thinkingMode: isThinkingModel(this.model) || !!this.providerOptions?.deepseek?.thinking,
153
158
  });
154
159
 
155
160
  const result = await loop.generate({ messages, systemPrompt, model: this.model, client, ...this.providerOptions });
156
- messages.push(...result.response.messages);
161
+ // ★ 不要再 push:ToolLoop.generate 就地 mutate 并返回同一个 messages 引用,
162
+ // messages.push(...result.response.messages) 等于 push(...messages),会让整段历史翻倍。
157
163
  const full_text = cleanResponse(result.text);
158
- this.emit('complete', { message: full_text, steps: result.steps?.length || 0 });
159
- return { success: true, message: full_text, steps: result.steps?.length || 0, messages };
164
+ // maxSteps 耗尽(最后一步仍是工具调用、无最终答复)不能当成功,
165
+ // 否则调用方拿到空/半截结果却以为完成。
166
+ if (result.stopReason === 'max_steps') {
167
+ const msg = `子Agent「${this.name}」达到最大步数(${maxSteps})仍未给出最终答复`;
168
+ logger.warn(`[SubAgent:${this.name}] ${msg}`);
169
+ this.emit('error', { error: msg });
170
+ return { success: false, message: full_text, error: msg, stopReason: 'max_steps', steps: result.steps || 0, messages };
171
+ }
172
+ this.emit('complete', { message: full_text, steps: result.steps || 0 });
173
+ return { success: true, message: full_text, steps: result.steps || 0, messages };
160
174
  } catch (err) {
161
175
  lastError = err;
162
176
  if (isNetworkError(err) && attempt < maxRetries) {