@memberjunction/ai-agents 6.1.5 → 6.1.6
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 +2 -0
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +32 -9
- package/dist/AgentRunner.js.map +1 -1
- package/dist/ConversationCompactionManager.d.ts +7 -1
- package/dist/ConversationCompactionManager.d.ts.map +1 -1
- package/dist/ConversationCompactionManager.js +4 -1
- package/dist/ConversationCompactionManager.js.map +1 -1
- package/dist/KnowledgeAgent.d.ts.map +1 -1
- package/dist/KnowledgeAgent.js +12 -7
- package/dist/KnowledgeAgent.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts +4 -2
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +20 -13
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +13 -0
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +69 -22
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/native-tools/json-argument.d.ts +41 -0
- package/dist/native-tools/json-argument.d.ts.map +1 -0
- package/dist/native-tools/json-argument.js +79 -0
- package/dist/native-tools/json-argument.js.map +1 -0
- package/dist/realtime/realtime-client-session-service.d.ts +58 -7
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +71 -11
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/package.json +18 -18
package/dist/base-agent.js
CHANGED
|
@@ -18,9 +18,9 @@ import { looksLikeLoopEnvelope } from './native-tools/dual-channel.js';
|
|
|
18
18
|
import { Metadata, RunView, LogStatus, LogStatusEx, LogError, LogErrorEx, IsVerboseLoggingEnabled, DatabaseProviderBase } from '@memberjunction/core';
|
|
19
19
|
import { AgentRunWatchdog } from './agent-run-watchdog.js';
|
|
20
20
|
import { AIPromptRunner, GetToolCallingDecision } from '@memberjunction/ai-prompts';
|
|
21
|
-
import { BaseRealtimeModel, GetAIAPIKey } from '@memberjunction/ai';
|
|
21
|
+
import { BaseRealtimeModel, GetAIAPIKey, CredentialScopeAllows } from '@memberjunction/ai';
|
|
22
22
|
import { BaseAgentType } from './agent-types/base-agent-type.js';
|
|
23
|
-
import { CopyScalarsAndArrays, JSONValidator, MJGlobal, SafeExpressionEvaluator, UUIDsEqual, EscapeSQLString } from '@memberjunction/global';
|
|
23
|
+
import { CopyScalarsAndArrays, JSONValidator, MJGlobal, SafeExpressionEvaluator, UUIDsEqual, EscapeSQLString, IsValidUUID } from '@memberjunction/global';
|
|
24
24
|
// token optimization via @memberjunction/context-crush (SmartCrusher/CacheAligner-inspired)
|
|
25
25
|
import { CrushJSON, DescribeCrush, PartitionStablePrefix } from '@memberjunction/context-crush';
|
|
26
26
|
// AST-aware code reduction (CodeCompressor-inspired) — opt-in per agent type
|
|
@@ -1604,6 +1604,7 @@ export class BaseAgent {
|
|
|
1604
1604
|
? (params.data?.realtimeSelfNames).filter((n) => typeof n === 'string')
|
|
1605
1605
|
: undefined;
|
|
1606
1606
|
return {
|
|
1607
|
+
CredentialScope: params.CredentialScope,
|
|
1607
1608
|
CoAgent: params.agent,
|
|
1608
1609
|
TargetAgentID: targetID,
|
|
1609
1610
|
AgentSessionID: params.data?.agentSessionId ?? '',
|
|
@@ -1649,7 +1650,8 @@ export class BaseAgent {
|
|
|
1649
1650
|
if (!vendor) {
|
|
1650
1651
|
continue;
|
|
1651
1652
|
}
|
|
1652
|
-
|
|
1653
|
+
// Realtime only ever uses the platform key here, so a scope that rules that out has no key.
|
|
1654
|
+
const apiKey = CredentialScopeAllows(params.CredentialScope, 'Environment') ? GetAIAPIKey(vendor.DriverClass) : undefined;
|
|
1653
1655
|
if (!apiKey) {
|
|
1654
1656
|
continue;
|
|
1655
1657
|
}
|
|
@@ -1926,6 +1928,7 @@ export class BaseAgent {
|
|
|
1926
1928
|
parentDepth: this._depth,
|
|
1927
1929
|
configurationId: params.configurationId,
|
|
1928
1930
|
apiKeys: params.apiKeys,
|
|
1931
|
+
CredentialScope: params.CredentialScope,
|
|
1929
1932
|
data: params.data,
|
|
1930
1933
|
verbose: params.verbose,
|
|
1931
1934
|
// Progress streams BOTH to the runner's narration consumer (request.OnProgress —
|
|
@@ -2449,6 +2452,13 @@ export class BaseAgent {
|
|
|
2449
2452
|
this.logStatus(`🔄 Executing step ${stepCount + 1} for agent '${params.agent.Name}'`, true, params);
|
|
2450
2453
|
const nextStep = await this.executeNextStep(params, config, currentNextStep, stepCount);
|
|
2451
2454
|
stepCount++;
|
|
2455
|
+
// A failed step cut short by a cancellation is not a failure: end the run as cancelled
|
|
2456
|
+
// before the step is counted toward the consecutive-failure limit, which would end it as
|
|
2457
|
+
// Failed. A step that finished is kept: a final answer the user stopped too late to
|
|
2458
|
+
// prevent still completes the run.
|
|
2459
|
+
if (nextStep.step === 'Failed' && params.cancellationToken?.aborted) {
|
|
2460
|
+
throw new Error('Cancelled during execution');
|
|
2461
|
+
}
|
|
2452
2462
|
// Promote any media outputs from this step to the agent's outputs
|
|
2453
2463
|
if (nextStep.promoteMediaOutputs && nextStep.promoteMediaOutputs.length > 0) {
|
|
2454
2464
|
this.promoteMediaOutputs(nextStep.promoteMediaOutputs);
|
|
@@ -3381,6 +3391,7 @@ export class BaseAgent {
|
|
|
3381
3391
|
if (params.apiKeys && params.apiKeys.length > 0) {
|
|
3382
3392
|
childPromptParams.apiKeys = params.apiKeys;
|
|
3383
3393
|
}
|
|
3394
|
+
childPromptParams.CredentialScope = params.CredentialScope;
|
|
3384
3395
|
// Pass through configurationId to both parent and child prompts if provided
|
|
3385
3396
|
if (params.configurationId) {
|
|
3386
3397
|
promptParams.configurationId = params.configurationId;
|
|
@@ -3416,6 +3427,10 @@ export class BaseAgent {
|
|
|
3416
3427
|
promptParams.apiKeys = params.apiKeys;
|
|
3417
3428
|
this.logStatus(`🔑 Using ${params.apiKeys.length} API key(s) provided at runtime`, true, params);
|
|
3418
3429
|
}
|
|
3430
|
+
promptParams.CredentialScope = params.CredentialScope;
|
|
3431
|
+
if (!CredentialScopeAllows(params.CredentialScope, 'Environment')) {
|
|
3432
|
+
this.logStatus(`🔒 Credential scope is ${params.CredentialScope}: the platform's environment API keys will not be used`, true, params);
|
|
3433
|
+
}
|
|
3419
3434
|
// Thread the per-request provider so prompt run records are saved through the isolated provider
|
|
3420
3435
|
promptParams.provider = params.provider || this._activeProvider;
|
|
3421
3436
|
// Overlay scope-resolved run settings (model / vendor / configuration / effort / sampling
|
|
@@ -5318,10 +5333,10 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
5318
5333
|
throw new Error(`The '${BaseAgent.SummarizeRangePromptName}' system prompt is not present in this environment`);
|
|
5319
5334
|
}
|
|
5320
5335
|
const promptParams = new AIPromptParams();
|
|
5336
|
+
Object.assign(promptParams, this.runPromptExecutionScope(params));
|
|
5321
5337
|
promptParams.prompt = prompt;
|
|
5322
5338
|
// Keys are the summarize-range.template.md contract ({{ lens }}, {{ messages }})
|
|
5323
5339
|
promptParams.data = { lens, messages: rangeText };
|
|
5324
|
-
promptParams.contextUser = params.contextUser;
|
|
5325
5340
|
promptParams.agentId = params.agent.ID;
|
|
5326
5341
|
const result = await this._promptRunner.ExecutePrompt(promptParams);
|
|
5327
5342
|
const text = ExtractPromptResultText(result);
|
|
@@ -6187,7 +6202,10 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
6187
6202
|
ContextUser: contextUser,
|
|
6188
6203
|
Filters: [],
|
|
6189
6204
|
SkipActionLog: false,
|
|
6190
|
-
Context: actionContext
|
|
6205
|
+
Context: actionContext,
|
|
6206
|
+
// AICredentialScope → actions-base's RuntimeCredentialScope mirror: a value added to the
|
|
6207
|
+
// former and not the latter fails to compile here, so the two cannot drift apart.
|
|
6208
|
+
CredentialScope: params.CredentialScope
|
|
6191
6209
|
});
|
|
6192
6210
|
if (result.Success) {
|
|
6193
6211
|
this.logStatus(` ✅ Action '${action.name}' completed successfully`, true, params);
|
|
@@ -6418,6 +6436,7 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
6418
6436
|
configurationId: params.configurationId, // propagate configuration ID to sub-agent
|
|
6419
6437
|
effortLevel: params.effortLevel, // propagate effort level to sub-agent
|
|
6420
6438
|
apiKeys: params.apiKeys, // propagate API keys to sub-agent
|
|
6439
|
+
CredentialScope: params.CredentialScope, // a sub-agent may not spend keys its parent could not
|
|
6421
6440
|
inputArtifacts: params.inputArtifacts, // propagate input artifacts so sub-agents inherit the parent's artifact manifest + tools (e.g. a Codesmith delegate can read a Data Snapshot the parent references)
|
|
6422
6441
|
data: {
|
|
6423
6442
|
...params.data,
|
|
@@ -7068,6 +7087,16 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
7068
7087
|
// For now, returning a placeholder
|
|
7069
7088
|
return 'General';
|
|
7070
7089
|
}
|
|
7090
|
+
/**
|
|
7091
|
+
* Throws unless `lastRunId` is absent or a UUID. The value can come from a client, and the run
|
|
7092
|
+
* initialization places it in `ExtraFilter` clauses (the payload lookup, {@link validateRunChain}
|
|
7093
|
+
* and {@link resolvePlanModeGate}).
|
|
7094
|
+
*/
|
|
7095
|
+
assertLastRunIdIsUUID(lastRunId) {
|
|
7096
|
+
if (lastRunId && !IsValidUUID(lastRunId)) {
|
|
7097
|
+
throw new Error('Invalid lastRunId: expected the UUID of a prior AI Agent Run.');
|
|
7098
|
+
}
|
|
7099
|
+
}
|
|
7071
7100
|
/**
|
|
7072
7101
|
* Initializes the agent run tracking by creating MJAIAgentRunEntityExtended and setting up context.
|
|
7073
7102
|
*
|
|
@@ -7075,6 +7104,7 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
7075
7104
|
* @param {ExecuteAgentParams} params - The execution parameters
|
|
7076
7105
|
*/
|
|
7077
7106
|
async initializeAgentRun(params) {
|
|
7107
|
+
this.assertLastRunIdIsUUID(params.lastRunId);
|
|
7078
7108
|
// Handle autoPopulateLastRunPayload if requested
|
|
7079
7109
|
let modifiedParams = params;
|
|
7080
7110
|
if (params.lastRunId && params.autoPopulateLastRunPayload) {
|
|
@@ -8040,6 +8070,23 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
8040
8070
|
if (promptResult.modelSelectionInfo) {
|
|
8041
8071
|
this._lastModelSelectionInfo = promptResult.modelSelectionInfo;
|
|
8042
8072
|
}
|
|
8073
|
+
// Check for cancellation after prompt execution — before the failure check, because a prompt
|
|
8074
|
+
// the caller cancelled comes back failed, and that is not a prompt failure. The step does not
|
|
8075
|
+
// terminate the loop: a terminating step would finalize the run as Failed. The loop's own
|
|
8076
|
+
// cancellation check, before the next step, ends the run as Cancelled.
|
|
8077
|
+
if (params.cancellationToken?.aborted) {
|
|
8078
|
+
if (stepEntity && payload) {
|
|
8079
|
+
stepEntity.PayloadAtEnd = this.serializePayloadAtEnd(payload);
|
|
8080
|
+
}
|
|
8081
|
+
await this.finalizeStepEntity(stepEntity, false, 'Cancelled during prompt execution');
|
|
8082
|
+
return {
|
|
8083
|
+
errorMessage: 'Cancelled during prompt execution',
|
|
8084
|
+
step: 'Failed',
|
|
8085
|
+
terminate: false,
|
|
8086
|
+
previousPayload: payload,
|
|
8087
|
+
newPayload: payload
|
|
8088
|
+
};
|
|
8089
|
+
}
|
|
8043
8090
|
// Check if prompt execution failed
|
|
8044
8091
|
if (!promptResult.success) {
|
|
8045
8092
|
// CRITICAL FIX: Preserve payload before finalizing step
|
|
@@ -8068,22 +8115,6 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
8068
8115
|
newPayload: payload
|
|
8069
8116
|
};
|
|
8070
8117
|
}
|
|
8071
|
-
// Check for cancellation after prompt execution
|
|
8072
|
-
if (params.cancellationToken?.aborted) {
|
|
8073
|
-
// CRITICAL FIX: Preserve payload before finalizing step
|
|
8074
|
-
if (stepEntity && payload) {
|
|
8075
|
-
stepEntity.PayloadAtEnd = this.serializePayloadAtEnd(payload);
|
|
8076
|
-
}
|
|
8077
|
-
await this.finalizeStepEntity(stepEntity, false, 'Cancelled during prompt execution');
|
|
8078
|
-
const cancelledResult = await this.createCancelledResult('Cancelled during prompt execution', params.contextUser);
|
|
8079
|
-
return {
|
|
8080
|
-
...cancelledResult,
|
|
8081
|
-
terminate: true,
|
|
8082
|
-
step: 'Failed', // Cancelled is treated as failed
|
|
8083
|
-
previousPayload: cancelledResult.payload,
|
|
8084
|
-
newPayload: cancelledResult.payload // No changes, just return the same payload
|
|
8085
|
-
};
|
|
8086
|
-
}
|
|
8087
8118
|
// Report decision processing progress
|
|
8088
8119
|
this.safeOnProgress(params, {
|
|
8089
8120
|
step: 'decision_processing',
|
|
@@ -12340,6 +12371,21 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
12340
12371
|
LogError(`Post-turn cross-turn compaction error (contained): ${error instanceof Error ? error.message : error}`);
|
|
12341
12372
|
});
|
|
12342
12373
|
}
|
|
12374
|
+
/**
|
|
12375
|
+
* The {@link AIPromptExecutionScope} of a prompt this run starts outside the agent's own turn —
|
|
12376
|
+
* summarizing a range, compacting a message, compacting the conversation. Each built its params
|
|
12377
|
+
* with only `contextUser`, so it ran on the platform's keys and default configuration inside a
|
|
12378
|
+
* run on a customer's keys, and under a `'RuntimeOnly'` scope would have bypassed it.
|
|
12379
|
+
*/
|
|
12380
|
+
runPromptExecutionScope(params) {
|
|
12381
|
+
return {
|
|
12382
|
+
contextUser: params.contextUser,
|
|
12383
|
+
provider: params.provider || this._activeProvider,
|
|
12384
|
+
configurationId: params.configurationId,
|
|
12385
|
+
apiKeys: params.apiKeys,
|
|
12386
|
+
CredentialScope: params.CredentialScope,
|
|
12387
|
+
};
|
|
12388
|
+
}
|
|
12343
12389
|
/**
|
|
12344
12390
|
* Runs one compaction pass and records it as a `StepType='Compaction'` run step —
|
|
12345
12391
|
* TargetID = the summary prompt, TargetLogID = the summary AIPromptRun (the same ID
|
|
@@ -12358,6 +12404,7 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
12358
12404
|
Budget: budget,
|
|
12359
12405
|
ContextUser: params.contextUser,
|
|
12360
12406
|
Provider: this.ProviderToUse,
|
|
12407
|
+
ExecutionScope: this.runPromptExecutionScope(params),
|
|
12361
12408
|
EstimateTokens: (messages) => this.estimateConversationTokens(messages),
|
|
12362
12409
|
Verbose: params.verbose,
|
|
12363
12410
|
// The in-flight agent-response placeholder row: a post-turn pass runs while
|
|
@@ -12582,6 +12629,7 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
12582
12629
|
const step = await this.createCompactionStep(prompt, message, params);
|
|
12583
12630
|
// Execute summarization prompt
|
|
12584
12631
|
const promptParams = new AIPromptParams();
|
|
12632
|
+
Object.assign(promptParams, this.runPromptExecutionScope(params));
|
|
12585
12633
|
promptParams.prompt = prompt;
|
|
12586
12634
|
promptParams.data = {
|
|
12587
12635
|
originalContent,
|
|
@@ -12590,7 +12638,6 @@ The context is now within limits. Please retry your request with the recovered c
|
|
|
12590
12638
|
messageType: message.metadata?.messageType || 'unknown',
|
|
12591
12639
|
turnAdded: message.metadata?.turnAdded || 0
|
|
12592
12640
|
};
|
|
12593
|
-
promptParams.contextUser = params.contextUser;
|
|
12594
12641
|
promptParams.agentId = params.agent.ID;
|
|
12595
12642
|
const runner = new AIPromptRunner();
|
|
12596
12643
|
const result = await runner.ExecutePrompt(promptParams);
|