bare-agent 0.2.2 → 0.3.0
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/index.js +2 -0
- package/package.json +1 -1
- package/src/errors.js +7 -0
- package/src/loop.js +4 -1
- package/src/planner.js +22 -1
- package/src/provider-clipipe.js +2 -1
package/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
TimeoutError,
|
|
18
18
|
ValidationError,
|
|
19
19
|
CircuitOpenError,
|
|
20
|
+
MaxRoundsError,
|
|
20
21
|
} = require('./src/errors');
|
|
21
22
|
|
|
22
23
|
module.exports = {
|
|
@@ -36,4 +37,5 @@ module.exports = {
|
|
|
36
37
|
TimeoutError,
|
|
37
38
|
ValidationError,
|
|
38
39
|
CircuitOpenError,
|
|
40
|
+
MaxRoundsError,
|
|
39
41
|
};
|
package/package.json
CHANGED
package/src/errors.js
CHANGED
|
@@ -43,6 +43,12 @@ class CircuitOpenError extends BareAgentError {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
class MaxRoundsError extends BareAgentError {
|
|
47
|
+
constructor(message, opts = {}) {
|
|
48
|
+
super(message || 'Loop exceeded maximum rounds', { code: 'MAX_ROUNDS', retryable: false, ...opts });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
module.exports = {
|
|
47
53
|
BareAgentError,
|
|
48
54
|
ProviderError,
|
|
@@ -50,4 +56,5 @@ module.exports = {
|
|
|
50
56
|
TimeoutError,
|
|
51
57
|
ValidationError,
|
|
52
58
|
CircuitOpenError,
|
|
59
|
+
MaxRoundsError,
|
|
53
60
|
};
|
package/src/loop.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { ToolError } = require('./errors');
|
|
3
|
+
const { ToolError, MaxRoundsError } = require('./errors');
|
|
4
4
|
|
|
5
5
|
class Loop {
|
|
6
6
|
/**
|
|
@@ -25,6 +25,7 @@ class Loop {
|
|
|
25
25
|
this.onToolCall = options.onToolCall || null;
|
|
26
26
|
this.onText = options.onText || null;
|
|
27
27
|
this.onError = options.onError || null;
|
|
28
|
+
this.throwOnError = options.throwOnError !== undefined ? options.throwOnError : true;
|
|
28
29
|
this.store = options.store || null;
|
|
29
30
|
this._stopped = false;
|
|
30
31
|
this._history = []; // for chat() stateful mode
|
|
@@ -78,6 +79,7 @@ class Loop {
|
|
|
78
79
|
} catch (err) {
|
|
79
80
|
this.stream?.emit({ type: 'loop:error', data: { error: err.message, round } });
|
|
80
81
|
this.onError?.(err);
|
|
82
|
+
if (this.throwOnError) throw err;
|
|
81
83
|
return { text: '', toolCalls: [], usage: lastUsage, error: err.message };
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -148,6 +150,7 @@ class Loop {
|
|
|
148
150
|
// maxRounds exceeded
|
|
149
151
|
const warning = `[Loop] ended after ${this.maxRounds} rounds without final response`;
|
|
150
152
|
this.stream?.emit({ type: 'loop:done', data: { text: '', warning } });
|
|
153
|
+
if (this.throwOnError) throw new MaxRoundsError(warning);
|
|
151
154
|
return { text: '', toolCalls: [], usage: lastUsage, error: warning };
|
|
152
155
|
}
|
|
153
156
|
|
package/src/planner.js
CHANGED
|
@@ -25,6 +25,8 @@ class Planner {
|
|
|
25
25
|
if (!options.provider) throw new Error('[Planner] requires a provider');
|
|
26
26
|
this.provider = options.provider;
|
|
27
27
|
this.prompt = options.prompt || PLAN_PROMPT;
|
|
28
|
+
this._cacheTTL = options.cacheTTL || 0;
|
|
29
|
+
this._cache = new Map();
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
/**
|
|
@@ -37,6 +39,14 @@ class Planner {
|
|
|
37
39
|
* @throws {Error} `[Planner] step missing id or action` — when a step lacks required fields.
|
|
38
40
|
*/
|
|
39
41
|
async plan(goal, context = {}) {
|
|
42
|
+
if (this._cacheTTL > 0) {
|
|
43
|
+
const cacheKey = goal + '|' + (context.info || '');
|
|
44
|
+
const cached = this._cache.get(cacheKey);
|
|
45
|
+
if (cached && Date.now() < cached.expiresAt) {
|
|
46
|
+
return cached.result;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
const messages = [
|
|
41
51
|
{ role: 'system', content: this.prompt },
|
|
42
52
|
];
|
|
@@ -50,7 +60,18 @@ class Planner {
|
|
|
50
60
|
temperature: 0,
|
|
51
61
|
});
|
|
52
62
|
|
|
53
|
-
|
|
63
|
+
const steps = this._parse(result.text);
|
|
64
|
+
|
|
65
|
+
if (this._cacheTTL > 0) {
|
|
66
|
+
const cacheKey = goal + '|' + (context.info || '');
|
|
67
|
+
this._cache.set(cacheKey, { result: steps, expiresAt: Date.now() + this._cacheTTL });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return steps;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
clearCache() {
|
|
74
|
+
this._cache.clear();
|
|
54
75
|
}
|
|
55
76
|
|
|
56
77
|
_parse(text) {
|
package/src/provider-clipipe.js
CHANGED
|
@@ -23,6 +23,7 @@ class CLIPipeProvider {
|
|
|
23
23
|
this.env = options.env || undefined;
|
|
24
24
|
this.timeout = options.timeout ?? 30000;
|
|
25
25
|
this.systemPromptFlag = options.systemPromptFlag || null;
|
|
26
|
+
this.onChunk = options.onChunk || null;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
/**
|
|
@@ -88,7 +89,7 @@ class CLIPipeProvider {
|
|
|
88
89
|
let stderr = '';
|
|
89
90
|
let killed = false;
|
|
90
91
|
|
|
91
|
-
child.stdout.on('data', d => { stdout += d; });
|
|
92
|
+
child.stdout.on('data', d => { stdout += d; this.onChunk?.(d.toString()); });
|
|
92
93
|
child.stderr.on('data', d => { stderr += d; });
|
|
93
94
|
|
|
94
95
|
child.on('error', err => {
|