foliko 1.1.6 → 1.1.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/.agent/data/email/processed-emails.json +1 -0
- package/.agent/data/plugins-state.json +5 -1
- package/.agent/data/web/web-config.json +5 -0
- package/.agent/memory/feedback/mnt7jrlt-d67qs7.md +15 -0
- package/.agent/memory/feedback/mnt88ja3-al4fuy.md +9 -0
- package/.agent/plugins/test-plugin.py +108 -0
- package/.agent/sessions/cli_default.json +514 -5298
- package/.claude/settings.local.json +2 -1
- package/SPEC.md +735 -696
- package/output/zen_silence.png +0 -0
- package/package.json +2 -2
- package/plugins/ambient-agent/EventWatcher.js +33 -37
- package/plugins/ambient-agent/ExplorerLoop.js +338 -36
- package/plugins/ambient-agent/GoalManager.js +7 -3
- package/plugins/ambient-agent/StateStore.js +30 -1
- package/plugins/ambient-agent/constants.js +15 -1
- package/plugins/ambient-agent/index.js +26 -33
- package/plugins/coordinator-plugin.js +3 -3
- package/plugins/default-plugins.js +2 -2
- package/plugins/email/index.js +150 -36
- package/plugins/email/monitor.js +79 -5
- package/plugins/email/reply.js +15 -25
- package/plugins/extension-executor-plugin.js +160 -31
- package/plugins/file-system-plugin.js +57 -24
- package/plugins/memory-plugin.js +176 -64
- package/plugins/python-plugin-loader.js +79 -9
- package/plugins/scheduler-plugin.js +64 -24
- package/plugins/think-plugin.js +7 -2
- package/plugins/web-plugin.js +263 -4
- package/skills/ambient-agent/SKILL.md +342 -314
- package/src/core/agent-chat.js +64 -9
- package/src/core/agent.js +118 -59
- package/src/core/tool-registry.js +5 -5
- package/src/executors/mcp-executor.js +188 -26
- package/src/utils/id.js +5 -0
- package/system.md +3480 -0
- package/.agent/data/ambient/goals.json +0 -50
- package/.agent/data/ambient/memories.json +0 -7
- package/.agent/memory/core.md +0 -1
- package/.agent/memory/feedback/mnrsiuoc-e1ru74.md +0 -9
- package/.agent/memory/feedback/mnrt2mmz-98az6n.md +0 -9
- package/.agent/memory/feedback/mnrtqrhm-kxsicz.md +0 -9
- package/.agent/memory/feedback/mnrts8vg-i0ngzp.md +0 -15
- package/.agent/memory/feedback/mnrtt7jt-c0trb2.md +0 -9
- package/.agent/memory/feedback/mnruc2f0-5s52la.md +0 -16
- package/.agent/memory/feedback/mnrumbmx-63sa0v.md +0 -9
- package/.agent/memory/project/mnn93ogy-ypjn27.md +0 -9
- package/.agent/memory/project/mnn98fqy-5nhc1u.md +0 -25
- package/.agent/memory/project/mnrp7p5n-8enm2a.md +0 -31
- package/.agent/memory/project/mnrp9ifb-yynks0.md +0 -40
- package/.agent/memory/project/mnrpb3b8-f617s4.md +0 -25
- package/.agent/memory/project/mnrrmqgg-focprv.md +0 -9
- package/.agent/memory/project/mnrtykbh-6atsor.md +0 -9
- package/.agent/memory/project/mnru9jiu-kgau16.md +0 -35
- package/.agent/memory/reference/mnq3oenw-46haj6.md +0 -63
- package/.agent/memory/reference/mnq5qxm2-mjoooh.md +0 -116
- package/.agent/memory/reference/mnrnvpwo-rcqv9m.md +0 -52
- package/.agent/memory/reference/mnrovxvz-zy9xqm.md +0 -25
- package/.agent/memory/reference/mnroxabj-1b3930.md +0 -68
- package/.agent/memory/reference/mnrpjtlp-mnb9od.md +0 -35
- package/.agent/memory/reference/mnrps1x3-6b8xfm.md +0 -28
- package/.agent/memory/reference/mnrpt9ov-15er5w.md +0 -22
- package/.agent/memory/reference/mnrq82dn-y9tv9e.md +0 -50
- package/.agent/memory/reference/mnrqnr5v-v75drf.md +0 -34
- package/.agent/memory/reference/mnrrfzys-urudaf.md +0 -31
- package/.agent/memory/reference/mnrrocha-t0027n.md +0 -21
- package/.agent/memory/reference/mnrukklc-bxndsb.md +0 -35
- package/.agent/memory/user/mnm67t9m-x8rekk.md +0 -9
- package/.agent/memory/user/mnn5mmqh-w6aktx.md +0 -11
- package/.agent/memory/user/mnnbfhhn-dk1bd1.md +0 -22
- package/.agent/memory/user/mnrt39t8-8eosy0.md +0 -9
- package/foliko-cloud-rising.png +0 -0
- package/foliko-dawn-of-ai.png +0 -0
- package/foliko-mindful-observation.png +0 -0
- package/foliko-stellar-dreams.png +0 -0
- package/foliko-zen-jing.png +0 -0
- package/foliko-zen-kong.png +0 -0
- package/foliko-zen-wu.png +0 -0
- package/zen_karesansui.png +0 -0
|
@@ -10,7 +10,7 @@ const path = require('path');
|
|
|
10
10
|
const { z } = require('zod');
|
|
11
11
|
const { createMCPClient } = require('@ai-sdk/mcp');
|
|
12
12
|
const { StdioClientTransport } = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
13
|
-
const {
|
|
13
|
+
const { zodSchemaToMarkdown } = require('@chnak/zod-to-markdown');
|
|
14
14
|
const { logger } = require('../utils/logger');
|
|
15
15
|
|
|
16
16
|
const log = logger.child('MCPExecutor');
|
|
@@ -193,7 +193,7 @@ class MCPClientWrapper {
|
|
|
193
193
|
class MCPExecutorPlugin extends Plugin {
|
|
194
194
|
constructor(config = {}) {
|
|
195
195
|
super();
|
|
196
|
-
this.name = 'mcp
|
|
196
|
+
this.name = 'mcp';
|
|
197
197
|
this.version = '1.0.0';
|
|
198
198
|
this.description = 'MCP (Model Context Protocol) 执行器';
|
|
199
199
|
this.priority = 11;
|
|
@@ -203,6 +203,9 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
203
203
|
// serverName -> { client, tools: [{ name, description, inputSchema }], toolObjects: { toolName: actualTool } }
|
|
204
204
|
this._clients = new Map();
|
|
205
205
|
this._config = config;
|
|
206
|
+
// 注册的工具对象(extension-executor 会扫描这个)
|
|
207
|
+
// 格式: { 'server_toolname': { name, description, inputSchema, execute } }
|
|
208
|
+
this.tools = {};
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
install(framework) {
|
|
@@ -520,6 +523,8 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
520
523
|
if (!inputSchema) return {};
|
|
521
524
|
// 处理 {jsonSchema: {...}} 格式
|
|
522
525
|
if (inputSchema.jsonSchema) return inputSchema.jsonSchema;
|
|
526
|
+
// 处理 {inputSchema: {...}} 格式 (某些 MCP 服务器返回这种格式)
|
|
527
|
+
if (inputSchema.inputSchema) return inputSchema.inputSchema;
|
|
523
528
|
// 处理直接是 schema 的格式
|
|
524
529
|
return inputSchema;
|
|
525
530
|
}
|
|
@@ -532,49 +537,71 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
532
537
|
return '';
|
|
533
538
|
}
|
|
534
539
|
|
|
535
|
-
let desc = '【MCP Servers】 工具合集\n\n';
|
|
536
|
-
desc += '
|
|
540
|
+
let desc = '## 【MCP Servers】 工具合集\n\n';
|
|
541
|
+
desc += 'MCP 服务器工具已注册为 `服务器_工具名` 格式(如 github_search)。\n';
|
|
542
|
+
desc += '通过 `ext_call` 调用:\n\n';
|
|
537
543
|
|
|
538
544
|
for (const [serverName, info] of this._clients) {
|
|
539
545
|
desc += `### ${serverName}\n\n`;
|
|
540
546
|
for (const tool of info.tools) {
|
|
541
|
-
|
|
542
|
-
desc +=
|
|
547
|
+
const fullName = `${serverName}_${tool.name}`;
|
|
548
|
+
desc += `- **${fullName}**: ${tool.description || '无描述'}\n`;
|
|
543
549
|
|
|
544
550
|
// 使用 zodSchemaToMarkdown 生成参数文档
|
|
545
|
-
const
|
|
551
|
+
const rawSchema = tool.inputSchema;
|
|
552
|
+
const schema = this._extractSchema(rawSchema);
|
|
546
553
|
if (schema) {
|
|
547
554
|
try {
|
|
548
|
-
|
|
555
|
+
let schemaResult = null;
|
|
556
|
+
let zodSchemaForFallback = null; // 保存 Zod schema 供 fallback 使用
|
|
557
|
+
// 检查是否是 Zod schema (有 shape 方法或 _def 属性)
|
|
558
|
+
const isZodSchema =
|
|
559
|
+
typeof schema.shape === 'function' || (schema._def && schema._def.typeName);
|
|
560
|
+
if (isZodSchema) {
|
|
549
561
|
// Zod schema 直接转换
|
|
550
|
-
|
|
551
|
-
|
|
562
|
+
schemaResult = zodSchemaToMarkdown(schema);
|
|
563
|
+
zodSchemaForFallback = schema;
|
|
552
564
|
} else if (schema.jsonSchema) {
|
|
553
565
|
// JSON Schema 格式,尝试转换为 Zod schema
|
|
554
566
|
const zodSchema = this._jsonSchemaToZod(schema.jsonSchema || schema);
|
|
555
567
|
if (zodSchema) {
|
|
556
|
-
|
|
557
|
-
|
|
568
|
+
schemaResult = zodSchemaToMarkdown(zodSchema);
|
|
569
|
+
zodSchemaForFallback = zodSchema;
|
|
558
570
|
}
|
|
559
571
|
} else if (schema.properties) {
|
|
560
572
|
// 已经是对象格式
|
|
561
573
|
const zodSchema = this._jsonSchemaToZod(schema);
|
|
562
574
|
if (zodSchema) {
|
|
575
|
+
schemaResult = zodSchemaToMarkdown(zodSchema);
|
|
576
|
+
zodSchemaForFallback = zodSchema;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// 检查是否包含未解析的原始 Zod 类型名或只有类型信息没有参数
|
|
581
|
+
if (schemaResult) {
|
|
582
|
+
const hasUnparsedTypes = /\|.*\bZod\w+\b.*\|/.test(schemaResult);
|
|
583
|
+
// 检查是否只有类型信息而没有实际参数(如 "Type: Object" 或 "Type: ZodAny")
|
|
584
|
+
const hasOnlyType =
|
|
585
|
+
/^-\s+\w+:\s+.+\n?$/.test(schemaResult.trim()) && !schemaResult.includes('`');
|
|
586
|
+
if (hasUnparsedTypes || hasOnlyType) {
|
|
587
|
+
// zodSchemaToMarkdown 未正确解析,使用 fallback
|
|
588
|
+
desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
|
|
589
|
+
} else {
|
|
563
590
|
desc += `**参数:**\n\n`;
|
|
564
|
-
desc +=
|
|
591
|
+
desc += schemaResult + '\n\n';
|
|
565
592
|
}
|
|
566
593
|
}
|
|
567
594
|
} catch (e) {
|
|
568
595
|
// 如果转换失败,使用简化格式
|
|
569
|
-
desc += this._fallbackParamsDesc(schema);
|
|
596
|
+
desc += this._fallbackParamsDesc(zodSchemaForFallback || schema);
|
|
570
597
|
}
|
|
571
598
|
}
|
|
572
599
|
}
|
|
573
|
-
desc += '
|
|
600
|
+
desc += '\n';
|
|
574
601
|
}
|
|
575
602
|
|
|
576
603
|
desc += '**调用格式:**\n';
|
|
577
|
-
desc += '```\
|
|
604
|
+
desc += '```\next_call({ plugin: "mcp", tool: "服务器_工具名", args: {参数} })\n';
|
|
578
605
|
desc += '```\n';
|
|
579
606
|
return desc.trim();
|
|
580
607
|
}
|
|
@@ -648,21 +675,126 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
648
675
|
* 回退的参数描述(当 zodSchemaToMarkdown 失败时)
|
|
649
676
|
*/
|
|
650
677
|
_fallbackParamsDesc(schema) {
|
|
678
|
+
// 优先尝试 JSON Schema 格式
|
|
651
679
|
const props = schema.properties || {};
|
|
652
680
|
const required = schema.required || [];
|
|
653
681
|
|
|
654
|
-
if (Object.keys(props).length
|
|
655
|
-
|
|
682
|
+
if (Object.keys(props).length > 0) {
|
|
683
|
+
let desc = '**参数:**\n\n';
|
|
684
|
+
for (const [key, prop] of Object.entries(props)) {
|
|
685
|
+
const isRequired = required.includes(key);
|
|
686
|
+
const type = prop.type || 'any';
|
|
687
|
+
const desc_text = prop.description || '';
|
|
688
|
+
desc += `- \`${key}\`${isRequired ? ' (必填)' : ''}: ${type} ${desc_text}\n`;
|
|
689
|
+
}
|
|
690
|
+
return desc + '\n';
|
|
656
691
|
}
|
|
657
692
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
693
|
+
// 尝试 Zod schema 格式
|
|
694
|
+
if (typeof schema.shape === 'function' || (schema._def && schema._def.shape)) {
|
|
695
|
+
const shape = typeof schema.shape === 'function' ? schema.shape() : schema._def.shape();
|
|
696
|
+
if (shape && typeof shape === 'object') {
|
|
697
|
+
let desc = '**参数:**\n\n';
|
|
698
|
+
for (const [key, field] of Object.entries(shape)) {
|
|
699
|
+
const typeInfo = this._extractZodFieldType(field);
|
|
700
|
+
const isOptional = typeInfo.isOptional ? ' (可选)' : ' (必填)';
|
|
701
|
+
desc += `- \`${key}\`${isOptional}: ${typeInfo.type}\n`;
|
|
702
|
+
}
|
|
703
|
+
return desc + '\n';
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return '';
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* 从 Zod schema 字段提取类型信息
|
|
712
|
+
*/
|
|
713
|
+
_extractZodFieldType(field) {
|
|
714
|
+
const typeName = field._def?.typeName || field.constructor?.name || '';
|
|
715
|
+
const description = field.description || field._def?.description || '';
|
|
716
|
+
|
|
717
|
+
switch (typeName) {
|
|
718
|
+
case 'ZodOptional': {
|
|
719
|
+
const inner = field._def.innerType;
|
|
720
|
+
return this._extractZodFieldType(inner);
|
|
721
|
+
}
|
|
722
|
+
case 'ZodArray': {
|
|
723
|
+
const innerInfo = this._extractZodFieldType(field._def.type);
|
|
724
|
+
return { type: `${innerInfo.type}[]`, isOptional: false, description };
|
|
725
|
+
}
|
|
726
|
+
case 'ZodObject': {
|
|
727
|
+
const shape = field._def.shape();
|
|
728
|
+
const props = Object.keys(shape).join(', ');
|
|
729
|
+
return { type: `object{${props}}`, isOptional: false, description };
|
|
730
|
+
}
|
|
731
|
+
case 'ZodString':
|
|
732
|
+
return { type: 'string', isOptional: false, description };
|
|
733
|
+
case 'ZodNumber':
|
|
734
|
+
return { type: 'number', isOptional: false, description };
|
|
735
|
+
case 'ZodBoolean':
|
|
736
|
+
return { type: 'boolean', isOptional: false, description };
|
|
737
|
+
case 'ZodEnum':
|
|
738
|
+
return {
|
|
739
|
+
type: field._def.values.map((v) => `"${v}"`).join(' | '),
|
|
740
|
+
isOptional: false,
|
|
741
|
+
description,
|
|
742
|
+
};
|
|
743
|
+
case 'ZodUnion': {
|
|
744
|
+
const types = field._def.options.map((opt) => this._extractZodFieldType(opt).type);
|
|
745
|
+
return { type: `union(${types.join(' | ')})`, isOptional: false, description };
|
|
746
|
+
}
|
|
747
|
+
case 'ZodLiteral':
|
|
748
|
+
return { type: JSON.stringify(field._def.value), isOptional: false, description };
|
|
749
|
+
case 'ZodRecord': {
|
|
750
|
+
const keyType = this._extractZodFieldType(field._def.keyType).type;
|
|
751
|
+
const valueType = this._extractZodFieldType(field._def.valueType).type;
|
|
752
|
+
return { type: `record<${keyType}, ${valueType}>`, isOptional: false, description };
|
|
753
|
+
}
|
|
754
|
+
case 'ZodMap': {
|
|
755
|
+
const keyType = this._extractZodFieldType(field._def.keyType).type;
|
|
756
|
+
const valueType = this._extractZodFieldType(field._def.valueType).type;
|
|
757
|
+
return { type: `map<${keyType}, ${valueType}>`, isOptional: false, description };
|
|
758
|
+
}
|
|
759
|
+
case 'ZodSet': {
|
|
760
|
+
const valueType = this._extractZodFieldType(field._def.valueType).type;
|
|
761
|
+
return { type: `set<${valueType}>`, isOptional: false, description };
|
|
762
|
+
}
|
|
763
|
+
case 'ZodAny':
|
|
764
|
+
return { type: 'any', isOptional: false, description };
|
|
765
|
+
case 'ZodUnknown':
|
|
766
|
+
return { type: 'unknown', isOptional: false, description };
|
|
767
|
+
case 'ZodNever':
|
|
768
|
+
return { type: 'never', isOptional: false, description };
|
|
769
|
+
case 'ZodNull':
|
|
770
|
+
return { type: 'null', isOptional: false, description };
|
|
771
|
+
case 'ZodUndefined':
|
|
772
|
+
return { type: 'undefined', isOptional: false, description };
|
|
773
|
+
case 'ZodDate':
|
|
774
|
+
return { type: 'date', isOptional: false, description };
|
|
775
|
+
case 'ZodBigInt':
|
|
776
|
+
return { type: 'bigint', isOptional: false, description };
|
|
777
|
+
case 'ZodFunction':
|
|
778
|
+
return { type: 'function', isOptional: false, description };
|
|
779
|
+
case 'ZodLazy':
|
|
780
|
+
return { type: 'lazy', isOptional: false, description };
|
|
781
|
+
case 'ZodNativeEnum':
|
|
782
|
+
return { type: 'nativeEnum', isOptional: false, description };
|
|
783
|
+
case 'ZodDefault': {
|
|
784
|
+
const innerInfo = this._extractZodFieldType(field._def.innerType);
|
|
785
|
+
return { type: innerInfo.type, isOptional: false, description };
|
|
786
|
+
}
|
|
787
|
+
case 'ZodEffects':
|
|
788
|
+
return { type: 'effects', isOptional: false, description };
|
|
789
|
+
case 'ZodPipeline':
|
|
790
|
+
return { type: 'pipeline', isOptional: false, description };
|
|
791
|
+
default:
|
|
792
|
+
return {
|
|
793
|
+
type: typeName.replace('Zod', '').toLowerCase() || 'any',
|
|
794
|
+
isOptional: false,
|
|
795
|
+
description,
|
|
796
|
+
};
|
|
664
797
|
}
|
|
665
|
-
return desc + '\n';
|
|
666
798
|
}
|
|
667
799
|
|
|
668
800
|
_getParentAgent() {
|
|
@@ -765,6 +897,22 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
765
897
|
description: tool.description || '',
|
|
766
898
|
inputSchema: tool.inputSchema || {},
|
|
767
899
|
});
|
|
900
|
+
|
|
901
|
+
// 注册为 server_toolname 格式,供 ext_call 使用
|
|
902
|
+
const registeredName = `${name}_${toolName}`;
|
|
903
|
+
this.tools[registeredName] = {
|
|
904
|
+
name: registeredName,
|
|
905
|
+
description: `[${name}] ${tool.description || ''}`,
|
|
906
|
+
inputSchema: tool.inputSchema || {},
|
|
907
|
+
execute: async (args) => {
|
|
908
|
+
// 路由到 mcp_call
|
|
909
|
+
return await this._framework.executeTool('mcp_call', {
|
|
910
|
+
server: name,
|
|
911
|
+
tool: toolName,
|
|
912
|
+
args_json: JSON.stringify(args || {}),
|
|
913
|
+
});
|
|
914
|
+
},
|
|
915
|
+
};
|
|
768
916
|
}
|
|
769
917
|
}
|
|
770
918
|
|
|
@@ -775,7 +923,13 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
775
923
|
toolObjects, // 实际工具对象,供 mcp_call 直接调用
|
|
776
924
|
});
|
|
777
925
|
|
|
778
|
-
log.info(
|
|
926
|
+
log.info(
|
|
927
|
+
` Added server '${name}' with ${toolsInfo.length} tools (ext_call names: ${Object.keys(
|
|
928
|
+
this.tools
|
|
929
|
+
)
|
|
930
|
+
.filter((k) => k.startsWith(name + '_'))
|
|
931
|
+
.join(', ')})`
|
|
932
|
+
);
|
|
779
933
|
}
|
|
780
934
|
|
|
781
935
|
/**
|
|
@@ -796,6 +950,14 @@ class MCPExecutorPlugin extends Plugin {
|
|
|
796
950
|
} catch (e) {
|
|
797
951
|
// ignore
|
|
798
952
|
}
|
|
953
|
+
|
|
954
|
+
// 清理已注册的工具
|
|
955
|
+
for (const toolName of Object.keys(this.tools)) {
|
|
956
|
+
if (toolName.startsWith(name + '_')) {
|
|
957
|
+
delete this.tools[toolName];
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
799
961
|
this._clients.delete(name);
|
|
800
962
|
}
|
|
801
963
|
}
|
package/src/utils/id.js
CHANGED