@ai.ntellect/core 0.4.1 → 0.5.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/README.FR.md +569 -18
- package/agent/index.ts +54 -147
- package/agent/workflow/conditions.ts +16 -0
- package/agent/workflow/handlers/interpreter.handler.ts +48 -0
- package/agent/workflow/handlers/memory.handler.ts +106 -0
- package/agent/workflow/handlers/orchestrator.handler.ts +23 -0
- package/agent/workflow/handlers/queue.handler.ts +34 -0
- package/agent/workflow/handlers/scheduler.handler.ts +61 -0
- package/agent/workflow/index.ts +62 -0
- package/{agent/tools → examples/actions}/get-rss.ts +8 -1
- package/examples/index.ts +10 -15
- package/index.html +42 -0
- package/llm/dynamic-condition/example.ts +36 -0
- package/llm/dynamic-condition/index.ts +108 -0
- package/llm/interpreter/context.ts +5 -12
- package/llm/interpreter/index.ts +20 -16
- package/llm/memory-manager/context.ts +4 -6
- package/llm/memory-manager/index.ts +32 -80
- package/llm/orchestrator/context.ts +5 -8
- package/llm/orchestrator/index.ts +62 -102
- package/llm/orchestrator/types.ts +2 -2
- package/package.json +3 -1
- package/script.js +167 -0
- package/services/{scheduler.ts → agenda.ts} +20 -35
- package/services/cache.ts +298 -0
- package/services/queue.ts +3 -3
- package/services/workflow.ts +491 -0
- package/t.ts +21 -129
- package/tsconfig.json +2 -1
- package/types.ts +91 -12
- package/utils/generate-object.ts +24 -12
- package/utils/inject-actions.ts +3 -3
- package/utils/state-manager.ts +25 -0
- package/bull.ts +0 -5
- package/services/redis-cache.ts +0 -128
- package/t.spec +0 -38
@@ -1,30 +1,17 @@
|
|
1
|
-
import { LanguageModelV1 } from "ai";
|
1
|
+
import { generateObject, LanguageModelV1 } from "ai";
|
2
2
|
import { z } from "zod";
|
3
3
|
import { CacheMemory } from "../../memory/cache";
|
4
4
|
import { PersistentMemory } from "../../memory/persistent";
|
5
|
-
import {
|
6
|
-
import { CacheConfig, RedisCache } from "../../services/redis-cache";
|
7
|
-
import { TaskScheduler } from "../../services/scheduler";
|
8
|
-
import {
|
9
|
-
ActionSchema,
|
10
|
-
GenerateObjectResponse,
|
11
|
-
MemoryScope,
|
12
|
-
QueueCallbacks,
|
13
|
-
} from "../../types";
|
14
|
-
import { generateObject } from "../../utils/generate-object";
|
5
|
+
import { ActionSchema, MemoryScope, MyContext, SharedState } from "../../types";
|
15
6
|
import { LLMHeaderBuilder } from "../../utils/header-builder";
|
16
7
|
import { injectActions } from "../../utils/inject-actions";
|
17
8
|
import { Interpreter } from "../interpreter";
|
18
9
|
import { orchestratorInstructions } from "./context";
|
19
|
-
import { State } from "./types";
|
20
10
|
|
21
|
-
export class
|
11
|
+
export class Orchestrator {
|
22
12
|
private readonly model: LanguageModelV1;
|
23
13
|
private readonly tools: ActionSchema[];
|
24
14
|
private readonly interpreters: Interpreter[];
|
25
|
-
private readonly queueManager: ActionQueueManager;
|
26
|
-
private readonly scheduler: TaskScheduler;
|
27
|
-
private readonly cache: RedisCache;
|
28
15
|
private memory?: {
|
29
16
|
persistent?: PersistentMemory;
|
30
17
|
cache?: CacheMemory;
|
@@ -34,23 +21,18 @@ export class AgentRuntime {
|
|
34
21
|
model: LanguageModelV1,
|
35
22
|
tools: ActionSchema[],
|
36
23
|
interpreters: Interpreter[],
|
37
|
-
redisConfig: CacheConfig,
|
38
24
|
memory?: {
|
39
25
|
persistent?: PersistentMemory;
|
40
26
|
cache?: CacheMemory;
|
41
|
-
}
|
42
|
-
callbacks?: QueueCallbacks
|
27
|
+
}
|
43
28
|
) {
|
44
29
|
this.model = model;
|
45
30
|
this.tools = tools;
|
46
31
|
this.interpreters = interpreters;
|
47
|
-
this.queueManager = new ActionQueueManager(tools, callbacks);
|
48
32
|
this.memory = memory;
|
49
|
-
this.cache = new RedisCache(redisConfig);
|
50
|
-
this.scheduler = new TaskScheduler(this, this.cache);
|
51
33
|
}
|
52
34
|
|
53
|
-
private async buildContext(state:
|
35
|
+
private async buildContext(state: SharedState<MyContext>): Promise<string> {
|
54
36
|
console.log("🧠 Building context with RAG and CAG...");
|
55
37
|
const context = LLMHeaderBuilder.create();
|
56
38
|
|
@@ -65,18 +47,10 @@ export class AgentRuntime {
|
|
65
47
|
// Add tools to context
|
66
48
|
context.addHeader("TOOLS", injectActions(this.tools));
|
67
49
|
|
68
|
-
// Add previous actions if any
|
69
|
-
if (state.previousActions?.length) {
|
70
|
-
context.addHeader(
|
71
|
-
"PREVIOUS_ACTIONS",
|
72
|
-
JSON.stringify(state.previousActions)
|
73
|
-
);
|
74
|
-
}
|
75
|
-
|
76
50
|
// Get recent similar actions (CAG)
|
77
|
-
if (this.memory?.cache) {
|
51
|
+
if (this.memory?.cache && state.messages) {
|
78
52
|
const cacheMemories = await this.memory.cache.findSimilarActions(
|
79
|
-
state.
|
53
|
+
state.messages[state.messages.length - 1].content.toString(),
|
80
54
|
{
|
81
55
|
similarityThreshold: 80,
|
82
56
|
maxResults: 3,
|
@@ -90,10 +64,10 @@ export class AgentRuntime {
|
|
90
64
|
}
|
91
65
|
|
92
66
|
// Get relevant knowledge (RAG)
|
93
|
-
if (this.memory?.persistent) {
|
67
|
+
if (this.memory?.persistent && state.messages) {
|
94
68
|
const persistentMemory =
|
95
69
|
await this.memory.persistent.findRelevantDocuments(
|
96
|
-
state.
|
70
|
+
state.messages[state.messages.length - 1].content.toString(),
|
97
71
|
{
|
98
72
|
similarityThreshold: 80,
|
99
73
|
}
|
@@ -109,15 +83,25 @@ export class AgentRuntime {
|
|
109
83
|
|
110
84
|
// Add available interpreters
|
111
85
|
context.addHeader(
|
112
|
-
"
|
86
|
+
"INTERPRETERS (choose one)",
|
113
87
|
JSON.stringify(this.interpreters.map((i) => i.name))
|
88
|
+
.replace("[", "")
|
89
|
+
.replace("]", "")
|
114
90
|
);
|
115
|
-
console.log("Context built with memories", context.toString());
|
116
91
|
return context.toString();
|
117
92
|
}
|
118
93
|
|
119
|
-
async process(
|
120
|
-
|
94
|
+
async process(
|
95
|
+
state: SharedState<MyContext>,
|
96
|
+
callbacks?: {
|
97
|
+
onStart?: () => void;
|
98
|
+
onFinish?: (event: any) => void;
|
99
|
+
}
|
100
|
+
): Promise<{
|
101
|
+
processing: {
|
102
|
+
stop: boolean;
|
103
|
+
stopReason?: string;
|
104
|
+
};
|
121
105
|
actions: Array<{
|
122
106
|
name: string;
|
123
107
|
parameters: Array<{
|
@@ -126,37 +110,40 @@ export class AgentRuntime {
|
|
126
110
|
}>;
|
127
111
|
scheduler?: {
|
128
112
|
isScheduled: boolean;
|
129
|
-
|
130
|
-
interval?: string;
|
113
|
+
cronExpression?: string;
|
131
114
|
reason?: string;
|
132
115
|
};
|
133
116
|
}>;
|
134
|
-
|
135
|
-
|
136
|
-
response?: string;
|
137
|
-
isPartialResponse?: boolean;
|
138
|
-
};
|
139
|
-
interpreter?: string;
|
117
|
+
response: string;
|
118
|
+
interpreter?: string | null;
|
140
119
|
results?: string;
|
141
120
|
}> {
|
142
|
-
|
143
|
-
console.dir(state, { depth: null });
|
144
|
-
if (state.previousActions?.length) {
|
145
|
-
console.log(
|
146
|
-
"📊 Previous actions:",
|
147
|
-
state.previousActions
|
148
|
-
.map((a) => (typeof a === "string" ? a : a.name))
|
149
|
-
.join(", ")
|
150
|
-
);
|
151
|
-
}
|
121
|
+
if (callbacks?.onStart) callbacks.onStart();
|
152
122
|
|
153
123
|
const context = await this.buildContext(state);
|
124
|
+
let prompt = LLMHeaderBuilder.create();
|
125
|
+
if (state.messages) {
|
126
|
+
prompt.addHeader(
|
127
|
+
"REQUEST",
|
128
|
+
state.messages[state.messages.length - 1].content.toString()
|
129
|
+
);
|
130
|
+
|
131
|
+
if (state.messages.length > 1) {
|
132
|
+
prompt.addHeader("RECENT_MESSAGES", JSON.stringify(state.messages));
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if (state.context.results) {
|
136
|
+
prompt.addHeader("ACTIONS_DONE", JSON.stringify(state.context.results));
|
137
|
+
}
|
154
138
|
|
155
|
-
console.log("\n🧠 Generating response from
|
156
|
-
const response = await generateObject
|
139
|
+
console.log("\n🧠 Generating response from Orchestrator...");
|
140
|
+
const response = await generateObject({
|
157
141
|
model: this.model,
|
158
142
|
schema: z.object({
|
159
|
-
|
143
|
+
processing: z.object({
|
144
|
+
stop: z.boolean(),
|
145
|
+
reason: z.string(),
|
146
|
+
}),
|
160
147
|
actions: z.array(
|
161
148
|
z.object({
|
162
149
|
name: z.string(),
|
@@ -166,67 +153,40 @@ export class AgentRuntime {
|
|
166
153
|
value: z.any(),
|
167
154
|
})
|
168
155
|
),
|
169
|
-
scheduler: z
|
170
|
-
.
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
})
|
175
|
-
.optional(),
|
156
|
+
scheduler: z.object({
|
157
|
+
isScheduled: z.boolean(),
|
158
|
+
cronExpression: z.string(),
|
159
|
+
reason: z.string(),
|
160
|
+
}),
|
176
161
|
})
|
177
162
|
),
|
178
|
-
|
179
|
-
|
180
|
-
shouldRespond: z.boolean(),
|
181
|
-
response: z.string().optional(),
|
182
|
-
isPartialResponse: z.boolean().optional(),
|
183
|
-
})
|
184
|
-
.optional(),
|
185
|
-
interpreter: z.string().optional(),
|
163
|
+
response: z.string(),
|
164
|
+
interpreter: z.string().or(z.null()),
|
186
165
|
}),
|
187
|
-
prompt: state.currentContext,
|
188
166
|
system: context.toString(),
|
189
167
|
temperature: 0,
|
168
|
+
prompt: prompt.toString(),
|
190
169
|
});
|
191
170
|
console.log("🔄 Orchestrator response:");
|
192
171
|
console.dir(response.object, { depth: null });
|
193
172
|
|
194
173
|
// Force shouldContinue to false if no actions are planned
|
195
174
|
if (response.object.actions.length === 0) {
|
196
|
-
response.object.
|
197
|
-
console.log("⚠️ No actions planned, forcing
|
175
|
+
response.object.processing.stop = true;
|
176
|
+
console.log("⚠️ No actions planned, forcing isProcessing to false");
|
198
177
|
}
|
199
178
|
|
200
179
|
// Handle social interactions and actions in a single block
|
201
|
-
if (response.object.
|
180
|
+
if (response.object.response) {
|
202
181
|
console.log("\n💬 Processing social response");
|
203
|
-
if (response.object.
|
204
|
-
console.log("📢 Response:", response.object.
|
182
|
+
if (response.object.response) {
|
183
|
+
console.log("📢 Response:", response.object.response);
|
205
184
|
// Ensure all parameters have a value property
|
206
185
|
}
|
207
186
|
}
|
208
187
|
|
209
|
-
|
210
|
-
for (const action of response.object.actions) {
|
211
|
-
if (action.scheduler?.isScheduled) {
|
212
|
-
await this.scheduler.scheduleRequest({
|
213
|
-
originalRequest: state.currentContext,
|
214
|
-
cronExpression: action.scheduler.cronExpression,
|
215
|
-
});
|
216
|
-
}
|
217
|
-
}
|
218
|
-
|
219
|
-
// Store actions in Redis cache
|
220
|
-
if (response.object.actions.length > 0) {
|
221
|
-
const requestId = crypto.randomUUID();
|
222
|
-
await this.cache.storePreviousActions(requestId, response.object.actions);
|
223
|
-
}
|
224
|
-
|
225
|
-
// Store message in recent messages
|
226
|
-
await this.cache.storeRecentMessage(state.currentContext, {
|
227
|
-
socialResponse: response.object.socialResponse,
|
228
|
-
});
|
188
|
+
if (callbacks?.onFinish) callbacks.onFinish(response.object);
|
229
189
|
|
230
|
-
return response.object;
|
190
|
+
return response.object as any;
|
231
191
|
}
|
232
192
|
}
|
@@ -1,11 +1,11 @@
|
|
1
|
+
import { CoreMessage } from "ai";
|
1
2
|
import { QueueResult } from "../../types";
|
2
3
|
|
3
4
|
export interface State {
|
4
5
|
currentContext: string;
|
5
6
|
previousActions: (string | QueueResult)[];
|
6
|
-
reward?: number;
|
7
|
-
userRequest?: string;
|
8
7
|
results?: string;
|
8
|
+
recentMessages: CoreMessage[];
|
9
9
|
}
|
10
10
|
|
11
11
|
export interface Action {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ai.ntellect/core",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -16,7 +16,9 @@
|
|
16
16
|
"@ai-sdk/openai": "1.0.6",
|
17
17
|
"@types/node-cron": "^3.0.11",
|
18
18
|
"ai": "^3.0.0",
|
19
|
+
"chalk": "^5.4.1",
|
19
20
|
"ethers": "^6.13.5",
|
21
|
+
"ioredis": "^5.4.2",
|
20
22
|
"langchain": "^0.3.11",
|
21
23
|
"node-cron": "^3.0.3",
|
22
24
|
"readline": "^1.3.0",
|
package/script.js
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
// Dimensions de l'espace SVG
|
2
|
+
const width = 800;
|
3
|
+
const height = 600;
|
4
|
+
|
5
|
+
// Exemple de données pour les nœuds et les arêtes
|
6
|
+
const nodes = [
|
7
|
+
{ id: "fetchData", name: "Fetch Data", group: 1, selected: false },
|
8
|
+
{ id: "analyzeData", name: "Analyze Data", group: 1, selected: false },
|
9
|
+
{ id: "sendAlert", name: "Send Alert", group: 1, selected: false },
|
10
|
+
];
|
11
|
+
|
12
|
+
const links = [
|
13
|
+
{ source: "fetchData", target: "analyzeData" },
|
14
|
+
{ source: "analyzeData", target: "sendAlert" },
|
15
|
+
];
|
16
|
+
|
17
|
+
// Simulation de force
|
18
|
+
const simulation = d3
|
19
|
+
.forceSimulation(nodes)
|
20
|
+
.force(
|
21
|
+
"link",
|
22
|
+
d3.forceLink(links).id((d) => d.id)
|
23
|
+
)
|
24
|
+
.force("charge", d3.forceManyBody().strength(-300))
|
25
|
+
.force("center", d3.forceCenter(width / 2, height / 2));
|
26
|
+
|
27
|
+
// Créer le conteneur SVG
|
28
|
+
const svg = d3.select("#graph").attr("width", width).attr("height", height);
|
29
|
+
|
30
|
+
// Groupes pour liens et nœuds
|
31
|
+
const linkGroup = svg
|
32
|
+
.append("g")
|
33
|
+
.attr("class", "links")
|
34
|
+
.attr("stroke", "#999")
|
35
|
+
.attr("stroke-opacity", 0.6);
|
36
|
+
|
37
|
+
const nodeGroup = svg.append("g").attr("class", "nodes");
|
38
|
+
|
39
|
+
// Fonction pour mettre à jour le graphe
|
40
|
+
function updateGraph() {
|
41
|
+
// Mettre à jour les liens
|
42
|
+
const link = linkGroup.selectAll("line").data(links);
|
43
|
+
|
44
|
+
link
|
45
|
+
.enter()
|
46
|
+
.append("line")
|
47
|
+
.attr("stroke-width", 2)
|
48
|
+
.merge(link)
|
49
|
+
.attr("x1", (d) => d.source.x)
|
50
|
+
.attr("y1", (d) => d.source.y)
|
51
|
+
.attr("x2", (d) => d.target.x)
|
52
|
+
.attr("y2", (d) => d.target.y);
|
53
|
+
|
54
|
+
link.exit().remove();
|
55
|
+
|
56
|
+
// Mettre à jour les nœuds
|
57
|
+
const node = nodeGroup.selectAll("circle").data(nodes, (d) => d.id);
|
58
|
+
|
59
|
+
node.exit().remove();
|
60
|
+
|
61
|
+
const nodeEnter = node
|
62
|
+
.enter()
|
63
|
+
.append("circle")
|
64
|
+
.attr("r", 20)
|
65
|
+
.attr("fill", (d) => (d.selected ? "orange" : "#69b3a2"))
|
66
|
+
.attr("stroke", "#fff")
|
67
|
+
.attr("stroke-width", 1.5)
|
68
|
+
.call(
|
69
|
+
d3
|
70
|
+
.drag()
|
71
|
+
.on("start", dragstarted)
|
72
|
+
.on("drag", dragged)
|
73
|
+
.on("end", dragended)
|
74
|
+
)
|
75
|
+
.on("click", nodeClicked);
|
76
|
+
|
77
|
+
nodeEnter
|
78
|
+
.merge(node)
|
79
|
+
.attr("cx", (d) => d.x)
|
80
|
+
.attr("cy", (d) => d.y)
|
81
|
+
.attr("fill", (d) => (d.selected ? "orange" : "#69b3a2"));
|
82
|
+
|
83
|
+
// Ajouter des labels
|
84
|
+
const label = nodeGroup.selectAll("text").data(nodes);
|
85
|
+
|
86
|
+
label.exit().remove();
|
87
|
+
|
88
|
+
label
|
89
|
+
.enter()
|
90
|
+
.append("text")
|
91
|
+
.attr("dy", 4)
|
92
|
+
.attr("dx", 25)
|
93
|
+
.merge(label)
|
94
|
+
.attr("x", (d) => d.x)
|
95
|
+
.attr("y", (d) => d.y)
|
96
|
+
.text((d) => d.name);
|
97
|
+
|
98
|
+
simulation.on("tick", () => {
|
99
|
+
link
|
100
|
+
.attr("x1", (d) => d.source.x)
|
101
|
+
.attr("y1", (d) => d.source.y)
|
102
|
+
.attr("x2", (d) => d.target.x)
|
103
|
+
.attr("y2", (d) => d.target.y);
|
104
|
+
|
105
|
+
node.attr("cx", (d) => d.x).attr("cy", (d) => d.y);
|
106
|
+
|
107
|
+
label.attr("x", (d) => d.x + 25).attr("y", (d) => d.y);
|
108
|
+
});
|
109
|
+
|
110
|
+
updateWorkflowOrder();
|
111
|
+
}
|
112
|
+
|
113
|
+
// Fonction pour mettre à jour l'ordre du workflow
|
114
|
+
function updateWorkflowOrder() {
|
115
|
+
const selectedNodes = nodes.filter((node) => node.selected);
|
116
|
+
if (selectedNodes.length > 0) {
|
117
|
+
workflowOrder = selectedNodes.map((node) => node.name);
|
118
|
+
} else {
|
119
|
+
const startNode = nodes.find(
|
120
|
+
(node) => !links.some((link) => link.target === node.id)
|
121
|
+
);
|
122
|
+
|
123
|
+
if (!startNode) {
|
124
|
+
workflowOrder = [];
|
125
|
+
console.log("Workflow Order: []");
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
workflowOrder = [];
|
130
|
+
let currentNode = startNode;
|
131
|
+
while (currentNode) {
|
132
|
+
workflowOrder.push(currentNode.name);
|
133
|
+
const nextLink = links.find((link) => link.source === currentNode.id);
|
134
|
+
currentNode = nextLink
|
135
|
+
? nodes.find((node) => node.id === nextLink.target)
|
136
|
+
: null;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
console.log("Workflow Order:", workflowOrder);
|
140
|
+
}
|
141
|
+
|
142
|
+
// Gestion de la sélection multiple
|
143
|
+
function nodeClicked(event, node) {
|
144
|
+
node.selected = !node.selected;
|
145
|
+
updateGraph();
|
146
|
+
}
|
147
|
+
|
148
|
+
// Gestion du drag & drop
|
149
|
+
function dragstarted(event, d) {
|
150
|
+
if (!event.active) simulation.alphaTarget(0.3).restart();
|
151
|
+
d.fx = d.x;
|
152
|
+
d.fy = d.y;
|
153
|
+
}
|
154
|
+
|
155
|
+
function dragged(event, d) {
|
156
|
+
d.fx = event.x;
|
157
|
+
d.fy = event.y;
|
158
|
+
}
|
159
|
+
|
160
|
+
function dragended(event, d) {
|
161
|
+
if (!event.active) simulation.alphaTarget(0);
|
162
|
+
d.fx = null;
|
163
|
+
d.fy = null;
|
164
|
+
}
|
165
|
+
|
166
|
+
// Initialisation
|
167
|
+
updateGraph();
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import cron from "node-cron";
|
2
|
-
import {
|
3
|
-
import { RedisCache } from "./
|
2
|
+
import { Orchestrator } from "../llm/orchestrator";
|
3
|
+
import { RedisCache } from "./cache";
|
4
4
|
|
5
5
|
interface ScheduledRequest {
|
6
6
|
id: string;
|
@@ -10,24 +10,30 @@ interface ScheduledRequest {
|
|
10
10
|
createdAt: Date;
|
11
11
|
}
|
12
12
|
|
13
|
-
export class
|
13
|
+
export class Agenda {
|
14
14
|
private scheduledRequests: Map<string, ScheduledRequest> = new Map();
|
15
15
|
private cronJobs: Map<string, cron.ScheduledTask> = new Map();
|
16
|
-
private readonly
|
16
|
+
private readonly orchestrator: Orchestrator;
|
17
17
|
private readonly cache: RedisCache;
|
18
18
|
|
19
|
-
constructor(
|
20
|
-
this.
|
19
|
+
constructor(orchestrator: Orchestrator, cache: RedisCache) {
|
20
|
+
this.orchestrator = orchestrator;
|
21
21
|
this.cache = cache;
|
22
22
|
}
|
23
23
|
|
24
24
|
/**
|
25
25
|
* Schedule a new request to be processed later
|
26
26
|
*/
|
27
|
-
async scheduleRequest(
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
async scheduleRequest(
|
28
|
+
request: {
|
29
|
+
originalRequest: string;
|
30
|
+
cronExpression: string;
|
31
|
+
},
|
32
|
+
callbacks?: {
|
33
|
+
onScheduled?: (id: string) => void;
|
34
|
+
onExecuted?: (id: string, originalRequest: string) => void;
|
35
|
+
}
|
36
|
+
): Promise<string> {
|
31
37
|
const id = crypto.randomUUID();
|
32
38
|
|
33
39
|
const scheduledRequest: ScheduledRequest = {
|
@@ -42,6 +48,9 @@ export class TaskScheduler {
|
|
42
48
|
const cronJob = cron.schedule(request.cronExpression, async () => {
|
43
49
|
await this.executeScheduledRequest(scheduledRequest);
|
44
50
|
|
51
|
+
if (callbacks?.onExecuted)
|
52
|
+
callbacks.onExecuted(id, scheduledRequest.originalRequest);
|
53
|
+
|
45
54
|
if (!scheduledRequest.isRecurring) {
|
46
55
|
this.cancelScheduledRequest(id);
|
47
56
|
}
|
@@ -51,9 +60,7 @@ export class TaskScheduler {
|
|
51
60
|
this.scheduledRequests.set(id, scheduledRequest);
|
52
61
|
this.cronJobs.set(id, cronJob);
|
53
62
|
|
54
|
-
|
55
|
-
`✅ Request scheduled with cron expression: ${request.cronExpression}`
|
56
|
-
);
|
63
|
+
if (callbacks?.onScheduled) callbacks.onScheduled(id);
|
57
64
|
|
58
65
|
return id;
|
59
66
|
}
|
@@ -67,28 +74,6 @@ export class TaskScheduler {
|
|
67
74
|
try {
|
68
75
|
console.log(`🔄 Executing scheduled request from ${request.createdAt}`);
|
69
76
|
|
70
|
-
// Récupérer les actions précédentes du cache
|
71
|
-
const previousActions = await this.cache.getPreviousActions(request.id);
|
72
|
-
|
73
|
-
// Add context about when this request was scheduled
|
74
|
-
const contextualRequest = `You are a scheduler.
|
75
|
-
You were asked to execute this request: ${request.originalRequest}\n
|
76
|
-
Date of the request: ${request.createdAt.toISOString()}\n
|
77
|
-
Act like if you know the request was scheduled.
|
78
|
-
Don't reschedule the same action.
|
79
|
-
Just execute it.`;
|
80
|
-
|
81
|
-
// Process the request as if it was just received
|
82
|
-
const result = await this.agentRuntime.process({
|
83
|
-
currentContext: contextualRequest,
|
84
|
-
previousActions,
|
85
|
-
});
|
86
|
-
|
87
|
-
// Store the new actions in cache
|
88
|
-
if (result.actions.length > 0) {
|
89
|
-
await this.cache.storePreviousActions(request.id, result.actions);
|
90
|
-
}
|
91
|
-
|
92
77
|
console.log(`✅ Scheduled request executed successfully`);
|
93
78
|
} catch (error) {
|
94
79
|
console.error(`❌ Failed to execute scheduled request:`, error);
|