foliko 2.0.2 → 2.0.4

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.
Files changed (80) hide show
  1. package/README.md +6 -6
  2. package/docs/public-api.md +91 -0
  3. package/docs/system-prompt.md +219 -0
  4. package/docs/usage.md +6 -6
  5. package/package.json +1 -1
  6. package/plugins/ambient/ExplorerLoop.js +1 -0
  7. package/plugins/ambient/index.js +1 -0
  8. package/plugins/core/coordinator/index.js +10 -5
  9. package/plugins/core/default/bootstrap.js +21 -3
  10. package/plugins/core/default/config.js +12 -3
  11. package/plugins/core/python-loader/index.js +3 -3
  12. package/plugins/core/scheduler/index.js +26 -2
  13. package/plugins/core/skill-manager/index.js +198 -151
  14. package/plugins/core/sub-agent/index.js +34 -15
  15. package/plugins/core/think/index.js +1 -0
  16. package/plugins/core/workflow/index.js +5 -4
  17. package/plugins/executors/data-splitter/index.js +14 -1
  18. package/plugins/executors/extension/index.js +52 -38
  19. package/plugins/executors/python/index.js +3 -3
  20. package/plugins/executors/shell/index.js +6 -4
  21. package/plugins/io/web/index.js +2 -1
  22. package/plugins/memory/index.js +29 -74
  23. package/plugins/messaging/email/handlers.js +1 -19
  24. package/plugins/messaging/email/monitor.js +2 -17
  25. package/plugins/messaging/email/reply.js +2 -1
  26. package/plugins/messaging/email/utils.js +20 -1
  27. package/plugins/messaging/feishu/index.js +1 -1
  28. package/plugins/messaging/qq/index.js +1 -1
  29. package/plugins/messaging/telegram/index.js +1 -1
  30. package/plugins/messaging/weixin/index.js +1 -1
  31. package/plugins/plugin-manager/index.js +1 -33
  32. package/plugins/tools/index.js +14 -1
  33. package/skills/plugins/SKILL.md +316 -0
  34. package/skills/skill-guide/SKILL.md +5 -5
  35. package/skills/{subagent-guide → subagents}/SKILL.md +1 -1
  36. package/skills/{workflow-guide → workflows}/SKILL.md +3 -3
  37. package/skills/{workflow-troubleshooting → workflows/workflow-troubleshooting}/DEBUGGING.md +197 -197
  38. package/skills/{workflow-troubleshooting → workflows/workflow-troubleshooting}/SKILL.md +391 -391
  39. package/src/agent/base.js +5 -20
  40. package/src/agent/chat.js +67 -5
  41. package/src/agent/index.js +20 -8
  42. package/src/agent/main.js +100 -23
  43. package/src/agent/prompt-registry.js +296 -0
  44. package/src/agent/sub-config.js +1 -78
  45. package/src/agent/sub.js +20 -25
  46. package/src/cli/commands/plugin.js +1 -60
  47. package/src/cli/ui/chat-ui-old.js +1 -1
  48. package/src/cli/ui/chat-ui.js +21 -17
  49. package/src/cli/ui/components/agent-mention-provider.js +1 -1
  50. package/src/common/constants.js +42 -0
  51. package/src/common/id.js +13 -0
  52. package/src/common/queue.js +3 -3
  53. package/src/context/compressor.js +17 -9
  54. package/src/framework/framework.js +218 -0
  55. package/src/framework/index.js +1 -2
  56. package/src/framework/lifecycle.js +102 -1
  57. package/src/framework/loader.js +1 -55
  58. package/src/index.js +11 -2
  59. package/src/plugin/base.js +69 -55
  60. package/src/plugin/loader.js +1 -57
  61. package/src/session/chat.js +1 -1
  62. package/src/session/entry.js +1 -11
  63. package/src/storage/manager.js +1 -12
  64. package/src/tool/executor.js +3 -2
  65. package/src/tool/router.js +5 -5
  66. package/src/utils/data-splitter.js +2 -1
  67. package/src/utils/index.js +150 -0
  68. package/src/utils/message-validator.js +21 -17
  69. package/src/utils/plugin-helpers.js +19 -5
  70. package/subagent.md +2 -2
  71. package/tests/core/plugin-prompts.test.js +219 -0
  72. package/tests/core/prompt-registry.test.js +209 -0
  73. package/src/cli/utils/plugin-config.js +0 -50
  74. package/src/config/plugin-config.js +0 -50
  75. /package/skills/{ambient-agent → ambient}/SKILL.md +0 -0
  76. /package/skills/{foliko-dev → foliko}/AGENTS.md +0 -0
  77. /package/skills/{foliko-dev → foliko}/SKILL.md +0 -0
  78. /package/skills/{mcp-usage → mcp}/SKILL.md +0 -0
  79. /package/skills/{plugin-guide → plugins-guide}/SKILL.md +0 -0
  80. /package/skills/{python-plugin-dev → python}/SKILL.md +0 -0
package/src/agent/base.js CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  /**
4
4
  * BaseAgent - 所有 Agent 类型的公共基类
5
- * 提供事件、状态、prompt 部分注册等公共功能
5
+ * 提供事件、状态、prompt 等公共功能
6
6
  */
7
7
 
8
8
  const { EventEmitter } = require('../common/events');
9
- const { SystemPromptBuilder } = require('./prompt');
9
+ const { PromptRegistry } = require('./prompt-registry');
10
10
 
11
11
  class BaseAgent extends EventEmitter {
12
12
  constructor(framework, config = {}) {
@@ -15,7 +15,9 @@ class BaseAgent extends EventEmitter {
15
15
  this.config = config;
16
16
  this.name = config.name || 'Agent';
17
17
  this._status = 'idle';
18
- this._promptBuilder = new SystemPromptBuilder();
18
+ // Agent 私有的 prompt 注册表(新 API)
19
+ this._promptRegistry = new PromptRegistry();
20
+ this.promptRegistry = this._promptRegistry;
19
21
  }
20
22
 
21
23
  // === Status ===
@@ -28,23 +30,6 @@ class BaseAgent extends EventEmitter {
28
30
  return this;
29
31
  }
30
32
 
31
- // === Prompt Parts ===
32
-
33
- registerPromptPart(name, priority, provider) {
34
- this._promptBuilder.register(name, priority, provider);
35
- return this;
36
- }
37
-
38
- unregisterPromptPart(name) {
39
- this._promptBuilder.unregister(name);
40
- return this;
41
- }
42
-
43
- invalidatePromptPart(name) {
44
- this._promptBuilder.invalidate(name);
45
- return this;
46
- }
47
-
48
33
  // === Destroy ===
49
34
 
50
35
  destroy() {
package/src/agent/chat.js CHANGED
@@ -473,7 +473,7 @@ class AgentChatHandler extends EventEmitter {
473
473
  const { messageStore, messages } = await this._prepareSession(message, sessionId);
474
474
 
475
475
  if (!this._aiClient) {
476
- throw new Error('AI client not configured.');
476
+ throw new Error('AI 客户端未配置');
477
477
  }
478
478
  this._validateToolCalls(messages);
479
479
  const systemPrompt = framework.getSystemPrompt();
@@ -497,7 +497,12 @@ class AgentChatHandler extends EventEmitter {
497
497
  let reasoningContent = '';
498
498
 
499
499
  const result = await framework.runInSession(sessionId, {}, async () => {
500
- return agent.stream({ messages, ...this.providerOptions, onError: handleSDKError });
500
+ return agent.stream({
501
+ messages,
502
+ ...this.providerOptions,
503
+ onError: handleSDKError,
504
+ abortSignal: framework.getAbortSignal?.(),
505
+ });
501
506
  });
502
507
 
503
508
  const stream = result.fullStream;
@@ -595,7 +600,10 @@ class AgentChatHandler extends EventEmitter {
595
600
  // 统一错误处理:提取简洁消息并通过 yield 传递
596
601
  const friendlyMessage = err?.message?.split('\n')[0] || '未知错误';
597
602
 
598
- this.emit('message:error', { sessionId, error: friendlyMessage, originalError: err });
603
+ // 用户主动中断(framework.stop())不上报 message:error,避免与上游重复
604
+ if (err.name !== 'AbortError') {
605
+ this.emit('message:error', { sessionId, error: friendlyMessage, originalError: err });
606
+ }
599
607
  yield { type: 'error', error: friendlyMessage };
600
608
  } finally {
601
609
  const messageStore = this._getSessionMessageStore(sessionId);
@@ -648,7 +656,7 @@ class AgentChatHandler extends EventEmitter {
648
656
  const { messageStore, messages } = await this._prepareSession(message, sessionId);
649
657
 
650
658
  if (!this._aiClient) {
651
- throw new Error('AI client not configured.');
659
+ throw new Error('AI 客户端未配置');
652
660
  }
653
661
  this._validateToolCalls(messages);
654
662
  const systemPrompt = framework.getSystemPrompt();
@@ -669,7 +677,7 @@ class AgentChatHandler extends EventEmitter {
669
677
  });
670
678
 
671
679
  const result = await framework.runInSession(sessionId, {}, async () => {
672
- return agent.generate({ messages, ...apiOptions });
680
+ return agent.generate({ messages, ...apiOptions, abortSignal: framework.getAbortSignal?.() });
673
681
  });
674
682
 
675
683
  if (result.usage && (result.usage.promptTokens > 0 || result.usage.completionTokens > 0)) {
@@ -780,6 +788,9 @@ class AgentChatHandler extends EventEmitter {
780
788
  messages.push(userMessage);
781
789
  this._validateToolCalls(messages);
782
790
 
791
+ // 最终兜底:暴力清理所有 orphaned tool 消息,确保 AI SDK 不报错
792
+ this._stripOrphanedToolMessages(messages);
793
+
783
794
  return { messageStore, messages };
784
795
  }
785
796
 
@@ -832,6 +843,57 @@ class AgentChatHandler extends EventEmitter {
832
843
  messageStore._cacheMessageCount = messageStore.messages.length;
833
844
  }
834
845
 
846
+ /**
847
+ * 最终兜底:暴力清理所有 orphaned tool 消息
848
+ * 遍历所有 tool 角色消息,删除没有对应 tool-call 的
849
+ * 处理数组格式(AI SDK)、字符串格式(OpenAI 兼容)、tool_call_id 格式
850
+ */
851
+ _stripOrphanedToolMessages(messages) {
852
+ const validIds = new Set();
853
+ for (const msg of messages) {
854
+ if (msg.role !== 'assistant') continue;
855
+ if (Array.isArray(msg.content)) {
856
+ for (const item of msg.content) {
857
+ if ((item.type === 'tool-call' || item.type === 'tool-use') && item.toolCallId) validIds.add(item.toolCallId);
858
+ }
859
+ }
860
+ if (Array.isArray(msg.tool_calls)) {
861
+ for (const tc of msg.tool_calls) { if (tc.id) validIds.add(tc.id); }
862
+ }
863
+ }
864
+
865
+ let removed = 0;
866
+ for (let i = messages.length - 1; i >= 0; i--) {
867
+ const msg = messages[i];
868
+ if (msg.role !== 'tool') continue;
869
+
870
+ let isOrphaned = false;
871
+ if (Array.isArray(msg.content)) {
872
+ msg.content = msg.content.filter(item => {
873
+ if (item && (item.type === 'tool-result' || item.type === 'tool_result') && item.toolCallId && !validIds.has(item.toolCallId)) {
874
+ return false;
875
+ }
876
+ return true;
877
+ });
878
+ if (msg.content.length === 0) isOrphaned = true;
879
+ } else if (msg.tool_call_id && !validIds.has(msg.tool_call_id)) {
880
+ isOrphaned = true;
881
+ } else if (!msg.tool_call_id && validIds.size === 0) {
882
+ // 没有任何 tool-call,所有 tool 消息都是 orphaned
883
+ isOrphaned = true;
884
+ }
885
+
886
+ if (isOrphaned) {
887
+ messages.splice(i, 1);
888
+ removed++;
889
+ }
890
+ }
891
+
892
+ if (removed > 0) {
893
+ logger.debug(`[_stripOrphanedToolMessages] removed ${removed} orphaned tool message(s)`);
894
+ }
895
+ }
896
+
835
897
  /**
836
898
  * 计算工具列表缓存 key
837
899
  * @private
@@ -5,6 +5,7 @@ const { MainAgent } = require('./main');
5
5
  const { SubAgent } = require('./sub');
6
6
  const { WorkerAgent } = require('./worker');
7
7
  const { SystemPromptBuilder } = require('./prompt');
8
+ const { PromptRegistry } = require('./prompt-registry');
8
9
 
9
10
  /**
10
11
  * Create a MainAgent instance
@@ -51,6 +52,7 @@ function createSubAgent(framework, config = {}) {
51
52
  framework,
52
53
  maxRetries: config.maxRetries,
53
54
  disableTools: config.disableTools,
55
+ hidden: config.hidden,
54
56
  });
55
57
  _syncPromptParts(framework, subagent);
56
58
  framework._agents.push(subagent);
@@ -84,16 +86,25 @@ function _mergeAIConfig(framework, target) {
84
86
 
85
87
  /**
86
88
  * Sync main agent prompt parts to subagent
89
+ * 从 framework.promptRegistry 同步到 subagent.promptRegistry
87
90
  */
88
91
  function _syncPromptParts(framework, subagent) {
89
- if (!framework._mainAgent?._systemPromptBuilder?._parts) return;
90
- const mainParts = framework._mainAgent._systemPromptBuilder._parts;
91
- const registeredNames = new Set(subagent._promptParts?.map(p => p.name) || []);
92
- for (const [name, part] of mainParts) {
93
- if (['original-prompt', 'shared-prompt', 'datetime', 'metadata', 'capabilities'].includes(name)) continue;
94
- if (!registeredNames.has(name)) {
95
- subagent.registerPromptPart(name, part.priority, part.provider);
96
- registeredNames.add(name);
92
+ const reg = framework?.promptRegistry;
93
+ if (!reg || reg.count() === 0) return;
94
+ const subReg = subagent?.promptRegistry || subagent?._promptRegistry;
95
+ for (const part of reg.list()) {
96
+ // 跳过主 Agent 私有的 5 个内置 part
97
+ if (part.owner === '_main' && ['original-prompt', 'shared-prompt', 'datetime', 'metadata', 'capabilities'].includes(part.name)) {
98
+ continue;
99
+ }
100
+ // 已同步过则跳过
101
+ if (subReg && subReg.has(part.owner, part.name)) continue;
102
+ if (subReg) {
103
+ subReg.register(part.owner, part.name, part.provider, {
104
+ slot: part.slot,
105
+ order: part.order,
106
+ description: part.description,
107
+ });
97
108
  }
98
109
  }
99
110
  }
@@ -104,6 +115,7 @@ module.exports = {
104
115
  SubAgent,
105
116
  WorkerAgent,
106
117
  SystemPromptBuilder,
118
+ PromptRegistry,
107
119
  createAgent,
108
120
  createSubAgent,
109
121
  createSessionAgent,
package/src/agent/main.js CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  const { BaseAgent } = require('./base');
9
9
  const { Logger, LOG_LEVELS } = require('../common/logger');
10
- const { PROMPT_PRIORITY, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_TEMPERATURE } = require('../common/constants');
10
+ const { PROMPT_PRIORITY, PROMPT_PRIORITY_TO_SLOT, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_TEMPERATURE } = require('../common/constants');
11
11
  const { SystemPromptBuilder } = require('./prompt');
12
12
  const os = require('os');
13
13
 
@@ -44,6 +44,10 @@ class MainAgent extends BaseAgent {
44
44
  this._skipSyncTools = config.skipSyncTools || false;
45
45
  this._subAgents = new Map();
46
46
  this._systemPromptBuilder = new SystemPromptBuilder();
47
+ this._systemPromptCache = null; // 确保首次调用 _buildSystemPrompt 不走早期返回
48
+ this._systemPromptDirty = true;
49
+ // 新注册表:默认 part 注册到 framework.promptRegistry(带 slot)
50
+ // _systemPromptBuilder 保留为降级兜底
47
51
  this._registerDefaultPromptParts();
48
52
  this.systemPrompt = this._buildSystemPrompt();
49
53
 
@@ -54,25 +58,48 @@ class MainAgent extends BaseAgent {
54
58
  }
55
59
 
56
60
  _registerDefaultPromptParts() {
57
- this._systemPromptBuilder.register('original-prompt', PROMPT_PRIORITY.ORIGINAL_PROMPT, () => this._originalPrompt);
58
- this._systemPromptBuilder.register('shared-prompt', PROMPT_PRIORITY.SHARED_PROMPT, () => {
61
+ // 优先注册到 framework.promptRegistry(带 slot 的新路径)
62
+ // 同时保留 _systemPromptBuilder 的旧路径以兼容老 Plugin.registerPromptPart
63
+ const reg = this.framework?.promptRegistry;
64
+ const MAIN = '_main';
65
+
66
+ const registerBoth = (name, priority, provider, slot) => {
67
+ // 旧路径(降级兜底)
68
+ this._systemPromptBuilder.register(name, priority, provider);
69
+ // 新路径(slot 排序)
70
+ // original-prompt 是 per-Agent 的,不走全局注册表(由 _buildSystemPrompt 直接注入)
71
+ if (name === 'original-prompt') return;
72
+ if (reg && !reg.has(MAIN, name)) {
73
+ reg.register(MAIN, name, provider, {
74
+ slot: slot || PROMPT_PRIORITY_TO_SLOT[name] || 'CUSTOM',
75
+ order: priority,
76
+ description: `内置 part: ${name}`,
77
+ });
78
+ }
79
+ };
80
+
81
+ registerBoth('original-prompt', PROMPT_PRIORITY.ORIGINAL_PROMPT, () => this._originalPrompt, 'IDENTITY');
82
+ registerBoth('shared-prompt', PROMPT_PRIORITY.SHARED_PROMPT, () => {
59
83
  return this._sharedPrompt ? this._replacePlaceholders(this._sharedPrompt) : null;
60
- });
61
- this._systemPromptBuilder.register('datetime', PROMPT_PRIORITY.DATETIME, () => {
84
+ }, 'USER');
85
+ registerBoth('metadata', PROMPT_PRIORITY.METADATA, () => {
62
86
  const now = new Date();
63
87
  const timeStr = now.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
64
88
  const dateStr = now.toLocaleDateString('zh-CN', { timeZone: 'Asia/Shanghai', weekday: 'long' });
65
- return `【当前时间】${timeStr}(${dateStr})`;
66
- });
67
- this._systemPromptBuilder.register('metadata', PROMPT_PRIORITY.METADATA, () => {
68
- if (this._metadata.size === 0) return null;
69
- const metaParts = ['【元数据】'];
70
- for (const [key, value] of this._metadata) {
71
- metaParts.push(`- ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
89
+ const metaParts = ['【运行环境】'];
90
+ metaParts.push(`- 当前时间: ${timeStr}(${dateStr})`);
91
+ metaParts.push(`- 工作目录: ${this.framework?.getCwd?.() ?? process.cwd()}`);
92
+ metaParts.push(`- 平台: ${os.platform()} ${os.release()}`);
93
+ metaParts.push(`- 主机: ${os.hostname()}`);
94
+ // 插件显式设置的元数据
95
+ if (this._metadata.size > 0) {
96
+ for (const [key, value] of this._metadata) {
97
+ metaParts.push(`- ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
98
+ }
72
99
  }
73
100
  return metaParts.join('\n');
74
- });
75
- this._systemPromptBuilder.register('capabilities', PROMPT_PRIORITY.CAPABILITIES, () => this._buildCapabilitiesDescription());
101
+ }, 'USER');
102
+ registerBoth('capabilities', PROMPT_PRIORITY.CAPABILITIES, () => this._buildCapabilitiesDescription(), 'CAPABILITY');
76
103
  }
77
104
 
78
105
  _getMetadataValue(key) {
@@ -97,18 +124,59 @@ class MainAgent extends BaseAgent {
97
124
  if (!plugins || plugins.length === 0) return '';
98
125
  const keyPlugins = plugins.filter(p => p.name !== 'defaults' && p.name !== 'agent');
99
126
  if (keyPlugins.length === 0) return '';
100
- const lines = ['## 系统能力', ''];
101
- keyPlugins.forEach((plugin, index) => {
102
- const name = plugin.instance?.name || plugin.name || 'unknown';
103
- const description = plugin.instance?.description || '无描述';
104
- lines.push(`${index + 1}. **${name}**:${description}`);
105
- });
127
+
128
+ // 按类别分组,输出紧凑列表(工具列表已在 API 层描述,这里仅给出概览)
129
+ // const categories = {
130
+ // core: [], executor: [], io: [], messaging: [], other: [],
131
+ // };
132
+ // const catMap = {
133
+ // ai: 'core', storage: 'core', 'skill-manager': 'core', 'subagent-manager': 'core',
134
+ // session: 'core', scheduler: 'core', workflow: 'core', rules: 'core', audit: 'core',
135
+ // tools: 'core', 'plugin-manager': 'core', install: 'core', 'python-loader': 'core',
136
+ // 'data-splitter': 'core', coordinator: 'core',
137
+ // shell: 'executor', python: 'executor', extension: 'executor', mcp: 'executor',
138
+ // 'file-system': 'io', web: 'io',
139
+ // telegram: 'messaging', qq: 'messaging', weixin: 'messaging', feishu: 'messaging', email: 'messaging',
140
+ // };
141
+ // for (const p of keyPlugins) {
142
+ // const name = p.instance?.name || p.name || 'unknown';
143
+ // const cat = catMap[name] || 'other';
144
+ // categories[cat].push(name);
145
+ // }
146
+ const lines = [];
147
+ // const lines = ['## 插件概览'];
148
+ // const catLabels = { core: '核心', executor: '执行器', io: '文件/网络', messaging: '消息', other: '其他' };
149
+ // for (const [cat, names] of Object.entries(categories)) {
150
+ // if (names.length === 0) continue;
151
+ // lines.push(`- **${catLabels[cat]}**: ${names.sort().join(', ')}`);
152
+ // }
106
153
  return lines.join('\n');
107
154
  }
108
155
 
109
156
  _buildSystemPrompt() {
110
157
  if (!this._systemPromptDirty && this._systemPromptCache !== null) return this._systemPromptCache;
111
- this._systemPromptCache = this._systemPromptBuilder.build();
158
+
159
+ // 1. Agent 自己的 originalPrompt(per-Agent)
160
+ const parts = [this._originalPrompt];
161
+
162
+ // 2. 全局注册表(skills, tools, extensions 等共享部分,跳过 _main 的 original-prompt)
163
+ const reg = this.framework?.promptRegistry;
164
+ if (reg && reg.count() > 0) {
165
+ try {
166
+ for (const part of reg.list()) {
167
+ if (part.owner === '_main' && part.name === 'original-prompt') continue;
168
+ const content = part.get();
169
+ if (content && content.trim()) parts.push(content.trim());
170
+ }
171
+ } catch (err) {
172
+ // 注册表 build 失败时降级到旧 builder
173
+ this._systemPromptCache = this._systemPromptBuilder.build();
174
+ this._systemPromptDirty = false;
175
+ return this._systemPromptCache;
176
+ }
177
+ }
178
+
179
+ this._systemPromptCache = parts.join('\n\n');
112
180
  this._systemPromptDirty = false;
113
181
  return this._systemPromptCache;
114
182
  }
@@ -116,6 +184,7 @@ class MainAgent extends BaseAgent {
116
184
  _invalidateSystemPromptCache() {
117
185
  this._systemPromptDirty = true;
118
186
  this._systemPromptBuilder.invalidateAll();
187
+ this.framework?.promptRegistry?.invalidateAll();
119
188
  }
120
189
 
121
190
  _refreshContext() {
@@ -158,14 +227,22 @@ class MainAgent extends BaseAgent {
158
227
  }
159
228
 
160
229
  registerPromptPart(name, priority, provider) {
161
- this._systemPromptBuilder.register(name, priority, provider);
230
+ // [DEPRECATED] 推荐使用 framework.prompts.register(this.name, ...)
231
+ const reg = this.framework?.promptRegistry;
232
+ if (reg && !reg.has(this.name, name)) {
233
+ reg.register(this.name, name, provider, {
234
+ slot: PROMPT_PRIORITY_TO_SLOT[name] || 'CUSTOM',
235
+ order: priority,
236
+ description: `Legacy registerPromptPart from ${this.name}`,
237
+ });
238
+ }
162
239
  this._invalidateSystemPromptCache();
163
240
  this._refreshContext();
164
241
  return this;
165
242
  }
166
243
 
167
244
  unregisterPromptPart(name) {
168
- this._systemPromptBuilder.unregister(name);
245
+ this.framework?.promptRegistry?.unregister(this.name, name);
169
246
  this._invalidateSystemPromptCache();
170
247
  this._refreshContext();
171
248
  return this;