illuma-agents 1.0.60 → 1.0.61
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/package.json
CHANGED
package/src/graphs/Graph.ts
CHANGED
|
@@ -1136,10 +1136,17 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1136
1136
|
);
|
|
1137
1137
|
|
|
1138
1138
|
// Check if structured output mode is enabled
|
|
1139
|
-
|
|
1139
|
+
// IMPORTANT: If tools are available, we need to let the model use them first.
|
|
1140
|
+
// Only use structured output when:
|
|
1141
|
+
// 1. No tools are configured, OR
|
|
1142
|
+
// 2. The model has already used tools and is ready to give final response
|
|
1143
|
+
const hasTools = agentContext.tools && agentContext.tools.length > 0;
|
|
1144
|
+
const shouldUseStructuredOutputNow =
|
|
1140
1145
|
agentContext.isStructuredOutputMode &&
|
|
1141
|
-
agentContext.structuredOutput
|
|
1142
|
-
|
|
1146
|
+
agentContext.structuredOutput &&
|
|
1147
|
+
!hasTools; // Only use structured output immediately if no tools
|
|
1148
|
+
|
|
1149
|
+
if (shouldUseStructuredOutputNow) {
|
|
1143
1150
|
const schema = agentContext.getStructuredOutputSchema();
|
|
1144
1151
|
if (!schema) {
|
|
1145
1152
|
throw new Error('Structured output schema is not configured');
|
|
@@ -1190,7 +1197,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1190
1197
|
currentModel: structuredModel,
|
|
1191
1198
|
finalMessages,
|
|
1192
1199
|
schema,
|
|
1193
|
-
structuredOutputConfig: agentContext.structuredOutput
|
|
1200
|
+
structuredOutputConfig: agentContext.structuredOutput!,
|
|
1194
1201
|
provider: agentContext.provider,
|
|
1195
1202
|
},
|
|
1196
1203
|
config
|
|
@@ -1463,6 +1470,107 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1463
1470
|
if (!result) {
|
|
1464
1471
|
throw new Error('No result after model invocation');
|
|
1465
1472
|
}
|
|
1473
|
+
|
|
1474
|
+
// Check if we need to apply structured output for the final response
|
|
1475
|
+
// This handles the case where tools were used, and now the model is giving its final answer
|
|
1476
|
+
const resultMessage = result.messages?.[0] as AIMessageChunk | undefined;
|
|
1477
|
+
const hasToolCalls = (resultMessage?.tool_calls?.length ?? 0) > 0;
|
|
1478
|
+
|
|
1479
|
+
if (
|
|
1480
|
+
agentContext.isStructuredOutputMode &&
|
|
1481
|
+
agentContext.structuredOutput &&
|
|
1482
|
+
!hasToolCalls && // Model is giving final response (no tool calls)
|
|
1483
|
+
hasTools // We skipped structured output earlier because tools were available
|
|
1484
|
+
) {
|
|
1485
|
+
const schema = agentContext.getStructuredOutputSchema();
|
|
1486
|
+
if (schema) {
|
|
1487
|
+
try {
|
|
1488
|
+
console.log('[Graph] Applying structured output for final response after tool execution');
|
|
1489
|
+
|
|
1490
|
+
// Get a fresh model for structured output
|
|
1491
|
+
const structuredClientOptions = { ...agentContext.clientOptions } as t.ClientOptions;
|
|
1492
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1493
|
+
(structuredClientOptions as any).streaming = false;
|
|
1494
|
+
|
|
1495
|
+
// Remove thinking configuration
|
|
1496
|
+
if (agentContext.provider === Providers.BEDROCK) {
|
|
1497
|
+
const bedrockOpts = structuredClientOptions as t.BedrockAnthropicClientOptions;
|
|
1498
|
+
if (bedrockOpts.additionalModelRequestFields) {
|
|
1499
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1500
|
+
const additionalFields = Object.assign({}, bedrockOpts.additionalModelRequestFields) as any;
|
|
1501
|
+
delete additionalFields.thinking;
|
|
1502
|
+
delete additionalFields.budgetTokens;
|
|
1503
|
+
bedrockOpts.additionalModelRequestFields = additionalFields;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (agentContext.provider === Providers.ANTHROPIC) {
|
|
1507
|
+
const anthropicOpts = structuredClientOptions as t.AnthropicClientOptions;
|
|
1508
|
+
if (anthropicOpts.thinking) {
|
|
1509
|
+
delete anthropicOpts.thinking;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
const structuredModel = this.getNewModel({
|
|
1514
|
+
provider: agentContext.provider,
|
|
1515
|
+
clientOptions: structuredClientOptions,
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
// Include the current result in the messages so the model knows what it just said
|
|
1519
|
+
const messagesWithResult = [...finalMessages];
|
|
1520
|
+
if (resultMessage) {
|
|
1521
|
+
messagesWithResult.push(resultMessage);
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
const { structuredResponse, rawMessage } =
|
|
1525
|
+
await this.attemptStructuredInvoke(
|
|
1526
|
+
{
|
|
1527
|
+
currentModel: structuredModel,
|
|
1528
|
+
finalMessages: messagesWithResult,
|
|
1529
|
+
schema,
|
|
1530
|
+
structuredOutputConfig: agentContext.structuredOutput!,
|
|
1531
|
+
provider: agentContext.provider,
|
|
1532
|
+
},
|
|
1533
|
+
config
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
// Emit structured output event
|
|
1537
|
+
await safeDispatchCustomEvent(
|
|
1538
|
+
GraphEvents.ON_STRUCTURED_OUTPUT,
|
|
1539
|
+
{
|
|
1540
|
+
structuredResponse,
|
|
1541
|
+
schema,
|
|
1542
|
+
raw: rawMessage,
|
|
1543
|
+
},
|
|
1544
|
+
config
|
|
1545
|
+
);
|
|
1546
|
+
|
|
1547
|
+
agentContext.currentUsage = rawMessage
|
|
1548
|
+
? this.getUsageMetadata(rawMessage)
|
|
1549
|
+
: undefined;
|
|
1550
|
+
this.cleanupSignalListener();
|
|
1551
|
+
|
|
1552
|
+
// Return clean message without tool_calls
|
|
1553
|
+
let cleanMessage: AIMessageChunk | undefined;
|
|
1554
|
+
if (rawMessage) {
|
|
1555
|
+
cleanMessage = new AIMessageChunk({
|
|
1556
|
+
content: JSON.stringify(structuredResponse, null, 2),
|
|
1557
|
+
id: rawMessage.id,
|
|
1558
|
+
response_metadata: rawMessage.response_metadata,
|
|
1559
|
+
usage_metadata: rawMessage.usage_metadata,
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
return {
|
|
1564
|
+
messages: cleanMessage ? [cleanMessage] : [],
|
|
1565
|
+
structuredResponse,
|
|
1566
|
+
};
|
|
1567
|
+
} catch (structuredError) {
|
|
1568
|
+
console.error('[Graph] Structured output failed after tool execution:', structuredError);
|
|
1569
|
+
// Fall through to return normal result
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1466
1574
|
agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
|
|
1467
1575
|
this.cleanupSignalListener();
|
|
1468
1576
|
return result;
|