@memberjunction/ai-prompts 6.2.0-edge.2 → 6.2.0-edge.3
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 +8 -0
- package/dist/AIPromptRunner.d.ts +21 -0
- package/dist/AIPromptRunner.d.ts.map +1 -1
- package/dist/AIPromptRunner.js +72 -29
- package/dist/AIPromptRunner.js.map +1 -1
- package/dist/BaseModelRunner.d.ts +25 -0
- package/dist/BaseModelRunner.d.ts.map +1 -1
- package/dist/BaseModelRunner.js +58 -11
- package/dist/BaseModelRunner.js.map +1 -1
- package/dist/ParallelExecution.d.ts +2 -2
- package/dist/ParallelExecution.d.ts.map +1 -1
- package/dist/ParallelExecutionCoordinator.d.ts +4 -2
- package/dist/ParallelExecutionCoordinator.d.ts.map +1 -1
- package/dist/ParallelExecutionCoordinator.js +7 -4
- package/dist/ParallelExecutionCoordinator.js.map +1 -1
- package/dist/decision/AIDecisionRunner.d.ts.map +1 -1
- package/dist/decision/AIDecisionRunner.js +6 -1
- package/dist/decision/AIDecisionRunner.js.map +1 -1
- package/dist/decision/LLMDecision.d.ts +8 -0
- package/dist/decision/LLMDecision.d.ts.map +1 -1
- package/dist/decision/LLMDecision.js +4 -1
- package/dist/decision/LLMDecision.js.map +1 -1
- package/dist/image/AIImageGenerationRunner.d.ts +1 -1
- package/dist/image/AIImageGenerationRunner.d.ts.map +1 -1
- package/dist/image/AIImageGenerationRunner.js +2 -1
- package/dist/image/AIImageGenerationRunner.js.map +1 -1
- package/dist/image/image-runner.types.d.ts +7 -1
- package/dist/image/image-runner.types.d.ts.map +1 -1
- package/dist/media/BaseMediaRunner.d.ts +1 -1
- package/dist/media/BaseMediaRunner.d.ts.map +1 -1
- package/dist/media/BaseMediaRunner.js +2 -1
- package/dist/media/BaseMediaRunner.js.map +1 -1
- package/dist/media/media-runner.types.d.ts +7 -1
- package/dist/media/media-runner.types.d.ts.map +1 -1
- package/dist/nativeToolCallingGate.d.ts +17 -1
- package/dist/nativeToolCallingGate.d.ts.map +1 -1
- package/dist/nativeToolCallingGate.js +24 -0
- package/dist/nativeToolCallingGate.js.map +1 -1
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -198,6 +198,14 @@ Hierarchical credential resolution for API keys:
|
|
|
198
198
|
5. `AIPromptParams.apiKeys[]` (legacy runtime keys)
|
|
199
199
|
6. `AI_VENDOR_API_KEY__<DRIVER>` environment variables (legacy)
|
|
200
200
|
|
|
201
|
+
**Credential scope.** `AIPromptParams.CredentialScope` (`'Any' | 'RuntimeOnly'`, default `'Any'`)
|
|
202
|
+
decides which of these tiers a run may use. Under `'RuntimeOnly'` only 1 and 5 count — the caller's
|
|
203
|
+
own `credentialId` and `apiKeys`. Credential bindings, the vendor default and environment keys are
|
|
204
|
+
skipped, a candidate the run has no key for is unavailable, so failover stays on the caller's
|
|
205
|
+
vendors, and a run the keys do not cover fails with *"… The credential scope is RuntimeOnly …"*
|
|
206
|
+
instead of running on the platform's account. Prompts the runner starts on a caller's behalf (JSON
|
|
207
|
+
repair, the result-selector judge, decisions' chat prompts) run under the caller's scope.
|
|
208
|
+
|
|
201
209
|
### Failover
|
|
202
210
|
|
|
203
211
|
When a model fails due to rate limiting, authentication errors, or other transient issues, the runner can automatically retry with alternate models from the selection candidates.
|
package/dist/AIPromptRunner.d.ts
CHANGED
|
@@ -321,8 +321,29 @@ export declare class AIPromptRunner extends BaseModelRunner {
|
|
|
321
321
|
* otherwise succeed, so any configuration problem resolves to the path that has always worked.
|
|
322
322
|
*/
|
|
323
323
|
ResolveNativeToolCallingDecision(prompt: MJAIPromptEntityExtended, params: AIPromptParams, model: MJAIModelEntityExtended, vendorId: string | null, promptModelConfiguration?: AIPromptConfiguration | null): NativeToolCallingDecision;
|
|
324
|
+
/**
|
|
325
|
+
* Returns the template data with `_NATIVE_TOOL_CALLING` and `_NATIVE_CONTROL_FLOW` set.
|
|
326
|
+
*
|
|
327
|
+
* With a decision, both carry the gate's real answer. Without one (a run that declares no tools),
|
|
328
|
+
* they are set to the envelope path's values unless the caller already supplied them. The Loop
|
|
329
|
+
* system prompt reads both unconditionally, so template parameter extraction marks them required,
|
|
330
|
+
* and a run that left them unset failed to render.
|
|
331
|
+
*
|
|
332
|
+
* @param data The caller's template data, if any
|
|
333
|
+
* @param decision The resolved native tool-calling decision, or null when no tools were declared
|
|
334
|
+
*/
|
|
335
|
+
protected ApplyNativeTemplateFlags(data: Record<string, unknown> | undefined, decision: NativeToolCallingDecision | null): Record<string, unknown>;
|
|
324
336
|
/** @deprecated Use {@link ResolveNativeToolCallingDecision}. */
|
|
325
337
|
resolveNativeToolCallingDecision(prompt: MJAIPromptEntityExtended, params: AIPromptParams, model: MJAIModelEntityExtended, vendorId: string | null, promptModelConfiguration?: AIPromptConfiguration | null): NativeToolCallingDecision;
|
|
338
|
+
/**
|
|
339
|
+
* The merged catalog configuration for the selected model on the selected vendor.
|
|
340
|
+
*
|
|
341
|
+
* Must resolve the INFERENCE PROVIDER row, not the Model Developer row: most models carry two
|
|
342
|
+
* AIModelVendor rows for the same VendorID, and ModelVendors has no guaranteed order. Picking the
|
|
343
|
+
* developer row merges an empty config layer and silently drops any per-serving-path LLM.* knob
|
|
344
|
+
* (notably the SupportsNativeToolCalling kill switch).
|
|
345
|
+
*/
|
|
346
|
+
private catalogConfigurationFor;
|
|
326
347
|
private applyNativeToolCalling;
|
|
327
348
|
/**
|
|
328
349
|
* Whether a failed result failed for a TOOLS-specific reason, and so is worth one retry with the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AIPromptRunner.d.ts","sourceRoot":"","sources":["../src/AIPromptRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,UAAU,EAAmB,WAAW,EAAwD,qBAAqB,
|
|
1
|
+
{"version":3,"file":"AIPromptRunner.d.ts","sourceRoot":"","sources":["../src/AIPromptRunner.ts"],"names":[],"mappings":"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"}
|
package/dist/AIPromptRunner.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseLLM, ChatParams, ChatMessageRole, ErrorAnalyzer, ResolveFileInputStrategy, EncodeToolTurnsAsText } from '@memberjunction/ai';
|
|
1
|
+
import { BaseLLM, ChatParams, ChatMessageRole, ErrorAnalyzer, ResolveFileInputStrategy, EncodeToolTurnsAsText, CredentialScopeAllows } from '@memberjunction/ai';
|
|
2
2
|
import { BaseModelRunner, } from './BaseModelRunner.js';
|
|
3
|
-
import { GetToolCallingDecision, GetToolCallingMode, RecordToolCallingDecision, RecordToolCallingMode, ResolveNativeToolCalling } from './nativeToolCallingGate.js';
|
|
3
|
+
import { GetToolCallingDecision, GetToolCallingMode, RecordToolCallingDecision, RecordToolCallingMode, ResolveNativeToolCalling, ResolveToolChoiceForRequest } from './nativeToolCallingGate.js';
|
|
4
4
|
import { AIModelRunner } from './AIModelRunner.js';
|
|
5
|
-
import { AIModelSelectionInfo } from '@memberjunction/ai-core-plus';
|
|
5
|
+
import { AIModelSelectionInfo, PickPromptExecutionScope } from '@memberjunction/ai-core-plus';
|
|
6
6
|
import { LogStatus, IsVerboseLoggingEnabled, Metadata } from '@memberjunction/core';
|
|
7
7
|
import { CleanJSON, RepairJSONEscaping, MJGlobal, JSONValidator, ValidationResult, ValidationErrorInfo, ValidationErrorType, UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
|
|
8
8
|
import { TemplateEngineServer } from '@memberjunction/templates';
|
|
@@ -174,7 +174,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
174
174
|
// Select model using the appropriate prompt — capture the FULL result
|
|
175
175
|
selection = await this.selectModel(modelSelectionPrompt, params.override?.modelId, params.contextUser, params.configurationId, params.override?.vendorId, params);
|
|
176
176
|
if (!selection.model) {
|
|
177
|
-
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, selection.selectionInfo));
|
|
177
|
+
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, selection.selectionInfo, params.CredentialScope));
|
|
178
178
|
}
|
|
179
179
|
// Tell the template which path this run is actually taking, BEFORE it renders. The loop
|
|
180
180
|
// template drops its action catalog and the `'Actions'` step type under native mode
|
|
@@ -190,15 +190,10 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
190
190
|
// actually selected — not merely the caller's override, which is usually absent — and the
|
|
191
191
|
// selected candidate's AIPromptModel bag. Resolving without those skips the two layers the
|
|
192
192
|
// capability is normally declared on and silently inverts the decision.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
_NATIVE_TOOL_CALLING: nativeDecision.useNativeTools,
|
|
198
|
-
// The template renders the implicit-mode section only when this is the gate's REAL answer.
|
|
199
|
-
_NATIVE_CONTROL_FLOW: nativeDecision.controlFlow
|
|
200
|
-
};
|
|
201
|
-
}
|
|
193
|
+
const nativeDecision = params.tools?.length
|
|
194
|
+
? this.ResolveNativeToolCallingDecision(prompt, params, selection.model, selection.selectionInfo?.vendorSelected?.ID ?? params.override?.vendorId ?? null, selection.promptModelConfiguration)
|
|
195
|
+
: null;
|
|
196
|
+
params.data = this.ApplyNativeTemplateFlags(params.data, nativeDecision);
|
|
202
197
|
// Check if we have a system prompt override
|
|
203
198
|
if (params.systemPromptOverride) {
|
|
204
199
|
// Use the override instead of rendering child templates and parent template
|
|
@@ -253,7 +248,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
253
248
|
}
|
|
254
249
|
selection = await this.selectModel(modelSelectionPrompt, params.override?.modelId, params.contextUser, params.configurationId, params.override?.vendorId, params);
|
|
255
250
|
if (!selection.model) {
|
|
256
|
-
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, selection.selectionInfo));
|
|
251
|
+
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, selection.selectionInfo, params.CredentialScope));
|
|
257
252
|
}
|
|
258
253
|
}
|
|
259
254
|
// Check if we need parallel execution based on ParallelizationMode
|
|
@@ -373,7 +368,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
373
368
|
allCandidates = modelResult.allCandidates || [];
|
|
374
369
|
credentialAvailability = modelResult.credentialAvailability;
|
|
375
370
|
if (!selectedModel) {
|
|
376
|
-
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, modelSelectionInfo));
|
|
371
|
+
throw new Error(this.buildNoModelFoundMessage(modelSelectionPrompt.Name, modelSelectionInfo, params.CredentialScope));
|
|
377
372
|
}
|
|
378
373
|
}
|
|
379
374
|
// Check for cancellation after model selection
|
|
@@ -535,7 +530,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
535
530
|
method: 'PromptSelector',
|
|
536
531
|
selectorPromptId: prompt.ResultSelectorPromptID,
|
|
537
532
|
};
|
|
538
|
-
const aiSelectedResult = await this.ParallelCoordinator.selectBestResult(successfulResults, selectionConfig, consolidatedPromptRun.ID, params.cancellationToken, params.contextUser);
|
|
533
|
+
const aiSelectedResult = await this.ParallelCoordinator.selectBestResult(successfulResults, selectionConfig, consolidatedPromptRun.ID, params.cancellationToken, params.contextUser, PickPromptExecutionScope(params));
|
|
539
534
|
if (aiSelectedResult) {
|
|
540
535
|
selectedResult = aiSelectedResult;
|
|
541
536
|
}
|
|
@@ -1253,7 +1248,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1253
1248
|
* Includes details about which models were considered and why they were unavailable
|
|
1254
1249
|
* so the error message is actionable for end users (e.g., missing API credentials).
|
|
1255
1250
|
*/
|
|
1256
|
-
buildNoModelFoundMessage(promptName, selectionInfo) {
|
|
1251
|
+
buildNoModelFoundMessage(promptName, selectionInfo, credentialScope) {
|
|
1257
1252
|
const base = `No suitable model found for prompt ${promptName}`;
|
|
1258
1253
|
// A selection step that threw (for example the model-type floor) records its error here; show it
|
|
1259
1254
|
// rather than the generic "no candidates" text. Every other reason keeps its detailed message below.
|
|
@@ -1271,9 +1266,14 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1271
1266
|
return `${m.model.Name}/${vendorName}`;
|
|
1272
1267
|
}).join(', ');
|
|
1273
1268
|
const suffix = unavailableModels.length > 5 ? ` (${unavailableModels.length} total)` : '';
|
|
1269
|
+
// When the scope rules out the platform's credentials, "configure them" would point the reader
|
|
1270
|
+
// at exactly the fallback the caller ruled out.
|
|
1271
|
+
const platformAllowed = CredentialScopeAllows(credentialScope, 'Environment') || CredentialScopeAllows(credentialScope, 'PlatformCredential');
|
|
1272
|
+
const remedy = platformAllowed
|
|
1273
|
+
? `Please configure API credentials in your environment or AI Credential settings.`
|
|
1274
|
+
: `The credential scope is ${credentialScope}, so only the API keys supplied with this run count; supply a key for one of these vendors.`;
|
|
1274
1275
|
return `${base}. No valid API credentials/keys are configured for any of the candidate model-vendor combinations. ` +
|
|
1275
|
-
`Tried: ${triedSummary}${suffix}.
|
|
1276
|
-
`Please configure API credentials in your environment or AI Credential settings.`;
|
|
1276
|
+
`Tried: ${triedSummary}${suffix}. ${remedy}`;
|
|
1277
1277
|
}
|
|
1278
1278
|
return `${base}. ${selectionInfo.selectionReason || 'Unknown reason'}`;
|
|
1279
1279
|
}
|
|
@@ -1416,14 +1416,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1416
1416
|
ResolveNativeToolCallingDecision(prompt, params, model, vendorId, promptModelConfiguration) {
|
|
1417
1417
|
try {
|
|
1418
1418
|
return ResolveNativeToolCalling({
|
|
1419
|
-
catalogConfiguration:
|
|
1420
|
-
// Must be the INFERENCE PROVIDER row, not the Model Developer row: most models carry
|
|
1421
|
-
// two AIModelVendor rows for the same VendorID, and ModelVendors has no guaranteed
|
|
1422
|
-
// order. Picking the developer row merges an empty config layer and silently drops any
|
|
1423
|
-
// per-serving-path LLM.* knob (notably the SupportsNativeToolCalling kill switch).
|
|
1424
|
-
? model.ModelVendors?.find(mv => UUIDsEqual(mv.VendorID, vendorId)
|
|
1425
|
-
&& mv.Status === 'Active' && this.IsInferenceProvider(mv))?.ID
|
|
1426
|
-
: undefined),
|
|
1419
|
+
catalogConfiguration: this.catalogConfigurationFor(model, vendorId),
|
|
1427
1420
|
promptConfiguration: prompt.PromptConfigurationObject,
|
|
1428
1421
|
promptModelConfiguration,
|
|
1429
1422
|
// Action tools and control-flow tools are counted separately: under the hybrid the control
|
|
@@ -1438,10 +1431,51 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1438
1431
|
return { useNativeTools: false, mode: 'Envelope', controlFlow: 'envelope', toolResults: false };
|
|
1439
1432
|
}
|
|
1440
1433
|
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Returns the template data with `_NATIVE_TOOL_CALLING` and `_NATIVE_CONTROL_FLOW` set.
|
|
1436
|
+
*
|
|
1437
|
+
* With a decision, both carry the gate's real answer. Without one (a run that declares no tools),
|
|
1438
|
+
* they are set to the envelope path's values unless the caller already supplied them. The Loop
|
|
1439
|
+
* system prompt reads both unconditionally, so template parameter extraction marks them required,
|
|
1440
|
+
* and a run that left them unset failed to render.
|
|
1441
|
+
*
|
|
1442
|
+
* @param data The caller's template data, if any
|
|
1443
|
+
* @param decision The resolved native tool-calling decision, or null when no tools were declared
|
|
1444
|
+
*/
|
|
1445
|
+
ApplyNativeTemplateFlags(data, decision) {
|
|
1446
|
+
const current = data ?? {};
|
|
1447
|
+
if (decision) {
|
|
1448
|
+
return {
|
|
1449
|
+
...current,
|
|
1450
|
+
_NATIVE_TOOL_CALLING: decision.useNativeTools,
|
|
1451
|
+
// The template renders the implicit-mode section only when this is the gate's REAL answer.
|
|
1452
|
+
_NATIVE_CONTROL_FLOW: decision.controlFlow
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
return {
|
|
1456
|
+
...current,
|
|
1457
|
+
_NATIVE_TOOL_CALLING: current._NATIVE_TOOL_CALLING ?? false,
|
|
1458
|
+
_NATIVE_CONTROL_FLOW: current._NATIVE_CONTROL_FLOW ?? 'envelope'
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1441
1461
|
/** @deprecated Use {@link ResolveNativeToolCallingDecision}. */
|
|
1442
1462
|
resolveNativeToolCallingDecision(prompt, params, model, vendorId, promptModelConfiguration) {
|
|
1443
1463
|
return this.ResolveNativeToolCallingDecision(prompt, params, model, vendorId, promptModelConfiguration);
|
|
1444
1464
|
}
|
|
1465
|
+
/**
|
|
1466
|
+
* The merged catalog configuration for the selected model on the selected vendor.
|
|
1467
|
+
*
|
|
1468
|
+
* Must resolve the INFERENCE PROVIDER row, not the Model Developer row: most models carry two
|
|
1469
|
+
* AIModelVendor rows for the same VendorID, and ModelVendors has no guaranteed order. Picking the
|
|
1470
|
+
* developer row merges an empty config layer and silently drops any per-serving-path LLM.* knob
|
|
1471
|
+
* (notably the SupportsNativeToolCalling kill switch).
|
|
1472
|
+
*/
|
|
1473
|
+
catalogConfigurationFor(model, vendorId) {
|
|
1474
|
+
return AIEngine.Instance.GetEffectiveModelConfiguration(model.ID, vendorId
|
|
1475
|
+
? model.ModelVendors?.find(mv => UUIDsEqual(mv.VendorID, vendorId)
|
|
1476
|
+
&& mv.Status === 'Active' && this.IsInferenceProvider(mv))?.ID
|
|
1477
|
+
: undefined);
|
|
1478
|
+
}
|
|
1445
1479
|
applyNativeToolCalling(chatParams, prompt, params, model, vendorId, promptModelConfiguration) {
|
|
1446
1480
|
const decision = this.ResolveNativeToolCallingDecision(prompt, params, model, vendorId, promptModelConfiguration);
|
|
1447
1481
|
if (decision.warning) {
|
|
@@ -1455,7 +1489,7 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1455
1489
|
chatParams.tools = decision.controlFlow === 'implicit'
|
|
1456
1490
|
? params.tools
|
|
1457
1491
|
: params.tools?.filter((t) => !control.has(t.name));
|
|
1458
|
-
chatParams.toolChoice = params.toolChoice;
|
|
1492
|
+
chatParams.toolChoice = ResolveToolChoiceForRequest(params.toolChoice, chatParams.tools, this.catalogConfigurationFor(model, vendorId));
|
|
1459
1493
|
chatParams.parallelToolCalls = params.parallelToolCalls;
|
|
1460
1494
|
}
|
|
1461
1495
|
// Recorded even on the envelope path, so a run is always attributable to a path. The whole
|
|
@@ -1564,6 +1598,13 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
1564
1598
|
}
|
|
1565
1599
|
// Resolve credentials using hierarchical resolution (Credentials system with legacy fallback)
|
|
1566
1600
|
const apiKey = await this.ResolveCredentialForExecution(driverClass, prompt.ID, model.ID, vendorId ?? undefined, params);
|
|
1601
|
+
// No key under a scope that rules out the environment must not reach a driver: the OpenAI and
|
|
1602
|
+
// Anthropic SDKs read OPENAI_API_KEY / ANTHROPIC_API_KEY themselves when handed none. Selection
|
|
1603
|
+
// and failover already skip unkeyed candidates; parallel tasks are planned without the scope.
|
|
1604
|
+
if (!apiKey?.trim() && !CredentialScopeAllows(params.CredentialScope, 'Environment')) {
|
|
1605
|
+
throw new Error(`No credentials found for driver class '${driverClass}': the credential scope is ${params.CredentialScope}, ` +
|
|
1606
|
+
`and this run carries no API key for it.`);
|
|
1607
|
+
}
|
|
1567
1608
|
// Create LLM instance with vendor-specific driver class
|
|
1568
1609
|
llm = MJGlobal.Instance.ClassFactory.CreateInstance(BaseLLM, driverClass, apiKey);
|
|
1569
1610
|
// Prepare chat parameters
|
|
@@ -2799,9 +2840,11 @@ export class AIPromptRunner extends BaseModelRunner {
|
|
|
2799
2840
|
throw new Error('Repair JSON prompt not found in MJ: System category');
|
|
2800
2841
|
}
|
|
2801
2842
|
// Run the repair prompt
|
|
2843
|
+
// The repair runs inside the caller's run, so it runs on the caller's user, configuration and
|
|
2844
|
+
// credentials — under RuntimeOnly it must not reach a key the caller's prompt could not.
|
|
2802
2845
|
const repairResult = await this.ExecutePrompt({
|
|
2846
|
+
...PickPromptExecutionScope(params),
|
|
2803
2847
|
parentPromptRunId: currentPromptRun.ID,
|
|
2804
|
-
contextUser: params.contextUser,
|
|
2805
2848
|
prompt: repairPrompt,
|
|
2806
2849
|
data: {
|
|
2807
2850
|
ERROR_MESSAGE: trueError,
|