@memberjunction/testing-engine 6.1.0-edge.5 → 6.1.0-edge.7

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.
Files changed (68) hide show
  1. package/dist/drivers/AgentPromptComposer.d.ts +50 -0
  2. package/dist/drivers/AgentPromptComposer.d.ts.map +1 -0
  3. package/dist/drivers/AgentPromptComposer.js +60 -0
  4. package/dist/drivers/AgentPromptComposer.js.map +1 -0
  5. package/dist/drivers/PinnedVendorPromptRunner.d.ts +30 -0
  6. package/dist/drivers/PinnedVendorPromptRunner.d.ts.map +1 -0
  7. package/dist/drivers/PinnedVendorPromptRunner.js +30 -0
  8. package/dist/drivers/PinnedVendorPromptRunner.js.map +1 -0
  9. package/dist/drivers/PromptEvalDriver.d.ts +158 -0
  10. package/dist/drivers/PromptEvalDriver.d.ts.map +1 -0
  11. package/dist/drivers/PromptEvalDriver.js +365 -0
  12. package/dist/drivers/PromptEvalDriver.js.map +1 -0
  13. package/dist/drivers/index.d.ts +1 -0
  14. package/dist/drivers/index.d.ts.map +1 -1
  15. package/dist/drivers/index.js +1 -0
  16. package/dist/drivers/index.js.map +1 -1
  17. package/dist/engine/TestEngine.d.ts.map +1 -1
  18. package/dist/engine/TestEngine.js +5 -0
  19. package/dist/engine/TestEngine.js.map +1 -1
  20. package/dist/eval/corpus.d.ts +91 -0
  21. package/dist/eval/corpus.d.ts.map +1 -0
  22. package/dist/eval/corpus.js +141 -0
  23. package/dist/eval/corpus.js.map +1 -0
  24. package/dist/eval/decision.d.ts +156 -0
  25. package/dist/eval/decision.d.ts.map +1 -0
  26. package/dist/eval/decision.js +257 -0
  27. package/dist/eval/decision.js.map +1 -0
  28. package/dist/eval/expectation.d.ts +76 -0
  29. package/dist/eval/expectation.d.ts.map +1 -0
  30. package/dist/eval/expectation.js +160 -0
  31. package/dist/eval/expectation.js.map +1 -0
  32. package/dist/eval/history.d.ts +17 -0
  33. package/dist/eval/history.d.ts.map +1 -0
  34. package/dist/eval/history.js +19 -0
  35. package/dist/eval/history.js.map +1 -0
  36. package/dist/eval/index.d.ts +15 -0
  37. package/dist/eval/index.d.ts.map +1 -0
  38. package/dist/eval/index.js +15 -0
  39. package/dist/eval/index.js.map +1 -0
  40. package/dist/eval/matchers.d.ts +88 -0
  41. package/dist/eval/matchers.d.ts.map +1 -0
  42. package/dist/eval/matchers.js +119 -0
  43. package/dist/eval/matchers.js.map +1 -0
  44. package/dist/eval/subAgentTrace.d.ts +52 -0
  45. package/dist/eval/subAgentTrace.d.ts.map +1 -0
  46. package/dist/eval/subAgentTrace.js +61 -0
  47. package/dist/eval/subAgentTrace.js.map +1 -0
  48. package/dist/eval/wellFormed.d.ts +41 -0
  49. package/dist/eval/wellFormed.d.ts.map +1 -0
  50. package/dist/eval/wellFormed.js +83 -0
  51. package/dist/eval/wellFormed.js.map +1 -0
  52. package/dist/index.d.ts +5 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +5 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/oracles/AgentDecisionOracle.d.ts +54 -0
  57. package/dist/oracles/AgentDecisionOracle.d.ts.map +1 -0
  58. package/dist/oracles/AgentDecisionOracle.js +107 -0
  59. package/dist/oracles/AgentDecisionOracle.js.map +1 -0
  60. package/dist/oracles/TraceSubAgentValidatorOracle.d.ts +44 -0
  61. package/dist/oracles/TraceSubAgentValidatorOracle.d.ts.map +1 -0
  62. package/dist/oracles/TraceSubAgentValidatorOracle.js +105 -0
  63. package/dist/oracles/TraceSubAgentValidatorOracle.js.map +1 -0
  64. package/dist/oracles/index.d.ts +2 -0
  65. package/dist/oracles/index.d.ts.map +1 -1
  66. package/dist/oracles/index.js +2 -0
  67. package/dist/oracles/index.js.map +1 -1
  68. package/package.json +10 -10
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @fileoverview Agent-decision oracles — the centrepiece of the prompt-eval corpus (test plan §3.2).
3
+ * @module @memberjunction/testing-engine
4
+ */
5
+ import { normalizeDecision } from '../eval/decision.js';
6
+ import { evaluateCorpusExpectation } from '../eval/corpus.js';
7
+ import { evaluateWellFormed } from '../eval/wellFormed.js';
8
+ function readActual(input) {
9
+ const actual = input.actualOutput;
10
+ // A driver that produced nothing at all still has to be judged rather than crash the run —
11
+ // "no output" is the single most important observation this suite makes.
12
+ return actual?.turn ? actual : { turn: { text: typeof actual === 'string' ? actual : '' } };
13
+ }
14
+ /**
15
+ * `agent-decision-match` — did the agent decide the right thing?
16
+ *
17
+ * Reads the decision off whichever channel the model used (envelope or native tool calls) and
18
+ * compares it against an encoding-independent expectation. That normalization is what lets a
19
+ * baseline cell and a native cell be compared on an identical corpus case: the
20
+ * yardstick does not move between them, only the model's behavior does.
21
+ *
22
+ * The result's `details` carry the components separately — decision kind, action accuracy, param
23
+ * fidelity, per-matcher outcomes — so §6.1's metrics aggregate out of persisted `ResultDetails`
24
+ * without re-running anything.
25
+ *
26
+ * Configuration is the {@link DecisionExpectation} itself.
27
+ */
28
+ export class AgentDecisionOracle {
29
+ constructor() {
30
+ this.type = 'agent-decision-match';
31
+ }
32
+ async evaluate(input, config) {
33
+ try {
34
+ const expectation = config;
35
+ if (!expectation?.kind) {
36
+ return { oracleType: this.type, passed: false, score: 0, message: "Configuration requires a 'kind' (the expected decision)" };
37
+ }
38
+ const actual = readActual(input);
39
+ const observed = normalizeDecision(actual.turn);
40
+ // evaluateCorpusExpectation, NOT evaluateDecision: only the former unwraps `anyOf`.
41
+ // `anyOf` is a corpus-level kind — a case that legitimately admits several decisions —
42
+ // and evaluateDecision would compare the literal string 'anyOf' against the observed
43
+ // kind and fail every time, which is a scored failure the model can never avoid.
44
+ const evaluation = evaluateCorpusExpectation((input.test?.Name ?? 'case'), expectation, observed);
45
+ return {
46
+ oracleType: this.type,
47
+ passed: evaluation.passed,
48
+ score: evaluation.score,
49
+ message: evaluation.passed
50
+ ? `decided '${observed.kind}' via ${observed.encoding} as expected`
51
+ : evaluation.messages.join('; '),
52
+ details: {
53
+ expectedKind: expectation.kind,
54
+ observedKind: observed.kind,
55
+ encoding: observed.encoding,
56
+ decisionKindMatch: evaluation.decisionKindMatch,
57
+ actionAccuracy: evaluation.actionAccuracy,
58
+ paramFidelity: evaluation.paramFidelity,
59
+ paramResults: evaluation.paramResults,
60
+ forbiddenViolations: evaluation.forbiddenViolations,
61
+ observedActions: observed.actions.map((a) => a.name),
62
+ observedSubAgents: observed.subAgents.map((s) => s.name),
63
+ // Surfaced so the scorecard can count dual-channel
64
+ // turns and concatenated envelopes without re-running anything.
65
+ dualChannel: observed.dualChannel ?? false,
66
+ payloadChanged: observed.payloadChange !== undefined,
67
+ narrationWithCalls: observed.narrationWithCalls ?? false,
68
+ placeholderCall: observed.placeholderCall ?? false,
69
+ shadowEnvelopeKind: observed.shadowEnvelopeKind,
70
+ diagnostic: observed.diagnostic
71
+ }
72
+ };
73
+ }
74
+ catch (error) {
75
+ return { oracleType: this.type, passed: false, score: 0, message: `Decision evaluation error: ${error.message}` };
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * `response-well-formed` — was the output usable at all?
81
+ *
82
+ * This is the oracle that measures the malformed/discard class directly — the issue's headline
83
+ * number. It asks strictly less than {@link AgentDecisionOracle}: a turn can be well-formed and
84
+ * wrong, but never malformed and right. Keeping them apart is what lets a comparison say *which* of
85
+ * "malformed rate fell" and "decision accuracy rose" actually happened.
86
+ *
87
+ * Configuration is a {@link WellFormedConfig}. Note `requireEnvelope` defaults to **off**: measurement
88
+ * measured that a correct native tool call carries no text at all on Google, so requiring an
89
+ * envelope unconditionally would fail every correct native turn.
90
+ */
91
+ export class ResponseWellFormedOracle {
92
+ constructor() {
93
+ this.type = 'response-well-formed';
94
+ }
95
+ async evaluate(input, config) {
96
+ try {
97
+ const actual = readActual(input);
98
+ const observed = normalizeDecision(actual.turn);
99
+ const result = evaluateWellFormed({ decision: observed, finishReason: actual.finishReason, executionError: actual.executionError }, config);
100
+ return { oracleType: this.type, passed: result.passed, score: result.score, message: result.message, details: result.details };
101
+ }
102
+ catch (error) {
103
+ return { oracleType: this.type, passed: false, score: 0, message: `Well-formedness evaluation error: ${error.message}` };
104
+ }
105
+ }
106
+ }
107
+ //# sourceMappingURL=AgentDecisionOracle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentDecisionOracle.js","sourceRoot":"","sources":["../../src/oracles/AgentDecisionOracle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview Sub-agent dispatch oracle — the shipped-but-missing `trace-validate-sub-agents`.
3
+ * @module @memberjunction/testing-engine
4
+ */
5
+ import { IOracle } from './IOracle.js';
6
+ import { OracleInput, OracleConfig, OracleResult } from '../types.js';
7
+ /**
8
+ * Validates which sub-agents an agent run dispatched, and how many iterations it took.
9
+ *
10
+ * **This oracle was referenced by shipped metadata before it existed.** Both stock research-agent
11
+ * tests configure `trace-validate-sub-agents` and weight it at 0.25 and 0.3 respectively; with no
12
+ * implementation registered, the engine logged `Oracle not found` and a quarter to a third of each
13
+ * test's weight silently vanished from the score. The tests reported green on the remaining
14
+ * oracles. That is the defect this closes (test plan §2, gap 5).
15
+ *
16
+ * **Traversal.** Sub-agent runs are reached through the **Sub-Agent step's `TargetLogID`**, not
17
+ * through `AIAgentRun.ParentRunID`. The generated ORM is explicit that ParentRunID "records
18
+ * parentage but is not a link the tree traverses", and the platform's own run-tree walk uses the
19
+ * step link — so querying by ParentRunID would find runs the platform does not consider part of
20
+ * this tree, and miss none that it does. The walk recurses, because a sub-agent may dispatch its
21
+ * own, and a required agent two levels down was still dispatched by this run.
22
+ *
23
+ * Configuration (as the shipped tests already supply it):
24
+ * - `requiredAgents`: names that must appear
25
+ * - `forbiddenAgents`: names that must not
26
+ * - `minIterations`: minimum Prompt steps on the top-level run
27
+ *
28
+ * @example
29
+ * ```json
30
+ * { "type": "trace-validate-sub-agents", "weight": 0.3,
31
+ * "config": { "requiredAgents": ["Database Research Agent", "Web Research Agent"], "minIterations": 1 } }
32
+ * ```
33
+ */
34
+ export declare class TraceSubAgentValidatorOracle implements IOracle {
35
+ readonly type = "trace-validate-sub-agents";
36
+ /** Guard against a cyclic or pathologically deep run tree; real trees are 2–3 levels. */
37
+ private static readonly MAX_DEPTH;
38
+ evaluate(input: OracleInput, config: OracleConfig): Promise<OracleResult>;
39
+ /** Walks the run tree, collecting dispatched sub-agent names and the parent's iteration count. */
40
+ private collectFacts;
41
+ private loadSteps;
42
+ private loadRun;
43
+ }
44
+ //# sourceMappingURL=TraceSubAgentValidatorOracle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceSubAgentValidatorOracle.d.ts","sourceRoot":"","sources":["../../src/oracles/TraceSubAgentValidatorOracle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGnE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,4BAA6B,YAAW,OAAO;IACxD,QAAQ,CAAC,IAAI,+BAA+B;IAE5C,yFAAyF;IACzF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAK;IAEhC,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB/E,kGAAkG;YACpF,YAAY;YA8BZ,SAAS;YAUT,OAAO;CAQxB"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @fileoverview Sub-agent dispatch oracle — the shipped-but-missing `trace-validate-sub-agents`.
3
+ * @module @memberjunction/testing-engine
4
+ */
5
+ import { RunView } from '@memberjunction/core';
6
+ import { evaluateSubAgentTrace } from '../eval/subAgentTrace.js';
7
+ /**
8
+ * Validates which sub-agents an agent run dispatched, and how many iterations it took.
9
+ *
10
+ * **This oracle was referenced by shipped metadata before it existed.** Both stock research-agent
11
+ * tests configure `trace-validate-sub-agents` and weight it at 0.25 and 0.3 respectively; with no
12
+ * implementation registered, the engine logged `Oracle not found` and a quarter to a third of each
13
+ * test's weight silently vanished from the score. The tests reported green on the remaining
14
+ * oracles. That is the defect this closes (test plan §2, gap 5).
15
+ *
16
+ * **Traversal.** Sub-agent runs are reached through the **Sub-Agent step's `TargetLogID`**, not
17
+ * through `AIAgentRun.ParentRunID`. The generated ORM is explicit that ParentRunID "records
18
+ * parentage but is not a link the tree traverses", and the platform's own run-tree walk uses the
19
+ * step link — so querying by ParentRunID would find runs the platform does not consider part of
20
+ * this tree, and miss none that it does. The walk recurses, because a sub-agent may dispatch its
21
+ * own, and a required agent two levels down was still dispatched by this run.
22
+ *
23
+ * Configuration (as the shipped tests already supply it):
24
+ * - `requiredAgents`: names that must appear
25
+ * - `forbiddenAgents`: names that must not
26
+ * - `minIterations`: minimum Prompt steps on the top-level run
27
+ *
28
+ * @example
29
+ * ```json
30
+ * { "type": "trace-validate-sub-agents", "weight": 0.3,
31
+ * "config": { "requiredAgents": ["Database Research Agent", "Web Research Agent"], "minIterations": 1 } }
32
+ * ```
33
+ */
34
+ export class TraceSubAgentValidatorOracle {
35
+ constructor() {
36
+ this.type = 'trace-validate-sub-agents';
37
+ }
38
+ /** Guard against a cyclic or pathologically deep run tree; real trees are 2–3 levels. */
39
+ static { this.MAX_DEPTH = 6; }
40
+ async evaluate(input, config) {
41
+ try {
42
+ const agentRun = input.targetEntity;
43
+ if (!agentRun?.ID) {
44
+ return { oracleType: this.type, passed: false, score: 0, message: 'No agent run entity provided' };
45
+ }
46
+ const facts = await this.collectFacts(agentRun.ID, input.contextUser);
47
+ const result = evaluateSubAgentTrace(facts, config);
48
+ return { oracleType: this.type, passed: result.passed, score: result.score, message: result.message, details: result.details };
49
+ }
50
+ catch (error) {
51
+ return {
52
+ oracleType: this.type,
53
+ passed: false,
54
+ score: 0,
55
+ message: `Sub-agent trace validation error: ${error.message}`
56
+ };
57
+ }
58
+ }
59
+ /** Walks the run tree, collecting dispatched sub-agent names and the parent's iteration count. */
60
+ async collectFacts(rootRunID, contextUser) {
61
+ const dispatchedAgents = [];
62
+ const visited = new Set();
63
+ const rootSteps = await this.loadSteps(rootRunID, contextUser);
64
+ // Iterations are the PARENT's prompt steps only — a sub-agent's prompts are its own passes.
65
+ const iterations = rootSteps.filter((s) => s.StepType === 'Prompt').length;
66
+ const walk = async (steps, depth) => {
67
+ if (depth > TraceSubAgentValidatorOracle.MAX_DEPTH) {
68
+ return;
69
+ }
70
+ for (const step of steps) {
71
+ if (step.StepType !== 'Sub-Agent' || !step.TargetLogID || visited.has(step.TargetLogID)) {
72
+ continue;
73
+ }
74
+ visited.add(step.TargetLogID);
75
+ const childRun = await this.loadRun(step.TargetLogID, contextUser);
76
+ // Fall back to the step name when the child run is unreadable: a dispatch that
77
+ // happened is a fact worth recording even if the child row cannot be loaded.
78
+ dispatchedAgents.push(childRun?.Agent?.trim() || step.StepName?.trim() || '(unnamed sub-agent)');
79
+ if (childRun) {
80
+ await walk(await this.loadSteps(childRun.ID, contextUser), depth + 1);
81
+ }
82
+ }
83
+ };
84
+ await walk(rootSteps, 1);
85
+ return { dispatchedAgents, iterations };
86
+ }
87
+ async loadSteps(agentRunID, contextUser) {
88
+ const result = await new RunView().RunView({
89
+ EntityName: 'MJ: AI Agent Run Steps',
90
+ ExtraFilter: `AgentRunID='${agentRunID}'`,
91
+ OrderBy: 'StepNumber',
92
+ ResultType: 'entity_object'
93
+ }, contextUser);
94
+ return result.Success ? (result.Results ?? []) : [];
95
+ }
96
+ async loadRun(agentRunID, contextUser) {
97
+ const result = await new RunView().RunView({
98
+ EntityName: 'MJ: AI Agent Runs',
99
+ ExtraFilter: `ID='${agentRunID}'`,
100
+ ResultType: 'entity_object'
101
+ }, contextUser);
102
+ return result.Success && result.Results?.length === 1 ? result.Results[0] : null;
103
+ }
104
+ }
105
+ //# sourceMappingURL=TraceSubAgentValidatorOracle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceSubAgentValidatorOracle.js","sourceRoot":"","sources":["../../src/oracles/TraceSubAgentValidatorOracle.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@
4
4
  export * from './IOracle.js';
5
5
  export * from './SchemaValidatorOracle.js';
6
6
  export * from './TraceValidatorOracle.js';
7
+ export * from './TraceSubAgentValidatorOracle.js';
8
+ export * from './AgentDecisionOracle.js';
7
9
  export * from './LLMJudgeOracle.js';
8
10
  export * from './ExactMatchOracle.js';
9
11
  export * from './SQLValidatorOracle.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oracles/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oracles/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
@@ -4,6 +4,8 @@
4
4
  export * from './IOracle.js';
5
5
  export * from './SchemaValidatorOracle.js';
6
6
  export * from './TraceValidatorOracle.js';
7
+ export * from './TraceSubAgentValidatorOracle.js';
8
+ export * from './AgentDecisionOracle.js';
7
9
  export * from './LLMJudgeOracle.js';
8
10
  export * from './ExactMatchOracle.js';
9
11
  export * from './SQLValidatorOracle.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oracles/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/oracles/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memberjunction/testing-engine",
3
3
  "type": "module",
4
- "version": "6.1.0-edge.5",
4
+ "version": "6.1.0-edge.7",
5
5
  "description": "MemberJunction Testing Framework Engine - Core test execution and evaluation engine supporting multiple test types",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -17,15 +17,15 @@
17
17
  "vitest": "^4.0.18"
18
18
  },
19
19
  "dependencies": {
20
- "@memberjunction/ai": "6.1.0-edge.5",
21
- "@memberjunction/ai-agents": "6.1.0-edge.5",
22
- "@memberjunction/ai-core-plus": "6.1.0-edge.5",
23
- "@memberjunction/ai-prompts": "6.1.0-edge.5",
24
- "@memberjunction/aiengine": "6.1.0-edge.5",
25
- "@memberjunction/core": "6.1.0-edge.5",
26
- "@memberjunction/core-entities": "6.1.0-edge.5",
27
- "@memberjunction/global": "6.1.0-edge.5",
28
- "@memberjunction/testing-engine-base": "6.1.0-edge.5",
20
+ "@memberjunction/ai": "6.1.0-edge.7",
21
+ "@memberjunction/ai-agents": "6.1.0-edge.7",
22
+ "@memberjunction/ai-core-plus": "6.1.0-edge.7",
23
+ "@memberjunction/ai-prompts": "6.1.0-edge.7",
24
+ "@memberjunction/aiengine": "6.1.0-edge.7",
25
+ "@memberjunction/core": "6.1.0-edge.7",
26
+ "@memberjunction/core-entities": "6.1.0-edge.7",
27
+ "@memberjunction/global": "6.1.0-edge.7",
28
+ "@memberjunction/testing-engine-base": "6.1.0-edge.7",
29
29
  "debug": "^4.4.3",
30
30
  "rxjs": "^7.8.2",
31
31
  "zod": "^3.25.0"