foliko 2.0.17 → 2.0.19

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/install.sh CHANGED
@@ -1,121 +1,121 @@
1
- #!/bin/bash
2
- # Foliko Installer
3
-
4
- set -e
5
-
6
- echo -e "\033[36mFoliko Installer\033[0m"
7
- echo -e "\033[36m=================\033[0m"
8
- echo ""
9
-
10
- # Detect OS
11
- detect_os() {
12
- if [[ "$OSTYPE" == "darwin"* ]]; then
13
- echo "macOS"
14
- elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
15
- echo "Linux"
16
- else
17
- echo "unknown"
18
- fi
19
- }
20
-
21
- OS=$(detect_os)
22
-
23
- # ============ Check/Install Node.js ============
24
- echo -e "\033[36mChecking Node.js...\033[0m"
25
- if command -v node &> /dev/null; then
26
- echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
27
- else
28
- echo -e "\033[33mNode.js not found, installing...\033[0m"
29
-
30
- if [[ "$OS" == "macOS" ]]; then
31
- if command -v brew &> /dev/null; then
32
- brew install node
33
- else
34
- echo -e "\033[31mHomebrew not found. Install it first:\033[0m"
35
- echo "/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
36
- exit 1
37
- fi
38
- elif [[ "$OS" == "Linux" ]]; then
39
- if command -v apt-get &> /dev/null; then
40
- sudo apt-get update && sudo apt-get install -y nodejs npm
41
- elif command -v yum &> /dev/null; then
42
- sudo yum install -y nodejs npm
43
- elif command -v pacman &> /dev/null; then
44
- sudo pacman -S nodejs npm
45
- else
46
- echo -e "\033[31mNo package manager found. Install Node.js manually: https://nodejs.org/\033[0m"
47
- exit 1
48
- fi
49
- fi
50
-
51
- if command -v node &> /dev/null; then
52
- echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
53
- else
54
- echo -e "\033[31mNode.js installation failed\033[0m"
55
- exit 1
56
- fi
57
- fi
58
- echo ""
59
-
60
- # ============ Check/Install Python ============
61
- echo -e "\033[36mChecking Python...\033[0m"
62
- if command -v python3 &> /dev/null; then
63
- echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
64
- else
65
- echo -e "\033[33mPython not found, installing...\033[0m"
66
-
67
- if [[ "$OS" == "macOS" ]]; then
68
- if command -v brew &> /dev/null; then
69
- brew install python3
70
- fi
71
- elif [[ "$OS" == "Linux" ]]; then
72
- if command -v apt-get &> /dev/null; then
73
- sudo apt-get update && sudo apt-get install -y python3 python3-venv python3-pip
74
- elif command -v yum &> /dev/null; then
75
- sudo yum install -y python3
76
- elif command -v pacman &> /dev/null; then
77
- sudo pacman -S python python-pip
78
- fi
79
- fi
80
-
81
- if command -v python3 &> /dev/null; then
82
- echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
83
- else
84
- echo -e "\033[33mPython installation failed (optional)\033[0m"
85
- fi
86
- fi
87
- echo ""
88
-
89
- # ============ Check/Install uv ============
90
- echo -e "\033[36mChecking uv...\033[0m"
91
- if command -v uv &> /dev/null; then
92
- echo -e "\033[32muv installed: $(uv --version)\033[0m"
93
- else
94
- echo -e "\033[33muv not found, installing...\033[0m"
95
-
96
- if [[ "$OS" == "macOS" ]] || [[ "$OS" == "Linux" ]]; then
97
- curl -LsSf https://astral.sh/uv/install.sh | sh
98
- source $HOME/.local/bin/env 2>/dev/null || true
99
-
100
- if command -v uv &> /dev/null; then
101
- echo -e "\033[32muv installed: $(uv --version)\033[0m"
102
- else
103
- echo -e "\033[33muv installation failed (optional)\033[0m"
104
- fi
105
- fi
106
- fi
107
- echo ""
108
-
109
- # ============ Install Foliko ============
110
- echo -e "\033[36mInstalling Foliko...\033[0m"
111
- npm install -g foliko
112
-
113
- if command -v foliko &> /dev/null; then
114
- echo ""
115
- echo -e "\033[32mInstallation complete!\033[0m"
116
- echo "Run: foliko chat"
117
- else
118
- echo ""
119
- echo -e "\033[31mInstallation failed. Try manually: npm install -g foliko\033[0m"
120
- exit 1
121
- fi
1
+ #!/bin/bash
2
+ # Foliko Installer
3
+
4
+ set -e
5
+
6
+ echo -e "\033[36mFoliko Installer\033[0m"
7
+ echo -e "\033[36m=================\033[0m"
8
+ echo ""
9
+
10
+ # Detect OS
11
+ detect_os() {
12
+ if [[ "$OSTYPE" == "darwin"* ]]; then
13
+ echo "macOS"
14
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
15
+ echo "Linux"
16
+ else
17
+ echo "unknown"
18
+ fi
19
+ }
20
+
21
+ OS=$(detect_os)
22
+
23
+ # ============ Check/Install Node.js ============
24
+ echo -e "\033[36mChecking Node.js...\033[0m"
25
+ if command -v node &> /dev/null; then
26
+ echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
27
+ else
28
+ echo -e "\033[33mNode.js not found, installing...\033[0m"
29
+
30
+ if [[ "$OS" == "macOS" ]]; then
31
+ if command -v brew &> /dev/null; then
32
+ brew install node
33
+ else
34
+ echo -e "\033[31mHomebrew not found. Install it first:\033[0m"
35
+ echo "/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
36
+ exit 1
37
+ fi
38
+ elif [[ "$OS" == "Linux" ]]; then
39
+ if command -v apt-get &> /dev/null; then
40
+ sudo apt-get update && sudo apt-get install -y nodejs npm
41
+ elif command -v yum &> /dev/null; then
42
+ sudo yum install -y nodejs npm
43
+ elif command -v pacman &> /dev/null; then
44
+ sudo pacman -S nodejs npm
45
+ else
46
+ echo -e "\033[31mNo package manager found. Install Node.js manually: https://nodejs.org/\033[0m"
47
+ exit 1
48
+ fi
49
+ fi
50
+
51
+ if command -v node &> /dev/null; then
52
+ echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
53
+ else
54
+ echo -e "\033[31mNode.js installation failed\033[0m"
55
+ exit 1
56
+ fi
57
+ fi
58
+ echo ""
59
+
60
+ # ============ Check/Install Python ============
61
+ echo -e "\033[36mChecking Python...\033[0m"
62
+ if command -v python3 &> /dev/null; then
63
+ echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
64
+ else
65
+ echo -e "\033[33mPython not found, installing...\033[0m"
66
+
67
+ if [[ "$OS" == "macOS" ]]; then
68
+ if command -v brew &> /dev/null; then
69
+ brew install python3
70
+ fi
71
+ elif [[ "$OS" == "Linux" ]]; then
72
+ if command -v apt-get &> /dev/null; then
73
+ sudo apt-get update && sudo apt-get install -y python3 python3-venv python3-pip
74
+ elif command -v yum &> /dev/null; then
75
+ sudo yum install -y python3
76
+ elif command -v pacman &> /dev/null; then
77
+ sudo pacman -S python python-pip
78
+ fi
79
+ fi
80
+
81
+ if command -v python3 &> /dev/null; then
82
+ echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
83
+ else
84
+ echo -e "\033[33mPython installation failed (optional)\033[0m"
85
+ fi
86
+ fi
87
+ echo ""
88
+
89
+ # ============ Check/Install uv ============
90
+ echo -e "\033[36mChecking uv...\033[0m"
91
+ if command -v uv &> /dev/null; then
92
+ echo -e "\033[32muv installed: $(uv --version)\033[0m"
93
+ else
94
+ echo -e "\033[33muv not found, installing...\033[0m"
95
+
96
+ if [[ "$OS" == "macOS" ]] || [[ "$OS" == "Linux" ]]; then
97
+ curl -LsSf https://astral.sh/uv/install.sh | sh
98
+ source $HOME/.local/bin/env 2>/dev/null || true
99
+
100
+ if command -v uv &> /dev/null; then
101
+ echo -e "\033[32muv installed: $(uv --version)\033[0m"
102
+ else
103
+ echo -e "\033[33muv installation failed (optional)\033[0m"
104
+ fi
105
+ fi
106
+ fi
107
+ echo ""
108
+
109
+ # ============ Install Foliko ============
110
+ echo -e "\033[36mInstalling Foliko...\033[0m"
111
+ npm install -g foliko
112
+
113
+ if command -v foliko &> /dev/null; then
114
+ echo ""
115
+ echo -e "\033[32mInstallation complete!\033[0m"
116
+ echo "Run: foliko chat"
117
+ else
118
+ echo ""
119
+ echo -e "\033[31mInstallation failed. Try manually: npm install -g foliko\033[0m"
120
+ exit 1
121
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foliko",
3
- "version": "2.0.17",
3
+ "version": "2.0.19",
4
4
  "description": "简约的插件化 Agent 框架",
5
5
  "main": "src/index.js",
6
6
  "type": "commonjs",
@@ -234,12 +234,12 @@ class ExplorerLoop {
234
234
  // 非事件驱动目标可以完成
235
235
  this._goalManager.completeGoal(goal.id)
236
236
  this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
237
- this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
237
+ await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
238
238
  } else if (!outcome.shouldContinue && !isEventDriven) {
239
239
  // 非事件驱动目标可以失败
240
240
  this._goalManager.failGoal(goal.id, '达到最大尝试次数')
241
241
  this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
242
- this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
242
+ await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
243
243
  } else {
244
244
  // 事件驱动目标:不论结果如何,都重置并继续等待下一事件
245
245
  this._addActivity('actions_completed', { goalId: goal.id, actionCount: results.length })
@@ -250,7 +250,7 @@ class ExplorerLoop {
250
250
  // 一次性目标:所有 actions 完成后直接完成
251
251
  this._goalManager.completeGoal(goal.id)
252
252
  this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
253
- this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
253
+ await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
254
254
  } else if (hasNewEvents) {
255
255
  // 持久化目标且有新事件,重置 actions
256
256
  this._resetGoalForNextEvent(goal)
@@ -269,7 +269,7 @@ class ExplorerLoop {
269
269
  // 一次性目标:所有 actions 完成后直接完成
270
270
  this._goalManager.completeGoal(goal.id)
271
271
  this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
272
- this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
272
+ await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
273
273
  } else {
274
274
  // 持久化目标:等待下一事件
275
275
  this._resetGoalForNextEvent(goal)
@@ -281,7 +281,7 @@ class ExplorerLoop {
281
281
  if (!hasNewEvents && this._reflector.checkLoopDetection(goal, action.id)) {
282
282
  this._addActivity('goal_failed', { goalId: goal.id, reason: '检测到循环' })
283
283
  // 通知用户目标失败
284
- this._notifyUser('目标失败', `目标 "${goal.title}" 失败:检测到循环(同一操作连续重复)`, 'error')
284
+ await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:检测到循环(同一操作连续重复)`, 'error')
285
285
  continue
286
286
  }
287
287
 
@@ -298,12 +298,12 @@ class ExplorerLoop {
298
298
  this._goalManager.completeGoal(goal.id)
299
299
  this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
300
300
  // 通知用户目标完成
301
- this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
301
+ await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
302
302
  } else if (!outcome.shouldContinue) {
303
303
  this._goalManager.failGoal(goal.id, '达到最大尝试次数')
304
304
  this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
305
305
  // 通知用户目标失败
306
- this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
306
+ await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
307
307
  } else {
308
308
  this._addActivity('action_executed', { goalId: goal.id, action: action.id, hasEvents: hasNewEvents })
309
309
 
@@ -313,7 +313,7 @@ class ExplorerLoop {
313
313
  // 一次性目标:所有 actions 完成后直接完成
314
314
  this._goalManager.completeGoal(goal.id)
315
315
  this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
316
- this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
316
+ await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
317
317
  } else if (hasNewEvents) {
318
318
  // 持久化目标且有新事件,重置 actions
319
319
  this._resetGoalForNextEvent(goal)
@@ -1019,14 +1019,14 @@ ${lastResultStr}
1019
1019
  /**
1020
1020
  * 通知用户(通过事件发送给消息插件)
1021
1021
  */
1022
- _notifyUser(title, message, level = 'info') {
1022
+ async _notifyUser(title, message, level = 'info') {
1023
1023
  if (!this._framework) return
1024
1024
 
1025
1025
  // 获取目标相关的sessionId(如果有)
1026
1026
  let sessionId = null
1027
1027
  const sessionPlugin = this._framework.pluginManager.get('session')
1028
1028
  if (sessionPlugin) {
1029
- const sessions = sessionPlugin.listSessions()
1029
+ const sessions = await sessionPlugin.listSessions()
1030
1030
  if (sessions.length > 0) {
1031
1031
  // 取最新的会话
1032
1032
  sessions.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
@@ -391,7 +391,7 @@ class SchedulerPlugin extends Plugin {
391
391
  if (!targetSessionId) {
392
392
  const sessionPlugin = this._framework?.pluginManager?.get('session');
393
393
  if (sessionPlugin) {
394
- const sessions = sessionPlugin.listSessions();
394
+ const sessions = await sessionPlugin.listSessions();
395
395
  if (sessions.length > 0) {
396
396
  sessions.sort((a, b) => {
397
397
  const aTime = a.lastActive ? new Date(a.lastActive).getTime() : 0;
@@ -84,6 +84,7 @@ class SessionPlugin extends Plugin {
84
84
  try {
85
85
  const manager = SessionManager.open(filePath, sessionDir, cwd);
86
86
  sessions.push({
87
+ id:path.basename(filePath, path.extname(filePath)),
87
88
  sessionId: manager.getSessionId(),
88
89
  sessionFile: manager.getSessionFile(),
89
90
  messageCount: manager.getEntries().length,