@chanl/scorecards-core 0.4.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.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/dist/dto/create-scorecard-category.dto.d.ts +7 -0
  3. package/dist/dto/create-scorecard-category.dto.d.ts.map +1 -0
  4. package/dist/dto/create-scorecard-category.dto.js +38 -0
  5. package/dist/dto/create-scorecard-category.dto.js.map +1 -0
  6. package/dist/dto/create-scorecard-criteria.dto.d.ts +11 -0
  7. package/dist/dto/create-scorecard-criteria.dto.d.ts.map +1 -0
  8. package/dist/dto/create-scorecard-criteria.dto.js +63 -0
  9. package/dist/dto/create-scorecard-criteria.dto.js.map +1 -0
  10. package/dist/dto/create-scorecard-result.dto.d.ts +8 -0
  11. package/dist/dto/create-scorecard-result.dto.d.ts.map +1 -0
  12. package/dist/dto/create-scorecard-result.dto.js +41 -0
  13. package/dist/dto/create-scorecard-result.dto.js.map +1 -0
  14. package/dist/dto/create-scorecard.dto.d.ts +9 -0
  15. package/dist/dto/create-scorecard.dto.d.ts.map +1 -0
  16. package/dist/dto/create-scorecard.dto.js +54 -0
  17. package/dist/dto/create-scorecard.dto.js.map +1 -0
  18. package/dist/dto/index.d.ts +8 -0
  19. package/dist/dto/index.d.ts.map +1 -0
  20. package/dist/dto/index.js +18 -0
  21. package/dist/dto/index.js.map +1 -0
  22. package/dist/dto/update-scorecard-category.dto.d.ts +6 -0
  23. package/dist/dto/update-scorecard-category.dto.d.ts.map +1 -0
  24. package/dist/dto/update-scorecard-category.dto.js +9 -0
  25. package/dist/dto/update-scorecard-category.dto.js.map +1 -0
  26. package/dist/dto/update-scorecard-criteria.dto.d.ts +6 -0
  27. package/dist/dto/update-scorecard-criteria.dto.d.ts.map +1 -0
  28. package/dist/dto/update-scorecard-criteria.dto.js +9 -0
  29. package/dist/dto/update-scorecard-criteria.dto.js.map +1 -0
  30. package/dist/dto/update-scorecard.dto.d.ts +6 -0
  31. package/dist/dto/update-scorecard.dto.d.ts.map +1 -0
  32. package/dist/dto/update-scorecard.dto.js +9 -0
  33. package/dist/dto/update-scorecard.dto.js.map +1 -0
  34. package/dist/evaluation/evaluation.service.d.ts +35 -0
  35. package/dist/evaluation/evaluation.service.d.ts.map +1 -0
  36. package/dist/evaluation/evaluation.service.js +225 -0
  37. package/dist/evaluation/evaluation.service.js.map +1 -0
  38. package/dist/evaluation/index.d.ts +2 -0
  39. package/dist/evaluation/index.d.ts.map +1 -0
  40. package/dist/evaluation/index.js +6 -0
  41. package/dist/evaluation/index.js.map +1 -0
  42. package/dist/handlers/conversation-completeness.handler.d.ts +7 -0
  43. package/dist/handlers/conversation-completeness.handler.d.ts.map +1 -0
  44. package/dist/handlers/conversation-completeness.handler.js +74 -0
  45. package/dist/handlers/conversation-completeness.handler.js.map +1 -0
  46. package/dist/handlers/criteria-handler-registry.d.ts +12 -0
  47. package/dist/handlers/criteria-handler-registry.d.ts.map +1 -0
  48. package/dist/handlers/criteria-handler-registry.js +45 -0
  49. package/dist/handlers/criteria-handler-registry.js.map +1 -0
  50. package/dist/handlers/criteria-handler.interface.d.ts +81 -0
  51. package/dist/handlers/criteria-handler.interface.d.ts.map +1 -0
  52. package/dist/handlers/criteria-handler.interface.js +3 -0
  53. package/dist/handlers/criteria-handler.interface.js.map +1 -0
  54. package/dist/handlers/hallucination.handler.d.ts +7 -0
  55. package/dist/handlers/hallucination.handler.d.ts.map +1 -0
  56. package/dist/handlers/hallucination.handler.js +86 -0
  57. package/dist/handlers/hallucination.handler.js.map +1 -0
  58. package/dist/handlers/index.d.ts +13 -0
  59. package/dist/handlers/index.d.ts.map +1 -0
  60. package/dist/handlers/index.js +29 -0
  61. package/dist/handlers/index.js.map +1 -0
  62. package/dist/handlers/keyword.handler.d.ts +7 -0
  63. package/dist/handlers/keyword.handler.d.ts.map +1 -0
  64. package/dist/handlers/keyword.handler.js +64 -0
  65. package/dist/handlers/keyword.handler.js.map +1 -0
  66. package/dist/handlers/knowledge-retention.handler.d.ts +7 -0
  67. package/dist/handlers/knowledge-retention.handler.d.ts.map +1 -0
  68. package/dist/handlers/knowledge-retention.handler.js +74 -0
  69. package/dist/handlers/knowledge-retention.handler.js.map +1 -0
  70. package/dist/handlers/prompt.handler.d.ts +7 -0
  71. package/dist/handlers/prompt.handler.d.ts.map +1 -0
  72. package/dist/handlers/prompt.handler.js +77 -0
  73. package/dist/handlers/prompt.handler.js.map +1 -0
  74. package/dist/handlers/rag-faithfulness.handler.d.ts +7 -0
  75. package/dist/handlers/rag-faithfulness.handler.d.ts.map +1 -0
  76. package/dist/handlers/rag-faithfulness.handler.js +110 -0
  77. package/dist/handlers/rag-faithfulness.handler.js.map +1 -0
  78. package/dist/handlers/response-time.handler.d.ts +7 -0
  79. package/dist/handlers/response-time.handler.d.ts.map +1 -0
  80. package/dist/handlers/response-time.handler.js +56 -0
  81. package/dist/handlers/response-time.handler.js.map +1 -0
  82. package/dist/handlers/role-adherence.handler.d.ts +7 -0
  83. package/dist/handlers/role-adherence.handler.d.ts.map +1 -0
  84. package/dist/handlers/role-adherence.handler.js +74 -0
  85. package/dist/handlers/role-adherence.handler.js.map +1 -0
  86. package/dist/handlers/scoring-utils.d.ts +10 -0
  87. package/dist/handlers/scoring-utils.d.ts.map +1 -0
  88. package/dist/handlers/scoring-utils.js +88 -0
  89. package/dist/handlers/scoring-utils.js.map +1 -0
  90. package/dist/handlers/tool-call.handler.d.ts +7 -0
  91. package/dist/handlers/tool-call.handler.d.ts.map +1 -0
  92. package/dist/handlers/tool-call.handler.js +43 -0
  93. package/dist/handlers/tool-call.handler.js.map +1 -0
  94. package/dist/index.d.ts +8 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +52 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/schemas/index.d.ts +5 -0
  99. package/dist/schemas/index.d.ts.map +1 -0
  100. package/dist/schemas/index.js +23 -0
  101. package/dist/schemas/index.js.map +1 -0
  102. package/dist/schemas/scorecard-category.schema.d.ts +20 -0
  103. package/dist/schemas/scorecard-category.schema.d.ts.map +1 -0
  104. package/dist/schemas/scorecard-category.schema.js +83 -0
  105. package/dist/schemas/scorecard-category.schema.js.map +1 -0
  106. package/dist/schemas/scorecard-criteria.schema.d.ts +92 -0
  107. package/dist/schemas/scorecard-criteria.schema.d.ts.map +1 -0
  108. package/dist/schemas/scorecard-criteria.schema.js +153 -0
  109. package/dist/schemas/scorecard-criteria.schema.js.map +1 -0
  110. package/dist/schemas/scorecard-result.schema.d.ts +47 -0
  111. package/dist/schemas/scorecard-result.schema.d.ts.map +1 -0
  112. package/dist/schemas/scorecard-result.schema.js +96 -0
  113. package/dist/schemas/scorecard-result.schema.js.map +1 -0
  114. package/dist/schemas/scorecard.schema.d.ts +21 -0
  115. package/dist/schemas/scorecard.schema.d.ts.map +1 -0
  116. package/dist/schemas/scorecard.schema.js +90 -0
  117. package/dist/schemas/scorecard.schema.js.map +1 -0
  118. package/dist/scorecards.controller.d.ts +104 -0
  119. package/dist/scorecards.controller.d.ts.map +1 -0
  120. package/dist/scorecards.controller.js +366 -0
  121. package/dist/scorecards.controller.js.map +1 -0
  122. package/dist/scorecards.module.d.ts +3 -0
  123. package/dist/scorecards.module.d.ts.map +1 -0
  124. package/dist/scorecards.module.js +59 -0
  125. package/dist/scorecards.module.js.map +1 -0
  126. package/dist/scorecards.service.d.ts +89 -0
  127. package/dist/scorecards.service.d.ts.map +1 -0
  128. package/dist/scorecards.service.js +587 -0
  129. package/dist/scorecards.service.js.map +1 -0
  130. package/package.json +39 -0
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleAdherenceHandler = exports.ConversationCompletenessHandler = exports.KnowledgeRetentionHandler = exports.ToolCallHandler = exports.ResponseTimeHandler = exports.RagFaithfulnessHandler = exports.PromptHandler = exports.KeywordHandler = exports.HallucinationHandler = exports.normalizeScore = exports.checkThreshold = exports.CriteriaHandlerRegistry = void 0;
4
+ var criteria_handler_registry_1 = require("./criteria-handler-registry");
5
+ Object.defineProperty(exports, "CriteriaHandlerRegistry", { enumerable: true, get: function () { return criteria_handler_registry_1.CriteriaHandlerRegistry; } });
6
+ var scoring_utils_1 = require("./scoring-utils");
7
+ Object.defineProperty(exports, "checkThreshold", { enumerable: true, get: function () { return scoring_utils_1.checkThreshold; } });
8
+ Object.defineProperty(exports, "normalizeScore", { enumerable: true, get: function () { return scoring_utils_1.normalizeScore; } });
9
+ // Built-in handlers (text-only — voice handlers removed for OSS)
10
+ var hallucination_handler_1 = require("./hallucination.handler");
11
+ Object.defineProperty(exports, "HallucinationHandler", { enumerable: true, get: function () { return hallucination_handler_1.HallucinationHandler; } });
12
+ var keyword_handler_1 = require("./keyword.handler");
13
+ Object.defineProperty(exports, "KeywordHandler", { enumerable: true, get: function () { return keyword_handler_1.KeywordHandler; } });
14
+ var prompt_handler_1 = require("./prompt.handler");
15
+ Object.defineProperty(exports, "PromptHandler", { enumerable: true, get: function () { return prompt_handler_1.PromptHandler; } });
16
+ var rag_faithfulness_handler_1 = require("./rag-faithfulness.handler");
17
+ Object.defineProperty(exports, "RagFaithfulnessHandler", { enumerable: true, get: function () { return rag_faithfulness_handler_1.RagFaithfulnessHandler; } });
18
+ var response_time_handler_1 = require("./response-time.handler");
19
+ Object.defineProperty(exports, "ResponseTimeHandler", { enumerable: true, get: function () { return response_time_handler_1.ResponseTimeHandler; } });
20
+ var tool_call_handler_1 = require("./tool-call.handler");
21
+ Object.defineProperty(exports, "ToolCallHandler", { enumerable: true, get: function () { return tool_call_handler_1.ToolCallHandler; } });
22
+ // Multi-turn conversation metric handlers
23
+ var knowledge_retention_handler_1 = require("./knowledge-retention.handler");
24
+ Object.defineProperty(exports, "KnowledgeRetentionHandler", { enumerable: true, get: function () { return knowledge_retention_handler_1.KnowledgeRetentionHandler; } });
25
+ var conversation_completeness_handler_1 = require("./conversation-completeness.handler");
26
+ Object.defineProperty(exports, "ConversationCompletenessHandler", { enumerable: true, get: function () { return conversation_completeness_handler_1.ConversationCompletenessHandler; } });
27
+ var role_adherence_handler_1 = require("./role-adherence.handler");
28
+ Object.defineProperty(exports, "RoleAdherenceHandler", { enumerable: true, get: function () { return role_adherence_handler_1.RoleAdherenceHandler; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":";;;AAKA,yEAAsE;AAA7D,oIAAA,uBAAuB,OAAA;AAChC,iDAAiE;AAAxD,+GAAA,cAAc,OAAA;AAAE,+GAAA,cAAc,OAAA;AAEvC,iEAAiE;AACjE,iEAA+D;AAAtD,6HAAA,oBAAoB,OAAA;AAC7B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,uEAAoE;AAA3D,kIAAA,sBAAsB,OAAA;AAC/B,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,yDAAsD;AAA7C,oHAAA,eAAe,OAAA;AAExB,0CAA0C;AAC1C,6EAA0E;AAAjE,wIAAA,yBAAyB,OAAA;AAClC,yFAAsF;AAA7E,oJAAA,+BAA+B,OAAA;AACxC,mEAAgE;AAAvD,8HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class KeywordHandler implements CriteriaHandler {
4
+ readonly type = "keyword";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=keyword.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/keyword.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAC;AACxE,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAEtC,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAEpB,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CAkElC"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KeywordHandler = void 0;
4
+ class KeywordHandler {
5
+ constructor() {
6
+ this.type = 'keyword';
7
+ }
8
+ async evaluate(criteria, context) {
9
+ const settings = criteria.settings;
10
+ // Support both 'keyword' (singular) and 'keywords' (plural) from DB
11
+ const rawKeywords = settings.keywords || settings.keyword;
12
+ if (!rawKeywords || (Array.isArray(rawKeywords) && rawKeywords.length === 0)) {
13
+ return {
14
+ result: false,
15
+ passed: false,
16
+ reasoning: 'No keywords configured for this criterion.',
17
+ evidence: [],
18
+ };
19
+ }
20
+ const keywords = Array.isArray(rawKeywords) ? rawKeywords : [rawKeywords];
21
+ const caseSensitive = settings.caseSensitive ?? false;
22
+ // Support 'any'/'all' matchType aliases alongside 'must_contain'/'must_not_contain'
23
+ const rawMatchType = settings.matchType || 'must_contain';
24
+ const matchType = rawMatchType === 'any' ? 'must_contain'
25
+ : rawMatchType === 'none' ? 'must_not_contain'
26
+ : rawMatchType;
27
+ const text = caseSensitive
28
+ ? context.transcriptText
29
+ : context.transcriptText.toLowerCase();
30
+ const normalizedKeywords = caseSensitive
31
+ ? keywords
32
+ : keywords.map((k) => k.toLowerCase());
33
+ const foundKeywords = [];
34
+ const evidence = [];
35
+ for (const keyword of normalizedKeywords) {
36
+ if (text.includes(keyword)) {
37
+ foundKeywords.push(keyword);
38
+ // Extract evidence snippets from segments
39
+ if (context.segments) {
40
+ for (const seg of context.segments) {
41
+ const segText = caseSensitive ? seg.text : seg.text.toLowerCase();
42
+ if (segText.includes(keyword) && evidence.length < 3) {
43
+ evidence.push(`[${seg.speaker}]: "${seg.text.substring(0, 200)}"`);
44
+ }
45
+ }
46
+ }
47
+ if (evidence.length >= 3)
48
+ break;
49
+ }
50
+ }
51
+ const found = foundKeywords.length > 0;
52
+ const passed = matchType === 'must_contain' ? found : !found;
53
+ const reasoning = matchType === 'must_contain'
54
+ ? found
55
+ ? `Keywords found: ${foundKeywords.join(', ')}`
56
+ : `None of the expected keywords were found: ${keywords.join(', ')}`
57
+ : found
58
+ ? `Prohibited keywords found: ${foundKeywords.join(', ')}`
59
+ : `No prohibited keywords were found`;
60
+ return { result: passed, passed, reasoning, evidence };
61
+ }
62
+ }
63
+ exports.KeywordHandler = KeywordHandler;
64
+ //# sourceMappingURL=keyword.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword.handler.js","sourceRoot":"","sources":["../../src/handlers/keyword.handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class KnowledgeRetentionHandler implements CriteriaHandler {
4
+ readonly type = "knowledge_retention";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=knowledge-retention.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-retention.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/knowledge-retention.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAGtC,qBAAa,yBAA0B,YAAW,eAAe;IAC/D,QAAQ,CAAC,IAAI,yBAAyB;IAEhC,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CAwElC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KnowledgeRetentionHandler = void 0;
4
+ const schemas_1 = require("../schemas");
5
+ const scoring_utils_1 = require("./scoring-utils");
6
+ class KnowledgeRetentionHandler {
7
+ constructor() {
8
+ this.type = 'knowledge_retention';
9
+ }
10
+ async evaluate(criteria, context) {
11
+ const settings = criteria.settings;
12
+ const evaluationType = settings?.evaluationType || 'score';
13
+ // No LLM available — return fallback
14
+ if (!context.llmEvaluate) {
15
+ return {
16
+ result: 5,
17
+ passed: false,
18
+ reasoning: 'LLM evaluator not available',
19
+ evidence: [],
20
+ };
21
+ }
22
+ // Empty transcript — nothing to evaluate
23
+ if (!context.transcriptText || context.transcriptText.trim() === '') {
24
+ return {
25
+ result: 5,
26
+ passed: false,
27
+ reasoning: 'Empty transcript',
28
+ evidence: [],
29
+ };
30
+ }
31
+ // Build threshold info for LLM (same pattern as prompt.handler)
32
+ let thresholdInfo;
33
+ if (criteria.threshold) {
34
+ if ((0, schemas_1.isBooleanThreshold)(criteria.threshold)) {
35
+ thresholdInfo = {
36
+ type: 'boolean',
37
+ expectedValue: criteria.threshold.expectedValue,
38
+ };
39
+ }
40
+ else if ((0, schemas_1.isNumericalThreshold)(criteria.threshold)) {
41
+ thresholdInfo = {
42
+ type: 'numerical',
43
+ min: criteria.threshold.min,
44
+ max: criteria.threshold.max,
45
+ };
46
+ }
47
+ }
48
+ try {
49
+ const llmResult = await context.llmEvaluate({
50
+ criterionName: criteria.name,
51
+ description: 'Review the multi-turn conversation and identify specific facts, names, products, order numbers, or details the customer mentioned. Did the agent correctly reference or recall these details in subsequent turns without asking the customer to repeat? Score 1-10 where 10 means perfect retention of all customer-provided information.',
52
+ evaluationType,
53
+ transcript: context.transcriptText,
54
+ threshold: thresholdInfo,
55
+ });
56
+ return {
57
+ result: llmResult.result,
58
+ passed: llmResult.passed ?? (0, scoring_utils_1.checkThreshold)(criteria, llmResult.result),
59
+ reasoning: llmResult.reasoning || 'Knowledge retention evaluation completed.',
60
+ evidence: llmResult.evidence || [],
61
+ };
62
+ }
63
+ catch (error) {
64
+ return {
65
+ result: 5,
66
+ passed: false,
67
+ reasoning: `Knowledge retention evaluation failed: ${error.message}. Using fallback.`,
68
+ evidence: [],
69
+ };
70
+ }
71
+ }
72
+ }
73
+ exports.KnowledgeRetentionHandler = KnowledgeRetentionHandler;
74
+ //# sourceMappingURL=knowledge-retention.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-retention.handler.js","sourceRoot":"","sources":["../../src/handlers/knowledge-retention.handler.ts"],"names":[],"mappings":";;;AAAA,wCAKoB;AAMpB,mDAAiD;AAEjD,MAAa,yBAAyB;IAAtC;QACW,SAAI,GAAG,qBAAqB,CAAC;IA6ExC,CAAC;IA3EC,KAAK,CAAC,QAAQ,CACZ,QAA2B,EAC3B,OAA0B;QAE1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAA8C,CAAC;QACzE,MAAM,cAAc,GAAG,QAAQ,EAAE,cAAc,IAAI,OAAO,CAAC;QAE3D,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,6BAA6B;gBACxC,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACpE,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,kBAAkB;gBAC7B,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,gEAAgE;QAChE,IAAI,aAKS,CAAC;QAEd,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,IAAI,IAAA,4BAAkB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3C,aAAa,GAAG;oBACd,IAAI,EAAE,SAAS;oBACf,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC,aAAa;iBAChD,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAA,8BAAoB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpD,aAAa,GAAG;oBACd,IAAI,EAAE,WAAW;oBACjB,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;oBAC3B,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;iBAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;gBAC1C,aAAa,EAAE,QAAQ,CAAC,IAAI;gBAC5B,WAAW,EACT,2UAA2U;gBAC7U,cAAc;gBACd,UAAU,EAAE,OAAO,CAAC,cAAc;gBAClC,SAAS,EAAE,aAAa;aACzB,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,IAAA,8BAAc,EAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC;gBACtE,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,2CAA2C;gBAC7E,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE;aACnC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,0CAA0C,KAAK,CAAC,OAAO,mBAAmB;gBACrF,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AA9ED,8DA8EC"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class PromptHandler implements CriteriaHandler {
4
+ readonly type = "prompt";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=prompt.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/prompt.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAGtC,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,YAAY;IAEnB,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CA0ElC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PromptHandler = void 0;
4
+ const schemas_1 = require("../schemas");
5
+ const scoring_utils_1 = require("./scoring-utils");
6
+ class PromptHandler {
7
+ constructor() {
8
+ this.type = 'prompt';
9
+ }
10
+ async evaluate(criteria, context) {
11
+ const settings = criteria.settings;
12
+ const evaluationType = settings.evaluationType || 'boolean';
13
+ // No LLM available — return fallback
14
+ if (!context.llmEvaluate) {
15
+ const fallbackResult = evaluationType === 'boolean' ? false : 5;
16
+ return {
17
+ result: fallbackResult,
18
+ passed: false,
19
+ reasoning: 'No LLM evaluator available. Using fallback value.',
20
+ evidence: [],
21
+ };
22
+ }
23
+ // No transcript text — return fallback
24
+ if (!context.transcriptText || context.transcriptText.trim() === '') {
25
+ const fallbackResult = evaluationType === 'boolean' ? false : 5;
26
+ return {
27
+ result: fallbackResult,
28
+ passed: false,
29
+ reasoning: 'No transcript available for evaluation.',
30
+ evidence: [],
31
+ };
32
+ }
33
+ // Build threshold info for LLM
34
+ let thresholdInfo;
35
+ if (criteria.threshold) {
36
+ if ((0, schemas_1.isBooleanThreshold)(criteria.threshold)) {
37
+ thresholdInfo = {
38
+ type: 'boolean',
39
+ expectedValue: criteria.threshold.expectedValue,
40
+ };
41
+ }
42
+ else if ((0, schemas_1.isNumericalThreshold)(criteria.threshold)) {
43
+ thresholdInfo = {
44
+ type: 'numerical',
45
+ min: criteria.threshold.min,
46
+ max: criteria.threshold.max,
47
+ };
48
+ }
49
+ }
50
+ try {
51
+ const llmResult = await context.llmEvaluate({
52
+ criterionName: criteria.name,
53
+ description: settings.description,
54
+ evaluationType,
55
+ transcript: context.transcriptText,
56
+ threshold: thresholdInfo,
57
+ });
58
+ return {
59
+ result: llmResult.result,
60
+ passed: llmResult.passed ?? (0, scoring_utils_1.checkThreshold)(criteria, llmResult.result),
61
+ reasoning: llmResult.reasoning || 'LLM evaluation completed.',
62
+ evidence: llmResult.evidence || [],
63
+ };
64
+ }
65
+ catch (error) {
66
+ const fallbackResult = evaluationType === 'boolean' ? false : 5;
67
+ return {
68
+ result: fallbackResult,
69
+ passed: false,
70
+ reasoning: `LLM evaluation failed: ${error.message}. Using fallback.`,
71
+ evidence: [],
72
+ };
73
+ }
74
+ }
75
+ }
76
+ exports.PromptHandler = PromptHandler;
77
+ //# sourceMappingURL=prompt.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.handler.js","sourceRoot":"","sources":["../../src/handlers/prompt.handler.ts"],"names":[],"mappings":";;;AAAA,wCAKoB;AAMpB,mDAAiD;AAEjD,MAAa,aAAa;IAA1B;QACW,SAAI,GAAG,QAAQ,CAAC;IA+E3B,CAAC;IA7EC,KAAK,CAAC,QAAQ,CACZ,QAA2B,EAC3B,OAA0B;QAE1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAkC,CAAC;QAC7D,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,SAAS,CAAC;QAE5D,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,cAAc,GAAG,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO;gBACL,MAAM,EAAE,cAAc;gBACtB,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,mDAAmD;gBAC9D,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACpE,MAAM,cAAc,GAAG,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO;gBACL,MAAM,EAAE,cAAc;gBACtB,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,yCAAyC;gBACpD,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,IAAI,aAKS,CAAC;QAEd,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,IAAI,IAAA,4BAAkB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3C,aAAa,GAAG;oBACd,IAAI,EAAE,SAAS;oBACf,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC,aAAa;iBAChD,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAA,8BAAoB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpD,aAAa,GAAG;oBACd,IAAI,EAAE,WAAW;oBACjB,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;oBAC3B,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;iBAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;gBAC1C,aAAa,EAAE,QAAQ,CAAC,IAAI;gBAC5B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,cAAc;gBACd,UAAU,EAAE,OAAO,CAAC,cAAc;gBAClC,SAAS,EAAE,aAAa;aACzB,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,IAAA,8BAAc,EAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC;gBACtE,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,2BAA2B;gBAC7D,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE;aACnC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,cAAc,GAAG,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO;gBACL,MAAM,EAAE,cAAc;gBACtB,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,0BAA0B,KAAK,CAAC,OAAO,mBAAmB;gBACrE,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAhFD,sCAgFC"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class RagFaithfulnessHandler implements CriteriaHandler {
4
+ readonly type = "rag_faithfulness";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=rag-faithfulness.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rag-faithfulness.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/rag-faithfulness.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAWtC,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,QAAQ,CAAC,IAAI,sBAAsB;IAE7B,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CA8GlC"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RagFaithfulnessHandler = void 0;
4
+ const schemas_1 = require("../schemas");
5
+ const scoring_utils_1 = require("./scoring-utils");
6
+ /** Default tool names considered as retrieval/RAG tools */
7
+ const DEFAULT_RETRIEVAL_TOOL_NAMES = [
8
+ 'search',
9
+ 'kb_search',
10
+ 'retrieve',
11
+ 'knowledge_search',
12
+ ];
13
+ class RagFaithfulnessHandler {
14
+ constructor() {
15
+ this.type = 'rag_faithfulness';
16
+ }
17
+ async evaluate(criteria, context) {
18
+ const settings = criteria.settings;
19
+ const evaluationType = settings?.evaluationType || 'boolean';
20
+ // Extract tool calls, default to empty array
21
+ const toolCalls = context.toolCalls ?? [];
22
+ // Determine which tool names count as retrieval tools
23
+ const retrievalToolNames = settings?.retrievalToolNames?.length
24
+ ? settings.retrievalToolNames
25
+ : DEFAULT_RETRIEVAL_TOOL_NAMES;
26
+ // Filter tool calls that match retrieval tool names
27
+ const retrievalCalls = toolCalls.filter((tc) => {
28
+ const toolName = tc.name || tc.function?.name || '';
29
+ return retrievalToolNames.includes(toolName);
30
+ });
31
+ // No retrieval tool calls found — nothing to check faithfulness against
32
+ if (retrievalCalls.length === 0) {
33
+ return {
34
+ result: true,
35
+ passed: true,
36
+ reasoning: 'No retrieval tools detected',
37
+ evidence: [],
38
+ notApplicable: true,
39
+ };
40
+ }
41
+ // No LLM available — cannot evaluate faithfulness
42
+ if (!context.llmEvaluate) {
43
+ return {
44
+ result: false,
45
+ passed: false,
46
+ reasoning: 'LLM evaluator not available',
47
+ evidence: [],
48
+ };
49
+ }
50
+ // Empty transcript — nothing to evaluate
51
+ if (!context.transcriptText || context.transcriptText.trim() === '') {
52
+ return {
53
+ result: true,
54
+ passed: true,
55
+ reasoning: 'Empty transcript — skipped',
56
+ evidence: [],
57
+ };
58
+ }
59
+ // Extract retrieved document content from matching tool calls
60
+ const retrievalResults = retrievalCalls.map((tc) => ({
61
+ tool: tc.name || tc.function?.name,
62
+ arguments: tc.arguments,
63
+ result: tc.result,
64
+ }));
65
+ // Build enhanced transcript with retrieved documents prepended
66
+ const enhancedTranscript = `## Retrieved Documents\n${JSON.stringify(retrievalResults, null, 2)}\n\n## Conversation Transcript\n${context.transcriptText}`;
67
+ // Build threshold info for LLM (same pattern as prompt/hallucination handlers)
68
+ let thresholdInfo;
69
+ if (criteria.threshold) {
70
+ if ((0, schemas_1.isBooleanThreshold)(criteria.threshold)) {
71
+ thresholdInfo = {
72
+ type: 'boolean',
73
+ expectedValue: criteria.threshold.expectedValue,
74
+ };
75
+ }
76
+ else if ((0, schemas_1.isNumericalThreshold)(criteria.threshold)) {
77
+ thresholdInfo = {
78
+ type: 'numerical',
79
+ min: criteria.threshold.min,
80
+ max: criteria.threshold.max,
81
+ };
82
+ }
83
+ }
84
+ try {
85
+ const llmResult = await context.llmEvaluate({
86
+ criterionName: criteria.name,
87
+ description: 'Evaluate whether the agent\'s responses are faithful to the retrieved documents. Check: Does the agent only make claims supported by the retrieved documents? Does it avoid fabricating information not present in the documents? Does it accurately represent the retrieved information without distortion?',
88
+ evaluationType,
89
+ transcript: enhancedTranscript,
90
+ threshold: thresholdInfo,
91
+ });
92
+ return {
93
+ result: llmResult.result,
94
+ passed: llmResult.passed ?? (0, scoring_utils_1.checkThreshold)(criteria, llmResult.result),
95
+ reasoning: llmResult.reasoning || 'RAG faithfulness evaluation completed.',
96
+ evidence: llmResult.evidence || [],
97
+ };
98
+ }
99
+ catch (error) {
100
+ return {
101
+ result: false,
102
+ passed: false,
103
+ reasoning: `RAG faithfulness evaluation failed: ${error.message}`,
104
+ evidence: [],
105
+ };
106
+ }
107
+ }
108
+ }
109
+ exports.RagFaithfulnessHandler = RagFaithfulnessHandler;
110
+ //# sourceMappingURL=rag-faithfulness.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rag-faithfulness.handler.js","sourceRoot":"","sources":["../../src/handlers/rag-faithfulness.handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class ResponseTimeHandler implements CriteriaHandler {
4
+ readonly type = "response_time";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=response-time.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-time.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/response-time.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAgC,MAAM,YAAY,CAAC;AAC7E,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAGtC,qBAAa,mBAAoB,YAAW,eAAe;IACzD,QAAQ,CAAC,IAAI,mBAAmB;IAE1B,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CAoDlC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseTimeHandler = void 0;
4
+ const scoring_utils_1 = require("./scoring-utils");
5
+ class ResponseTimeHandler {
6
+ constructor() {
7
+ this.type = 'response_time';
8
+ }
9
+ async evaluate(criteria, context) {
10
+ const settings = criteria.settings;
11
+ const participant = settings?.participant || 'agent';
12
+ let responseTime = null;
13
+ let source = '';
14
+ // Primary: firstResponseLatency from metrics
15
+ if (context.metrics?.firstResponseLatency !== undefined) {
16
+ responseTime = context.metrics.firstResponseLatency;
17
+ source = 'first response latency';
18
+ }
19
+ // Fallback: average segment length by participant
20
+ else if (context.metrics?.avgSegmentLength?.[participant] !== undefined) {
21
+ responseTime = context.metrics.avgSegmentLength[participant];
22
+ source = `average ${participant} segment length`;
23
+ }
24
+ // Last resort: calculate from segments
25
+ else if (context.segments && context.segments.length >= 2) {
26
+ // Find first response from the participant
27
+ for (let i = 1; i < context.segments.length; i++) {
28
+ if (context.segments[i].speaker.toLowerCase().includes(participant) &&
29
+ context.segments[i].startTime !== undefined &&
30
+ context.segments[i - 1].endTime !== undefined) {
31
+ responseTime =
32
+ context.segments[i].startTime - context.segments[i - 1].endTime;
33
+ source = 'calculated from segments';
34
+ break;
35
+ }
36
+ }
37
+ }
38
+ if (responseTime === null) {
39
+ return {
40
+ result: 0,
41
+ passed: false,
42
+ reasoning: 'No response time data available.',
43
+ evidence: [],
44
+ };
45
+ }
46
+ const passed = (0, scoring_utils_1.checkThreshold)(criteria, responseTime);
47
+ return {
48
+ result: responseTime,
49
+ passed,
50
+ reasoning: `${participant} response time: ${responseTime.toFixed(1)}s (source: ${source})`,
51
+ evidence: [],
52
+ };
53
+ }
54
+ }
55
+ exports.ResponseTimeHandler = ResponseTimeHandler;
56
+ //# sourceMappingURL=response-time.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-time.handler.js","sourceRoot":"","sources":["../../src/handlers/response-time.handler.ts"],"names":[],"mappings":";;;AAMA,mDAAiD;AAEjD,MAAa,mBAAmB;IAAhC;QACW,SAAI,GAAG,eAAe,CAAC;IAyDlC,CAAC;IAvDC,KAAK,CAAC,QAAQ,CACZ,QAA2B,EAC3B,OAA0B;QAE1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAwC,CAAC;QACnE,MAAM,WAAW,GAAG,QAAQ,EAAE,WAAW,IAAI,OAAO,CAAC;QAErD,IAAI,YAAY,GAAkB,IAAI,CAAC;QACvC,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,6CAA6C;QAC7C,IAAI,OAAO,CAAC,OAAO,EAAE,oBAAoB,KAAK,SAAS,EAAE,CAAC;YACxD,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;YACpD,MAAM,GAAG,wBAAwB,CAAC;QACpC,CAAC;QACD,kDAAkD;aAC7C,IAAI,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;YACxE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC7D,MAAM,GAAG,WAAW,WAAW,iBAAiB,CAAC;QACnD,CAAC;QACD,uCAAuC;aAClC,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC1D,2CAA2C;YAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACjD,IACE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;oBAC/D,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS;oBAC3C,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,EAC7C,CAAC;oBACD,YAAY;wBACV,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAQ,CAAC;oBACpE,MAAM,GAAG,0BAA0B,CAAC;oBACpC,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,kCAAkC;gBAC7C,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,8BAAc,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEtD,OAAO;YACL,MAAM,EAAE,YAAY;YACpB,MAAM;YACN,SAAS,EAAE,GAAG,WAAW,mBAAmB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,MAAM,GAAG;YAC1F,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;CACF;AA1DD,kDA0DC"}
@@ -0,0 +1,7 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ import { CriteriaHandler, CriteriaHandlerResult, EvaluationContext } from './criteria-handler.interface';
3
+ export declare class RoleAdherenceHandler implements CriteriaHandler {
4
+ readonly type = "role_adherence";
5
+ evaluate(criteria: ScorecardCriteria, context: EvaluationContext): Promise<CriteriaHandlerResult>;
6
+ }
7
+ //# sourceMappingURL=role-adherence.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-adherence.handler.d.ts","sourceRoot":"","sources":["../../src/handlers/role-adherence.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAGtC,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,QAAQ,CAAC,IAAI,oBAAoB;IAE3B,QAAQ,CACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,qBAAqB,CAAC;CAwElC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleAdherenceHandler = void 0;
4
+ const schemas_1 = require("../schemas");
5
+ const scoring_utils_1 = require("./scoring-utils");
6
+ class RoleAdherenceHandler {
7
+ constructor() {
8
+ this.type = 'role_adherence';
9
+ }
10
+ async evaluate(criteria, context) {
11
+ const settings = criteria.settings;
12
+ const evaluationType = settings?.evaluationType || 'score';
13
+ // No LLM available — return fallback
14
+ if (!context.llmEvaluate) {
15
+ return {
16
+ result: 5,
17
+ passed: false,
18
+ reasoning: 'LLM evaluator not available',
19
+ evidence: [],
20
+ };
21
+ }
22
+ // Empty transcript — nothing to evaluate
23
+ if (!context.transcriptText || context.transcriptText.trim() === '') {
24
+ return {
25
+ result: 5,
26
+ passed: false,
27
+ reasoning: 'Empty transcript',
28
+ evidence: [],
29
+ };
30
+ }
31
+ // Build threshold info for LLM (same pattern as prompt.handler)
32
+ let thresholdInfo;
33
+ if (criteria.threshold) {
34
+ if ((0, schemas_1.isBooleanThreshold)(criteria.threshold)) {
35
+ thresholdInfo = {
36
+ type: 'boolean',
37
+ expectedValue: criteria.threshold.expectedValue,
38
+ };
39
+ }
40
+ else if ((0, schemas_1.isNumericalThreshold)(criteria.threshold)) {
41
+ thresholdInfo = {
42
+ type: 'numerical',
43
+ min: criteria.threshold.min,
44
+ max: criteria.threshold.max,
45
+ };
46
+ }
47
+ }
48
+ try {
49
+ const llmResult = await context.llmEvaluate({
50
+ criterionName: criteria.name,
51
+ description: "Evaluate whether the agent maintained its assigned role and persona throughout the entire conversation. Check for: breaking character (e.g., 'As an AI...', 'I'm just a language model', 'I don't have feelings'), refusing tasks it should handle within its role, revealing system prompts or internal instructions, behaving inconsistently with its stated role or capabilities. Score 1-10 where 10 means perfect role adherence.",
52
+ evaluationType,
53
+ transcript: context.transcriptText,
54
+ threshold: thresholdInfo,
55
+ });
56
+ return {
57
+ result: llmResult.result,
58
+ passed: llmResult.passed ?? (0, scoring_utils_1.checkThreshold)(criteria, llmResult.result),
59
+ reasoning: llmResult.reasoning || 'Role adherence evaluation completed.',
60
+ evidence: llmResult.evidence || [],
61
+ };
62
+ }
63
+ catch (error) {
64
+ return {
65
+ result: 5,
66
+ passed: false,
67
+ reasoning: `Role adherence evaluation failed: ${error.message}. Using fallback.`,
68
+ evidence: [],
69
+ };
70
+ }
71
+ }
72
+ }
73
+ exports.RoleAdherenceHandler = RoleAdherenceHandler;
74
+ //# sourceMappingURL=role-adherence.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-adherence.handler.js","sourceRoot":"","sources":["../../src/handlers/role-adherence.handler.ts"],"names":[],"mappings":";;;AAAA,wCAKoB;AAMpB,mDAAiD;AAEjD,MAAa,oBAAoB;IAAjC;QACW,SAAI,GAAG,gBAAgB,CAAC;IA6EnC,CAAC;IA3EC,KAAK,CAAC,QAAQ,CACZ,QAA2B,EAC3B,OAA0B;QAE1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAyC,CAAC;QACpE,MAAM,cAAc,GAAG,QAAQ,EAAE,cAAc,IAAI,OAAO,CAAC;QAE3D,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,6BAA6B;gBACxC,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACpE,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,kBAAkB;gBAC7B,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;QAED,gEAAgE;QAChE,IAAI,aAKS,CAAC;QAEd,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,IAAI,IAAA,4BAAkB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3C,aAAa,GAAG;oBACd,IAAI,EAAE,SAAS;oBACf,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC,aAAa;iBAChD,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAA,8BAAoB,EAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpD,aAAa,GAAG;oBACd,IAAI,EAAE,WAAW;oBACjB,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;oBAC3B,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG;iBAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;gBAC1C,aAAa,EAAE,QAAQ,CAAC,IAAI;gBAC5B,WAAW,EACT,waAAwa;gBAC1a,cAAc;gBACd,UAAU,EAAE,OAAO,CAAC,cAAc;gBAClC,SAAS,EAAE,aAAa;aACzB,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,IAAA,8BAAc,EAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC;gBACtE,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,sCAAsC;gBACxE,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE;aACnC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,qCAAqC,KAAK,CAAC,OAAO,mBAAmB;gBAChF,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AA9ED,oDA8EC"}
@@ -0,0 +1,10 @@
1
+ import { ScorecardCriteria } from '../schemas';
2
+ /**
3
+ * Check whether a result passes the criteria's threshold.
4
+ */
5
+ export declare function checkThreshold(criteria: ScorecardCriteria, result: any): boolean;
6
+ /**
7
+ * Normalize a criteria result to the 0-10 scale for category averaging.
8
+ */
9
+ export declare function normalizeScore(result: any, criteria: ScorecardCriteria, passed?: boolean): number;
10
+ //# sourceMappingURL=scoring-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring-utils.d.ts","sourceRoot":"","sources":["../../src/handlers/scoring-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAKlB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,GAAG,GACV,OAAO,CAmCT;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,OAAO,GACf,MAAM,CA2CR"}