# Foliko Framework 规划文档

## 一、设计目标

1. **纯 JS 实现** - 无 TypeScript，简明易懂
2. **架构简约** - 核心仅包含必要组件，通过插件扩展功能
3. **插件系统与 Agent 分离** - Agent 专注于对话推理，插件提供扩展能力
4. **手动热重载** - 不监测文件变化，通过 API 手动调用重载

## 二、核心架构

```
┌─────────────────────────────────────────────────┐
│                  Foliko Framework               │
├─────────────────────────────────────────────────┤
│  Framework (容器层)                              │
│  ├── pluginManager    - 插件加载/卸载/重载       │
│  ├── toolRegistry    - 工具注册表              │
│  ├── skillManager    - Skill管理 (可选)        │
│  └── eventEmitter    - 事件总线                │
├─────────────────────────────────────────────────┤
│  Agent (对话层)                                  │
│  ├── chat()           - 对话接口                 │
│  ├── tools           - 从 Framework 获取       │
│  └── events          - 事件监听                │
└─────────────────────────────────────────────────┘
```

### 2.1 Framework 类

```javascript
class Framework {
  constructor(config = {})
  registerPlugin(plugin)     // 注册插件
  loadPlugin(pluginDef)      // 加载插件
  unloadPlugin(name)         // 卸载插件
  reloadPlugin(name)         // 重载单个插件
  reloadAllPlugins()         // 重载所有插件
  registerTool(tool)         // 注册工具
  getTools()                 // 获取所有工具
  on(event, handler)        // 监听事件
  emit(event, data)         // 触发事件
  ready()                    // 等待初始化完成
}
```

### 2.2 Agent 类

```javascript
// 创建 Agent
const agent = framework.createAgent({
  name: 'MyAgent', // Agent 名称
  systemPrompt: '你是一个助手', // 系统提示

  // 共享提示模板 (支持 {{VAR}} 占位符)
  sharedPrompt: `工作目录: {{WORK_DIR}}`,

  // 元数据 (供 sharedPrompt 和自身使用)
  metadata: {
    projectName: 'MyProject',
    version: '1.0.0',
  },
});

// 运行时元数据操作
agent.setMetadata('task', '数据分析'); // 设置单个
agent.setMetadata({ key: 'value' }); // 批量设置
agent.getMetadata('task'); // 获取
agent.deleteMetadata('task'); // 删除
agent.clearMetadata(); // 清空
```

**内置占位符：**
| 占位符 | 说明 |
|--------|------|
| `{{WORK_DIR}}` | 工作目录 |
| `{{HOME_DIR}}` | 主目录 |
| `{{HOST_NAME}}` | 主机名 |
| `{{PLATFORM}}` | 平台 |
| `{{TIME}}` | 当前时间 |
| `{{DATE}}` | 当前日期 |

**Agent 方法：**

```javascript
class Agent {
  constructor(framework, config)    // 创建 Agent
  chat(message, options)           // 发送消息
  chatStream(message, options)     // 流式发送消息
  setSystemPrompt(prompt)          // 设置系统提示
  registerTool(tool)              // 注册工具
  getTools()                      // 获取工具列表
  clearHistory()                  // 清空对话历史
  getStatus()                     // 获取状态
  destroy()                       // 销毁 Agent

  // 元数据管理
  setMetadata(key, value)         // 设置元数据
  getMetadata(key)                // 获取元数据
  deleteMetadata(key)              // 删除元数据
  clearMetadata()                  // 清空元数据
}
```

**生成的 System Prompt 示例：**

```
你是一个助手。

工作目录: D:\project

【元数据】
- projectName: MyProject
- version: 1.0.0

【可用工具】
- shell: 执行命令
- python: 执行Python代码
```

### 2.3 插件基类

```javascript
class Plugin {
  name; // 插件名称 (必填)
  version = '1.0.0';
  description; // 插件描述

  install(framework) {} // 安装时调用
  start(framework) {} // 启动时调用
  reload(framework) {} // 热重载时调用
  uninstall(framework) {} // 卸载时调用
}
```

## 三、目录结构

```
D:\code\foliko\
├── src/
│   ├── core/
│   │   ├── framework.js     # 核心容器
│   │   ├── agent.js         # Agent类
│   │   ├── agent-chat.js    # 聊天处理器
│   │   ├── plugin-manager.js# 插件管理器
│   │   ├── plugin-base.js   # 插件基类
│   │   ├── tool-registry.js # 工具注册表
│   │   ├── provider.js      # AI Provider 工厂
│   │   └── index.js         # 统一导出
│   ├── capabilities/
│   │   ├── skill-manager.js # Skill 管理器
│   │   └── workflow-engine.js # 工作流引擎
│   ├── executors/
│   │   ├── executor-base.js # 执行器基类
│   │   └── mcp-executor.js  # MCP 执行器
│   ├── utils/
│   │   └── event-emitter.js # 事件发射器
│   └── index.js
├── plugins/                  # 内置插件
│   ├── ai-plugin.js         # AI对话插件
│   ├── tools-plugin.js       # 内置工具插件
│   ├── default-plugins.js   # 默认插件加载器
│   ├── shell-executor-plugin.js # Shell执行器插件
│   ├── python-executor-plugin.js # Python执行器插件
│   ├── session-plugin.js    # Session会话管理插件
│   ├── audit-plugin.js      # Audit审计日志插件
│   ├── rules-plugin.js      # Rules规则引擎插件
│   ├── scheduler-plugin.js   # Scheduler定时任务插件
│   ├── storage-plugin.js     # Storage存储插件
│   ├── subagent-plugin.js    # SubAgent子代理插件
│   ├── email.js              # Email邮件插件
│   └── telegram-plugin.js    # Telegram对话插件
├── examples/
│   ├── basic.js              # 基础示例
│   ├── bootstrap.js          # Bootstrap示例
│   └── workflow.js           # 工作流示例
├── .agent/                   # Agent 配置目录
│   ├── config                # 配置文件
│   ├── ai.json              # AI 配置
│   ├── plugins.json         # 插件列表
│   ├── mcp_config.json      # MCP 服务器配置
│   └── skills/              # Skill 目录
├── package.json
└── SPEC.md
```

## 四、核心模块

### 4.5 插件配置持久化

插件状态和配置自动保存到 `.agent/data/plugins-state.json`

```javascript
// 更新插件配置
framework.updatePluginConfig('telegram', { allowedChats: ['123'] });

// 启用/禁用插件
framework.enablePlugin('telegram');
framework.disablePlugin('telegram');
```

**保存的内容：**

- `enabled` - 插件启用状态
- `config` - 插件配置对象

**自动恢复：** 框架启动时自动加载保存的状态

### 4.1 Framework (src/core/framework.js)

**职责**：

- 管理插件生命周期
- 提供工具注册表
- 事件总线
- 初始化协调

**API**：

```javascript
const framework = new Framework({
  debug: false
})

// 插件操作
framework.registerPlugin(myPlugin)
await framework.loadPlugin({ type: 'ai-plugin', config: {...} })
await framework.unloadPlugin('my-plugin')
await framework.reloadPlugin('my-plugin')  // 手动热重载
await framework.reloadAllPlugins()

// 工具操作
framework.registerTool({
  name: 'my_tool',
  description: '...',
  execute: async (args) => { ... }
})

// 事件
framework.on('plugin:loaded', (plugin) => { ... })
framework.emit('agent:message', { content: '...' })

// 就绪
await framework.ready()
```

### 4.2 Agent (src/core/agent.js)

**职责**：

- 维护对话上下文
- 调用 AI 进行对话
- 管理工具调用循环

**API**：

```javascript
const agent = framework.createAgent({
  systemPrompt: '你是一个有帮助的助手',
  model: 'deepseek-chat',
  apiKey: '...'
})

agent.on('message', (msg) => { ... })
agent.on('tool-call', (tool) => { ... })

const response = await agent.chat('你好')
```

### 4.3 PluginManager (src/core/plugin-manager.js)

**职责**：

- 维护已加载插件列表
- 按优先级排序加载
- 协调插件生命周期

**生命周期**：

1. `install()` - 注册工具/事件
2. `start()` - 初始化完成，开始工作
3. `reload()` - 热重载
4. `uninstall()` - 清理

### 4.4 ToolRegistry (src/core/tool-registry.js)

**职责**：

- 注册工具
- 调用工具
- 工具描述管理

**工具格式**：

```javascript
{
  name: 'tool_name',
  description: '工具描述',
  parameters: { ... },  // Zod schema 或 JSON schema
  execute: async (args, framework) => { ... }
}
```

## 五、事件系统

```javascript
// 事件列表
'framework:ready'; // 框架就绪
'plugin:install'; // 插件安装
'plugin:start'; // 插件启动
'plugin:reload'; // 插件重载
'plugin:uninstall'; // 插件卸载
'plugin:enabled'; // 插件启用
'plugin:disabled'; // 插件禁用
'agent:message'; // Agent消息
'agent:tool-call'; // Agent调用工具
'agent:tool-result'; // 工具执行结果
'notification'; // 统一通知事件（推送用户）
'scheduler:reminder'; // 定时提醒触发（业务事件）
'think:thought_completed'; // 思考完成
'email:received'; // 收到新邮件
'webhook:received'; // 收到Webhook请求
```

### 通知事件 (notification)

统一的通知事件，用于向用户发送通知。消息插件（微信、飞书、Telegram）监听此事件并推送给用户。

```javascript
{
  title: '目标完成',           // 通知标题
  message: '目标 "xxx" 已完成', // 通知内容
  source: 'ambient',          // 来源：'scheduler' | 'ambient' | 'email' | 'webhook'
  level: 'success',        // 级别：'info' | 'warning' | 'success' | 'error'
  sessionId: 'weixin_xxx', // 会话ID（可选）
  timestamp: new Date()    // 时间戳
}
```

### 业务事件

业务事件用于触发 Ambient Agent 的目标，不直接通知用户。

| 事件                      | 数据                                            | 说明              |
| ------------------------- | ----------------------------------------------- | ----------------- |
| `scheduler:reminder`      | `{ taskId, taskName, message, sessionId, llm }` | 定时提醒触发时    |
| `think:thought_completed` | `thought`                                       | 思考完成时        |
| `email:received`          | `email`                                         | 收到新邮件时      |
| `webhook:received`        | `{ webhook, data, response, sessionId }`        | 收到Webhook请求时 |
| `tool:result`             | `{ name, args, result }`                        | 工具执行结果      |
| `agent:message`           | `{ content }`                                   | Agent发送消息时   |

## 六、热重载机制

### 设计原则

- **不监测文件变化** - 避免复杂性和性能开销
- **手动调用重载** - 通过 API 触发
- **插件自管理** - 插件提供 reload() 方法

### API

```javascript
// 重载单个插件
await framework.reloadPlugin('my-plugin');

// 重载所有插件
await framework.reloadAllPlugins();

// 在 Agent 中调用
agent.chat('请重载 my-plugin 插件');
// 需要插件提供 reload_plugins 工具
```

### 重载流程

1. 调用 `plugin.reload(framework)`
2. 插件清理旧资源
3. 插件重新初始化
4. 更新工具注册表

## 七、内置插件

### 7.1 AI Plugin (plugins/ai-plugin.js)

**功能**：

- AI 对话能力
- 工具调用循环

**配置**：

```javascript
{
  type: 'ai-plugin',
  provider: 'deepseek',      // deepseek / openai / anthropic
  model: 'deepseek-chat',
  apiKey: '...',
  baseURL: '...'            // 可选，自定义端点
}
```

### 7.2 Tools Plugin (plugins/tools-plugin.js)

**功能**：

- 内置工具注册
- 工具调用执行

**内置工具**：

- `reload_plugins` - 热重载插件
- `list_plugins` - 列出已加载插件
- `enable_plugin` - 启用插件
- `disable_plugin` - 禁用插件
- `get_plugin_config` - 获取插件配置
- `update_plugin_config` - 更新插件配置

### 7.3 Email Plugin (plugins/email-plugin.js)

**功能**：

- SMTP 发送邮件
- IMAP 读取邮件

**工具**：

- `email_send` - 发送邮件
- `email_read` - 读取邮件
- `email_unread_count` - 未读数量
- `email_mark_read` - 标记已读

### 7.4 Telegram Plugin (plugins/telegram-plugin.js)

**功能**：

- Telegram Bot 对话
- 绑定主 Agent 持续对话
- 支持 MarkdownV2
- 图片/文档接收保存
- 监听 `scheduler:reminder` 事件发送定时提醒

**监听事件**：

- `scheduler:reminder` - 接收定时任务提醒并发送到 Telegram

**配置**：

```javascript
{
  botToken: '...',
  allowedChats: ['123'],
  groupMode: false,
  prefix: '/'
}
```

### 7.5 Scheduler Plugin (plugins/scheduler-plugin.js)

**功能**：

- 定时任务调度（Cron 表达式、相对时间、绝对时间）
- 支持 LLM 自动检测（简单提醒直接显示，需要处理的任务启用 LLM）
- 会话自动检测（自动发送到最近活跃的会话）
- 事件系统（供其他插件监听和响应）

**工具**：

- `schedule_task` - 创建定时任务
- `schedule_list` - 列出所有任务
- `schedule_cancel` - 取消任务
- `cron_examples` - Cron 表达式示例

**schedule_task 参数**：

```javascript
{
  name: '任务名称',           // 可选
  scheduleTime: '10 minutes', // 必填，支持多种格式
  message: '提醒内容',         // 必填
  repeat: false,              // 可选，是否重复
  cronExpression: '*/5 * * * *',  // 可选，Cron 表达式
  sessionId: 'telegram_123', // 可选，会话 ID
  llm: true                  // 可选，是否需要 LLM 处理（自动检测）
}
```

**时间格式**：
| 格式 | 示例 | 说明 |
|------|------|------|
| 相对时间 | `10 seconds`, `5 minutes`, `1 hour`, `2 days` | 多久后执行 |
| 绝对时间 | `12:00`, `14:30:00` | 具体时间（次日开始） |
| Cron | `*/5 * * * *`, `0 9 * * *` | Cron 表达式 |

**自动 LLM 检测**：

- 简单提醒（喝水、吃饭）→ 直接显示
- 查询/分析任务（查看列表、分析数据）→ 启用 LLM

**持久化**：

- 任务自动保存到 `.agent/data/scheduler/tasks.json`
- 重启后自动恢复 Cron 任务和未执行的一次性任务

**通知**：

- 任务完成/失败/取消时发送 `notification` 事件
- 消息插件（微信、飞书）自动推送给用户

## 八、Ambient Agent 插件

### 8.1 Ambient Agent (plugins/ambient-agent-plugin.js)

**功能**：

- 持续后台运行的智能代理
- 监控事件并主动执行操作
- 目标（Goal）管理系统
- 持久化记忆

**支持的事件**：

- `tool:result` - 工具执行结果
- `scheduler:reminder` - 定时提醒
- `agent:message` - 代理消息
- `think:thought_completed` - 思考完成
- `email:received` - 收到邮件
- `webhook:received` - 收到Webhook

**工具**：

- `ambient_goals` - 管理目标（列出/创建/更新/删除/激活）
- `ambient_status` - 获取状态
- `ambient_think` - 触发主动思考
- `ambient_remember` - 存储/检索记忆
- `ambient_control` - 控制循环（暂停/恢复/调整）

**目标结构**：

```javascript
{
  title: '目标标题',
  description: '目标描述',
  priority: 5,           // 1-10，数值越高越重要
  actions: [            // 操作列表
    { type: 'tool', name: 'tool_name', args: {...} },
    { type: 'message', content: '消息内容' },
    { type: 'think', mode: 'reflect', topic: '思考主题' }
  ],
  conditions: {          // 激活条件（可选）
    events: ['email:received'],  // 监听的事件类型
    toolNames: ['email_read']     // 过滤的工具名称
  }
}
```

**通知**：

- 目标完成时发送 `notification` 事件（level: 'success'）
- 目标失败时发送 `notification` 事件（level: 'error'）

## 九、使用示例

### 9.1 基础用法

```javascript
const { Framework } = require('./src');

const framework = new Framework({ debug: true });

// 注册插件
framework.registerPlugin({
  name: 'my-plugin',
  install(f) {
    f.registerTool({
      name: 'greet',
      description: '打招呼',
      execute: async (args) => `Hello, ${args.name}!`,
    });
  },
});

await framework.ready();

const agent = framework.createAgent({
  systemPrompt: '你是一个助手',
  model: 'deepseek-chat',
  apiKey: process.env.API_KEY,
});

const response = await agent.chat('你好');
console.log(response);
```

### 9.2 热重载

```javascript
// 重载单个插件
await framework.reloadPlugin('my-plugin');

// 重载所有插件
await framework.reloadAllPlugins();
```

## 九、代码规范

### 9.1 文件命名

- 类文件：`小写-连字符.js`，如 `plugin-base.js`
- 目录：`小写-连字符`，如 `src/core`

### 9.2 类命名

- 类名：`大写驼峰`，如 `Framework`, `Agent`
- 方法名：`小写驼峰`，如 `registerTool`, `loadPlugin`

### 9.3 变量命名

- 类属性：`小写驼峰`
- 常量：`全大写+下划线`，如 `DEFAULT_PRIORITY`
- 私有属性：`_下划线前缀`

### 9.4 注释

```javascript
/**
 * 类描述
 */
class Framework {
  /**
   * 方法描述
   * @param {string} name - 参数描述
   * @returns {Promise<void>}
   */
  async loadPlugin(name) {}
}
```

## 十、已实现功能

### Phase 1 - 核心框架 ✓

- [x] Framework 核心类 (`src/core/framework.js`)
- [x] Agent 基础类 (`src/core/agent.js`)
- [x] 插件系统 (`src/core/plugin-manager.js`, `src/core/plugin-base.js`)
- [x] 工具注册表 (`src/core/tool-registry.js`)
- [x] 事件系统 (`src/utils/event-emitter.js`)
- [x] 热重载 API (`reloadPlugin()`, `reloadAllPlugins()`)

### Phase 2 - 内置插件 ✓

- [x] AI Plugin (`plugins/ai-plugin.js`) - 对接 Vercel AI SDK
- [x] 内置工具插件 (`plugins/tools-plugin.js`) - 热重载、列表工具

### Phase 3 - 高级功能 ✓

- [x] Skill 管理 (`src/capabilities/skill-manager.js`) - 加载和管理 Skill
- [x] 工作流引擎 (`src/capabilities/workflow-engine.js`) - 支持脚本、条件、循环等
- [x] MCP 执行器 (`src/executors/mcp-executor.js`) - 连接 MCP 服务器
- [x] Shell 执行器 (`plugins/shell-executor-plugin.js`) - 执行终端命令
- [x] Python 执行器 (`plugins/python-executor-plugin.js`) - 执行 Python 代码和脚本
- [x] Session 管理 (`plugins/session-plugin.js`) - 多会话支持、历史记录
- [x] Audit 审计日志 (`plugins/audit-plugin.js`) - 操作日志记录和查询
- [x] Rules 规则引擎 (`plugins/rules-plugin.js`) - 权限控制、内容过滤
- [x] Scheduler 定时任务 (`plugins/scheduler-plugin.js`) - Cron 调度、事件系统、自动 LLM 检测
- [x] Storage 存储 (`plugins/storage-plugin.js`) - 键值对持久化存储
- [x] SubAgent 子Agent (`plugins/subagent-plugin.js`) - 子Agent隔离工具集
- [x] Email 插件 (`plugins/email.js`) - 邮件收发
- [x] Telegram 插件 (`plugins/telegram-plugin.js`) - Telegram Bot 对话
- [x] 插件配置持久化 - enabled/config 保存到 plugins-state.json
- [x] AI 热重载 - LLM 配置更新后自动刷新已有 Agent

## 十一、依赖

```json
{
  "dependencies": {
    "@ai-sdk/anthropic": "^3.0.58",
    "@ai-sdk/mcp": "^1.0.25",
    "@ai-sdk/openai": "^3.0.41",
    "@ai-sdk/openai-compatible": "^2.0.35",
    "@anthropic-ai/sdk": "^0.39.0",
    "@modelcontextprotocol/sdk": "^1.27.1",
    "ai": "^6.0.116",
    "dotenv": "^17.3.1",
    "imap": "^0.8.19",
    "mailparser": "^3.7.2",
    "marked": "^11.2.0",
    "marked-terminal": "6",
    "node-cron": "^4.2.1",
    "node-telegram-bot-api": "^0.67.0",
    "nodemailer": "^6.10.0",
    "zod": "^3.24.0"
  }
}
```
