@jclaw/core 0.6.1 → 0.8.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/dist/cli/jclaw.js.backup +212 -0
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +5 -4
- package/dist/context/memsearch-ts-client.d.ts +37 -0
- package/dist/context/memsearch-ts-client.d.ts.map +1 -0
- package/dist/context/memsearch-ts-client.js +121 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/planning/index.d.ts +8 -0
- package/dist/planning/index.d.ts.map +1 -0
- package/dist/planning/index.js +6 -0
- package/dist/planning/planner.d.ts +23 -0
- package/dist/planning/planner.d.ts.map +1 -0
- package/dist/planning/planner.js +184 -0
- package/dist/planning/types.d.ts +34 -0
- package/dist/planning/types.d.ts.map +1 -0
- package/dist/planning/types.js +6 -0
- package/dist/runtime/agent.d.ts +3 -4
- package/dist/runtime/agent.d.ts.map +1 -1
- package/dist/runtime/agent.js +76 -45
- package/dist/runtime/task-executor.d.ts +5 -69
- package/dist/runtime/task-executor.d.ts.map +1 -1
- package/dist/runtime/task-executor.js +67 -151
- package/dist/runtime/task-executor.js.backup +295 -0
- package/package.json +26 -8
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Planning Module Types
|
|
3
|
+
*
|
|
4
|
+
* @module @jclaw/core/planning/types
|
|
5
|
+
*/
|
|
6
|
+
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed';
|
|
7
|
+
export interface Step {
|
|
8
|
+
id: string;
|
|
9
|
+
description: string;
|
|
10
|
+
status: StepStatus;
|
|
11
|
+
capability?: string;
|
|
12
|
+
input?: unknown;
|
|
13
|
+
output?: unknown;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface Plan {
|
|
17
|
+
taskId: string;
|
|
18
|
+
taskPrompt: string;
|
|
19
|
+
steps: Step[];
|
|
20
|
+
currentStepIndex: number;
|
|
21
|
+
createdAt: number;
|
|
22
|
+
completedAt?: number;
|
|
23
|
+
relevantExperiences?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface PlannerConfig {
|
|
26
|
+
maxSteps?: number;
|
|
27
|
+
verbose?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface PlanAdjustment {
|
|
30
|
+
type: 'retry' | 'skip' | 'abort' | 'alternative';
|
|
31
|
+
reason: string;
|
|
32
|
+
newSteps?: Step[];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/planning/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAExE,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;CACnB"}
|
package/dist/runtime/agent.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface AgentConfig {
|
|
|
11
11
|
systemPrompt?: string;
|
|
12
12
|
verbose?: boolean;
|
|
13
13
|
enableAutoSkill?: boolean;
|
|
14
|
+
enablePlanning?: boolean;
|
|
14
15
|
autoSkillConfig?: Partial<AutoSkillConfig>;
|
|
15
16
|
skillShConfig?: Partial<SkillShAdapterConfig>;
|
|
16
17
|
extensionRegistry?: ExtensionRegistry;
|
|
@@ -20,6 +21,7 @@ export declare class JClawAgent implements AgentRuntime {
|
|
|
20
21
|
private readonly config;
|
|
21
22
|
private llmClient?;
|
|
22
23
|
private taskExecutor?;
|
|
24
|
+
private planner?;
|
|
23
25
|
private running;
|
|
24
26
|
private autoSkillGenerator?;
|
|
25
27
|
private autoSkillInstaller?;
|
|
@@ -32,9 +34,6 @@ export declare class JClawAgent implements AgentRuntime {
|
|
|
32
34
|
stop(): Promise<void>;
|
|
33
35
|
execute(task: Task): Promise<TaskResult>;
|
|
34
36
|
private executeWithAutoSkill;
|
|
35
|
-
|
|
36
|
-
get name(): string;
|
|
37
|
-
get version(): string;
|
|
37
|
+
private storeExperience;
|
|
38
38
|
}
|
|
39
|
-
export declare function createAgent(config?: AgentConfig): JClawAgent;
|
|
40
39
|
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAOpE,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAOpE,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAIpF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC9C,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,qBAAa,UAAW,YAAW,YAAY;IAC7C,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAM;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,cAAc,CAAC,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,iBAAiB,CAAC,CAAoB;gBAElC,MAAM,GAAE,WAAgB;IAcpC,IAAI,OAAO,IAAI,cAAc,CAG5B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4CtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;YAkChC,oBAAoB;YA6CpB,eAAe;CAIgB"}
|
package/dist/runtime/agent.js
CHANGED
|
@@ -8,11 +8,13 @@ import { createSkillDiscoveryEngine } from '../skill-sh/discovery.js';
|
|
|
8
8
|
import { createSkillShAdapter } from '../skill-sh/adapter.js';
|
|
9
9
|
import { createSkillConverter } from '../skill-sh/converter.js';
|
|
10
10
|
import { fileOperationsExtension } from '../extensions/built-in/file-operations.js';
|
|
11
|
+
import { createPlanner } from '../planning/index.js';
|
|
11
12
|
export class JClawAgent {
|
|
12
13
|
executionMode;
|
|
13
14
|
config;
|
|
14
15
|
llmClient;
|
|
15
16
|
taskExecutor;
|
|
17
|
+
planner;
|
|
16
18
|
running = false;
|
|
17
19
|
autoSkillGenerator;
|
|
18
20
|
autoSkillInstaller;
|
|
@@ -27,6 +29,7 @@ export class JClawAgent {
|
|
|
27
29
|
systemPrompt: 'You are JClaw, a self-evolving AI agent.',
|
|
28
30
|
verbose: false,
|
|
29
31
|
enableAutoSkill: false,
|
|
32
|
+
enablePlanning: true,
|
|
30
33
|
...config,
|
|
31
34
|
};
|
|
32
35
|
this.executionMode = config.executionMode ?? 'local';
|
|
@@ -39,47 +42,48 @@ export class JClawAgent {
|
|
|
39
42
|
async start() {
|
|
40
43
|
if (this.running)
|
|
41
44
|
return;
|
|
42
|
-
console.log(
|
|
45
|
+
console.log("Starting " + this.config.name + " v" + this.config.version + "...");
|
|
43
46
|
if (this.config.llm) {
|
|
44
47
|
this.llmClient = new LLMClient(this.config.llm);
|
|
45
|
-
console.log(
|
|
48
|
+
console.log("LLM client initialized");
|
|
49
|
+
}
|
|
50
|
+
this.extensionRegistry = this.config.extensionRegistry ?? new ExtensionRegistry();
|
|
51
|
+
try {
|
|
52
|
+
this.extensionRegistry.register(fileOperationsExtension);
|
|
53
|
+
console.log("Built-in file operations registered");
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.warn("Failed to register file operations:", error);
|
|
57
|
+
}
|
|
58
|
+
if (this.llmClient) {
|
|
59
|
+
this.planner = createPlanner(this.llmClient, { verbose: this.config.verbose });
|
|
60
|
+
console.log("Planner initialized");
|
|
46
61
|
}
|
|
47
62
|
this.taskExecutor = new TaskExecutor({
|
|
48
63
|
llmClient: this.llmClient,
|
|
49
|
-
|
|
64
|
+
contextManager: this.config.contextManager,
|
|
65
|
+
extensionRegistry: this.extensionRegistry,
|
|
50
66
|
verbose: this.config.verbose,
|
|
51
67
|
});
|
|
52
68
|
if (this.config.enableAutoSkill) {
|
|
53
|
-
console.log(
|
|
69
|
+
console.log("AutoSkill enabled - initializing...");
|
|
54
70
|
this.evolutionEngine = new EvolutionEngine({ populationSize: 10, mutationRate: 0.1, selectionPressure: 0.5 });
|
|
55
|
-
this.extensionRegistry = this.config.extensionRegistry ?? new ExtensionRegistry();
|
|
56
71
|
const skillShAdapter = createSkillShAdapter(this.llmClient, this.config.skillShConfig);
|
|
57
72
|
const skillConverter = createSkillConverter(this.llmClient);
|
|
58
73
|
this.autoSkillGenerator = createAutoSkillGenerator(this.llmClient, this.extensionRegistry, this.evolutionEngine, this.config.autoSkillConfig);
|
|
59
74
|
this.autoSkillInstaller = createAutoSkillInstaller(this.extensionRegistry, this.config.autoSkillConfig?.storageDir);
|
|
60
75
|
this.skillDiscovery = createSkillDiscoveryEngine(this.llmClient, this.extensionRegistry, skillShAdapter, skillConverter, this.autoSkillGenerator);
|
|
61
|
-
console.log(
|
|
62
|
-
}
|
|
63
|
-
// Register built-in file operations extension
|
|
64
|
-
if (!this.extensionRegistry) {
|
|
65
|
-
this.extensionRegistry = new ExtensionRegistry();
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
this.extensionRegistry.register(fileOperationsExtension);
|
|
69
|
-
console.log("📁 Built-in file operations registered\n");
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
console.warn("⚠️ Failed to register file operations:", error);
|
|
76
|
+
console.log("AutoSkill components initialized");
|
|
73
77
|
}
|
|
74
78
|
this.running = true;
|
|
75
|
-
console.log(
|
|
79
|
+
console.log("Agent started");
|
|
76
80
|
}
|
|
77
81
|
async stop() {
|
|
78
82
|
if (!this.running)
|
|
79
83
|
return;
|
|
80
|
-
console.log(
|
|
84
|
+
console.log("Stopping agent...");
|
|
81
85
|
this.running = false;
|
|
82
|
-
console.log(
|
|
86
|
+
console.log("Agent stopped");
|
|
83
87
|
}
|
|
84
88
|
async execute(task) {
|
|
85
89
|
if (!this.running)
|
|
@@ -87,10 +91,34 @@ export class JClawAgent {
|
|
|
87
91
|
if (!this.taskExecutor)
|
|
88
92
|
throw new Error('Task executor not initialized');
|
|
89
93
|
if (this.config.verbose)
|
|
90
|
-
console.log(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
console.log("Executing task: " + task.prompt);
|
|
95
|
+
// Step 2: Retrieve relevant experiences
|
|
96
|
+
let relevantExperiences = '';
|
|
97
|
+
if (this.config.contextManager) {
|
|
98
|
+
try {
|
|
99
|
+
relevantExperiences = await this.config.contextManager.query(task.prompt, { topK: 3 });
|
|
100
|
+
if (relevantExperiences && this.config.verbose) {
|
|
101
|
+
console.log("Retrieved relevant experiences");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (this.config.verbose)
|
|
106
|
+
console.log("Failed to retrieve experiences");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Execute task
|
|
110
|
+
let result;
|
|
111
|
+
if (this.config.enableAutoSkill) {
|
|
112
|
+
result = await this.executeWithAutoSkill(task);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
result = await this.taskExecutor.execute(task);
|
|
116
|
+
}
|
|
117
|
+
// Step 8: Store experience (only if successful)
|
|
118
|
+
if (result.success && this.config.contextManager) {
|
|
119
|
+
await this.storeExperience(task, result);
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
94
122
|
}
|
|
95
123
|
async executeWithAutoSkill(task) {
|
|
96
124
|
if (!this.taskExecutor)
|
|
@@ -98,49 +126,52 @@ export class JClawAgent {
|
|
|
98
126
|
const maxAttempts = this.config.autoSkillConfig?.maxGenerationAttempts || 3;
|
|
99
127
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
100
128
|
try {
|
|
101
|
-
console.log(
|
|
129
|
+
console.log("Attempt " + attempt + "/" + maxAttempts);
|
|
102
130
|
const result = await this.taskExecutor.execute(task);
|
|
103
131
|
if (result.success) {
|
|
104
|
-
console.log(
|
|
132
|
+
console.log("Task completed successfully");
|
|
105
133
|
return result;
|
|
106
134
|
}
|
|
107
|
-
console.log(
|
|
135
|
+
console.log("Task failed: " + result.error);
|
|
108
136
|
if (!this.skillDiscovery || !this.autoSkillInstaller) {
|
|
109
|
-
console.log(
|
|
137
|
+
console.log("AutoSkill components not available");
|
|
110
138
|
return result;
|
|
111
139
|
}
|
|
112
|
-
console.log(
|
|
140
|
+
console.log("Analyzing missing capabilities...");
|
|
113
141
|
const discovery = await this.skillDiscovery.discover(task.prompt);
|
|
114
142
|
if (discovery.recommended && discovery.confidence > 0.5) {
|
|
115
|
-
console.log(
|
|
116
|
-
console.log(
|
|
117
|
-
console.log(
|
|
118
|
-
console.log(
|
|
143
|
+
console.log("Found skill: " + discovery.recommended.name);
|
|
144
|
+
console.log("Source: " + discovery.source);
|
|
145
|
+
console.log("Confidence: " + (discovery.confidence * 100).toFixed(0) + "%");
|
|
146
|
+
console.log("Installing skill...");
|
|
119
147
|
const installed = await this.skillDiscovery.installSkill(discovery.recommended);
|
|
120
148
|
if (installed) {
|
|
121
|
-
console.log(
|
|
122
|
-
console.log(
|
|
149
|
+
console.log("Skill installed successfully");
|
|
150
|
+
console.log("Retrying task with new capability...");
|
|
123
151
|
continue;
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
if (attempt >= maxAttempts) {
|
|
127
|
-
return { taskId: task.id, success: false, output: '', error:
|
|
155
|
+
return { taskId: task.id, success: false, output: '', error: "Task failed after " + maxAttempts + " attempts. Last error: " + result.error, duration: 0 };
|
|
128
156
|
}
|
|
129
157
|
}
|
|
130
158
|
catch (error) {
|
|
131
159
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
132
|
-
console.log(
|
|
160
|
+
console.log("Attempt " + attempt + " failed: " + errorMessage);
|
|
133
161
|
if (attempt >= maxAttempts) {
|
|
134
|
-
return { taskId: task.id, success: false, output: '', error:
|
|
162
|
+
return { taskId: task.id, success: false, output: '', error: "Task failed after " + maxAttempts + " attempts. Last error: " + errorMessage, duration: 0 };
|
|
135
163
|
}
|
|
136
164
|
}
|
|
137
165
|
}
|
|
138
|
-
return { taskId: task.id, success: false, output: '', error:
|
|
166
|
+
return { taskId: task.id, success: false, output: '', error: "Task failed after " + maxAttempts + " attempts", duration: 0 };
|
|
167
|
+
}
|
|
168
|
+
async storeExperience(task, result) {
|
|
169
|
+
if (!this.config.contextManager)
|
|
170
|
+
return;
|
|
171
|
+
try {
|
|
172
|
+
const title = "Experience: " + task.promp;
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
}
|
|
139
176
|
}
|
|
140
|
-
isRunning() { return this.running; }
|
|
141
|
-
get name() { return this.config.name; }
|
|
142
|
-
get version() { return this.config.version; }
|
|
143
|
-
}
|
|
144
|
-
export function createAgent(config) {
|
|
145
|
-
return new JClawAgent(config);
|
|
146
177
|
}
|
|
@@ -1,92 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Task Executor
|
|
3
|
-
*
|
|
4
|
-
* Manages task execution workflow including context retrieval,
|
|
5
|
-
* LLM interaction, and command execution.
|
|
6
|
-
*
|
|
7
|
-
* @module @jclaw/core/runtime/task-executor
|
|
2
|
+
* Task Executor - Enhanced with Capability Support
|
|
8
3
|
*/
|
|
9
4
|
import type { Task, TaskResult, ContextManager, Executor } from '../types.js';
|
|
10
5
|
import { LLMClient } from './llm-client.js';
|
|
11
|
-
|
|
12
|
-
* Configuration for task executor
|
|
13
|
-
*/
|
|
6
|
+
import { ExtensionRegistry } from '../extension-system/registry.js';
|
|
14
7
|
export interface TaskExecutorConfig {
|
|
15
|
-
/** LLM client for generating responses */
|
|
16
8
|
llmClient: LLMClient;
|
|
17
|
-
/** Context manager for knowledge retrieval */
|
|
18
9
|
contextManager?: ContextManager;
|
|
19
|
-
/** Command executor for running shell commands */
|
|
20
10
|
executor?: Executor;
|
|
21
|
-
|
|
11
|
+
extensionRegistry?: ExtensionRegistry;
|
|
22
12
|
systemPrompt?: string;
|
|
23
|
-
/** Maximum retries for failed tasks (default: 3) */
|
|
24
13
|
maxRetries?: number;
|
|
25
|
-
/** Enable verbose logging */
|
|
26
14
|
verbose?: boolean;
|
|
27
15
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Task Executor
|
|
30
|
-
*
|
|
31
|
-
* Orchestrates task execution by:
|
|
32
|
-
* - Retrieving relevant context
|
|
33
|
-
* - Generating plans with LLM
|
|
34
|
-
* - Executing commands when needed
|
|
35
|
-
* - Handling errors and retries
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```typescript
|
|
39
|
-
* const executor = new TaskExecutor({
|
|
40
|
-
* llmClient: createLLMClient(config),
|
|
41
|
-
* contextManager: openVikingClient,
|
|
42
|
-
* executor: localExecutor
|
|
43
|
-
* });
|
|
44
|
-
*
|
|
45
|
-
* const result = await executor.execute({
|
|
46
|
-
* id: 'task-1',
|
|
47
|
-
* prompt: 'List all files in the current directory'
|
|
48
|
-
* });
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
16
|
export declare class TaskExecutor {
|
|
52
17
|
private readonly config;
|
|
53
|
-
/**
|
|
54
|
-
* Create a new task executor instance.
|
|
55
|
-
*
|
|
56
|
-
* @param config - Configuration options
|
|
57
|
-
*/
|
|
58
18
|
constructor(config: TaskExecutorConfig);
|
|
59
|
-
/**
|
|
60
|
-
* Execute a task and return the result.
|
|
61
|
-
*
|
|
62
|
-
* @param task - The task to execute
|
|
63
|
-
* @returns Promise resolving to task result
|
|
64
|
-
*/
|
|
65
19
|
execute(task: Task): Promise<TaskResult>;
|
|
66
|
-
/**
|
|
67
|
-
* Internal method to execute a single task attempt.
|
|
68
|
-
*/
|
|
69
20
|
private executeTask;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
* Looks for commands in code blocks marked as shell/bash.
|
|
74
|
-
*/
|
|
21
|
+
private buildSystemPrompt;
|
|
22
|
+
private extractCapabilityCall;
|
|
75
23
|
private extractCommands;
|
|
76
|
-
/**
|
|
77
|
-
* Log message if verbose mode is enabled.
|
|
78
|
-
*/
|
|
79
24
|
private log;
|
|
80
|
-
/**
|
|
81
|
-
* Sleep for specified milliseconds.
|
|
82
|
-
*/
|
|
83
25
|
private sleep;
|
|
84
26
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Create a new task executor instance.
|
|
87
|
-
*
|
|
88
|
-
* @param config - Configuration options
|
|
89
|
-
* @returns New TaskExecutor instance
|
|
90
|
-
*/
|
|
91
27
|
export declare function createTaskExecutor(config: TaskExecutorConfig): TaskExecutor;
|
|
92
28
|
//# sourceMappingURL=task-executor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/task-executor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"task-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/task-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAIpE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIrB;gBAEU,MAAM,EAAE,kBAAkB;IAIhC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;YAqBhC,WAAW;IAiDzB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,KAAK;CAGd;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAE3E"}
|
|
@@ -1,66 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Task Executor
|
|
3
|
-
*
|
|
4
|
-
* Manages task execution workflow including context retrieval,
|
|
5
|
-
* LLM interaction, and command execution.
|
|
6
|
-
*
|
|
7
|
-
* @module @jclaw/core/runtime/task-executor
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* System prompt for the agent
|
|
11
|
-
*/
|
|
12
|
-
const DEFAULT_SYSTEM_PROMPT = `You are JClaw, a self-evolving AI agent.
|
|
13
|
-
You help users complete tasks by:
|
|
14
|
-
1. Understanding their request
|
|
15
|
-
2. Planning the necessary steps
|
|
16
|
-
3. Executing commands when needed
|
|
17
|
-
4. Reporting results clearly
|
|
18
|
-
|
|
19
|
-
Always think step by step and explain your reasoning.`;
|
|
20
|
-
/**
|
|
21
|
-
* Task Executor
|
|
22
|
-
*
|
|
23
|
-
* Orchestrates task execution by:
|
|
24
|
-
* - Retrieving relevant context
|
|
25
|
-
* - Generating plans with LLM
|
|
26
|
-
* - Executing commands when needed
|
|
27
|
-
* - Handling errors and retries
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```typescript
|
|
31
|
-
* const executor = new TaskExecutor({
|
|
32
|
-
* llmClient: createLLMClient(config),
|
|
33
|
-
* contextManager: openVikingClient,
|
|
34
|
-
* executor: localExecutor
|
|
35
|
-
* });
|
|
36
|
-
*
|
|
37
|
-
* const result = await executor.execute({
|
|
38
|
-
* id: 'task-1',
|
|
39
|
-
* prompt: 'List all files in the current directory'
|
|
40
|
-
* });
|
|
41
|
-
* ```
|
|
2
|
+
* Task Executor - Enhanced with Capability Support
|
|
42
3
|
*/
|
|
4
|
+
const DEFAULT_SYSTEM_PROMPT = "You are JClaw, a self-evolving AI agent. You help users complete tasks.";
|
|
43
5
|
export class TaskExecutor {
|
|
44
6
|
config;
|
|
45
|
-
/**
|
|
46
|
-
* Create a new task executor instance.
|
|
47
|
-
*
|
|
48
|
-
* @param config - Configuration options
|
|
49
|
-
*/
|
|
50
7
|
constructor(config) {
|
|
51
|
-
this.config = {
|
|
52
|
-
systemPrompt: DEFAULT_SYSTEM_PROMPT,
|
|
53
|
-
maxRetries: 3,
|
|
54
|
-
verbose: false,
|
|
55
|
-
...config,
|
|
56
|
-
};
|
|
8
|
+
this.config = { systemPrompt: DEFAULT_SYSTEM_PROMPT, maxRetries: 3, verbose: false, ...config };
|
|
57
9
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Execute a task and return the result.
|
|
60
|
-
*
|
|
61
|
-
* @param task - The task to execute
|
|
62
|
-
* @returns Promise resolving to task result
|
|
63
|
-
*/
|
|
64
10
|
async execute(task) {
|
|
65
11
|
const startTime = Date.now();
|
|
66
12
|
let attempts = 0;
|
|
@@ -69,134 +15,104 @@ export class TaskExecutor {
|
|
|
69
15
|
attempts++;
|
|
70
16
|
try {
|
|
71
17
|
const output = await this.executeTask(task);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
taskId: task.id,
|
|
75
|
-
success: true,
|
|
76
|
-
output,
|
|
77
|
-
duration,
|
|
78
|
-
};
|
|
18
|
+
return { taskId: task.id, success: true, output, duration: Date.now() - startTime };
|
|
79
19
|
}
|
|
80
20
|
catch (error) {
|
|
81
21
|
lastError = error instanceof Error ? error.message : 'Unknown error';
|
|
82
|
-
this.log(`Attempt ${attempts} failed: ${lastError}`);
|
|
83
|
-
// Wait before retry (exponential backoff)
|
|
84
22
|
if (attempts < this.config.maxRetries) {
|
|
85
23
|
await this.sleep(1000 * Math.pow(2, attempts - 1));
|
|
86
24
|
}
|
|
87
25
|
}
|
|
88
26
|
}
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
taskId: task.id,
|
|
92
|
-
success: false,
|
|
93
|
-
error: `Task failed after ${attempts} attempts. Last error: ${lastError}`,
|
|
94
|
-
duration,
|
|
95
|
-
};
|
|
27
|
+
return { taskId: task.id, success: false, error: lastError, duration: Date.now() - startTime };
|
|
96
28
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Internal method to execute a single task attempt.
|
|
99
|
-
*/
|
|
100
29
|
async executeTask(task) {
|
|
101
|
-
|
|
102
|
-
const messages = [
|
|
103
|
-
{ role: 'system', content: this.config.systemPrompt },
|
|
104
|
-
];
|
|
105
|
-
// Add context if available
|
|
30
|
+
const messages = [{ role: 'system', content: this.buildSystemPrompt() }];
|
|
106
31
|
if (this.config.contextManager) {
|
|
107
32
|
try {
|
|
108
33
|
const context = await this.config.contextManager.query(task.prompt, { topK: 5 });
|
|
109
|
-
if (context)
|
|
110
|
-
messages.push({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
34
|
+
if (context)
|
|
35
|
+
messages.push({ role: 'system', content: 'Relevant context: ' + context });
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
39
|
+
messages.push({ role: 'user', content: task.prompt });
|
|
40
|
+
if (task.context)
|
|
41
|
+
messages.push({ role: 'user', content: 'Additional context: ' + JSON.stringify(task.context) });
|
|
42
|
+
let iterationCount = 0;
|
|
43
|
+
const maxIterations = 5;
|
|
44
|
+
while (iterationCount < maxIterations) {
|
|
45
|
+
iterationCount++;
|
|
46
|
+
const response = await this.config.llmClient.chat(messages);
|
|
47
|
+
const capabilityCall = this.extractCapabilityCall(response.content);
|
|
48
|
+
if (capabilityCall && this.config.extensionRegistry) {
|
|
49
|
+
const registeredCap = this.config.extensionRegistry.getCapability(capabilityCall.name);
|
|
50
|
+
if (registeredCap && registeredCap.capability && registeredCap.capability.handler) {
|
|
51
|
+
try {
|
|
52
|
+
const result = await registeredCap.capability.handler(capabilityCall.input);
|
|
53
|
+
messages.push({ role: 'assistant', content: response.content });
|
|
54
|
+
messages.push({ role: 'system', content: 'Capability result: ' + JSON.stringify(result) });
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
messages.push({ role: 'assistant', content: response.content });
|
|
59
|
+
messages.push({ role: 'system', content: 'Capability failed: ' + error.message });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
114
62
|
}
|
|
115
63
|
}
|
|
116
|
-
|
|
117
|
-
|
|
64
|
+
const commands = this.extractCommands(response.content);
|
|
65
|
+
if (commands.length > 0 && this.config.executor) {
|
|
66
|
+
return response.content;
|
|
118
67
|
}
|
|
68
|
+
return response.content;
|
|
119
69
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
70
|
+
const lastResponse = await this.config.llmClient.chat(messages);
|
|
71
|
+
return lastResponse.content;
|
|
72
|
+
}
|
|
73
|
+
buildSystemPrompt() {
|
|
74
|
+
let prompt = this.config.systemPrompt;
|
|
75
|
+
if (this.config.extensionRegistry) {
|
|
76
|
+
const capabilities = this.config.extensionRegistry.getCapabilityNames();
|
|
77
|
+
if (capabilities.length > 0) {
|
|
78
|
+
prompt = prompt + '\n\nAvailable Capabilities:\n' + capabilities.map(function (c) { return '- ' + c; }).join('\n');
|
|
79
|
+
prompt = prompt + '\n\nTo use a capability, respond with:\n```capability\n{\n "name": "capability_name",\n "input": {...}\n}\n```';
|
|
80
|
+
}
|
|
128
81
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
});
|
|
139
|
-
if (result.exitCode !== 0) {
|
|
140
|
-
// Feed error back to LLM
|
|
141
|
-
messages.push({ role: 'assistant', content: response.content });
|
|
142
|
-
messages.push({
|
|
143
|
-
role: 'user',
|
|
144
|
-
content: `Command failed with exit code ${result.exitCode}:\n${result.stderr}`,
|
|
145
|
-
});
|
|
146
|
-
const retryResponse = await this.config.llmClient.chat(messages);
|
|
147
|
-
return retryResponse.content;
|
|
82
|
+
return prompt;
|
|
83
|
+
}
|
|
84
|
+
extractCapabilityCall(content) {
|
|
85
|
+
const match = /```capability\s*\n([\s\S]*?)\n\s*```/.exec(content);
|
|
86
|
+
if (match && match[1]) {
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(match[1].trim());
|
|
89
|
+
if (parsed.name && typeof parsed.name === 'string') {
|
|
90
|
+
return { name: parsed.name, input: parsed.input || {} };
|
|
148
91
|
}
|
|
149
|
-
// Feed output back to LLM
|
|
150
|
-
messages.push({ role: 'assistant', content: response.content });
|
|
151
|
-
messages.push({
|
|
152
|
-
role: 'user',
|
|
153
|
-
content: `Command output:\n${result.stdout}`,
|
|
154
|
-
});
|
|
155
92
|
}
|
|
156
|
-
|
|
157
|
-
return finalResponse.content;
|
|
93
|
+
catch (e) { }
|
|
158
94
|
}
|
|
159
|
-
return
|
|
95
|
+
return null;
|
|
160
96
|
}
|
|
161
|
-
/**
|
|
162
|
-
* Extract shell commands from LLM response.
|
|
163
|
-
*
|
|
164
|
-
* Looks for commands in code blocks marked as shell/bash.
|
|
165
|
-
*/
|
|
166
97
|
extractCommands(content) {
|
|
167
98
|
const commands = [];
|
|
168
|
-
|
|
169
|
-
const shellBlockRegex = /```(?:shell|bash|sh)\n([\s\S]*?)```/g;
|
|
99
|
+
const regex = /```(?:shell|bash|sh)\n([\s\S]*?)```/g;
|
|
170
100
|
let match;
|
|
171
|
-
while ((match =
|
|
172
|
-
const cmd = match[1]
|
|
173
|
-
if (cmd && !cmd.startsWith('#'))
|
|
101
|
+
while ((match = regex.exec(content)) !== null) {
|
|
102
|
+
const cmd = match[1] && match[1].trim();
|
|
103
|
+
if (cmd && !cmd.startsWith('#'))
|
|
174
104
|
commands.push(cmd);
|
|
175
|
-
}
|
|
176
105
|
}
|
|
177
106
|
return commands;
|
|
178
107
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Log message if verbose mode is enabled.
|
|
181
|
-
*/
|
|
182
108
|
log(message) {
|
|
183
|
-
if (this.config.verbose)
|
|
184
|
-
console.log(
|
|
185
|
-
}
|
|
109
|
+
if (this.config.verbose)
|
|
110
|
+
console.log('[TaskExecutor] ' + message);
|
|
186
111
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Sleep for specified milliseconds.
|
|
189
|
-
*/
|
|
190
112
|
sleep(ms) {
|
|
191
|
-
return new Promise((resolve)
|
|
113
|
+
return new Promise(function (resolve) { setTimeout(resolve, ms); });
|
|
192
114
|
}
|
|
193
115
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Create a new task executor instance.
|
|
196
|
-
*
|
|
197
|
-
* @param config - Configuration options
|
|
198
|
-
* @returns New TaskExecutor instance
|
|
199
|
-
*/
|
|
200
116
|
export function createTaskExecutor(config) {
|
|
201
117
|
return new TaskExecutor(config);
|
|
202
118
|
}
|