@memberjunction/ai-agents 5.34.0 → 5.35.0
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/AgentRunner.d.ts +1 -21
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +69 -99
- package/dist/AgentRunner.js.map +1 -1
- package/dist/ArtifactToolManager.d.ts +57 -46
- package/dist/ArtifactToolManager.d.ts.map +1 -1
- package/dist/ArtifactToolManager.js +161 -132
- package/dist/ArtifactToolManager.js.map +1 -1
- package/dist/artifact-tools/CSVToolLibrary.d.ts +8 -0
- package/dist/artifact-tools/CSVToolLibrary.d.ts.map +1 -0
- package/dist/artifact-tools/CSVToolLibrary.js +161 -0
- package/dist/artifact-tools/CSVToolLibrary.js.map +1 -0
- package/dist/artifact-tools/DataSnapshotToolLibrary.d.ts +2 -3
- package/dist/artifact-tools/DataSnapshotToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/DataSnapshotToolLibrary.js +4 -29
- package/dist/artifact-tools/DataSnapshotToolLibrary.js.map +1 -1
- package/dist/artifact-tools/DocxToolLibrary.d.ts +2 -2
- package/dist/artifact-tools/DocxToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/DocxToolLibrary.js +2 -2
- package/dist/artifact-tools/DocxToolLibrary.js.map +1 -1
- package/dist/artifact-tools/ExcelToolLibrary.d.ts +2 -2
- package/dist/artifact-tools/ExcelToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/ExcelToolLibrary.js +4 -4
- package/dist/artifact-tools/ExcelToolLibrary.js.map +1 -1
- package/dist/artifact-tools/GenericBinaryToolLibrary.d.ts +6 -0
- package/dist/artifact-tools/GenericBinaryToolLibrary.d.ts.map +1 -0
- package/dist/artifact-tools/GenericBinaryToolLibrary.js +49 -0
- package/dist/artifact-tools/GenericBinaryToolLibrary.js.map +1 -0
- package/dist/artifact-tools/JSONToolLibrary.d.ts +2 -2
- package/dist/artifact-tools/JSONToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/JSONToolLibrary.js +2 -2
- package/dist/artifact-tools/JSONToolLibrary.js.map +1 -1
- package/dist/artifact-tools/PDFToolLibrary.d.ts +6 -3
- package/dist/artifact-tools/PDFToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/PDFToolLibrary.js +41 -20
- package/dist/artifact-tools/PDFToolLibrary.js.map +1 -1
- package/dist/artifact-tools/SearchResultSetToolLibrary.d.ts +2 -2
- package/dist/artifact-tools/SearchResultSetToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/SearchResultSetToolLibrary.js +2 -2
- package/dist/artifact-tools/SearchResultSetToolLibrary.js.map +1 -1
- package/dist/artifact-tools/TextToolLibrary.d.ts +2 -2
- package/dist/artifact-tools/TextToolLibrary.d.ts.map +1 -1
- package/dist/artifact-tools/TextToolLibrary.js +2 -2
- package/dist/artifact-tools/TextToolLibrary.js.map +1 -1
- package/dist/base-agent.d.ts +27 -12
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +153 -70
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +17 -17
package/dist/base-agent.js
CHANGED
|
@@ -792,15 +792,28 @@ export class BaseAgent {
|
|
|
792
792
|
destinations.push(`payload(${Object.keys(preloadedResult.payload).length})`);
|
|
793
793
|
}
|
|
794
794
|
this.logStatus(`📊 Preloaded ${totalSources} data source(s) for agent '${params.agent.Name}': ${destinations.join(', ')}`, true, params);
|
|
795
|
-
// Merge with existing data/context/payload (caller values take precedence)
|
|
795
|
+
// Merge with existing data/context/payload (caller values take precedence).
|
|
796
|
+
// IMPORTANT: Do NOT spread params.context — it may be a class instance
|
|
797
|
+
// whose getters/methods would be destroyed by spreading into a plain object.
|
|
798
|
+
// Instead, copy preloaded properties onto the existing context object.
|
|
796
799
|
params.data = {
|
|
797
800
|
...preloadedResult.data,
|
|
798
801
|
...params.data
|
|
799
802
|
};
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
803
|
+
if (preloadedResult.context && typeof preloadedResult.context === 'object') {
|
|
804
|
+
if (!params.context || typeof params.context !== 'object') {
|
|
805
|
+
params.context = preloadedResult.context;
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
// Copy preloaded properties onto the existing context without
|
|
809
|
+
// replacing it, so class identity (prototype, getters) is preserved.
|
|
810
|
+
for (const key of Object.keys(preloadedResult.context)) {
|
|
811
|
+
if (!(key in params.context)) {
|
|
812
|
+
params.context[key] = preloadedResult.context[key];
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
804
817
|
params.payload = {
|
|
805
818
|
...preloadedResult.payload,
|
|
806
819
|
...params.payload
|
|
@@ -978,8 +991,12 @@ export class BaseAgent {
|
|
|
978
991
|
// Reset scratchpad and artifact tools for each new execution (ephemeral per run)
|
|
979
992
|
this._scratchpadManager.Clear();
|
|
980
993
|
this._artifactToolManager.Clear();
|
|
981
|
-
// Initialize artifact tools with any input artifacts
|
|
982
|
-
|
|
994
|
+
// Initialize artifact tools with any input artifacts attached to the run.
|
|
995
|
+
// Artifacts arrive as a typed first-class field on ExecuteAgentParams —
|
|
996
|
+
// they are NOT routed through `data` because prompt-template rendering
|
|
997
|
+
// would otherwise serialize artifact bodies into the LLM payload. Only
|
|
998
|
+
// the manifest (injected via _ARTIFACT_MANIFEST below) reaches the LLM.
|
|
999
|
+
const inputArtifacts = wrappedParams.inputArtifacts;
|
|
983
1000
|
if (inputArtifacts?.length) {
|
|
984
1001
|
this._artifactToolManager.Initialize(inputArtifacts);
|
|
985
1002
|
this.logStatus(`[ArtifactTools] Initialized with ${inputArtifacts.length} artifact(s): ${inputArtifacts.map(a => `${a.typeName}:"${a.name}"`).join(', ')}`, true, params);
|
|
@@ -1335,8 +1352,7 @@ export class BaseAgent {
|
|
|
1335
1352
|
}
|
|
1336
1353
|
const injector = new AgentContextInjector();
|
|
1337
1354
|
// Parse reranker configuration if present
|
|
1338
|
-
|
|
1339
|
-
const rerankerConfigJson = agent.Get('RerankerConfiguration');
|
|
1355
|
+
const rerankerConfigJson = agent.RerankerConfiguration;
|
|
1340
1356
|
const rerankerConfig = RerankerService.Instance.parseConfiguration(rerankerConfigJson);
|
|
1341
1357
|
// Get notes if injection enabled
|
|
1342
1358
|
const notes = agent.InjectNotes
|
|
@@ -1790,12 +1806,15 @@ export class BaseAgent {
|
|
|
1790
1806
|
promptParams.data['_SCRATCHPAD_TASKS'] = this._scratchpadManager.ToPromptString();
|
|
1791
1807
|
promptParams.data['_SCRATCHPAD_TASK_SUMMARY'] = this._scratchpadManager.GetTaskSummary();
|
|
1792
1808
|
}
|
|
1793
|
-
// Inject artifact tools template variables if enabled and artifacts are present
|
|
1809
|
+
// Inject artifact tools template variables if enabled and artifacts are present.
|
|
1810
|
+
// Note: prior tool results are NO LONGER injected via a per-turn template var.
|
|
1811
|
+
// They are pushed into conversationMessages as a one-shot 'tool-result'
|
|
1812
|
+
// message at execution time (see injectArtifactToolResultsMessage) and decay
|
|
1813
|
+
// via pruneAndCompactExpiredMessages — same lifecycle as action results.
|
|
1794
1814
|
const artifactToolsEnabled = agentTypePromptParams?.includeArtifactToolsDocs !== false;
|
|
1795
1815
|
if (artifactToolsEnabled && this._artifactToolManager.HasArtifacts()) {
|
|
1796
1816
|
promptParams.data['_ARTIFACT_MANIFEST'] = this._artifactToolManager.ToManifestString();
|
|
1797
1817
|
promptParams.data['_ARTIFACT_TOOLS'] = this._artifactToolManager.GetToolDocumentation();
|
|
1798
|
-
promptParams.data['_ARTIFACT_TOOL_RESULTS'] = this._artifactToolManager.GetPendingResults();
|
|
1799
1818
|
promptParams.data['_ARTIFACT_TOOL_SUMMARY'] = this._artifactToolManager.GetSummary();
|
|
1800
1819
|
this.logStatus(`[ArtifactTools] Injected manifest into prompt: ${this._artifactToolManager.GetSummary()}`, true, params);
|
|
1801
1820
|
}
|
|
@@ -2863,7 +2882,7 @@ export class BaseAgent {
|
|
|
2863
2882
|
return payload ? JSON.stringify(payload) : null;
|
|
2864
2883
|
}
|
|
2865
2884
|
/**
|
|
2866
|
-
* Recovery Strategy 1: Remove oldest
|
|
2885
|
+
* Recovery Strategy 1: Remove oldest tool-result messages.
|
|
2867
2886
|
* Targets messages older than minAge turns for removal.
|
|
2868
2887
|
*
|
|
2869
2888
|
* @param params - Agent execution parameters
|
|
@@ -2873,10 +2892,10 @@ export class BaseAgent {
|
|
|
2873
2892
|
* @returns Result with tokens saved and strategy description
|
|
2874
2893
|
* @protected
|
|
2875
2894
|
*/
|
|
2876
|
-
|
|
2895
|
+
recoveryStrategy_RemoveOldestToolResults(params, tokensToSave, currentStepCount, minAge = 5) {
|
|
2877
2896
|
let tokensSaved = 0;
|
|
2878
2897
|
const removedIndices = [];
|
|
2879
|
-
// Find
|
|
2898
|
+
// Find tool-result messages older than minAge turns
|
|
2880
2899
|
const candidates = params.conversationMessages
|
|
2881
2900
|
.map((msg, index) => ({
|
|
2882
2901
|
message: msg,
|
|
@@ -2895,7 +2914,7 @@ export class BaseAgent {
|
|
|
2895
2914
|
break;
|
|
2896
2915
|
removedIndices.push(candidate.index);
|
|
2897
2916
|
tokensSaved += candidate.tokens;
|
|
2898
|
-
this.logStatus(`Removing
|
|
2917
|
+
this.logStatus(`Removing tool-result from ${candidate.age} turns ago (${candidate.tokens} tokens)`, true, params);
|
|
2899
2918
|
}
|
|
2900
2919
|
// Remove in reverse order to maintain indices
|
|
2901
2920
|
removedIndices.sort((a, b) => b - a).forEach(index => {
|
|
@@ -2906,17 +2925,17 @@ export class BaseAgent {
|
|
|
2906
2925
|
turn: currentStepCount,
|
|
2907
2926
|
messageIndex: index,
|
|
2908
2927
|
message: removed,
|
|
2909
|
-
reason: 'Context recovery - oldest
|
|
2928
|
+
reason: 'Context recovery - oldest tool results',
|
|
2910
2929
|
tokensSaved: this.estimateTokens(removed.content)
|
|
2911
2930
|
});
|
|
2912
2931
|
});
|
|
2913
2932
|
return {
|
|
2914
2933
|
tokensSaved,
|
|
2915
|
-
strategyName: `Removed ${removedIndices.length} old
|
|
2934
|
+
strategyName: `Removed ${removedIndices.length} old tool-results (${minAge}+ turns)`
|
|
2916
2935
|
};
|
|
2917
2936
|
}
|
|
2918
2937
|
/**
|
|
2919
|
-
* Recovery Strategy 2: Compact old
|
|
2938
|
+
* Recovery Strategy 2: Compact old tool-result messages.
|
|
2920
2939
|
* Uses smart trimming to reduce size while preserving some content.
|
|
2921
2940
|
*
|
|
2922
2941
|
* @param params - Agent execution parameters
|
|
@@ -2926,10 +2945,10 @@ export class BaseAgent {
|
|
|
2926
2945
|
* @returns Result with tokens saved and strategy description
|
|
2927
2946
|
* @protected
|
|
2928
2947
|
*/
|
|
2929
|
-
async
|
|
2948
|
+
async recoveryStrategy_CompactOldToolResults(params, tokensToSave, currentStepCount, minAge = 3) {
|
|
2930
2949
|
let tokensSaved = 0;
|
|
2931
2950
|
let compactedCount = 0;
|
|
2932
|
-
// Find
|
|
2951
|
+
// Find tool-result messages to compact
|
|
2933
2952
|
const candidates = params.conversationMessages
|
|
2934
2953
|
.map((msg, index) => ({
|
|
2935
2954
|
message: msg,
|
|
@@ -2974,16 +2993,16 @@ export class BaseAgent {
|
|
|
2974
2993
|
};
|
|
2975
2994
|
tokensSaved += saved;
|
|
2976
2995
|
compactedCount++;
|
|
2977
|
-
this.logStatus(`Compacted
|
|
2996
|
+
this.logStatus(`Compacted tool-result from ${candidate.age} turns ago (saved ${saved} tokens)`, true, params);
|
|
2978
2997
|
}
|
|
2979
2998
|
}
|
|
2980
2999
|
return {
|
|
2981
3000
|
tokensSaved,
|
|
2982
|
-
strategyName: `Compacted ${compactedCount} old
|
|
3001
|
+
strategyName: `Compacted ${compactedCount} old tool-results (${minAge}+ turns)`
|
|
2983
3002
|
};
|
|
2984
3003
|
}
|
|
2985
3004
|
/**
|
|
2986
|
-
* Recovery Strategy 3: Aggressively compact ALL
|
|
3005
|
+
* Recovery Strategy 3: Aggressively compact ALL tool-result messages.
|
|
2987
3006
|
* Used when gentler strategies haven't freed enough space.
|
|
2988
3007
|
*
|
|
2989
3008
|
* @param params - Agent execution parameters
|
|
@@ -2991,10 +3010,10 @@ export class BaseAgent {
|
|
|
2991
3010
|
* @returns Result with tokens saved and strategy description
|
|
2992
3011
|
* @protected
|
|
2993
3012
|
*/
|
|
2994
|
-
async
|
|
3013
|
+
async recoveryStrategy_CompactAllToolResults(params, tokensToSave) {
|
|
2995
3014
|
let tokensSaved = 0;
|
|
2996
3015
|
let compactedCount = 0;
|
|
2997
|
-
// Find ALL
|
|
3016
|
+
// Find ALL tool-result messages that aren't already compacted
|
|
2998
3017
|
const candidates = params.conversationMessages
|
|
2999
3018
|
.map((msg, index) => ({
|
|
3000
3019
|
message: msg,
|
|
@@ -3040,7 +3059,7 @@ export class BaseAgent {
|
|
|
3040
3059
|
}
|
|
3041
3060
|
return {
|
|
3042
3061
|
tokensSaved,
|
|
3043
|
-
strategyName: `Aggressively compacted ${compactedCount}
|
|
3062
|
+
strategyName: `Aggressively compacted ${compactedCount} tool-results`
|
|
3044
3063
|
};
|
|
3045
3064
|
}
|
|
3046
3065
|
/**
|
|
@@ -3099,7 +3118,7 @@ export class BaseAgent {
|
|
|
3099
3118
|
/**
|
|
3100
3119
|
* Attempts to recover from a context length exceeded error using multiple strategies.
|
|
3101
3120
|
* Uses escalating strategies: remove old results → compact old results → compact all → trim user message.
|
|
3102
|
-
* This approach preserves the user's original request while removing stale
|
|
3121
|
+
* This approach preserves the user's original request while removing stale tool results.
|
|
3103
3122
|
*
|
|
3104
3123
|
* @param params - Agent execution parameters (conversationMessages will be modified)
|
|
3105
3124
|
* @param payload - Current payload to carry forward
|
|
@@ -3131,10 +3150,10 @@ export class BaseAgent {
|
|
|
3131
3150
|
const currentPromptTurn = this._promptTurnCount;
|
|
3132
3151
|
// Try multiple recovery strategies in order
|
|
3133
3152
|
const strategies = [
|
|
3134
|
-
() => this.
|
|
3135
|
-
() => this.
|
|
3136
|
-
() => this.
|
|
3137
|
-
() => this.
|
|
3153
|
+
() => this.recoveryStrategy_RemoveOldestToolResults(params, tokensToSave, currentPromptTurn, 5),
|
|
3154
|
+
() => this.recoveryStrategy_CompactOldToolResults(params, tokensToSave, currentPromptTurn, 3),
|
|
3155
|
+
() => this.recoveryStrategy_RemoveOldestToolResults(params, tokensToSave, currentPromptTurn, 2),
|
|
3156
|
+
() => this.recoveryStrategy_CompactAllToolResults(params, tokensToSave),
|
|
3138
3157
|
() => Promise.resolve(this.recoveryStrategy_TrimLastUserMessage(params, tokensToSave))
|
|
3139
3158
|
];
|
|
3140
3159
|
let tokensSaved = 0;
|
|
@@ -3203,30 +3222,88 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
3203
3222
|
return guardrailCheckedStep;
|
|
3204
3223
|
}
|
|
3205
3224
|
/**
|
|
3206
|
-
*
|
|
3225
|
+
* Executes a batch of artifact tool calls, recording each as its own
|
|
3226
|
+
* `Tool` AIAgentRunStep (a sibling of the Prompt step that requested them)
|
|
3227
|
+
* with full inputs/outputs captured in InputData/OutputData. Returns the
|
|
3228
|
+
* stored results so the caller can render them into a single recall-friendly
|
|
3229
|
+
* message for the next prompt turn.
|
|
3230
|
+
*
|
|
3231
|
+
* Step naming convention: `Artifact Tool: {toolName}` for log/UI clarity.
|
|
3207
3232
|
*
|
|
3208
|
-
* @param {AgentAction[]} actions - The actions that were executed
|
|
3209
|
-
* @param {any[]} results - The results from action execution
|
|
3210
|
-
* @returns {ChatMessage} A formatted message with action results
|
|
3211
3233
|
* @protected
|
|
3212
3234
|
*/
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3235
|
+
async executeArtifactToolCallsAsSteps(calls, params) {
|
|
3236
|
+
// No parentId: artifact tool steps are siblings of the prompt step that
|
|
3237
|
+
// requested them, matching how action steps render. ParentID is reserved
|
|
3238
|
+
// for genuine control-flow nesting (ForEach/While loops, sub-agents), which
|
|
3239
|
+
// artifact tools are never dispatched from.
|
|
3240
|
+
const results = await Promise.all(calls.map(async (call) => {
|
|
3241
|
+
const toolStep = await this.createStepEntity({
|
|
3242
|
+
stepType: 'Tool',
|
|
3243
|
+
stepName: `Artifact Tool: ${call.tool}`,
|
|
3244
|
+
contextUser: params.contextUser,
|
|
3245
|
+
inputData: {
|
|
3246
|
+
artifactId: call.artifactId,
|
|
3247
|
+
tool: call.tool,
|
|
3248
|
+
input: call.input,
|
|
3249
|
+
},
|
|
3250
|
+
});
|
|
3251
|
+
const stored = await this._artifactToolManager.ExecuteSingleToolCall(call);
|
|
3252
|
+
await this.finalizeStepEntity(toolStep, stored.result.success, stored.result.success ? undefined : stored.result.errorMessage, {
|
|
3253
|
+
artifactId: stored.artifactId,
|
|
3254
|
+
tool: stored.tool,
|
|
3255
|
+
input: stored.input,
|
|
3256
|
+
result: stored.result,
|
|
3257
|
+
durationMs: stored.durationMs,
|
|
3258
|
+
});
|
|
3259
|
+
return stored;
|
|
3260
|
+
}));
|
|
3261
|
+
return results;
|
|
3262
|
+
}
|
|
3263
|
+
/**
|
|
3264
|
+
* Pushes a single user-role message containing rendered artifact-tool
|
|
3265
|
+
* results into the conversation. This mirrors the action-result
|
|
3266
|
+
* "inject once, then expire" pattern — the LLM sees the results on its
|
|
3267
|
+
* next turn, and older messages are pruned/compacted by
|
|
3268
|
+
* `pruneAndCompactExpiredMessages` instead of being re-rendered into
|
|
3269
|
+
* every system-prompt turn.
|
|
3270
|
+
*
|
|
3271
|
+
* @protected
|
|
3272
|
+
*/
|
|
3273
|
+
injectArtifactToolResultsMessage(params, toolResults) {
|
|
3274
|
+
if (toolResults.length === 0)
|
|
3275
|
+
return;
|
|
3276
|
+
const header = toolResults.length === 1
|
|
3277
|
+
? 'Artifact tool result:'
|
|
3278
|
+
: `Artifact tool results (${toolResults.length} calls):`;
|
|
3279
|
+
const body = toolResults.map((r, i) => {
|
|
3280
|
+
const heading = `### ${i + 1}. ${r.artifactId}.${r.tool}(${JSON.stringify(r.input)})`;
|
|
3281
|
+
if (r.result.success) {
|
|
3282
|
+
const data = typeof r.result.data === 'string'
|
|
3283
|
+
? r.result.data
|
|
3284
|
+
: JSON.stringify(r.result.data, null, 2);
|
|
3285
|
+
return `${heading}\n\`\`\`json\n${data}\n\`\`\``;
|
|
3286
|
+
}
|
|
3287
|
+
return `${heading}\n**Error:** ${r.result.errorMessage}`;
|
|
3288
|
+
}).join('\n\n');
|
|
3289
|
+
const message = {
|
|
3227
3290
|
role: 'user',
|
|
3228
|
-
content:
|
|
3291
|
+
content: `${header}\n${body}`,
|
|
3292
|
+
metadata: {
|
|
3293
|
+
turnAdded: this._promptTurnCount,
|
|
3294
|
+
messageType: 'tool-result',
|
|
3295
|
+
// Default: keep results visible for a few turns then compact to a
|
|
3296
|
+
// first-N-chars preview. The LLM is taught (via the loop-agent
|
|
3297
|
+
// system prompt) that older tool results are summarised and that
|
|
3298
|
+
// it can re-call the tool if it needs the full result back.
|
|
3299
|
+
expirationTurns: 3,
|
|
3300
|
+
expirationMode: 'Compact',
|
|
3301
|
+
compactMode: 'First N Chars',
|
|
3302
|
+
compactLength: 500,
|
|
3303
|
+
compactPromptId: '',
|
|
3304
|
+
},
|
|
3229
3305
|
};
|
|
3306
|
+
params.conversationMessages.push(message);
|
|
3230
3307
|
}
|
|
3231
3308
|
/**
|
|
3232
3309
|
* Creates a chat message containing sub-agent execution results.
|
|
@@ -3491,16 +3568,16 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
3491
3568
|
Value: value,
|
|
3492
3569
|
Type: 'Input'
|
|
3493
3570
|
}));
|
|
3494
|
-
// Build action context: preserve the agent's context
|
|
3495
|
-
//
|
|
3496
|
-
//
|
|
3497
|
-
//
|
|
3498
|
-
|
|
3499
|
-
const actionContext = {
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
}
|
|
3571
|
+
// Build action context: preserve the agent's context by reference
|
|
3572
|
+
// (do NOT spread — spreading destroys class instances, losing
|
|
3573
|
+
// getters/methods on typed contexts like SkipAgentContext).
|
|
3574
|
+
// Stamp the calling agent's identity and resolved storage account ID
|
|
3575
|
+
// directly onto the original context object.
|
|
3576
|
+
const actionContext = typeof params.context === 'object' && params.context ? params.context : {};
|
|
3577
|
+
actionContext.AgentID = params.agent.ID;
|
|
3578
|
+
if (this._resolvedStorageAccountId) {
|
|
3579
|
+
actionContext.__resolvedStorageAccountId = this._resolvedStorageAccountId;
|
|
3580
|
+
}
|
|
3504
3581
|
// Execute the action and return the full ActionResult
|
|
3505
3582
|
const result = await actionEngine.RunAction({
|
|
3506
3583
|
Action: actionEntity,
|
|
@@ -4673,8 +4750,8 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
4673
4750
|
return await this.processSubAgentStep(params, previousDecision, undefined, undefined, stepCount);
|
|
4674
4751
|
case 'Actions':
|
|
4675
4752
|
return await this.executeActionsStep(params, previousDecision, undefined, true, stepCount);
|
|
4676
|
-
// Type assertion required because 'ClientTools' is not
|
|
4677
|
-
//
|
|
4753
|
+
// Type assertion required because 'ClientTools' is not part of the BaseAgentNextStep
|
|
4754
|
+
// step union — LoopAgentType.DetermineNextStep() emits it when the LLM chooses client tools.
|
|
4678
4755
|
case 'ClientTools':
|
|
4679
4756
|
return await this.executeClientToolsStep(params, config, previousDecision, stepCount);
|
|
4680
4757
|
case 'Chat':
|
|
@@ -4989,7 +5066,16 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
4989
5066
|
const artifactToolsExecutedThisTurn = !!(artifactToolCalls?.length);
|
|
4990
5067
|
if (artifactToolsExecutedThisTurn) {
|
|
4991
5068
|
this.logStatus(`[ArtifactTools] LLM requested ${artifactToolCalls.length} tool call(s): ${artifactToolCalls.map(c => `${c.artifactId}.${c.tool}`).join(', ')}`, true, params);
|
|
4992
|
-
|
|
5069
|
+
// Per-call observability: wrap each invocation in its own AIAgentRunStep
|
|
5070
|
+
// (StepType='Tool') so the run tree shows the calls + their inputs/outputs
|
|
5071
|
+
// at full fidelity instead of a summary buried inside the parent Prompt
|
|
5072
|
+
// step's OutputData. Step naming convention is "Artifact Tool: {tool}".
|
|
5073
|
+
// The result is also surfaced to the agent on the NEXT turn via a
|
|
5074
|
+
// one-shot ChatMessage push (see injectArtifactToolResultsMessage below),
|
|
5075
|
+
// mirroring the action-result inject-once-then-expire pattern instead of
|
|
5076
|
+
// the previous re-render-every-turn `_ARTIFACT_TOOL_RESULTS` template var.
|
|
5077
|
+
const toolResults = await this.executeArtifactToolCallsAsSteps(artifactToolCalls, params);
|
|
5078
|
+
this.injectArtifactToolResultsMessage(params, toolResults);
|
|
4993
5079
|
}
|
|
4994
5080
|
else if (this._artifactToolManager.HasArtifacts()) {
|
|
4995
5081
|
this.logStatus(`[ArtifactTools] LLM did not use artifact tools this turn (artifacts available but not accessed)`, true, params);
|
|
@@ -6350,12 +6436,7 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
6350
6436
|
// Execute tools sequentially (client may not support parallel UI operations)
|
|
6351
6437
|
for (const tool of clientTools) {
|
|
6352
6438
|
const stepEntity = await this.createStepEntity({
|
|
6353
|
-
|
|
6354
|
-
// entity's StepType value list does not yet include 'ClientTools'. A future database
|
|
6355
|
-
// migration will add 'ClientTools' to the allowed values in the StepType CHECK constraint
|
|
6356
|
-
// and CodeGen will regenerate the types. Until then, client tool steps are recorded under
|
|
6357
|
-
// 'Actions' in the run history. The step name ("Client Tool: {name}") distinguishes them.
|
|
6358
|
-
stepType: 'Actions',
|
|
6439
|
+
stepType: 'Tool',
|
|
6359
6440
|
stepName: `Client Tool: ${tool.Name}`,
|
|
6360
6441
|
inputData: { toolName: tool.Name, params: tool.Params },
|
|
6361
6442
|
contextUser: params.contextUser,
|
|
@@ -7848,7 +7929,9 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
7848
7929
|
*/
|
|
7849
7930
|
IsToolResultMessage(msg) {
|
|
7850
7931
|
const messageType = msg.metadata?.messageType;
|
|
7851
|
-
return messageType === 'action-result'
|
|
7932
|
+
return messageType === 'action-result'
|
|
7933
|
+
|| messageType === 'client-tool-result'
|
|
7934
|
+
|| messageType === 'tool-result';
|
|
7852
7935
|
}
|
|
7853
7936
|
estimateTokens(content, modelName) {
|
|
7854
7937
|
const text = typeof content === 'string'
|