@minded-ai/mindedjs 1.0.80-beta.8 → 1.0.80
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/agent.d.ts +5 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +81 -53
- package/dist/agent.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/edges/createLogicalRouter.d.ts +1 -1
- package/dist/edges/createLogicalRouter.d.ts.map +1 -1
- package/dist/edges/createLogicalRouter.js +5 -16
- package/dist/edges/createLogicalRouter.js.map +1 -1
- package/dist/edges/edgeFactory.d.ts.map +1 -1
- package/dist/edges/edgeFactory.js +2 -4
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/events/AgentEvents.d.ts +12 -8
- package/dist/events/AgentEvents.d.ts.map +1 -1
- package/dist/events/AgentEvents.js +1 -0
- package/dist/events/AgentEvents.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/nodes/addAppToolNode.d.ts.map +1 -1
- package/dist/nodes/addAppToolNode.js +9 -1
- package/dist/nodes/addAppToolNode.js.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +3 -2
- package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
- package/dist/nodes/addJumpToNode.d.ts +1 -1
- package/dist/nodes/addJumpToNode.d.ts.map +1 -1
- package/dist/nodes/addJumpToNode.js +2 -2
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +10 -1
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.js +1 -1
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +2 -1
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/nodes/addTriggerNode.js +1 -1
- package/dist/nodes/addTriggerNode.js.map +1 -1
- package/dist/types/Agent.types.d.ts +25 -13
- package/dist/types/Agent.types.d.ts.map +1 -1
- package/dist/types/Agent.types.js +9 -7
- package/dist/types/Agent.types.js.map +1 -1
- package/dist/types/Flows.types.d.ts +5 -1
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js +6 -1
- package/dist/types/Flows.types.js.map +1 -1
- package/dist/types/LangGraph.types.d.ts +3 -45
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +0 -5
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/utils/history.d.ts +3 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js +12 -0
- package/dist/utils/history.js.map +1 -0
- package/package.json +5 -8
- package/src/agent.ts +112 -60
- package/src/edges/createLogicalRouter.ts +5 -18
- package/src/edges/edgeFactory.ts +2 -4
- package/src/events/AgentEvents.ts +11 -8
- package/src/index.ts +8 -1
- package/src/nodes/addAppToolNode.ts +10 -2
- package/src/nodes/addHumanInTheLoopNode.ts +3 -2
- package/src/nodes/addJumpToNode.ts +3 -9
- package/src/nodes/addPromptNode.ts +10 -2
- package/src/nodes/addToolNode.ts +1 -1
- package/src/nodes/addToolRunNode.ts +2 -2
- package/src/nodes/addTriggerNode.ts +1 -1
- package/src/types/Agent.types.ts +28 -14
- package/src/types/Flows.types.ts +6 -1
- package/src/types/LangGraph.types.ts +2 -10
- package/src/utils/history.ts +9 -0
- package/dist/guidelines/guidelinesManager.d.ts +0 -37
- package/dist/guidelines/guidelinesManager.d.ts.map +0 -1
- package/dist/guidelines/guidelinesManager.js +0 -172
- package/dist/guidelines/guidelinesManager.js.map +0 -1
- package/dist/utils/extractToolMemoryResponse.d.ts +0 -4
- package/dist/utils/extractToolMemoryResponse.d.ts.map +0 -1
- package/dist/utils/extractToolMemoryResponse.js +0 -16
- package/dist/utils/extractToolMemoryResponse.js.map +0 -1
package/src/agent.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Flow, NodeType, Node, EdgeType, KnownTriggerNames, TriggerType, VoiceTriggerNode } from './types/Flows.types';
|
|
1
|
+
import { Flow, NodeType, Node, EdgeType, KnownTriggerNames, TriggerType, VoiceTriggerNode, internalNodesSuffix } from './types/Flows.types';
|
|
2
2
|
|
|
3
3
|
import { Tool } from './types/Tools.types';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
@@ -15,7 +15,15 @@ import { InvokeMessage, MindedConnectionSocketMessageType } from './platform/min
|
|
|
15
15
|
import * as fs from 'fs';
|
|
16
16
|
import * as path from 'path';
|
|
17
17
|
import * as yaml from 'js-yaml';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
AgentInvokeParams,
|
|
20
|
+
AppTrigggerHistoryStep,
|
|
21
|
+
TriggerHistoryStep,
|
|
22
|
+
HistoryStepType,
|
|
23
|
+
MindedSDKConfig,
|
|
24
|
+
SessionType,
|
|
25
|
+
HistoryStep,
|
|
26
|
+
} from './types/Agent.types';
|
|
19
27
|
import { createLlmInstance } from './llm/createLlmInstance';
|
|
20
28
|
import { createCheckpointSaver } from './checkpointer/checkpointSaverFactory';
|
|
21
29
|
import { getConfig } from './platform/config';
|
|
@@ -27,6 +35,7 @@ import { BaseVoiceMessage, OnVoiceAudioOut } from './platform/mindedConnectionTy
|
|
|
27
35
|
import { PIIGateway, PIIGatewayInstance } from './platform/piiGateway';
|
|
28
36
|
import { logger } from './utils/logger';
|
|
29
37
|
import { loadPlaybooks, Playbook } from './playbooks/playbooks';
|
|
38
|
+
import { createHistoryStep } from './utils/history';
|
|
30
39
|
|
|
31
40
|
type CreateAgentParams<Memory> = {
|
|
32
41
|
memorySchema: z.ZodSchema;
|
|
@@ -58,7 +67,7 @@ export class Agent {
|
|
|
58
67
|
private memorySchema: z.ZodSchema;
|
|
59
68
|
private flows!: Flow[];
|
|
60
69
|
public tools!: Tool<any, any>[];
|
|
61
|
-
|
|
70
|
+
private llm!: BaseLanguageModel;
|
|
62
71
|
public mindedConnection: MindedConnection | null = null;
|
|
63
72
|
// Langgraph memory saver. In memory for local development, Custom for Platform
|
|
64
73
|
private checkpointer!: BaseCheckpointSaver;
|
|
@@ -89,6 +98,7 @@ export class Agent {
|
|
|
89
98
|
|
|
90
99
|
private initialized = false;
|
|
91
100
|
private initPromise: Promise<void> | null = null;
|
|
101
|
+
private startingNodeId: string | null = null;
|
|
92
102
|
public voiceSessions: Map<string, VoiceSession> = new Map();
|
|
93
103
|
|
|
94
104
|
/**
|
|
@@ -284,10 +294,12 @@ export class Agent {
|
|
|
284
294
|
// Add edge from start to first node if no triggers exist
|
|
285
295
|
const hasTrigger = nodes.some((node) => node.type === NodeType.TRIGGER && node.triggerType !== TriggerType.MANUAL);
|
|
286
296
|
if (!hasTrigger && nodes.length > 0) {
|
|
297
|
+
this.startingNodeId = nodes[0].name;
|
|
287
298
|
graph.addEdge('__start__', nodes[0].name as any);
|
|
288
299
|
} else {
|
|
289
300
|
nodes.forEach((node) => {
|
|
290
301
|
if (node.type === NodeType.TRIGGER && node.triggerType !== TriggerType.MANUAL) {
|
|
302
|
+
this.startingNodeId = node.name;
|
|
291
303
|
graph.addEdge('__start__', node.name as any);
|
|
292
304
|
}
|
|
293
305
|
});
|
|
@@ -322,7 +334,6 @@ export class Agent {
|
|
|
322
334
|
memory: initialMemory,
|
|
323
335
|
triggerMetadata: null,
|
|
324
336
|
history: [],
|
|
325
|
-
triggerInvocations: [] as Array<TriggerInvocationHistory>,
|
|
326
337
|
sessionId: state.sessionId || uuidv4(), // Preserve existing sessionId or generate new one
|
|
327
338
|
sessionType: state.sessionType || SessionType.TEXT,
|
|
328
339
|
};
|
|
@@ -335,6 +346,33 @@ export class Agent {
|
|
|
335
346
|
return initialState;
|
|
336
347
|
}
|
|
337
348
|
|
|
349
|
+
private createTriggerHistoryStep(
|
|
350
|
+
currentHistory: HistoryStep[],
|
|
351
|
+
nodeId: string,
|
|
352
|
+
messageIds: string[],
|
|
353
|
+
triggerName: string,
|
|
354
|
+
triggerBody: any,
|
|
355
|
+
appName?: string,
|
|
356
|
+
): HistoryStep {
|
|
357
|
+
const baseStep = {
|
|
358
|
+
nodeId: nodeId,
|
|
359
|
+
nodeDisplayName: triggerName,
|
|
360
|
+
raw: triggerBody,
|
|
361
|
+
messageIds,
|
|
362
|
+
} as HistoryStep;
|
|
363
|
+
|
|
364
|
+
return appName
|
|
365
|
+
? createHistoryStep<AppTrigggerHistoryStep>(currentHistory, {
|
|
366
|
+
...baseStep,
|
|
367
|
+
type: HistoryStepType.APP_TRIGGER_NODE,
|
|
368
|
+
appName,
|
|
369
|
+
})
|
|
370
|
+
: createHistoryStep<TriggerHistoryStep>(currentHistory, {
|
|
371
|
+
...baseStep,
|
|
372
|
+
type: HistoryStepType.TRIGGER_NODE,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
338
376
|
/**
|
|
339
377
|
* Invoke a trigger to start agent execution with the specified parameters.
|
|
340
378
|
*
|
|
@@ -364,69 +402,83 @@ export class Agent {
|
|
|
364
402
|
* ```
|
|
365
403
|
*/
|
|
366
404
|
public async invoke({ triggerBody, triggerName, sessionId, appName }: AgentInvokeParams) {
|
|
367
|
-
await this.waitForInitialization();
|
|
368
|
-
let messages: Array<BaseMessage> = [];
|
|
369
|
-
let memoryUpdate = {};
|
|
370
|
-
let sessionType: SessionType = SessionType.TEXT;
|
|
371
405
|
sessionId = sessionId ?? uuidv4();
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
triggerName,
|
|
381
|
-
triggerBody,
|
|
382
|
-
sessionId,
|
|
383
|
-
});
|
|
384
|
-
if (results.length === 0) {
|
|
385
|
-
if (appName) {
|
|
386
|
-
messages = triggerTypeToDefaultMessage[appName]?.[triggerName]?.(triggerBody) ?? [new HumanMessage(JSON.stringify(triggerBody))];
|
|
387
|
-
} else {
|
|
388
|
-
messages = [new HumanMessage(JSON.stringify(triggerBody))];
|
|
406
|
+
try {
|
|
407
|
+
await this.waitForInitialization();
|
|
408
|
+
let messages: Array<BaseMessage> = [];
|
|
409
|
+
let memoryUpdate = {};
|
|
410
|
+
let sessionType: SessionType = SessionType.TEXT;
|
|
411
|
+
if (triggerName === KnownTriggerNames.DASHBOARD_MESSAGE || triggerName === KnownTriggerNames.VOICE_MESSAGE) {
|
|
412
|
+
if (!triggerBody.content) {
|
|
413
|
+
throw new Error(`Trigger body content is required for ${JSON.stringify(triggerBody)}`);
|
|
389
414
|
}
|
|
415
|
+
messages = [new HumanMessage({ content: triggerBody.content, id: uuidv4() })];
|
|
416
|
+
sessionType = triggerName === KnownTriggerNames.VOICE_MESSAGE ? SessionType.VOICE : SessionType.TEXT;
|
|
390
417
|
} else {
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
418
|
+
const results = await this.emit(AgentEvents.TRIGGER_EVENT, {
|
|
419
|
+
triggerName,
|
|
420
|
+
triggerBody,
|
|
421
|
+
sessionId,
|
|
422
|
+
});
|
|
423
|
+
if (results.length === 0) {
|
|
424
|
+
if (appName) {
|
|
425
|
+
messages = triggerTypeToDefaultMessage[appName]?.[triggerName]?.(triggerBody) ?? [
|
|
426
|
+
new HumanMessage({ content: JSON.stringify(triggerBody), id: uuidv4() }),
|
|
427
|
+
];
|
|
428
|
+
} else {
|
|
429
|
+
messages = [new HumanMessage({ content: JSON.stringify(triggerBody), id: uuidv4() })];
|
|
430
|
+
}
|
|
431
|
+
} else {
|
|
432
|
+
const handlerResult = results.find((r) => r !== undefined);
|
|
433
|
+
if (handlerResult) {
|
|
434
|
+
if (!handlerResult.isQualified) {
|
|
435
|
+
logger.info(`Trigger ${triggerName} was disqualified`);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
memoryUpdate = handlerResult.memory || {};
|
|
439
|
+
messages = handlerResult.messages ?? [];
|
|
440
|
+
sessionId = handlerResult.sessionId ?? sessionId;
|
|
396
441
|
}
|
|
397
|
-
memoryUpdate = handlerResult.memory || {};
|
|
398
|
-
messages = handlerResult.messages ?? [];
|
|
399
|
-
sessionId = handlerResult.sessionId ?? sessionId;
|
|
400
442
|
}
|
|
401
443
|
}
|
|
402
|
-
}
|
|
403
444
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
res = await this.compiledGraph.invoke(
|
|
418
|
-
new Command({
|
|
419
|
-
resume: { memory: memoryUpdate, messages, history, triggerInvocations: [triggerInvocation], sessionId, sessionType },
|
|
420
|
-
}),
|
|
421
|
-
langraphConfig,
|
|
422
|
-
);
|
|
423
|
-
} else {
|
|
424
|
-
res = await this.compiledGraph.invoke(
|
|
425
|
-
{ messages, memory: memoryUpdate, history, triggerInvocations: [triggerInvocation], sessionId, sessionType },
|
|
426
|
-
langraphConfig,
|
|
445
|
+
logger.info(`Invoking trigger ${triggerName} with session ${sessionId}`);
|
|
446
|
+
const langraphConfig = this.getLangraphConfig(sessionId || uuidv4());
|
|
447
|
+
const state = await this.compiledGraph.getState(langraphConfig);
|
|
448
|
+
const suffixes = Object.values(internalNodesSuffix);
|
|
449
|
+
let nodeToBeInvoked = state.next.length > 0 ? state.next[0] : this.startingNodeId!;
|
|
450
|
+
nodeToBeInvoked = nodeToBeInvoked.replace(new RegExp(suffixes.join('|'), 'g'), '');
|
|
451
|
+
const historyStep = this.createTriggerHistoryStep(
|
|
452
|
+
state.values.history,
|
|
453
|
+
nodeToBeInvoked,
|
|
454
|
+
messages.map((m) => m.id!),
|
|
455
|
+
triggerName,
|
|
456
|
+
triggerBody,
|
|
457
|
+
appName,
|
|
427
458
|
);
|
|
459
|
+
|
|
460
|
+
let res;
|
|
461
|
+
// Resume interruption
|
|
462
|
+
if (state.tasks?.[0]?.interrupts?.length > 0) {
|
|
463
|
+
res = await this.compiledGraph.invoke(
|
|
464
|
+
new Command({
|
|
465
|
+
resume: { memory: memoryUpdate, messages, history: historyStep, sessionId, sessionType },
|
|
466
|
+
}),
|
|
467
|
+
langraphConfig,
|
|
468
|
+
);
|
|
469
|
+
} else {
|
|
470
|
+
res = await this.compiledGraph.invoke(
|
|
471
|
+
{ messages, memory: memoryUpdate, history: historyStep, sessionId, sessionType },
|
|
472
|
+
langraphConfig,
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
return res;
|
|
476
|
+
} catch (error) {
|
|
477
|
+
logger.error({ message: 'Invoke error', error, sessionId });
|
|
478
|
+
const state = await this.compiledGraph.getState(this.getLangraphConfig(sessionId));
|
|
479
|
+
this.emit(AgentEvents.ERROR, { error: error instanceof Error ? error : new Error(JSON.stringify(error)), state: state.values });
|
|
480
|
+
throw error;
|
|
428
481
|
}
|
|
429
|
-
return res;
|
|
430
482
|
}
|
|
431
483
|
|
|
432
484
|
/**
|
|
@@ -450,7 +502,7 @@ export class Agent {
|
|
|
450
502
|
* memory: Memory; // Initial memory state (from your schema defaults)
|
|
451
503
|
* triggerInvocations: Array<...>; // Empty array - no triggers invoked yet
|
|
452
504
|
* triggerMetadata: null; // No trigger metadata initially
|
|
453
|
-
* history:
|
|
505
|
+
* history: HistoryStep[]; // Empty array - no flow history yet
|
|
454
506
|
* sessionId: string; // Session identifier (generated or provided)
|
|
455
507
|
* sessionType: SessionType; // Type of session (TEXT, VOICE, etc.)
|
|
456
508
|
* }
|
|
@@ -479,7 +531,7 @@ export class Agent {
|
|
|
479
531
|
* memory: Memory; // Current memory state (your defined memory schema)
|
|
480
532
|
* triggerInvocations: Array<...>; // Trigger invocation history
|
|
481
533
|
* triggerMetadata: {...} | null; // Current trigger metadata
|
|
482
|
-
* history:
|
|
534
|
+
* history: HistoryStep[]; // Flow execution history with detailed step information
|
|
483
535
|
* sessionId: string; // Session identifier
|
|
484
536
|
* }
|
|
485
537
|
* }
|
|
@@ -10,12 +10,7 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
10
10
|
return async (state: typeof stateAnnotation.State) => {
|
|
11
11
|
logger.debug(`Evaluating logical conditions for ${edges.length} edges`);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
const regularEdges = edges.filter(edge => edge.condition.trim() !== 'else');
|
|
15
|
-
const elseEdges = edges.filter(edge => edge.condition.trim() === 'else');
|
|
16
|
-
|
|
17
|
-
// First, evaluate all regular conditions
|
|
18
|
-
for (const edge of regularEdges) {
|
|
13
|
+
for (const edge of edges) {
|
|
19
14
|
try {
|
|
20
15
|
// Customer is responsible for providing valid JavaScript syntax
|
|
21
16
|
// We execute their condition in a sandboxed VM with timeout protection
|
|
@@ -58,11 +53,12 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
58
53
|
new Promise((_, reject) => setTimeout(() => reject(new Error('Condition execution timeout')), CONDITION_TIMEOUT)),
|
|
59
54
|
]);
|
|
60
55
|
|
|
61
|
-
if (result
|
|
56
|
+
if (result) {
|
|
62
57
|
logger.info(`Condition matched for edge ${edge.source} → ${edge.target}`);
|
|
63
58
|
return edge.target;
|
|
64
59
|
}
|
|
65
60
|
|
|
61
|
+
logger.debug(`Condition not matched for edge ${edge.source} → ${edge.target}`);
|
|
66
62
|
} catch (error) {
|
|
67
63
|
// Provide detailed error information back to the customer
|
|
68
64
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -82,17 +78,8 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
82
78
|
}
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
// If no regular conditions matched, check for "else" conditions
|
|
86
|
-
if (elseEdges.length > 0) {
|
|
87
|
-
logger.info(`No regular conditions matched, evaluating ${elseEdges.length} else condition(s)`);
|
|
88
|
-
// Return the first "else" condition's target
|
|
89
|
-
const elseEdge = elseEdges[0];
|
|
90
|
-
logger.info(`Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}`);
|
|
91
|
-
return elseEdge.target;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
81
|
// If no conditions matched or all failed, return to the source node
|
|
95
|
-
logger.info(
|
|
96
|
-
return
|
|
82
|
+
logger.info(`No conditions matched, returning to source: ${edges[0].source}`);
|
|
83
|
+
return edges[0].source;
|
|
97
84
|
};
|
|
98
85
|
};
|
package/src/edges/edgeFactory.ts
CHANGED
|
@@ -46,7 +46,7 @@ export const edgeFactory = ({
|
|
|
46
46
|
if (edgesBySource.logical.length > 0) {
|
|
47
47
|
const logicalRouter = createLogicalRouter({ edges: edgesBySource.logical });
|
|
48
48
|
const result = await logicalRouter(state);
|
|
49
|
-
if (result) {
|
|
49
|
+
if (result && result !== edgesBySource.logical[0].source) {
|
|
50
50
|
return result;
|
|
51
51
|
} else {
|
|
52
52
|
logger.debug('No logical conditions matched, continuing to prompt conditions');
|
|
@@ -68,9 +68,7 @@ export const edgeFactory = ({
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// Fallback: stay at current source node
|
|
71
|
-
|
|
72
|
-
logger.info(`No conditions matched, returning to source: ${source}`);
|
|
73
|
-
return source;
|
|
71
|
+
return sourceNode;
|
|
74
72
|
};
|
|
75
73
|
};
|
|
76
74
|
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import { BaseMessage } from '@langchain/core/messages';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { HistoryStep } from '../types/Agent.types';
|
|
3
|
+
import { State } from '../types/LangGraph.types';
|
|
4
4
|
|
|
5
5
|
export enum AgentEvents {
|
|
6
6
|
INIT = 'INIT',
|
|
7
7
|
AI_MESSAGE = 'AI_MESSAGE',
|
|
8
8
|
TRIGGER_EVENT = 'TRIGGER_EVENT',
|
|
9
|
+
ERROR = 'ERROR',
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
// Helper type to get the state type with proper memory typing
|
|
12
|
-
type StateWithMemory<Memory> = ReturnType<typeof createStateAnnotation<Memory>>['State'];
|
|
13
|
-
|
|
14
12
|
export type AgentEventRequestPayloads<Memory> = {
|
|
15
13
|
[AgentEvents.INIT]: {
|
|
16
|
-
state:
|
|
14
|
+
state: State<Memory>;
|
|
17
15
|
};
|
|
18
16
|
[AgentEvents.AI_MESSAGE]: {
|
|
19
17
|
message: string;
|
|
20
|
-
state:
|
|
18
|
+
state: State<Memory>;
|
|
21
19
|
};
|
|
22
20
|
[AgentEvents.TRIGGER_EVENT]: {
|
|
23
21
|
triggerName: string;
|
|
24
22
|
triggerBody: any;
|
|
25
23
|
sessionId?: string;
|
|
26
24
|
};
|
|
25
|
+
[AgentEvents.ERROR]: {
|
|
26
|
+
error: Error;
|
|
27
|
+
state?: State<Memory>;
|
|
28
|
+
};
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
export type AgentEventResponsePayloads<Memory> = {
|
|
@@ -33,7 +35,8 @@ export type AgentEventResponsePayloads<Memory> = {
|
|
|
33
35
|
isQualified: boolean;
|
|
34
36
|
messages?: BaseMessage[];
|
|
35
37
|
memory?: Memory;
|
|
36
|
-
history?:
|
|
38
|
+
history?: HistoryStep[];
|
|
37
39
|
sessionId?: string;
|
|
38
40
|
};
|
|
41
|
+
[AgentEvents.ERROR]: void;
|
|
39
42
|
};
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,14 @@ export {
|
|
|
35
35
|
KnownTriggerNames,
|
|
36
36
|
} from './types/Flows.types';
|
|
37
37
|
export type { Tool, ToolExecuteInput } from './types/Tools.types';
|
|
38
|
-
export {
|
|
38
|
+
export {
|
|
39
|
+
HistoryStepType,
|
|
40
|
+
HistoryStep,
|
|
41
|
+
TriggerHistoryStep,
|
|
42
|
+
AppActionInvocationHistoryStep,
|
|
43
|
+
CustomActionInvocationHistoryStep,
|
|
44
|
+
SessionType,
|
|
45
|
+
} from './types/Agent.types';
|
|
39
46
|
export type { AgentInvokeParams, MindedSDKConfig } from './types/Agent.types';
|
|
40
47
|
export type { Environment } from './types/Platform.types';
|
|
41
48
|
export type { State } from './types/LangGraph.types';
|
|
@@ -6,10 +6,11 @@ import { RunnableLike } from '@langchain/core/runnables';
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { LLMProviders } from '../types/LLM.types';
|
|
8
8
|
import { getAppActionRunnerTool } from '../internalTools/appActionRunnerTool';
|
|
9
|
-
import {
|
|
9
|
+
import { AppActionInvocationHistoryStep, HistoryStepType } from '../types/Agent.types';
|
|
10
10
|
import { Agent } from '../agent';
|
|
11
11
|
import { logger } from '../utils/logger';
|
|
12
12
|
import { compilePlaybooks } from '../playbooks/playbooks';
|
|
13
|
+
import { createHistoryStep } from '../utils/history';
|
|
13
14
|
|
|
14
15
|
export const addAppToolNode = async ({
|
|
15
16
|
graph,
|
|
@@ -80,7 +81,14 @@ export const addAppToolNode = async ({
|
|
|
80
81
|
};
|
|
81
82
|
return {
|
|
82
83
|
messages: [AIToolCallMessage, toolCallMessage],
|
|
83
|
-
history:
|
|
84
|
+
history: createHistoryStep<AppActionInvocationHistoryStep>(state.history, {
|
|
85
|
+
type: HistoryStepType.APP_ACTION_NODE,
|
|
86
|
+
nodeId: node.name,
|
|
87
|
+
nodeDisplayName: node.displayName!,
|
|
88
|
+
raw: AIToolCallMessage.tool_calls[0],
|
|
89
|
+
appName: node.appName,
|
|
90
|
+
messageIds: [AIToolCallMessage.id!],
|
|
91
|
+
}),
|
|
84
92
|
};
|
|
85
93
|
};
|
|
86
94
|
graph.addNode(node.name, callback);
|
|
@@ -2,13 +2,14 @@ import { interrupt } from '@langchain/langgraph';
|
|
|
2
2
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
3
3
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
|
+
import { internalNodesSuffix } from '../types/Flows.types';
|
|
5
6
|
|
|
6
7
|
type AddHumanInTheLoopNodeParams = {
|
|
7
8
|
graph: PreCompiledGraph;
|
|
8
9
|
attachedToNodeName: string;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
export const buildHumanInTheLoopNodeName = (nodeName: string) => `${nodeName}
|
|
12
|
+
export const buildHumanInTheLoopNodeName = (nodeName: string) => `${nodeName}${internalNodesSuffix.HUMAN_IN_THE_LOOP}`;
|
|
12
13
|
|
|
13
14
|
export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHumanInTheLoopNodeParams) => {
|
|
14
15
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
@@ -19,6 +20,6 @@ export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHu
|
|
|
19
20
|
return value;
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
|
-
graph.addNode(
|
|
23
|
+
graph.addNode(buildHumanInTheLoopNodeName(attachedToNodeName), callback);
|
|
23
24
|
graph.addEdge(attachedToNodeName as any, buildHumanInTheLoopNodeName(attachedToNodeName) as any);
|
|
24
25
|
};
|
|
@@ -3,19 +3,13 @@ import { PreCompiledGraph } from '../types/LangGraph.types';
|
|
|
3
3
|
import { JumpToNode } from '../types/Flows.types';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
5
|
|
|
6
|
-
export const addJumpToNode = async ({
|
|
7
|
-
graph,
|
|
8
|
-
node,
|
|
9
|
-
}: {
|
|
10
|
-
graph: PreCompiledGraph;
|
|
11
|
-
node: JumpToNode;
|
|
12
|
-
}) => {
|
|
6
|
+
export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph; node: JumpToNode }) => {
|
|
13
7
|
const callback: RunnableLike = async () => {
|
|
14
|
-
logger.info(`Executing jump node ${node.
|
|
8
|
+
logger.info(`Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}`);
|
|
15
9
|
// No state modifications are necessary; control flow is handled via edges.
|
|
16
10
|
return;
|
|
17
11
|
};
|
|
18
12
|
|
|
19
13
|
graph.addNode(node.name, callback);
|
|
20
14
|
graph.addEdge(node.name as any, node.targetNodeId as any);
|
|
21
|
-
};
|
|
15
|
+
};
|
|
@@ -7,12 +7,13 @@ import { SystemMessage, AIMessage, ToolMessage } from '@langchain/core/messages'
|
|
|
7
7
|
import { Tool } from '../types/Tools.types';
|
|
8
8
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
9
9
|
import { AgentEventRequestPayloads, AgentEvents } from '../events/AgentEvents';
|
|
10
|
-
import { EmitSignature } from '../types/Agent.types';
|
|
10
|
+
import { EmitSignature, HistoryStepType, HistoryStep } from '../types/Agent.types';
|
|
11
11
|
import { createLlmInstance } from '../llm/createLlmInstance';
|
|
12
12
|
import extractToolStateResponse from '../utils/extractStateMemoryResponse';
|
|
13
13
|
import { Agent } from '../agent';
|
|
14
14
|
import { logger } from '../utils/logger';
|
|
15
15
|
import { compilePlaybooks } from '../playbooks/playbooks';
|
|
16
|
+
import { createHistoryStep } from '../utils/history';
|
|
16
17
|
|
|
17
18
|
type AddPromptNodeParams = {
|
|
18
19
|
graph: PreCompiledGraph;
|
|
@@ -25,7 +26,7 @@ type AddPromptNodeParams = {
|
|
|
25
26
|
|
|
26
27
|
export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
|
|
27
28
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
28
|
-
logger.info(`Executing prompt node ${node.
|
|
29
|
+
logger.info(`Executing prompt node ${node.displayName}`);
|
|
29
30
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
30
31
|
|
|
31
32
|
const globalTools = tools
|
|
@@ -102,6 +103,13 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
return {
|
|
106
|
+
history: createHistoryStep<HistoryStep>(state.history, {
|
|
107
|
+
type: HistoryStepType.PROMPT_NODE,
|
|
108
|
+
nodeId: node.name,
|
|
109
|
+
nodeDisplayName: node.displayName,
|
|
110
|
+
raw: result.content,
|
|
111
|
+
messageIds: [result.id!],
|
|
112
|
+
}),
|
|
105
113
|
messages: [result],
|
|
106
114
|
};
|
|
107
115
|
};
|
package/src/nodes/addToolNode.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const addToolNode = async ({
|
|
|
28
28
|
throw new Error(`Tool not found: ${toolNode.toolName} in node ${node.name}`);
|
|
29
29
|
}
|
|
30
30
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
31
|
-
logger.info(`Executing tool node ${toolNode.
|
|
31
|
+
logger.info(`Executing tool node ${toolNode.displayName}`);
|
|
32
32
|
|
|
33
33
|
const tool = langchainTool(() => {}, {
|
|
34
34
|
name: matchedTool.name,
|
|
@@ -2,7 +2,7 @@ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
|
2
2
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
3
3
|
import { Tool } from '../types/Tools.types';
|
|
4
4
|
import { LLMProviders } from '../types/LLM.types';
|
|
5
|
-
import { ToolNode } from '../types/Flows.types';
|
|
5
|
+
import { internalNodesSuffix, ToolNode } from '../types/Flows.types';
|
|
6
6
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
7
7
|
import { ToolMessage } from '@langchain/core/messages';
|
|
8
8
|
import { z } from 'zod';
|
|
@@ -19,7 +19,7 @@ type AddToolRunNodeParams = {
|
|
|
19
19
|
agent: Agent;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export const buildToolRunNodeName = (nodeName: string) => `${nodeName}
|
|
22
|
+
export const buildToolRunNodeName = (nodeName: string) => `${nodeName}${internalNodesSuffix.TOOL_RUN}`;
|
|
23
23
|
|
|
24
24
|
export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeName, agent }: AddToolRunNodeParams) => {
|
|
25
25
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
@@ -5,7 +5,7 @@ import { logger } from '../utils/logger';
|
|
|
5
5
|
|
|
6
6
|
export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph; node: TriggerNode }) => {
|
|
7
7
|
const callback: RunnableLike = async () => {
|
|
8
|
-
logger.info(`Executing trigger node ${node.
|
|
8
|
+
logger.info(`Executing trigger node ${node.displayName}`);
|
|
9
9
|
return;
|
|
10
10
|
};
|
|
11
11
|
|
package/src/types/Agent.types.ts
CHANGED
|
@@ -30,26 +30,40 @@ export interface AgentInvokeParams {
|
|
|
30
30
|
appName?: string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export enum
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
export enum HistoryStepType {
|
|
34
|
+
APP_TRIGGER_NODE = 'appTriggerNode',
|
|
35
|
+
TRIGGER_NODE = 'triggerNode',
|
|
36
|
+
APP_ACTION_NODE = 'appActionNode',
|
|
37
|
+
CUSTOM_ACTION_NODE = 'customActionNode',
|
|
38
|
+
PROMPT_NODE = 'promptNode',
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
export interface
|
|
39
|
-
type:
|
|
41
|
+
export interface HistoryStep {
|
|
42
|
+
type: HistoryStepType;
|
|
43
|
+
step: number;
|
|
44
|
+
raw: any;
|
|
45
|
+
nodeId: string;
|
|
46
|
+
nodeDisplayName: string;
|
|
47
|
+
messageIds?: string[];
|
|
40
48
|
}
|
|
41
49
|
|
|
42
|
-
export interface
|
|
43
|
-
type:
|
|
44
|
-
appName
|
|
45
|
-
triggerName: string;
|
|
46
|
-
triggerBody: any;
|
|
50
|
+
export interface AppTrigggerHistoryStep extends HistoryStep {
|
|
51
|
+
type: HistoryStepType.APP_TRIGGER_NODE;
|
|
52
|
+
appName: string;
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
export interface
|
|
50
|
-
type:
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
export interface TriggerHistoryStep extends HistoryStep {
|
|
56
|
+
type: HistoryStepType.TRIGGER_NODE;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface AppActionInvocationHistoryStep extends HistoryStep {
|
|
60
|
+
type: HistoryStepType.APP_ACTION_NODE;
|
|
61
|
+
appName: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CustomActionInvocationHistoryStep extends HistoryStep {
|
|
65
|
+
type: HistoryStepType.CUSTOM_ACTION_NODE;
|
|
66
|
+
}
|
|
53
67
|
|
|
54
68
|
export enum SessionType {
|
|
55
69
|
VOICE = 'voice',
|
package/src/types/Flows.types.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface BaseNode {
|
|
|
25
25
|
position?: Position;
|
|
26
26
|
humanInTheLoop?: boolean;
|
|
27
27
|
canStayOnNode?: boolean;
|
|
28
|
-
displayName
|
|
28
|
+
displayName: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export enum TriggerType {
|
|
@@ -177,3 +177,8 @@ export enum KnownTriggerNames {
|
|
|
177
177
|
DASHBOARD_MESSAGE = 'dashboard_message',
|
|
178
178
|
VOICE_MESSAGE = 'voice_message',
|
|
179
179
|
}
|
|
180
|
+
|
|
181
|
+
export enum internalNodesSuffix {
|
|
182
|
+
HUMAN_IN_THE_LOOP = '_humanInTheLoop',
|
|
183
|
+
TOOL_RUN = '_toolRun',
|
|
184
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseMessage } from '@langchain/core/messages';
|
|
2
2
|
import { Annotation, CompiledStateGraph, StateGraph } from '@langchain/langgraph';
|
|
3
|
-
import {
|
|
3
|
+
import { HistoryStep, SessionType } from './Agent.types';
|
|
4
4
|
|
|
5
5
|
export const createStateAnnotation = <Memory = any>() =>
|
|
6
6
|
Annotation.Root({
|
|
@@ -25,15 +25,7 @@ export const createStateAnnotation = <Memory = any>() =>
|
|
|
25
25
|
default: () => ({} as Memory),
|
|
26
26
|
reducer: (a, b) => ({ ...a, ...b }),
|
|
27
27
|
}),
|
|
28
|
-
|
|
29
|
-
default: () => [],
|
|
30
|
-
reducer: (a, b) => a.concat(b),
|
|
31
|
-
}),
|
|
32
|
-
triggerMetadata: Annotation<{
|
|
33
|
-
name: string;
|
|
34
|
-
triggerBody: any;
|
|
35
|
-
} | null>,
|
|
36
|
-
history: Annotation<Array<FlowHistory>>({
|
|
28
|
+
history: Annotation<Array<HistoryStep>>({
|
|
37
29
|
default: () => [],
|
|
38
30
|
reducer: (a, b) => a.concat(b),
|
|
39
31
|
}),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HistoryStep } from '../types/Agent.types';
|
|
2
|
+
|
|
3
|
+
export const createHistoryStep = <T extends HistoryStep>(currentHistory: HistoryStep[], stepPayload: Omit<T, 'step'>): HistoryStep => {
|
|
4
|
+
const lastHistoryStep = currentHistory?.[currentHistory?.length - 1];
|
|
5
|
+
return {
|
|
6
|
+
...stepPayload,
|
|
7
|
+
step: lastHistoryStep?.step + 1 || 0,
|
|
8
|
+
} as HistoryStep;
|
|
9
|
+
};
|