illuma-agents 1.0.17 → 1.0.19
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/cjs/agents/AgentContext.cjs +3 -1
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +18 -9
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +5 -3
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +10 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +7 -8
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +17 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +11 -6
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +2 -2
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +2 -1
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/tools.cjs +2 -2
- package/dist/cjs/messages/tools.cjs.map +1 -1
- package/dist/cjs/stream.cjs +29 -16
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/BrowserTools.cjs +473 -0
- package/dist/cjs/tools/BrowserTools.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +209 -47
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +1 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +3 -1
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/utils/contextAnalytics.cjs +7 -5
- package/dist/cjs/utils/contextAnalytics.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/cjs/utils/toonFormat.cjs +42 -12
- package/dist/cjs/utils/toonFormat.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +3 -1
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +18 -9
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +5 -3
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +10 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +7 -8
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +2 -1
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +11 -6
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +2 -2
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +2 -1
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/tools.mjs +2 -2
- package/dist/esm/messages/tools.mjs.map +1 -1
- package/dist/esm/stream.mjs +29 -16
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/BrowserTools.mjs +458 -0
- package/dist/esm/tools/BrowserTools.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +208 -48
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +1 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +3 -1
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/utils/contextAnalytics.mjs +7 -5
- package/dist/esm/utils/contextAnalytics.mjs.map +1 -1
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/esm/utils/toonFormat.mjs +42 -12
- package/dist/esm/utils/toonFormat.mjs.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/tools/BrowserTools.d.ts +244 -0
- package/dist/types/tools/ProgrammaticToolCalling.d.ts +19 -0
- package/dist/types/types/tools.d.ts +3 -1
- package/package.json +6 -2
- package/src/agents/AgentContext.ts +28 -20
- package/src/graphs/Graph.ts +76 -37
- package/src/index.ts +1 -0
- package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +495 -473
- package/src/llm/bedrock/index.ts +47 -35
- package/src/llm/openrouter/index.ts +11 -1
- package/src/llm/vertexai/index.ts +9 -10
- package/src/messages/cache.ts +104 -55
- package/src/messages/core.ts +5 -3
- package/src/messages/format.ts +6 -2
- package/src/messages/tools.ts +2 -2
- package/src/scripts/simple.ts +1 -1
- package/src/specs/emergency-prune.test.ts +407 -355
- package/src/stream.ts +28 -20
- package/src/tools/BrowserTools.test.ts +528 -0
- package/src/tools/BrowserTools.ts +582 -0
- package/src/tools/ProgrammaticToolCalling.ts +246 -52
- package/src/tools/ToolNode.ts +4 -4
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +155 -0
- package/src/tools/search/jina-reranker.test.ts +32 -28
- package/src/tools/search/search.ts +3 -1
- package/src/tools/search/tool.ts +16 -7
- package/src/types/tools.ts +3 -1
- package/src/utils/contextAnalytics.ts +103 -95
- package/src/utils/llmConfig.ts +8 -1
- package/src/utils/run.ts +5 -4
- package/src/utils/toonFormat.ts +475 -437
package/src/graphs/Graph.ts
CHANGED
|
@@ -57,7 +57,10 @@ import {
|
|
|
57
57
|
joinKeys,
|
|
58
58
|
sleep,
|
|
59
59
|
} from '@/utils';
|
|
60
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
buildContextAnalytics,
|
|
62
|
+
type ContextAnalytics,
|
|
63
|
+
} from '@/utils/contextAnalytics';
|
|
61
64
|
import { getChatModelClass, manualToolStreamProviders } from '@/llm/providers';
|
|
62
65
|
import { ToolNode as CustomToolNode, toolsCondition } from '@/tools/ToolNode';
|
|
63
66
|
import { ChatOpenAI, AzureChatOpenAI } from '@/llm/openai';
|
|
@@ -214,7 +217,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
214
217
|
/**
|
|
215
218
|
* Estimates a human-friendly description of the conversation timeframe based on message count.
|
|
216
219
|
* Uses rough heuristics to provide context about how much history is available.
|
|
217
|
-
*
|
|
220
|
+
*
|
|
218
221
|
* @param messageCount - Number of messages in the remaining context
|
|
219
222
|
* @returns A friendly description like "the last few minutes", "the past hour", etc.
|
|
220
223
|
*/
|
|
@@ -224,7 +227,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
224
227
|
// - Normal chat: ~10-15 messages per hour
|
|
225
228
|
// - Slow/thoughtful chat: ~5-8 messages per hour
|
|
226
229
|
// We use a middle estimate of ~12 messages per hour
|
|
227
|
-
|
|
230
|
+
|
|
228
231
|
if (messageCount <= 5) {
|
|
229
232
|
return 'just the last few exchanges';
|
|
230
233
|
} else if (messageCount <= 15) {
|
|
@@ -712,7 +715,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
712
715
|
content: `[SESSION_CONTEXT]\n${agentContext.dynamicContext}`,
|
|
713
716
|
});
|
|
714
717
|
const ackMessage = new AIMessageChunk({
|
|
715
|
-
content:
|
|
718
|
+
content:
|
|
719
|
+
'Understood. I have noted the session context including the current date/time (CST) and will apply it appropriately.',
|
|
716
720
|
});
|
|
717
721
|
messages = [dynamicContextMessage, ackMessage, ...messages];
|
|
718
722
|
}
|
|
@@ -745,7 +749,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
745
749
|
this.config = config;
|
|
746
750
|
|
|
747
751
|
let messagesToUse = messages;
|
|
748
|
-
|
|
752
|
+
|
|
749
753
|
if (
|
|
750
754
|
!agentContext.pruneMessages &&
|
|
751
755
|
agentContext.tokenCounter &&
|
|
@@ -829,7 +833,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
829
833
|
* Handle edge case: when switching from a non-thinking agent to a thinking-enabled agent,
|
|
830
834
|
* convert AI messages with tool calls to HumanMessages to avoid thinking block requirements.
|
|
831
835
|
* This is required by Anthropic/Bedrock when thinking is enabled.
|
|
832
|
-
*
|
|
836
|
+
*
|
|
833
837
|
* IMPORTANT: This MUST happen BEFORE cache control is applied.
|
|
834
838
|
* If we add cachePoint to an AI message first, then convert that AI message to a HumanMessage,
|
|
835
839
|
* the cachePoint is lost. By converting first, we ensure cache control is applied to the
|
|
@@ -873,7 +877,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
873
877
|
// Both Claude and Nova models support cachePoint in system and messages
|
|
874
878
|
// (Llama, Titan, and other models do NOT support cachePoint)
|
|
875
879
|
const modelId = bedrockOptions?.model?.toLowerCase() ?? '';
|
|
876
|
-
const supportsCaching =
|
|
880
|
+
const supportsCaching =
|
|
881
|
+
modelId.includes('claude') ||
|
|
882
|
+
modelId.includes('anthropic') ||
|
|
883
|
+
modelId.includes('nova');
|
|
877
884
|
if (bedrockOptions?.promptCache === true && supportsCaching) {
|
|
878
885
|
finalMessages = addBedrockCacheControl<BaseMessage>(finalMessages);
|
|
879
886
|
}
|
|
@@ -909,10 +916,17 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
909
916
|
}
|
|
910
917
|
|
|
911
918
|
// Get model info for analytics
|
|
912
|
-
const bedrockOpts = agentContext.clientOptions as
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
919
|
+
const bedrockOpts = agentContext.clientOptions as
|
|
920
|
+
| t.BedrockAnthropicClientOptions
|
|
921
|
+
| undefined;
|
|
922
|
+
const modelId =
|
|
923
|
+
bedrockOpts?.model ||
|
|
924
|
+
(agentContext.clientOptions as t.AnthropicClientOptions | undefined)
|
|
925
|
+
?.modelName;
|
|
926
|
+
const thinkingConfig =
|
|
927
|
+
bedrockOpts?.additionalModelRequestFields?.['thinking'] ||
|
|
928
|
+
(agentContext.clientOptions as t.AnthropicClientOptions | undefined)
|
|
929
|
+
?.thinking;
|
|
916
930
|
|
|
917
931
|
// Build and emit context analytics for traces
|
|
918
932
|
const contextAnalytics = buildContextAnalytics(finalMessages, {
|
|
@@ -921,10 +935,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
921
935
|
instructionTokens: agentContext.instructionTokens,
|
|
922
936
|
indexTokenCountMap: agentContext.indexTokenCountMap,
|
|
923
937
|
});
|
|
924
|
-
|
|
938
|
+
|
|
925
939
|
// Store for retrieval via getContextAnalytics() after run completes
|
|
926
940
|
this.lastContextAnalytics = contextAnalytics;
|
|
927
|
-
|
|
941
|
+
|
|
928
942
|
await safeDispatchCustomEvent(
|
|
929
943
|
GraphEvents.ON_CONTEXT_ANALYTICS,
|
|
930
944
|
{
|
|
@@ -949,8 +963,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
949
963
|
);
|
|
950
964
|
} catch (primaryError) {
|
|
951
965
|
// Check if this is a "input too long" error from Bedrock/Anthropic
|
|
952
|
-
const errorMessage =
|
|
953
|
-
|
|
966
|
+
const errorMessage =
|
|
967
|
+
(primaryError as Error).message.toLowerCase() ?? '';
|
|
968
|
+
const isInputTooLongError =
|
|
954
969
|
errorMessage.includes('too long') ||
|
|
955
970
|
errorMessage.includes('input is too long') ||
|
|
956
971
|
errorMessage.includes('context length') ||
|
|
@@ -960,41 +975,50 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
960
975
|
|
|
961
976
|
// Log when we detect the error
|
|
962
977
|
if (isInputTooLongError) {
|
|
963
|
-
console.warn(
|
|
978
|
+
console.warn(
|
|
979
|
+
'[Graph] Detected input too long error:',
|
|
980
|
+
errorMessage.substring(0, 200)
|
|
981
|
+
);
|
|
964
982
|
console.warn('[Graph] Checking emergency pruning conditions:', {
|
|
965
983
|
hasPruneMessages: !!agentContext.pruneMessages,
|
|
966
984
|
hasTokenCounter: !!agentContext.tokenCounter,
|
|
967
985
|
maxContextTokens: agentContext.maxContextTokens,
|
|
968
|
-
indexTokenMapKeys: Object.keys(agentContext.indexTokenCountMap)
|
|
986
|
+
indexTokenMapKeys: Object.keys(agentContext.indexTokenCountMap)
|
|
987
|
+
.length,
|
|
969
988
|
});
|
|
970
989
|
}
|
|
971
990
|
|
|
972
991
|
// If input too long and we have pruning capability OR tokenCounter, retry with progressively more aggressive pruning
|
|
973
992
|
// Note: We can create emergency pruneMessages dynamically if we have tokenCounter and maxContextTokens
|
|
974
|
-
const canPrune =
|
|
993
|
+
const canPrune =
|
|
994
|
+
agentContext.tokenCounter && agentContext.maxContextTokens;
|
|
975
995
|
if (isInputTooLongError && canPrune) {
|
|
976
996
|
// Progressive reduction: 50% -> 25% -> 10% of original context
|
|
977
997
|
const reductionLevels = [0.5, 0.25, 0.1];
|
|
978
|
-
|
|
998
|
+
|
|
979
999
|
for (const reductionFactor of reductionLevels) {
|
|
980
1000
|
if (result) break; // Exit if we got a result
|
|
981
|
-
|
|
982
|
-
const reducedMaxTokens = Math.floor(
|
|
1001
|
+
|
|
1002
|
+
const reducedMaxTokens = Math.floor(
|
|
1003
|
+
agentContext.maxContextTokens! * reductionFactor
|
|
1004
|
+
);
|
|
983
1005
|
console.warn(
|
|
984
1006
|
`[Graph] Input too long. Retrying with ${reductionFactor * 100}% context (${reducedMaxTokens} tokens)...`
|
|
985
1007
|
);
|
|
986
|
-
|
|
1008
|
+
|
|
987
1009
|
// Build fresh indexTokenCountMap if missing/incomplete
|
|
988
1010
|
// This is needed when messages were dynamically added without updating the token map
|
|
989
1011
|
let tokenMapForPruning = agentContext.indexTokenCountMap;
|
|
990
1012
|
if (Object.keys(tokenMapForPruning).length < messages.length) {
|
|
991
|
-
console.warn(
|
|
1013
|
+
console.warn(
|
|
1014
|
+
'[Graph] Building fresh token count map for emergency pruning...'
|
|
1015
|
+
);
|
|
992
1016
|
tokenMapForPruning = {};
|
|
993
1017
|
for (let i = 0; i < messages.length; i++) {
|
|
994
1018
|
tokenMapForPruning[i] = agentContext.tokenCounter!(messages[i]);
|
|
995
1019
|
}
|
|
996
1020
|
}
|
|
997
|
-
|
|
1021
|
+
|
|
998
1022
|
const emergencyPrune = createPruneMessages({
|
|
999
1023
|
startIndex: this.startIndex,
|
|
1000
1024
|
provider: agentContext.provider,
|
|
@@ -1011,15 +1035,18 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
1011
1035
|
|
|
1012
1036
|
// Skip if we can't fit any messages
|
|
1013
1037
|
if (reducedMessages.length === 0) {
|
|
1014
|
-
console.warn(
|
|
1038
|
+
console.warn(
|
|
1039
|
+
`[Graph] Cannot fit any messages at ${reductionFactor * 100}% reduction, trying next level...`
|
|
1040
|
+
);
|
|
1015
1041
|
continue;
|
|
1016
1042
|
}
|
|
1017
1043
|
|
|
1018
1044
|
// Calculate how many messages were pruned and estimate context timeframe
|
|
1019
1045
|
const prunedCount = finalMessages.length - reducedMessages.length;
|
|
1020
1046
|
const remainingCount = reducedMessages.length;
|
|
1021
|
-
const estimatedContextDescription =
|
|
1022
|
-
|
|
1047
|
+
const estimatedContextDescription =
|
|
1048
|
+
this.getContextTimeframeDescription(remainingCount);
|
|
1049
|
+
|
|
1023
1050
|
// Inject a personalized context message to inform the agent about pruning
|
|
1024
1051
|
const pruneNoticeMessage = new HumanMessage({
|
|
1025
1052
|
content: `[CONTEXT NOTICE]
|
|
@@ -1027,11 +1054,11 @@ Our conversation has grown quite long, so I've focused on ${estimatedContextDesc
|
|
|
1027
1054
|
|
|
1028
1055
|
If I seem to be missing something we discussed earlier, just give me a quick reminder and I'll pick right back up! I'm still fully engaged and ready to help with whatever you need.`,
|
|
1029
1056
|
});
|
|
1030
|
-
|
|
1057
|
+
|
|
1031
1058
|
// Insert the notice after the system message (if any) but before conversation
|
|
1032
1059
|
const hasSystemMessage = reducedMessages[0]?.getType() === 'system';
|
|
1033
1060
|
const insertIndex = hasSystemMessage ? 1 : 0;
|
|
1034
|
-
|
|
1061
|
+
|
|
1035
1062
|
// Create new array with the pruning notice
|
|
1036
1063
|
const messagesWithNotice = [
|
|
1037
1064
|
...reducedMessages.slice(0, insertIndex),
|
|
@@ -1059,9 +1086,13 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1059
1086
|
| t.BedrockAnthropicClientOptions
|
|
1060
1087
|
| undefined;
|
|
1061
1088
|
const modelId = bedrockOptions?.model?.toLowerCase() ?? '';
|
|
1062
|
-
const supportsCaching =
|
|
1089
|
+
const supportsCaching =
|
|
1090
|
+
modelId.includes('claude') ||
|
|
1091
|
+
modelId.includes('anthropic') ||
|
|
1092
|
+
modelId.includes('nova');
|
|
1063
1093
|
if (bedrockOptions?.promptCache === true && supportsCaching) {
|
|
1064
|
-
retryMessages =
|
|
1094
|
+
retryMessages =
|
|
1095
|
+
addBedrockCacheControl<BaseMessage>(retryMessages);
|
|
1065
1096
|
}
|
|
1066
1097
|
}
|
|
1067
1098
|
|
|
@@ -1076,18 +1107,26 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1076
1107
|
config
|
|
1077
1108
|
);
|
|
1078
1109
|
// Success with reduced context
|
|
1079
|
-
console.info(
|
|
1110
|
+
console.info(
|
|
1111
|
+
`[Graph] ✅ Retry successful at ${reductionFactor * 100}% with ${reducedMessages.length} messages (reduced from ${finalMessages.length})`
|
|
1112
|
+
);
|
|
1080
1113
|
} catch (retryError) {
|
|
1081
|
-
const retryErrorMsg =
|
|
1082
|
-
|
|
1114
|
+
const retryErrorMsg =
|
|
1115
|
+
(retryError as Error).message.toLowerCase() ?? '';
|
|
1116
|
+
const stillTooLong =
|
|
1083
1117
|
retryErrorMsg.includes('too long') ||
|
|
1084
1118
|
retryErrorMsg.includes('context length') ||
|
|
1085
1119
|
retryErrorMsg.includes('validationexception');
|
|
1086
|
-
|
|
1120
|
+
|
|
1087
1121
|
if (stillTooLong && reductionFactor > 0.1) {
|
|
1088
|
-
console.warn(
|
|
1122
|
+
console.warn(
|
|
1123
|
+
`[Graph] Still too long at ${reductionFactor * 100}%, trying more aggressive pruning...`
|
|
1124
|
+
);
|
|
1089
1125
|
} else {
|
|
1090
|
-
console.error(
|
|
1126
|
+
console.error(
|
|
1127
|
+
`[Graph] Retry at ${reductionFactor * 100}% failed:`,
|
|
1128
|
+
(retryError as Error).message
|
|
1129
|
+
);
|
|
1091
1130
|
}
|
|
1092
1131
|
}
|
|
1093
1132
|
}
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './tools/Calculator';
|
|
|
13
13
|
export * from './tools/CodeExecutor';
|
|
14
14
|
export * from './tools/ProgrammaticToolCalling';
|
|
15
15
|
export * from './tools/ToolSearchRegex';
|
|
16
|
+
export * from './tools/BrowserTools';
|
|
16
17
|
export * from './tools/handlers';
|
|
17
18
|
export * from './tools/search';
|
|
18
19
|
|