agentic-api 1.0.6 → 2.0.31
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.md +336 -76
- package/dist/src/agents/agents.example.d.ts +3 -0
- package/dist/src/agents/agents.example.js +38 -0
- package/dist/src/agents/authentication.js +2 -0
- package/dist/src/agents/prompts.d.ts +2 -2
- package/dist/src/agents/prompts.js +112 -49
- package/dist/src/agents/reducer.core.d.ts +12 -0
- package/dist/src/agents/reducer.core.js +207 -0
- package/dist/src/agents/reducer.d.ts +3 -0
- package/dist/src/agents/reducer.example.d.ts +28 -0
- package/dist/src/agents/reducer.example.js +118 -0
- package/dist/src/agents/reducer.js +19 -0
- package/dist/src/agents/reducer.loaders.d.ts +34 -0
- package/dist/src/agents/reducer.loaders.js +122 -0
- package/dist/src/agents/reducer.process.d.ts +16 -0
- package/dist/src/agents/reducer.process.js +143 -0
- package/dist/src/agents/reducer.tools.d.ts +29 -0
- package/dist/src/agents/reducer.tools.js +157 -0
- package/dist/src/agents/reducer.types.d.ts +50 -0
- package/dist/src/agents/reducer.types.js +5 -0
- package/dist/src/agents/simulator.d.ts +47 -0
- package/dist/src/agents/simulator.executor.d.ts +26 -0
- package/dist/src/agents/simulator.executor.js +132 -0
- package/dist/src/agents/simulator.js +205 -0
- package/dist/src/agents/simulator.prompts.d.ts +16 -0
- package/dist/src/agents/simulator.prompts.js +108 -0
- package/dist/src/agents/simulator.types.d.ts +42 -0
- package/dist/src/agents/simulator.types.js +2 -0
- package/dist/src/agents/simulator.utils.d.ts +20 -0
- package/dist/src/agents/simulator.utils.js +87 -0
- package/dist/src/execute.d.ts +13 -6
- package/dist/src/execute.js +351 -85
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +14 -0
- package/dist/src/princing.openai.d.ts +9 -2
- package/dist/src/princing.openai.js +15 -11
- package/dist/src/prompts.d.ts +3 -2
- package/dist/src/prompts.js +159 -19
- package/dist/src/rag/embeddings.d.ts +103 -0
- package/dist/src/rag/embeddings.js +466 -0
- package/dist/src/rag/index.d.ts +12 -0
- package/dist/src/rag/index.js +40 -0
- package/dist/src/rag/lucene.d.ts +45 -0
- package/dist/src/rag/lucene.js +227 -0
- package/dist/src/rag/parser.d.ts +68 -0
- package/dist/src/rag/parser.js +192 -0
- package/dist/src/rag/tools.d.ts +76 -0
- package/dist/src/rag/tools.js +196 -0
- package/dist/src/rag/types.d.ts +178 -0
- package/dist/src/rag/types.js +21 -0
- package/dist/src/rag/usecase.d.ts +16 -0
- package/dist/src/rag/usecase.js +79 -0
- package/dist/src/rules/errors.d.ts +60 -0
- package/dist/src/rules/errors.js +97 -0
- package/dist/src/rules/git/git.e2e.helper.d.ts +104 -0
- package/dist/src/rules/git/git.e2e.helper.js +488 -0
- package/dist/src/rules/git/git.health.d.ts +66 -0
- package/dist/src/rules/git/git.health.js +354 -0
- package/dist/src/rules/git/git.helper.d.ts +129 -0
- package/dist/src/rules/git/git.helper.js +53 -0
- package/dist/src/rules/git/index.d.ts +6 -0
- package/dist/src/rules/git/index.js +76 -0
- package/dist/src/rules/git/repo.d.ts +128 -0
- package/dist/src/rules/git/repo.js +900 -0
- package/dist/src/rules/git/repo.pr.d.ts +137 -0
- package/dist/src/rules/git/repo.pr.js +589 -0
- package/dist/src/rules/git/repo.tools.d.ts +134 -0
- package/dist/src/rules/git/repo.tools.js +730 -0
- package/dist/src/rules/index.d.ts +8 -0
- package/dist/src/rules/index.js +25 -0
- package/dist/src/rules/messages.d.ts +17 -0
- package/dist/src/rules/messages.js +21 -0
- package/dist/src/rules/types.ctrl.d.ts +28 -0
- package/dist/src/rules/types.ctrl.js +2 -0
- package/dist/src/rules/types.d.ts +510 -0
- package/dist/src/rules/types.helpers.d.ts +132 -0
- package/dist/src/rules/types.helpers.js +2 -0
- package/dist/src/rules/types.js +33 -0
- package/dist/src/rules/user.mapper.d.ts +61 -0
- package/dist/src/rules/user.mapper.js +160 -0
- package/dist/src/rules/utils/slug.d.ts +22 -0
- package/dist/src/rules/utils/slug.js +35 -0
- package/dist/src/rules/utils.matter.d.ts +66 -0
- package/dist/src/rules/utils.matter.js +208 -0
- package/dist/src/rules/utils.slug.d.ts +22 -0
- package/dist/src/rules/utils.slug.js +35 -0
- package/dist/src/scrapper.d.ts +3 -2
- package/dist/src/scrapper.js +33 -37
- package/dist/src/stategraph/index.d.ts +8 -0
- package/dist/src/stategraph/index.js +21 -0
- package/dist/src/stategraph/stategraph.d.ts +91 -0
- package/dist/src/stategraph/stategraph.js +241 -0
- package/dist/src/stategraph/stategraph.storage.d.ts +41 -0
- package/dist/src/stategraph/stategraph.storage.js +166 -0
- package/dist/src/stategraph/types.d.ts +139 -0
- package/dist/src/stategraph/types.js +19 -0
- package/dist/src/types.d.ts +62 -39
- package/dist/src/types.js +53 -89
- package/dist/src/usecase.d.ts +4 -0
- package/dist/src/usecase.js +44 -0
- package/dist/src/utils.d.ts +12 -5
- package/dist/src/utils.js +30 -13
- package/package.json +9 -3
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native Loaders for MapLLM
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.StringNativeLoader = exports.FileNativeLoader = void 0;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
/**
|
|
9
|
+
* FileNativeLoader - Loader pour fichiers avec chunking par lignes
|
|
10
|
+
*/
|
|
11
|
+
class FileNativeLoader {
|
|
12
|
+
constructor(filePath, strategy = { type: 'lines', size: 50 }) {
|
|
13
|
+
this.chunks = [];
|
|
14
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
15
|
+
this.chunks = this.createChunks(content, strategy);
|
|
16
|
+
}
|
|
17
|
+
async loadNativeChunk(position) {
|
|
18
|
+
if (position >= this.chunks.length) {
|
|
19
|
+
throw new Error(`Position ${position} out of bounds (max: ${this.chunks.length - 1})`);
|
|
20
|
+
}
|
|
21
|
+
const content = this.chunks[position];
|
|
22
|
+
const nextPosition = position + 1;
|
|
23
|
+
const eof = nextPosition >= this.chunks.length;
|
|
24
|
+
return {
|
|
25
|
+
content,
|
|
26
|
+
eof,
|
|
27
|
+
position: nextPosition
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
createChunks(content, strategy) {
|
|
31
|
+
switch (strategy.type) {
|
|
32
|
+
case 'lines':
|
|
33
|
+
return this.chunkByLines(content, strategy.size);
|
|
34
|
+
case 'paragraphs':
|
|
35
|
+
return this.chunkByParagraphs(content, strategy.size);
|
|
36
|
+
default:
|
|
37
|
+
throw new Error(`Unsupported chunk strategy: ${strategy.type}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
chunkByLines(content, linesPerChunk) {
|
|
41
|
+
const lines = content.split('\n');
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for (let i = 0; i < lines.length; i += linesPerChunk) {
|
|
44
|
+
const chunkLines = lines.slice(i, i + linesPerChunk);
|
|
45
|
+
const chunkContent = chunkLines.join('\n').trim();
|
|
46
|
+
if (chunkContent) {
|
|
47
|
+
chunks.push(chunkContent);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return chunks;
|
|
51
|
+
}
|
|
52
|
+
chunkByParagraphs(content, paragraphsPerChunk) {
|
|
53
|
+
const paragraphs = content.split(/\n\s*\n/).filter(p => p.trim());
|
|
54
|
+
const chunks = [];
|
|
55
|
+
for (let i = 0; i < paragraphs.length; i += paragraphsPerChunk) {
|
|
56
|
+
const chunkParagraphs = paragraphs.slice(i, i + paragraphsPerChunk);
|
|
57
|
+
const chunkContent = chunkParagraphs.join('\n\n').trim();
|
|
58
|
+
if (chunkContent) {
|
|
59
|
+
chunks.push(chunkContent);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return chunks;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.FileNativeLoader = FileNativeLoader;
|
|
66
|
+
/**
|
|
67
|
+
* StringNativeLoader - Loader pour contenu en mémoire
|
|
68
|
+
*/
|
|
69
|
+
class StringNativeLoader {
|
|
70
|
+
constructor(content, strategy = { type: 'lines', size: 50 }) {
|
|
71
|
+
this.chunks = [];
|
|
72
|
+
this.chunks = this.createChunks(content, strategy);
|
|
73
|
+
}
|
|
74
|
+
async loadNativeChunk(position) {
|
|
75
|
+
if (position >= this.chunks.length) {
|
|
76
|
+
throw new Error(`Position ${position} out of bounds (max: ${this.chunks.length - 1})`);
|
|
77
|
+
}
|
|
78
|
+
const content = this.chunks[position];
|
|
79
|
+
const nextPosition = position + 1;
|
|
80
|
+
const eof = nextPosition >= this.chunks.length;
|
|
81
|
+
return {
|
|
82
|
+
content,
|
|
83
|
+
eof,
|
|
84
|
+
position: nextPosition
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
createChunks(content, strategy) {
|
|
88
|
+
switch (strategy.type) {
|
|
89
|
+
case 'lines':
|
|
90
|
+
return this.chunkByLines(content, strategy.size);
|
|
91
|
+
case 'paragraphs':
|
|
92
|
+
return this.chunkByParagraphs(content, strategy.size);
|
|
93
|
+
default:
|
|
94
|
+
throw new Error(`Unsupported chunk strategy: ${strategy.type}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
chunkByLines(content, linesPerChunk) {
|
|
98
|
+
const lines = content.split('\n');
|
|
99
|
+
const chunks = [];
|
|
100
|
+
for (let i = 0; i < lines.length; i += linesPerChunk) {
|
|
101
|
+
const chunkLines = lines.slice(i, i + linesPerChunk);
|
|
102
|
+
const chunkContent = chunkLines.join('\n').trim();
|
|
103
|
+
if (chunkContent) {
|
|
104
|
+
chunks.push(chunkContent);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return chunks;
|
|
108
|
+
}
|
|
109
|
+
chunkByParagraphs(content, paragraphsPerChunk) {
|
|
110
|
+
const paragraphs = content.split(/\n\s*\n/).filter(p => p.trim());
|
|
111
|
+
const chunks = [];
|
|
112
|
+
for (let i = 0; i < paragraphs.length; i += paragraphsPerChunk) {
|
|
113
|
+
const chunkParagraphs = paragraphs.slice(i, i + paragraphsPerChunk);
|
|
114
|
+
const chunkContent = chunkParagraphs.join('\n\n').trim();
|
|
115
|
+
if (chunkContent) {
|
|
116
|
+
chunks.push(chunkContent);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return chunks;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.StringNativeLoader = StringNativeLoader;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { StatefulReducerConfig, StatefulReduceResult, StatefulProcessOptions, ChunkLoader } from "./reducer.types";
|
|
2
|
+
/**
|
|
3
|
+
* Main function to process a document using the stateful agent reduce pattern
|
|
4
|
+
*
|
|
5
|
+
* @param sessionId - Session ID for the discussion/document to process
|
|
6
|
+
* @param config - Stateful reducer configuration
|
|
7
|
+
* @param loader - ChunkLoader interface for loading content chunks
|
|
8
|
+
* @param options - Additional options
|
|
9
|
+
* @returns Promise resolving to the stateful reduce result
|
|
10
|
+
*/
|
|
11
|
+
export declare function statefulReduceProcess<T = any>(sessionId: string, config: StatefulReducerConfig, loader: ChunkLoader, options?: StatefulProcessOptions): Promise<StatefulReduceResult<T>>;
|
|
12
|
+
/**
|
|
13
|
+
* Legacy function name for backward compatibility
|
|
14
|
+
* @deprecated Use statefulReduceProcess instead
|
|
15
|
+
*/
|
|
16
|
+
export declare function agentReduceProcess<T = any>(sessionId: string, config: any, loader: ChunkLoader, options?: any): Promise<any>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.statefulReduceProcess = statefulReduceProcess;
|
|
4
|
+
exports.agentReduceProcess = agentReduceProcess;
|
|
5
|
+
const execute_1 = require("../execute");
|
|
6
|
+
const reducer_tools_1 = require("./reducer.tools");
|
|
7
|
+
/**
|
|
8
|
+
* Main function to process a document using the stateful agent reduce pattern
|
|
9
|
+
*
|
|
10
|
+
* @param sessionId - Session ID for the discussion/document to process
|
|
11
|
+
* @param config - Stateful reducer configuration
|
|
12
|
+
* @param loader - ChunkLoader interface for loading content chunks
|
|
13
|
+
* @param options - Additional options
|
|
14
|
+
* @returns Promise resolving to the stateful reduce result
|
|
15
|
+
*/
|
|
16
|
+
async function statefulReduceProcess(sessionId, config, loader, options = {}) {
|
|
17
|
+
const { stdout = process.stdout, maxIterations = 50, model = (0, execute_1.modelConfig)("MEDIUM"), verbose = config.verbose || false } = options;
|
|
18
|
+
// Create the stateful reducer tools
|
|
19
|
+
const { statefulReduceProcessChunk, toolStatefulReduceProcessChunk } = (0, reducer_tools_1.createStatefulReduceTools)(loader, config);
|
|
20
|
+
// Create initial agent configuration with dynamic system prompt
|
|
21
|
+
let agentConfig = {
|
|
22
|
+
name: "statefulReducer",
|
|
23
|
+
model,
|
|
24
|
+
publicDescription: "Agent that processes large content using stateful reducer pattern with digest replacement",
|
|
25
|
+
instructions: `${config.systemTemplate.replace('{{reducerContent}}', '')}
|
|
26
|
+
|
|
27
|
+
IMPORTANT: Always use sessionId="${sessionId}" and template="${config.templates ? Object.keys(config.templates)[0] : 'semantic'}" when calling statefulReduceProcessChunk.
|
|
28
|
+
Start with position=0 and continue with the nextPosition returned by the tool.`,
|
|
29
|
+
tools: [toolStatefulReduceProcessChunk],
|
|
30
|
+
toolLogic: {
|
|
31
|
+
statefulReduceProcessChunk: (args, context) => statefulReduceProcessChunk(args, context)
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
// Track the conversation and results
|
|
35
|
+
let position = 0;
|
|
36
|
+
let iterations = 0;
|
|
37
|
+
let finalDigest;
|
|
38
|
+
let allMessages = [];
|
|
39
|
+
let totalUsage = { prompt: 0, completion: 0, total: 0, cost: 0 };
|
|
40
|
+
let compressionHistory = [];
|
|
41
|
+
if (verbose) {
|
|
42
|
+
console.log(`🚀 statefulReduceProcess: Starting stateful reduce process for session: ${sessionId}`);
|
|
43
|
+
}
|
|
44
|
+
// Process the document iteratively with stateful pattern
|
|
45
|
+
while (iterations < maxIterations) {
|
|
46
|
+
iterations++;
|
|
47
|
+
const templateName = config.templates ? Object.keys(config.templates)[0] : 'semantic';
|
|
48
|
+
const query = iterations === 1
|
|
49
|
+
? `Process the session "${sessionId}" with template "${templateName}" starting from position 0 using stateful reducer pattern.`
|
|
50
|
+
: `Continue processing from position ${position} with stateful reducer pattern.`;
|
|
51
|
+
if (verbose) {
|
|
52
|
+
console.log(`📝 statefulReduceProcess: Iteration ${iterations}: Processing from position ${position}`);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
// Execute the agent for this iteration
|
|
56
|
+
const result = await (0, execute_1.executeAgent)([agentConfig], {
|
|
57
|
+
query,
|
|
58
|
+
home: "statefulReducer",
|
|
59
|
+
stdout,
|
|
60
|
+
verbose
|
|
61
|
+
});
|
|
62
|
+
// Accumulate usage
|
|
63
|
+
if (result.usage) {
|
|
64
|
+
totalUsage.prompt += result.usage.prompt || 0;
|
|
65
|
+
totalUsage.completion += result.usage.completion || 0;
|
|
66
|
+
totalUsage.total += result.usage.total || 0;
|
|
67
|
+
totalUsage.cost += result.usage.cost || 0;
|
|
68
|
+
}
|
|
69
|
+
// Add messages to our conversation log
|
|
70
|
+
if (result.messages) {
|
|
71
|
+
allMessages.push(...result.messages);
|
|
72
|
+
}
|
|
73
|
+
// Parse the last tool result to get next position and check for EOF
|
|
74
|
+
const lastMessage = result.messages?.[result.messages.length - 1];
|
|
75
|
+
if (lastMessage?.role === 'tool') {
|
|
76
|
+
try {
|
|
77
|
+
const toolResult = JSON.parse(lastMessage.content);
|
|
78
|
+
if (toolResult.eof) {
|
|
79
|
+
finalDigest = toolResult.finalDigest;
|
|
80
|
+
if (verbose) {
|
|
81
|
+
console.log(`✅ Stateful document processing complete after ${iterations} iterations`);
|
|
82
|
+
console.log(`📊 Final digest size: ${toolResult.metadata?.finalDigestSize || 'unknown'} chars`);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
// Update position for next iteration
|
|
87
|
+
position = toolResult.nextPosition || position;
|
|
88
|
+
// Update agent configuration with new system prompt (STATEFUL)
|
|
89
|
+
if (toolResult.systemPrompt) {
|
|
90
|
+
agentConfig.instructions = toolResult.systemPrompt;
|
|
91
|
+
if (verbose) {
|
|
92
|
+
console.log(`🔄 System prompt updated for iteration ${iterations + 1}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Track compression if applied
|
|
96
|
+
if (toolResult.compressionApplied) {
|
|
97
|
+
compressionHistory.push(toolResult.compressionRatio || 0.8);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (verbose) {
|
|
102
|
+
console.error(`❌ Error parsing tool result:`, error);
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (verbose) {
|
|
110
|
+
console.error(`❌ Error in iteration ${iterations}:`, error);
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (iterations >= maxIterations) {
|
|
116
|
+
throw new Error(`Maximum iterations (${maxIterations}) reached without completion`);
|
|
117
|
+
}
|
|
118
|
+
if (finalDigest === undefined) {
|
|
119
|
+
throw new Error("Processing completed but no final digest was produced");
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
finalDigest: finalDigest,
|
|
123
|
+
iterations,
|
|
124
|
+
compressionHistory,
|
|
125
|
+
metadata: {
|
|
126
|
+
totalChunks: iterations,
|
|
127
|
+
finalDigestSize: typeof finalDigest === 'string' ? finalDigest.length : JSON.stringify(finalDigest).length,
|
|
128
|
+
averageCompressionRatio: compressionHistory.length > 0
|
|
129
|
+
? compressionHistory.reduce((a, b) => a + b, 0) / compressionHistory.length
|
|
130
|
+
: 1.0,
|
|
131
|
+
sessionId
|
|
132
|
+
},
|
|
133
|
+
messages: allMessages
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Legacy function name for backward compatibility
|
|
138
|
+
* @deprecated Use statefulReduceProcess instead
|
|
139
|
+
*/
|
|
140
|
+
async function agentReduceProcess(sessionId, config, loader, options = {}) {
|
|
141
|
+
console.warn('agentReduceProcess is deprecated. Use statefulReduceProcess instead.');
|
|
142
|
+
return statefulReduceProcess(sessionId, config, loader, options);
|
|
143
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Tool } from "../types";
|
|
2
|
+
import { StatefulReducerConfig, ChunkLoader } from "./reducer.types";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the stateful agent reduce tools with proper configuration
|
|
5
|
+
*
|
|
6
|
+
* @param loader - ChunkLoader interface for loading content chunks
|
|
7
|
+
* @param config - Stateful reducer configuration
|
|
8
|
+
* @returns Object containing the tool function and tool definition
|
|
9
|
+
*/
|
|
10
|
+
export declare function createStatefulReduceTools(loader: ChunkLoader, config: StatefulReducerConfig): {
|
|
11
|
+
statefulReduceProcessChunk: (args: any, context: any) => Promise<{
|
|
12
|
+
role: string;
|
|
13
|
+
name: string;
|
|
14
|
+
content: string;
|
|
15
|
+
}>;
|
|
16
|
+
toolStatefulReduceProcessChunk: Tool;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Legacy function name for backward compatibility
|
|
20
|
+
* @deprecated Use createStatefulReduceTools instead
|
|
21
|
+
*/
|
|
22
|
+
export declare function createAgentReduceTools(loader: ChunkLoader, config: any): {
|
|
23
|
+
statefulReduceProcessChunk: (args: any, context: any) => Promise<{
|
|
24
|
+
role: string;
|
|
25
|
+
name: string;
|
|
26
|
+
content: string;
|
|
27
|
+
}>;
|
|
28
|
+
toolStatefulReduceProcessChunk: Tool;
|
|
29
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStatefulReduceTools = createStatefulReduceTools;
|
|
4
|
+
exports.createAgentReduceTools = createAgentReduceTools;
|
|
5
|
+
const reducer_core_1 = require("./reducer.core");
|
|
6
|
+
/**
|
|
7
|
+
* Creates the tool definition for stateful agent reduce content processing
|
|
8
|
+
*/
|
|
9
|
+
const createStatefulReduceTool = () => ({
|
|
10
|
+
type: "function",
|
|
11
|
+
function: {
|
|
12
|
+
strict: true,
|
|
13
|
+
name: "statefulReduceProcessChunk",
|
|
14
|
+
description: `
|
|
15
|
+
This tool processes large content with a STATEFUL reducer pattern using digest replacement.
|
|
16
|
+
|
|
17
|
+
## Core Principles (STATEFUL)
|
|
18
|
+
1. Each call processes ONE chunk and updates internal digest state
|
|
19
|
+
2. First chunk: creates initial digest
|
|
20
|
+
3. Subsequent chunks: digest + reduce → REPLACES previous digest (no accumulation)
|
|
21
|
+
4. Continue calling until you receive "eof": true
|
|
22
|
+
5. System prompt is dynamically updated with current digest
|
|
23
|
+
|
|
24
|
+
## Parameters
|
|
25
|
+
- **sessionId** *(string)* - Session ID for the discussion/document to process
|
|
26
|
+
- **template** *(string)* - Processing template to apply
|
|
27
|
+
- **position** *(number)* - Byte offset to resume reading (0 for first call)
|
|
28
|
+
|
|
29
|
+
## Workflow (Stateful)
|
|
30
|
+
1. Load chunk from position
|
|
31
|
+
2. If first chunk: digest → update system prompt
|
|
32
|
+
3. If subsequent: digest + reduce with current state → REPLACE digest → update system prompt
|
|
33
|
+
4. Return current digest and continue until EOF
|
|
34
|
+
`,
|
|
35
|
+
parameters: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
sessionId: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Session ID for the discussion/document to process"
|
|
41
|
+
},
|
|
42
|
+
template: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: "Processing template to apply",
|
|
45
|
+
enum: ["facts", "compress", "semantic", "minutes", "custom", "weather", "aliments", "mobilite"]
|
|
46
|
+
},
|
|
47
|
+
position: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Current position in the document (0 for first call)"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
required: ["sessionId", "template", "position"],
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Creates the stateful agent reduce tools with proper configuration
|
|
59
|
+
*
|
|
60
|
+
* @param loader - ChunkLoader interface for loading content chunks
|
|
61
|
+
* @param config - Stateful reducer configuration
|
|
62
|
+
* @returns Object containing the tool function and tool definition
|
|
63
|
+
*/
|
|
64
|
+
function createStatefulReduceTools(loader, config) {
|
|
65
|
+
const toolStatefulReduceProcessChunk = createStatefulReduceTool();
|
|
66
|
+
// Stateful engine instance - maintains state across calls
|
|
67
|
+
let engine = null;
|
|
68
|
+
/**
|
|
69
|
+
* Stateful reduce process chunk tool implementation
|
|
70
|
+
*/
|
|
71
|
+
const statefulReduceProcessChunk = async (args, context) => {
|
|
72
|
+
const { sessionId, template, position } = args;
|
|
73
|
+
if (!sessionId) {
|
|
74
|
+
throw new Error("Session ID is required for stateful reduce processing");
|
|
75
|
+
}
|
|
76
|
+
// Initialize engine on first call
|
|
77
|
+
if (!engine) {
|
|
78
|
+
engine = new reducer_core_1.StatefulReducerEngine(config);
|
|
79
|
+
engine.setSessionId(sessionId);
|
|
80
|
+
if (config.verbose) {
|
|
81
|
+
console.log(`🚀 STATEFUL TOOL: Initialized engine for session ${sessionId}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (config.verbose) {
|
|
85
|
+
console.log(`🔄 STATEFUL TOOL: Loading chunk from position ${position} for session ${sessionId}`);
|
|
86
|
+
}
|
|
87
|
+
// Load the chunk using the external loader
|
|
88
|
+
const chunk = await loader.loadNativeChunk(sessionId, position);
|
|
89
|
+
if (!chunk || !chunk.content) {
|
|
90
|
+
throw new Error("Failed to load content chunk");
|
|
91
|
+
}
|
|
92
|
+
// Update engine position
|
|
93
|
+
engine.updatePosition(chunk.position);
|
|
94
|
+
// Check if template exists
|
|
95
|
+
if (!config.templates || !config.templates[template]) {
|
|
96
|
+
return {
|
|
97
|
+
role: "assistant",
|
|
98
|
+
name: "statefulReduceProcessChunk",
|
|
99
|
+
content: JSON.stringify({
|
|
100
|
+
error: `Missing template '${template}'. Available templates: ${Object.keys(config.templates || {}).join(', ')}`,
|
|
101
|
+
nextPosition: position,
|
|
102
|
+
eof: false,
|
|
103
|
+
systemPrompt: engine.getSystemPrompt()
|
|
104
|
+
})
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// If this is EOF, return the final result
|
|
108
|
+
if (chunk.eof && chunk.content.includes('EOF')) {
|
|
109
|
+
engine.setEof(true);
|
|
110
|
+
const finalResult = engine.getFinalResult();
|
|
111
|
+
return {
|
|
112
|
+
role: "assistant",
|
|
113
|
+
name: "statefulReduceProcessChunk",
|
|
114
|
+
content: JSON.stringify({
|
|
115
|
+
finalDigest: finalResult.finalDigest,
|
|
116
|
+
nextPosition: chunk.position,
|
|
117
|
+
eof: true,
|
|
118
|
+
systemPrompt: engine.getSystemPrompt(),
|
|
119
|
+
metadata: finalResult.metadata,
|
|
120
|
+
instructions: "This is the final result. The document processing is complete."
|
|
121
|
+
})
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Process chunk with stateful engine
|
|
125
|
+
const currentDigest = await engine.processChunk(chunk.content);
|
|
126
|
+
const state = engine.getState();
|
|
127
|
+
// Return current state and instructions for next iteration
|
|
128
|
+
return {
|
|
129
|
+
role: "assistant",
|
|
130
|
+
name: "statefulReduceProcessChunk",
|
|
131
|
+
content: JSON.stringify({
|
|
132
|
+
currentDigest,
|
|
133
|
+
nextPosition: chunk.position,
|
|
134
|
+
eof: chunk.eof,
|
|
135
|
+
systemPrompt: engine.getSystemPrompt(),
|
|
136
|
+
template,
|
|
137
|
+
iteration: state.iteration,
|
|
138
|
+
chunkCount: state.chunkCount,
|
|
139
|
+
instructions: state.iteration === 1
|
|
140
|
+
? `Premier digest créé. Continue avec le chunk suivant.`
|
|
141
|
+
: `Digest mis à jour (remplacement). Continue avec le chunk suivant.`
|
|
142
|
+
})
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
statefulReduceProcessChunk,
|
|
147
|
+
toolStatefulReduceProcessChunk
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Legacy function name for backward compatibility
|
|
152
|
+
* @deprecated Use createStatefulReduceTools instead
|
|
153
|
+
*/
|
|
154
|
+
function createAgentReduceTools(loader, config) {
|
|
155
|
+
console.warn('createAgentReduceTools is deprecated. Use createStatefulReduceTools instead.');
|
|
156
|
+
return createStatefulReduceTools(loader, config);
|
|
157
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the MapLLM reducer functionality
|
|
3
|
+
*/
|
|
4
|
+
import type { AgentModel } from '../types';
|
|
5
|
+
export interface NativeLoader {
|
|
6
|
+
loadNativeChunk(position: number): Promise<{
|
|
7
|
+
content: string;
|
|
8
|
+
eof: boolean;
|
|
9
|
+
position: number;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface StatefulReducerConfig {
|
|
13
|
+
/** Prompt for analyzing individual content chunks */
|
|
14
|
+
digestPrompt: string;
|
|
15
|
+
/** Prompt for synthesizing/fusing current analysis with previous results */
|
|
16
|
+
reducePrompt: string;
|
|
17
|
+
/** Modulo for reducing the digest */
|
|
18
|
+
reduceModulo?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface StructuredOutputFormat {
|
|
21
|
+
/** Schema name for the structured output */
|
|
22
|
+
name: string;
|
|
23
|
+
/** JSON Schema definition */
|
|
24
|
+
schema: Record<string, any>;
|
|
25
|
+
/** Whether to enforce strict mode */
|
|
26
|
+
strict?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface MapLLMReduceResult {
|
|
29
|
+
/** Accumulator - string for text mode, object for structured output */
|
|
30
|
+
acc: string | Record<string, any>;
|
|
31
|
+
continue?: boolean;
|
|
32
|
+
maxIterations?: boolean;
|
|
33
|
+
/** OpenAI structured output format configuration */
|
|
34
|
+
format?: StructuredOutputFormat;
|
|
35
|
+
/** Model configuration */
|
|
36
|
+
model?: AgentModel;
|
|
37
|
+
verbose?: boolean;
|
|
38
|
+
/** Processing metadata */
|
|
39
|
+
metadata?: {
|
|
40
|
+
iterations: number;
|
|
41
|
+
averageChunkSize: number;
|
|
42
|
+
/** Processing time in milliseconds */
|
|
43
|
+
processingTimeMs: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface ChunkStrategy {
|
|
47
|
+
type: 'lines' | 'pages' | 'paragraphs' | 'overlap';
|
|
48
|
+
size: number;
|
|
49
|
+
overlap?: number;
|
|
50
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { SimulatorConfig, SimulationOptions, SimulationResult } from './simulator.types';
|
|
2
|
+
export declare class AgentSimulator {
|
|
3
|
+
private config;
|
|
4
|
+
private executor;
|
|
5
|
+
private lastExecution?;
|
|
6
|
+
constructor(config: SimulatorConfig);
|
|
7
|
+
/**
|
|
8
|
+
* Exécuter la simulation complète
|
|
9
|
+
*
|
|
10
|
+
* Format de la query passée à l'agent testé :
|
|
11
|
+
* - Message initial : réponse du simulateur après analyse du scenario
|
|
12
|
+
* - Messages suivants : réponse conversationnelle du simulateur (sans tags d'évaluation)
|
|
13
|
+
*
|
|
14
|
+
* Format de la query passée au simulateur :
|
|
15
|
+
* - Message initial : buildSimulatorQuery(scenario) - format structuré avec SIMULATION SCENARIO
|
|
16
|
+
* - Messages suivants : réponse de l'agent testé (pour évaluation et réaction)
|
|
17
|
+
*/
|
|
18
|
+
executeSimulation(options: SimulationOptions): Promise<SimulationResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Compter les occurrences d'une action dans le dernier ExecutionResult
|
|
21
|
+
* @param name Nom exact de l'action (ex: 'lookupMfilesIntervenant', 'lookupKnowledge', 'sendInternalEmail')
|
|
22
|
+
* @returns { firstPos, count, total } où:
|
|
23
|
+
* - firstPos: index de la première occurrence (ou -1 si absente)
|
|
24
|
+
* - count: nombre d'occurrences de cette action
|
|
25
|
+
* - total: nombre total d'actions du même type (fonction vs transfert)
|
|
26
|
+
*/
|
|
27
|
+
executionActionCount(name: string): {
|
|
28
|
+
firstPos: number;
|
|
29
|
+
count: number;
|
|
30
|
+
total: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Fonction d'affichage pour les tests - n'altère pas la structure originale
|
|
34
|
+
* Crée une version simplifiée pour l'affichage avec juste les noms des actions
|
|
35
|
+
*/
|
|
36
|
+
printSimulationResult(result: SimulationResult): {
|
|
37
|
+
summary: any;
|
|
38
|
+
execution: any;
|
|
39
|
+
};
|
|
40
|
+
private isSimulationComplete;
|
|
41
|
+
private parseSimulationResult;
|
|
42
|
+
private extractConversationalPart;
|
|
43
|
+
/**
|
|
44
|
+
* Générer le rapport final en cas de timeout
|
|
45
|
+
*/
|
|
46
|
+
private generateTimeoutReport;
|
|
47
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SimulatorConfig, ExecutionContext } from './simulator.types';
|
|
2
|
+
export declare class AgentExecutor {
|
|
3
|
+
private config;
|
|
4
|
+
private simulatorAgent;
|
|
5
|
+
constructor(config: SimulatorConfig);
|
|
6
|
+
/**
|
|
7
|
+
* Initialiser les contextes agent et simulateur
|
|
8
|
+
*/
|
|
9
|
+
initializeContexts(): Promise<ExecutionContext>;
|
|
10
|
+
/**
|
|
11
|
+
* ✅ Exécuter l'agent testé et retourner sa réponse (extraction de agent-vs-agent.ts)
|
|
12
|
+
*/
|
|
13
|
+
executeAgent(context: ExecutionContext, query: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* ✅ Exécuter le simulateur et retourner sa réponse (extraction de client-simulator.ts)
|
|
16
|
+
*/
|
|
17
|
+
executeSimulator(context: ExecutionContext, query: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* ✅ Récupérer le dernier message de l'agent testé (extraction de agent-vs-agent.ts ligne 168-191)
|
|
20
|
+
*/
|
|
21
|
+
private getLastAgentMessage;
|
|
22
|
+
/**
|
|
23
|
+
* ✅ Récupérer le dernier message du simulateur (extraction de client-simulator.ts)
|
|
24
|
+
*/
|
|
25
|
+
private getLastAssistantMessage;
|
|
26
|
+
}
|