@ugm/desiagent 0.1.37 → 0.2.1
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 +298 -156
- package/dist/core/execution/agents.d.ts.map +1 -1
- package/dist/core/execution/agents.js +18 -4
- package/dist/core/execution/agents.js.map +1 -1
- package/dist/core/execution/dagExecutor.d.ts +15 -2
- package/dist/core/execution/dagExecutor.d.ts.map +1 -1
- package/dist/core/execution/dagExecutor.js +164 -30
- package/dist/core/execution/dagExecutor.js.map +1 -1
- package/dist/core/execution/dags.d.ts +19 -1
- package/dist/core/execution/dags.d.ts.map +1 -1
- package/dist/core/execution/dags.js +171 -92
- package/dist/core/execution/dags.js.map +1 -1
- package/dist/core/execution/inference.d.ts +20 -16
- package/dist/core/execution/inference.d.ts.map +1 -1
- package/dist/core/execution/inference.js +2 -1
- package/dist/core/execution/inference.js.map +1 -1
- package/dist/core/providers/factory.d.ts +1 -0
- package/dist/core/providers/factory.d.ts.map +1 -1
- package/dist/core/providers/factory.js +5 -4
- package/dist/core/providers/factory.js.map +1 -1
- package/dist/core/providers/openrouter.d.ts +9 -2
- package/dist/core/providers/openrouter.d.ts.map +1 -1
- package/dist/core/providers/openrouter.js +66 -9
- package/dist/core/providers/openrouter.js.map +1 -1
- package/dist/core/providers/types.d.ts +9 -0
- package/dist/core/providers/types.d.ts.map +1 -1
- package/dist/core/skills/detector.d.ts +8 -0
- package/dist/core/skills/detector.d.ts.map +1 -0
- package/dist/core/skills/detector.js +60 -0
- package/dist/core/skills/detector.js.map +1 -0
- package/dist/core/skills/registry.d.ts +44 -0
- package/dist/core/skills/registry.d.ts.map +1 -0
- package/dist/core/skills/registry.js +149 -0
- package/dist/core/skills/registry.js.map +1 -0
- package/dist/core/tools/base.d.ts +14 -1
- package/dist/core/tools/base.d.ts.map +1 -1
- package/dist/core/tools/base.js.map +1 -1
- package/dist/core/tools/bash.js +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.js +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/executor.d.ts +4 -1
- package/dist/core/tools/executor.d.ts.map +1 -1
- package/dist/core/tools/executor.js +8 -2
- package/dist/core/tools/executor.js.map +1 -1
- package/dist/core/tools/fetchPage.d.ts +1 -1
- package/dist/core/tools/fetchPage.d.ts.map +1 -1
- package/dist/core/tools/fetchPage.js +20 -4
- package/dist/core/tools/fetchPage.js.map +1 -1
- package/dist/core/tools/glob.js +1 -1
- package/dist/core/tools/glob.js.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/llmExecute.d.ts +41 -32
- package/dist/core/tools/llmExecute.d.ts.map +1 -1
- package/dist/core/tools/llmExecute.js +13 -0
- package/dist/core/tools/llmExecute.js.map +1 -1
- package/dist/core/tools/readEmail.d.ts +1 -1
- package/dist/core/tools/readEmail.d.ts.map +1 -1
- package/dist/core/tools/readEmail.js +6 -9
- package/dist/core/tools/readEmail.js.map +1 -1
- package/dist/core/tools/readFile.js +1 -1
- package/dist/core/tools/readFile.js.map +1 -1
- package/dist/core/tools/sendEmail.d.ts +7 -7
- package/dist/core/tools/sendEmail.d.ts.map +1 -1
- package/dist/core/tools/sendEmail.js +12 -17
- package/dist/core/tools/sendEmail.js.map +1 -1
- package/dist/core/tools/writeFile.d.ts +1 -1
- package/dist/core/tools/writeFile.js +1 -1
- package/dist/core/tools/writeFile.js.map +1 -1
- package/dist/core/workers/statsQueue.d.ts +69 -0
- package/dist/core/workers/statsQueue.d.ts.map +1 -0
- package/dist/core/workers/statsQueue.js +106 -0
- package/dist/core/workers/statsQueue.js.map +1 -0
- package/dist/core/workers/statsWorker.d.ts +11 -0
- package/dist/core/workers/statsWorker.d.ts.map +1 -0
- package/dist/core/workers/statsWorker.js +235 -0
- package/dist/core/workers/statsWorker.js.map +1 -0
- package/dist/db/client.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +21 -86
- package/dist/db/client.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +71 -33
- package/dist/index.js.map +1 -1
- package/dist/services/agentsSeedData.d.ts.map +1 -1
- package/dist/services/agentsSeedData.js +14 -0
- package/dist/services/agentsSeedData.js.map +1 -1
- package/dist/services/initDB.d.ts +6 -0
- package/dist/services/initDB.d.ts.map +1 -1
- package/dist/services/initDB.js +2 -2
- package/dist/services/initDB.js.map +1 -1
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +3 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/types/client.d.ts +1 -0
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/config.d.ts +40 -7
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +69 -7
- package/dist/types/config.js.map +1 -1
- package/dist/types/dag.d.ts +44 -44
- package/dist/types/dag.js +7 -7
- package/dist/types/dag.js.map +1 -1
- package/dist/util/logger.d.ts +1 -8
- package/dist/util/logger.d.ts.map +1 -1
- package/dist/util/logger.js +11 -60
- package/dist/util/logger.js.map +1 -1
- package/dist/util/sendEmailTool.d.ts +7 -7
- package/dist/util/sendEmailTool.d.ts.map +1 -1
- package/dist/util/sendEmailTool.js +8 -0
- package/dist/util/sendEmailTool.js.map +1 -1
- package/package.json +2 -1
|
@@ -16,6 +16,7 @@ import { DecomposerJobSchema } from '../../types/dag.js';
|
|
|
16
16
|
import { createLLMProvider } from '../providers/factory.js';
|
|
17
17
|
import { LlmExecuteTool } from '../tools/llmExecute.js';
|
|
18
18
|
import { DAGExecutor } from './dagExecutor.js';
|
|
19
|
+
import { MinimalSkillDetector } from '../skills/detector.js';
|
|
19
20
|
export function generateDAGId() {
|
|
20
21
|
return `dag_${nanoid(21)}`;
|
|
21
22
|
}
|
|
@@ -32,6 +33,12 @@ export class DAGsService {
|
|
|
32
33
|
agentsService;
|
|
33
34
|
scheduler;
|
|
34
35
|
artifactsDir;
|
|
36
|
+
staleExecutionMinutes;
|
|
37
|
+
apiKey;
|
|
38
|
+
ollamaBaseUrl;
|
|
39
|
+
skipGenerationStats;
|
|
40
|
+
skillRegistry;
|
|
41
|
+
statsQueue;
|
|
35
42
|
logger = getLogger();
|
|
36
43
|
constructor(deps) {
|
|
37
44
|
this.db = deps.db;
|
|
@@ -39,7 +46,13 @@ export class DAGsService {
|
|
|
39
46
|
this.toolRegistry = deps.toolRegistry;
|
|
40
47
|
this.agentsService = deps.agentsService;
|
|
41
48
|
this.scheduler = deps.scheduler;
|
|
42
|
-
this.artifactsDir = deps.artifactsDir
|
|
49
|
+
this.artifactsDir = deps.artifactsDir;
|
|
50
|
+
this.staleExecutionMinutes = deps.staleExecutionMinutes ?? 5;
|
|
51
|
+
this.apiKey = deps.apiKey;
|
|
52
|
+
this.ollamaBaseUrl = deps.ollamaBaseUrl;
|
|
53
|
+
this.skipGenerationStats = deps.skipGenerationStats;
|
|
54
|
+
this.skillRegistry = deps.skillRegistry;
|
|
55
|
+
this.statsQueue = deps.statsQueue;
|
|
43
56
|
}
|
|
44
57
|
buildGlobalContext(job) {
|
|
45
58
|
const entitiesStr = job.entities.length > 0
|
|
@@ -157,7 +170,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
157
170
|
let activeLLMProvider;
|
|
158
171
|
if (activeProvider && activeModel) {
|
|
159
172
|
this.logger.info({ requestedProvider: activeProvider, requestedModel: activeModel }, 'Creating custom LLM provider');
|
|
160
|
-
activeLLMProvider = createLLMProvider({ provider: activeProvider, model: activeModel });
|
|
173
|
+
activeLLMProvider = createLLMProvider({ provider: activeProvider, model: activeModel, apiKey: this.apiKey, baseUrl: this.ollamaBaseUrl, skipGenerationStats: this.skipGenerationStats });
|
|
161
174
|
const validationResult = await activeLLMProvider.validateToolCallSupport(activeModel);
|
|
162
175
|
if (!validationResult.supported) {
|
|
163
176
|
this.logger.warn({ model: activeModel, reason: validationResult.message }, 'Model does not support tool calling');
|
|
@@ -167,10 +180,20 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
167
180
|
activeLLMProvider = this.llmProvider;
|
|
168
181
|
this.logger.debug('Using default LLM provider');
|
|
169
182
|
}
|
|
183
|
+
// Detect relevant skills and build skills list for prompt injection
|
|
184
|
+
const skillsList = this.skillRegistry ? this.skillRegistry.getFormattedList() : '';
|
|
185
|
+
if (this.skillRegistry) {
|
|
186
|
+
const detector = new MinimalSkillDetector();
|
|
187
|
+
const detectedSkills = detector.detect(goalText, this.skillRegistry.getAll());
|
|
188
|
+
if (detectedSkills.length > 0) {
|
|
189
|
+
this.logger.info({ detectedSkills }, 'Skills detected for goal');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
170
192
|
const toolDefinitions = this.toolRegistry.getAllDefinitions();
|
|
171
193
|
const systemPrompt = agent.systemPrompt
|
|
172
194
|
.replace(/\{\{tools\}\}/g, JSON.stringify(toolDefinitions))
|
|
173
|
-
.replace(/\{\{currentDate\}\}/g, new Date().toLocaleString())
|
|
195
|
+
.replace(/\{\{currentDate\}\}/g, new Date().toLocaleString())
|
|
196
|
+
.replace(/\{\{skills\}\}/g, skillsList);
|
|
174
197
|
if (systemPrompt.length < 100) {
|
|
175
198
|
this.logger.warn('System prompt is empty after replacement');
|
|
176
199
|
throw new ValidationError('System prompt seems short! ', 'systemPrompt', systemPrompt);
|
|
@@ -195,10 +218,13 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
195
218
|
temperature,
|
|
196
219
|
maxTokens,
|
|
197
220
|
abortSignal: options.abortSignal,
|
|
221
|
+
deferGenerationStats: true,
|
|
198
222
|
});
|
|
199
223
|
const attemptUsage = response.usage;
|
|
200
224
|
const attemptCost = response.costUsd;
|
|
201
225
|
const attemptGenStats = response.generationStats;
|
|
226
|
+
const attemptGenStatsPromise = response.generationStatsPromise;
|
|
227
|
+
const attemptGenerationId = response.generationId;
|
|
202
228
|
if (attemptUsage) {
|
|
203
229
|
planningUsageTotal.promptTokens += attemptUsage.promptTokens ?? 0;
|
|
204
230
|
planningUsageTotal.completionTokens += attemptUsage.completionTokens ?? 0;
|
|
@@ -273,7 +299,6 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
273
299
|
continue;
|
|
274
300
|
}
|
|
275
301
|
const usage = response.usage ?? null;
|
|
276
|
-
const generationStats = response.generationStats ?? null;
|
|
277
302
|
const validatedResult = DecomposerJobSchema.safeParse(result);
|
|
278
303
|
if (!validatedResult.success) {
|
|
279
304
|
planningAttempts.push({
|
|
@@ -343,13 +368,12 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
343
368
|
const dagId = generateDAGId();
|
|
344
369
|
const now = new Date();
|
|
345
370
|
this.logger.info({ dagId }, 'DagID Generated for clarification');
|
|
346
|
-
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
347
371
|
const baseInsertData = {
|
|
348
372
|
id: dagId,
|
|
349
373
|
status: 'pending',
|
|
350
374
|
result: dag,
|
|
351
375
|
usage: usage,
|
|
352
|
-
generationStats:
|
|
376
|
+
generationStats: null,
|
|
353
377
|
attempts: attempt,
|
|
354
378
|
agentName,
|
|
355
379
|
dagTitle: null,
|
|
@@ -371,28 +395,6 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
371
395
|
createdAt: now,
|
|
372
396
|
updatedAt: now,
|
|
373
397
|
};
|
|
374
|
-
const titleResult = await titleMasterPromise;
|
|
375
|
-
if (titleResult) {
|
|
376
|
-
this.logger.info('TitleMaster generated Result for clarification');
|
|
377
|
-
baseInsertData.dagTitle = titleResult.title;
|
|
378
|
-
planningAttempts.push({
|
|
379
|
-
attempt,
|
|
380
|
-
reason: 'title_master',
|
|
381
|
-
usage: titleResult.usage,
|
|
382
|
-
costUsd: titleResult.costUsd,
|
|
383
|
-
generationStats: titleResult.generationStats,
|
|
384
|
-
});
|
|
385
|
-
if (titleResult.usage) {
|
|
386
|
-
planningUsageTotal.promptTokens += titleResult.usage.promptTokens ?? 0;
|
|
387
|
-
planningUsageTotal.completionTokens += titleResult.usage.completionTokens ?? 0;
|
|
388
|
-
planningUsageTotal.totalTokens += titleResult.usage.totalTokens ?? 0;
|
|
389
|
-
}
|
|
390
|
-
if (titleResult.costUsd != null) {
|
|
391
|
-
planningCostTotal += titleResult.costUsd;
|
|
392
|
-
}
|
|
393
|
-
baseInsertData.planningTotalUsage = planningUsageTotal;
|
|
394
|
-
baseInsertData.planningTotalCostUsd = planningCostTotal.toString();
|
|
395
|
-
}
|
|
396
398
|
try {
|
|
397
399
|
await this.db.insert(dags).values(baseInsertData);
|
|
398
400
|
}
|
|
@@ -402,6 +404,9 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
402
404
|
throw new Error(`Database insert failed for clarification DAG ${dagId}: ${errorMessage}`);
|
|
403
405
|
}
|
|
404
406
|
this.logger.info({ dagId, agentName, clarificationQuery: dag.clarification_query }, 'Clarification DAG saved to database');
|
|
407
|
+
// Fire-and-forget: update title and generation stats in the background
|
|
408
|
+
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
409
|
+
this.backgroundUpdateDag(dagId, attemptGenStatsPromise, attemptGenerationId, titleMasterPromise, [...planningAttempts], { ...planningUsageTotal }, planningCostTotal, attempt);
|
|
405
410
|
return {
|
|
406
411
|
status: 'clarification_required',
|
|
407
412
|
dagId,
|
|
@@ -414,15 +419,12 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
414
419
|
const dagId = generateDAGId();
|
|
415
420
|
const now = new Date();
|
|
416
421
|
this.logger.info({ dagId }, "DagID Generated");
|
|
417
|
-
// Run TitleMaster generation in parallel with preparing insert data
|
|
418
|
-
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
419
|
-
// Prepare base insert data (doesn't need title yet)
|
|
420
422
|
const baseInsertData = {
|
|
421
423
|
id: dagId,
|
|
422
424
|
status: 'success',
|
|
423
425
|
result: dag,
|
|
424
426
|
usage: usage,
|
|
425
|
-
generationStats:
|
|
427
|
+
generationStats: null,
|
|
426
428
|
attempts: attempt,
|
|
427
429
|
agentName,
|
|
428
430
|
dagTitle: null,
|
|
@@ -444,31 +446,6 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
444
446
|
createdAt: now,
|
|
445
447
|
updatedAt: now,
|
|
446
448
|
};
|
|
447
|
-
// Wait for title generation (runs in parallel with data prep above)
|
|
448
|
-
const titleResult = await titleMasterPromise;
|
|
449
|
-
if (titleResult) {
|
|
450
|
-
this.logger.info('TitleMaster generated Result');
|
|
451
|
-
baseInsertData.dagTitle = titleResult.title;
|
|
452
|
-
planningAttempts.push({
|
|
453
|
-
attempt,
|
|
454
|
-
reason: 'title_master',
|
|
455
|
-
usage: titleResult.usage,
|
|
456
|
-
costUsd: titleResult.costUsd,
|
|
457
|
-
generationStats: titleResult.generationStats,
|
|
458
|
-
});
|
|
459
|
-
if (titleResult.usage) {
|
|
460
|
-
planningUsageTotal.promptTokens += titleResult.usage.promptTokens ?? 0;
|
|
461
|
-
planningUsageTotal.completionTokens += titleResult.usage.completionTokens ?? 0;
|
|
462
|
-
planningUsageTotal.totalTokens += titleResult.usage.totalTokens ?? 0;
|
|
463
|
-
}
|
|
464
|
-
if (titleResult.costUsd != null) {
|
|
465
|
-
planningCostTotal += titleResult.costUsd;
|
|
466
|
-
}
|
|
467
|
-
// Update the totals in insert data
|
|
468
|
-
baseInsertData.planningTotalUsage = planningUsageTotal;
|
|
469
|
-
baseInsertData.planningTotalCostUsd = planningCostTotal.toString();
|
|
470
|
-
}
|
|
471
|
-
this.logger.info('Base insert data prepared');
|
|
472
449
|
try {
|
|
473
450
|
await this.db.insert(dags).values(baseInsertData);
|
|
474
451
|
}
|
|
@@ -477,14 +454,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
477
454
|
this.logger.error({ err: dbError, dagId, goalText: showGoalText }, 'Failed to insert DAG into database');
|
|
478
455
|
throw new Error(`Database insert failed for DAG ${dagId}: ${errorMessage}`);
|
|
479
456
|
}
|
|
480
|
-
this.logger.info({
|
|
481
|
-
dagId,
|
|
482
|
-
agentName,
|
|
483
|
-
goalText: showGoalText,
|
|
484
|
-
cronSchedule,
|
|
485
|
-
scheduleActive,
|
|
486
|
-
planningCost: planningCostTotal,
|
|
487
|
-
}, 'DAG saved to database');
|
|
457
|
+
this.logger.info({ dagId, agentName, goalText: showGoalText, cronSchedule, scheduleActive }, 'DAG saved to database');
|
|
488
458
|
if (this.scheduler && cronSchedule && scheduleActive) {
|
|
489
459
|
this.scheduler.registerDAGSchedule({
|
|
490
460
|
id: dagId,
|
|
@@ -494,6 +464,9 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
494
464
|
});
|
|
495
465
|
this.logger.info({ dagId, cronSchedule, timezone }, 'DAG schedule registered');
|
|
496
466
|
}
|
|
467
|
+
// Fire-and-forget: update title and generation stats in the background
|
|
468
|
+
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
469
|
+
this.backgroundUpdateDag(dagId, attemptGenStatsPromise, attemptGenerationId, titleMasterPromise, [...planningAttempts], { ...planningUsageTotal }, planningCostTotal, attempt);
|
|
497
470
|
return { status: 'success', dagId };
|
|
498
471
|
}
|
|
499
472
|
if (dag.validation.gaps && dag.validation.gaps.length > 0) {
|
|
@@ -508,13 +481,12 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
508
481
|
const dagId = generateDAGId();
|
|
509
482
|
const now = new Date();
|
|
510
483
|
this.logger.info({ dagId }, 'DagID Generated for low-coverage DAG');
|
|
511
|
-
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
512
484
|
const baseInsertData = {
|
|
513
485
|
id: dagId,
|
|
514
486
|
status: 'success',
|
|
515
487
|
result: dag,
|
|
516
488
|
usage: usage,
|
|
517
|
-
generationStats:
|
|
489
|
+
generationStats: null,
|
|
518
490
|
attempts: attempt,
|
|
519
491
|
agentName,
|
|
520
492
|
dagTitle: null,
|
|
@@ -536,28 +508,6 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
536
508
|
createdAt: now,
|
|
537
509
|
updatedAt: now,
|
|
538
510
|
};
|
|
539
|
-
const titleResult = await titleMasterPromise;
|
|
540
|
-
if (titleResult) {
|
|
541
|
-
this.logger.info('TitleMaster generated Result for low-coverage DAG');
|
|
542
|
-
baseInsertData.dagTitle = titleResult.title;
|
|
543
|
-
planningAttempts.push({
|
|
544
|
-
attempt,
|
|
545
|
-
reason: 'title_master',
|
|
546
|
-
usage: titleResult.usage,
|
|
547
|
-
costUsd: titleResult.costUsd,
|
|
548
|
-
generationStats: titleResult.generationStats,
|
|
549
|
-
});
|
|
550
|
-
if (titleResult.usage) {
|
|
551
|
-
planningUsageTotal.promptTokens += titleResult.usage.promptTokens ?? 0;
|
|
552
|
-
planningUsageTotal.completionTokens += titleResult.usage.completionTokens ?? 0;
|
|
553
|
-
planningUsageTotal.totalTokens += titleResult.usage.totalTokens ?? 0;
|
|
554
|
-
}
|
|
555
|
-
if (titleResult.costUsd != null) {
|
|
556
|
-
planningCostTotal += titleResult.costUsd;
|
|
557
|
-
}
|
|
558
|
-
baseInsertData.planningTotalUsage = planningUsageTotal;
|
|
559
|
-
baseInsertData.planningTotalCostUsd = planningCostTotal.toString();
|
|
560
|
-
}
|
|
561
511
|
try {
|
|
562
512
|
await this.db.insert(dags).values(baseInsertData);
|
|
563
513
|
}
|
|
@@ -567,6 +517,9 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
567
517
|
throw new Error(`Database insert failed for low-coverage DAG ${dagId}: ${errorMessage}`);
|
|
568
518
|
}
|
|
569
519
|
this.logger.info({ dagId, agentName }, 'Low-coverage DAG saved to database');
|
|
520
|
+
// Fire-and-forget: update title and generation stats in the background
|
|
521
|
+
const titleMasterPromise = this.generateTitleAsync(activeLLMProvider, goalText, options.abortSignal);
|
|
522
|
+
this.backgroundUpdateDag(dagId, attemptGenStatsPromise, attemptGenerationId, titleMasterPromise, [...planningAttempts], { ...planningUsageTotal }, planningCostTotal, attempt);
|
|
570
523
|
return { status: 'success', dagId };
|
|
571
524
|
}
|
|
572
525
|
throw new ValidationError(`Failed to create DAG after ${maxAttempts} attempts`, 'attempts', maxAttempts);
|
|
@@ -597,7 +550,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
597
550
|
this.logger.info({ dagId, originalGoalText: truncateForLog(originalGoalText) }, 'Resuming clarification DAG');
|
|
598
551
|
const planningResult = await this.createFromGoal({
|
|
599
552
|
goalText: augmentedGoalText,
|
|
600
|
-
agentName: params?.agentName || existingDag.agentName || '
|
|
553
|
+
agentName: params?.agentName || existingDag.agentName || process.env.DEFAULT_DECOMPOSER_AGENT || 'DecomposerV8',
|
|
601
554
|
provider: params?.provider,
|
|
602
555
|
model: params?.model,
|
|
603
556
|
temperature: params?.temperature ?? 0.7,
|
|
@@ -694,6 +647,11 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
694
647
|
llmProvider: this.llmProvider,
|
|
695
648
|
toolRegistry: this.toolRegistry,
|
|
696
649
|
artifactsDir: this.artifactsDir,
|
|
650
|
+
apiKey: this.apiKey,
|
|
651
|
+
ollamaBaseUrl: this.ollamaBaseUrl,
|
|
652
|
+
skipGenerationStats: this.skipGenerationStats,
|
|
653
|
+
skillRegistry: this.skillRegistry,
|
|
654
|
+
statsQueue: this.statsQueue,
|
|
697
655
|
});
|
|
698
656
|
// Start execution in background - don't await
|
|
699
657
|
dagExecutor.execute(job, executionId, dagId, originalGoalText, _options?.executionConfig).catch((error) => {
|
|
@@ -711,7 +669,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
711
669
|
}
|
|
712
670
|
// For 'running' executions, only allow resume if they are stale (no recent update)
|
|
713
671
|
if (execution.status === 'running') {
|
|
714
|
-
const staleMinutes =
|
|
672
|
+
const staleMinutes = this.staleExecutionMinutes;
|
|
715
673
|
const staleThreshold = new Date(Date.now() - staleMinutes * 60 * 1000);
|
|
716
674
|
const lastActivity = execution.updatedAt || execution.startedAt;
|
|
717
675
|
if (lastActivity && new Date(lastActivity) > staleThreshold) {
|
|
@@ -751,6 +709,11 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
751
709
|
llmProvider: this.llmProvider,
|
|
752
710
|
toolRegistry: this.toolRegistry,
|
|
753
711
|
artifactsDir: this.artifactsDir,
|
|
712
|
+
apiKey: this.apiKey,
|
|
713
|
+
ollamaBaseUrl: this.ollamaBaseUrl,
|
|
714
|
+
skipGenerationStats: this.skipGenerationStats,
|
|
715
|
+
skillRegistry: this.skillRegistry,
|
|
716
|
+
statsQueue: this.statsQueue,
|
|
754
717
|
});
|
|
755
718
|
// Start execution in background - don't await
|
|
756
719
|
dagExecutor.execute(job, executionId, execution.dagId, originalGoalText, executionConfig).catch((error) => {
|
|
@@ -810,7 +773,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
810
773
|
taskResults.set(taskId, snapshot.result);
|
|
811
774
|
}
|
|
812
775
|
const globalContext = this.buildGlobalContext(job);
|
|
813
|
-
const llmExecuteTool = new LlmExecuteTool();
|
|
776
|
+
const llmExecuteTool = new LlmExecuteTool({ apiKey: this.apiKey, baseUrl: this.ollamaBaseUrl, skipGenerationStats: this.skipGenerationStats });
|
|
814
777
|
const overrideProvider = params?.provider;
|
|
815
778
|
const overrideModel = params?.model;
|
|
816
779
|
try {
|
|
@@ -865,6 +828,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
865
828
|
runId: `redo-inference-${Date.now()}`,
|
|
866
829
|
executionId,
|
|
867
830
|
subStepId: pendingSubStepId,
|
|
831
|
+
artifactsDir: this.artifactsDir,
|
|
868
832
|
});
|
|
869
833
|
await this.db.update(dagSubSteps)
|
|
870
834
|
.set({
|
|
@@ -1118,6 +1082,7 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
1118
1082
|
temperature: 0.7,
|
|
1119
1083
|
maxTokens: 100,
|
|
1120
1084
|
abortSignal,
|
|
1085
|
+
deferGenerationStats: true,
|
|
1121
1086
|
});
|
|
1122
1087
|
const title = titleResponse.content.trim();
|
|
1123
1088
|
this.logger.info({ dagTitle: title }, 'Generated DAG title from TitleMaster');
|
|
@@ -1133,6 +1098,120 @@ Respond with ONLY the expected output format. Build upon dependencies for cohere
|
|
|
1133
1098
|
return null;
|
|
1134
1099
|
}
|
|
1135
1100
|
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Fire-and-forget: resolves generation stats + title in the background and updates the DAG row.
|
|
1103
|
+
*/
|
|
1104
|
+
backgroundUpdateDag(dagId, genStatsPromise, generationId, titlePromise, planningAttempts, planningUsageTotal, planningCostTotal, attempt) {
|
|
1105
|
+
// When statsQueue is available, offload generation stats to the background worker
|
|
1106
|
+
if (this.statsQueue && generationId) {
|
|
1107
|
+
this.statsQueue.enqueue({
|
|
1108
|
+
table: 'dags',
|
|
1109
|
+
id: dagId,
|
|
1110
|
+
generationId,
|
|
1111
|
+
attemptIndex: planningAttempts.length - 1,
|
|
1112
|
+
});
|
|
1113
|
+
// Still handle title in main thread (per requirement)
|
|
1114
|
+
const run = async () => {
|
|
1115
|
+
const updateData = {};
|
|
1116
|
+
try {
|
|
1117
|
+
const titleResult = await titlePromise;
|
|
1118
|
+
if (titleResult) {
|
|
1119
|
+
updateData.dagTitle = titleResult.title;
|
|
1120
|
+
planningAttempts.push({
|
|
1121
|
+
attempt,
|
|
1122
|
+
reason: 'title_master',
|
|
1123
|
+
usage: titleResult.usage,
|
|
1124
|
+
costUsd: titleResult.costUsd,
|
|
1125
|
+
generationStats: titleResult.generationStats,
|
|
1126
|
+
});
|
|
1127
|
+
if (titleResult.usage) {
|
|
1128
|
+
planningUsageTotal.promptTokens += titleResult.usage.promptTokens ?? 0;
|
|
1129
|
+
planningUsageTotal.completionTokens += titleResult.usage.completionTokens ?? 0;
|
|
1130
|
+
planningUsageTotal.totalTokens += titleResult.usage.totalTokens ?? 0;
|
|
1131
|
+
}
|
|
1132
|
+
if (titleResult.costUsd != null) {
|
|
1133
|
+
planningCostTotal += titleResult.costUsd;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
catch (err) {
|
|
1138
|
+
this.logger.warn({ err, dagId }, 'Background: failed to generate title');
|
|
1139
|
+
}
|
|
1140
|
+
updateData.planningAttempts = planningAttempts;
|
|
1141
|
+
updateData.planningTotalUsage = planningUsageTotal;
|
|
1142
|
+
updateData.planningTotalCostUsd = planningCostTotal.toString();
|
|
1143
|
+
updateData.updatedAt = new Date();
|
|
1144
|
+
try {
|
|
1145
|
+
await this.db.update(dags).set(updateData).where(eq(dags.id, dagId));
|
|
1146
|
+
this.logger.info({ dagId, dagTitle: updateData.dagTitle }, 'Background: DAG updated with title (stats deferred to worker)');
|
|
1147
|
+
}
|
|
1148
|
+
catch (err) {
|
|
1149
|
+
this.logger.error({ err, dagId }, 'Background: failed to update DAG row');
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
run().catch(err => this.logger.error({ err, dagId }, 'Background DAG update failed'));
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
// Fallback: original inline behavior when no statsQueue
|
|
1156
|
+
const run = async () => {
|
|
1157
|
+
const updateData = {};
|
|
1158
|
+
// Resolve main generation stats
|
|
1159
|
+
if (genStatsPromise) {
|
|
1160
|
+
try {
|
|
1161
|
+
const stats = await genStatsPromise;
|
|
1162
|
+
if (stats.generationStats) {
|
|
1163
|
+
updateData.generationStats = stats.generationStats;
|
|
1164
|
+
}
|
|
1165
|
+
if (stats.costUsd != null) {
|
|
1166
|
+
planningAttempts[planningAttempts.length - 1].costUsd = stats.costUsd;
|
|
1167
|
+
planningAttempts[planningAttempts.length - 1].generationStats = stats.generationStats;
|
|
1168
|
+
planningCostTotal += stats.costUsd;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
catch (err) {
|
|
1172
|
+
this.logger.warn({ err, dagId }, 'Background: failed to fetch generation stats');
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
// Resolve title
|
|
1176
|
+
try {
|
|
1177
|
+
const titleResult = await titlePromise;
|
|
1178
|
+
if (titleResult) {
|
|
1179
|
+
updateData.dagTitle = titleResult.title;
|
|
1180
|
+
planningAttempts.push({
|
|
1181
|
+
attempt,
|
|
1182
|
+
reason: 'title_master',
|
|
1183
|
+
usage: titleResult.usage,
|
|
1184
|
+
costUsd: titleResult.costUsd,
|
|
1185
|
+
generationStats: titleResult.generationStats,
|
|
1186
|
+
});
|
|
1187
|
+
if (titleResult.usage) {
|
|
1188
|
+
planningUsageTotal.promptTokens += titleResult.usage.promptTokens ?? 0;
|
|
1189
|
+
planningUsageTotal.completionTokens += titleResult.usage.completionTokens ?? 0;
|
|
1190
|
+
planningUsageTotal.totalTokens += titleResult.usage.totalTokens ?? 0;
|
|
1191
|
+
}
|
|
1192
|
+
if (titleResult.costUsd != null) {
|
|
1193
|
+
planningCostTotal += titleResult.costUsd;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
catch (err) {
|
|
1198
|
+
this.logger.warn({ err, dagId }, 'Background: failed to generate title');
|
|
1199
|
+
}
|
|
1200
|
+
// Update DB row
|
|
1201
|
+
updateData.planningAttempts = planningAttempts;
|
|
1202
|
+
updateData.planningTotalUsage = planningUsageTotal;
|
|
1203
|
+
updateData.planningTotalCostUsd = planningCostTotal.toString();
|
|
1204
|
+
updateData.updatedAt = new Date();
|
|
1205
|
+
try {
|
|
1206
|
+
await this.db.update(dags).set(updateData).where(eq(dags.id, dagId));
|
|
1207
|
+
this.logger.info({ dagId, dagTitle: updateData.dagTitle }, 'Background: DAG updated with title and stats');
|
|
1208
|
+
}
|
|
1209
|
+
catch (err) {
|
|
1210
|
+
this.logger.error({ err, dagId }, 'Background: failed to update DAG row');
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
run().catch(err => this.logger.error({ err, dagId }, 'Background DAG update failed'));
|
|
1214
|
+
}
|
|
1136
1215
|
mapDAG(record) {
|
|
1137
1216
|
return {
|
|
1138
1217
|
id: record.id,
|