@orq-ai/evaluatorq 1.2.2 → 1.2.3-rc.1

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 (93) hide show
  1. package/dist/lib/integrations/ai-sdk/index.d.ts +2 -0
  2. package/dist/lib/integrations/ai-sdk/index.d.ts.map +1 -1
  3. package/dist/lib/integrations/ai-sdk/index.js +1 -0
  4. package/dist/lib/integrations/ai-sdk/simulation-adapter.d.ts +47 -0
  5. package/dist/lib/integrations/ai-sdk/simulation-adapter.d.ts.map +1 -0
  6. package/dist/lib/integrations/ai-sdk/simulation-adapter.js +58 -0
  7. package/dist/lib/integrations/langchain/index.d.ts +2 -0
  8. package/dist/lib/integrations/langchain/index.d.ts.map +1 -1
  9. package/dist/lib/integrations/langchain/index.js +1 -0
  10. package/dist/lib/integrations/langchain/simulation-adapter.d.ts +49 -0
  11. package/dist/lib/integrations/langchain/simulation-adapter.d.ts.map +1 -0
  12. package/dist/lib/integrations/langchain/simulation-adapter.js +110 -0
  13. package/dist/lib/integrations/simulation/adapters.d.ts +57 -0
  14. package/dist/lib/integrations/simulation/adapters.d.ts.map +1 -0
  15. package/dist/lib/integrations/simulation/adapters.js +64 -0
  16. package/dist/lib/integrations/simulation/agents/base.d.ts +90 -0
  17. package/dist/lib/integrations/simulation/agents/base.d.ts.map +1 -0
  18. package/dist/lib/integrations/simulation/agents/base.js +227 -0
  19. package/dist/lib/integrations/simulation/agents/index.d.ts +10 -0
  20. package/dist/lib/integrations/simulation/agents/index.d.ts.map +1 -0
  21. package/dist/lib/integrations/simulation/agents/index.js +6 -0
  22. package/dist/lib/integrations/simulation/agents/judge.d.ts +50 -0
  23. package/dist/lib/integrations/simulation/agents/judge.d.ts.map +1 -0
  24. package/dist/lib/integrations/simulation/agents/judge.js +313 -0
  25. package/dist/lib/integrations/simulation/agents/user-simulator.d.ts +41 -0
  26. package/dist/lib/integrations/simulation/agents/user-simulator.d.ts.map +1 -0
  27. package/dist/lib/integrations/simulation/agents/user-simulator.js +82 -0
  28. package/dist/lib/integrations/simulation/convert.d.ts +22 -0
  29. package/dist/lib/integrations/simulation/convert.d.ts.map +1 -0
  30. package/dist/lib/integrations/simulation/convert.js +124 -0
  31. package/dist/lib/integrations/simulation/evaluators/index.d.ts +50 -0
  32. package/dist/lib/integrations/simulation/evaluators/index.d.ts.map +1 -0
  33. package/dist/lib/integrations/simulation/evaluators/index.js +100 -0
  34. package/dist/lib/integrations/simulation/generators/datapoint-generator.d.ts +60 -0
  35. package/dist/lib/integrations/simulation/generators/datapoint-generator.d.ts.map +1 -0
  36. package/dist/lib/integrations/simulation/generators/datapoint-generator.js +223 -0
  37. package/dist/lib/integrations/simulation/generators/first-message-generator.d.ts +38 -0
  38. package/dist/lib/integrations/simulation/generators/first-message-generator.d.ts.map +1 -0
  39. package/dist/lib/integrations/simulation/generators/first-message-generator.js +131 -0
  40. package/dist/lib/integrations/simulation/generators/index.d.ts +15 -0
  41. package/dist/lib/integrations/simulation/generators/index.d.ts.map +1 -0
  42. package/dist/lib/integrations/simulation/generators/index.js +10 -0
  43. package/dist/lib/integrations/simulation/generators/persona-generator.d.ts +60 -0
  44. package/dist/lib/integrations/simulation/generators/persona-generator.d.ts.map +1 -0
  45. package/dist/lib/integrations/simulation/generators/persona-generator.js +333 -0
  46. package/dist/lib/integrations/simulation/generators/scenario-generator.d.ts +77 -0
  47. package/dist/lib/integrations/simulation/generators/scenario-generator.d.ts.map +1 -0
  48. package/dist/lib/integrations/simulation/generators/scenario-generator.js +545 -0
  49. package/dist/lib/integrations/simulation/index.d.ts +33 -0
  50. package/dist/lib/integrations/simulation/index.d.ts.map +1 -0
  51. package/dist/lib/integrations/simulation/index.js +35 -0
  52. package/dist/lib/integrations/simulation/quality/index.d.ts +5 -0
  53. package/dist/lib/integrations/simulation/quality/index.d.ts.map +1 -0
  54. package/dist/lib/integrations/simulation/quality/index.js +4 -0
  55. package/dist/lib/integrations/simulation/quality/message-perturbation.d.ts +25 -0
  56. package/dist/lib/integrations/simulation/quality/message-perturbation.d.ts.map +1 -0
  57. package/dist/lib/integrations/simulation/quality/message-perturbation.js +150 -0
  58. package/dist/lib/integrations/simulation/runner/index.d.ts +5 -0
  59. package/dist/lib/integrations/simulation/runner/index.d.ts.map +1 -0
  60. package/dist/lib/integrations/simulation/runner/index.js +4 -0
  61. package/dist/lib/integrations/simulation/runner/simulation.d.ts +57 -0
  62. package/dist/lib/integrations/simulation/runner/simulation.d.ts.map +1 -0
  63. package/dist/lib/integrations/simulation/runner/simulation.js +336 -0
  64. package/dist/lib/integrations/simulation/schemas.d.ts +104 -0
  65. package/dist/lib/integrations/simulation/schemas.d.ts.map +1 -0
  66. package/dist/lib/integrations/simulation/schemas.js +76 -0
  67. package/dist/lib/integrations/simulation/simulation/index.d.ts +49 -0
  68. package/dist/lib/integrations/simulation/simulation/index.d.ts.map +1 -0
  69. package/dist/lib/integrations/simulation/simulation/index.js +159 -0
  70. package/dist/lib/integrations/simulation/types.d.ts +101 -0
  71. package/dist/lib/integrations/simulation/types.d.ts.map +1 -0
  72. package/dist/lib/integrations/simulation/types.js +90 -0
  73. package/dist/lib/integrations/simulation/utils/dataset-export.d.ts +31 -0
  74. package/dist/lib/integrations/simulation/utils/dataset-export.d.ts.map +1 -0
  75. package/dist/lib/integrations/simulation/utils/dataset-export.js +146 -0
  76. package/dist/lib/integrations/simulation/utils/extract-json.d.ts +17 -0
  77. package/dist/lib/integrations/simulation/utils/extract-json.d.ts.map +1 -0
  78. package/dist/lib/integrations/simulation/utils/extract-json.js +106 -0
  79. package/dist/lib/integrations/simulation/utils/prompt-builders.d.ts +34 -0
  80. package/dist/lib/integrations/simulation/utils/prompt-builders.d.ts.map +1 -0
  81. package/dist/lib/integrations/simulation/utils/prompt-builders.js +147 -0
  82. package/dist/lib/integrations/simulation/utils/sanitize.d.ts +15 -0
  83. package/dist/lib/integrations/simulation/utils/sanitize.d.ts.map +1 -0
  84. package/dist/lib/integrations/simulation/utils/sanitize.js +20 -0
  85. package/dist/lib/integrations/simulation/wrap-agent.d.ts +65 -0
  86. package/dist/lib/integrations/simulation/wrap-agent.d.ts.map +1 -0
  87. package/dist/lib/integrations/simulation/wrap-agent.js +140 -0
  88. package/dist/lib/send-results.d.ts.map +1 -1
  89. package/dist/lib/send-results.js +17 -2
  90. package/dist/lib/types.d.ts +2 -2
  91. package/dist/lib/types.d.ts.map +1 -1
  92. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  93. package/package.json +24 -2
@@ -0,0 +1,17 @@
1
+ /**
2
+ * JSON extraction utilities for parsing LLM responses.
3
+ */
4
+ /**
5
+ * Extract JSON from LLM response, handling markdown code blocks.
6
+ *
7
+ * Robust extraction that handles:
8
+ * - ```json ... ``` blocks
9
+ * - ``` ... ``` blocks (no language specifier)
10
+ * - Plain JSON arrays or objects (no code block)
11
+ * - Multiple code blocks (returns first one)
12
+ *
13
+ * @param content - Raw LLM response content
14
+ * @returns Extracted JSON string, stripped of whitespace
15
+ */
16
+ export declare function extractJsonFromResponse(content: string): string;
17
+ //# sourceMappingURL=extract-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-json.d.ts","sourceRoot":"","sources":["../../../../../src/lib/integrations/simulation/utils/extract-json.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAqB/D"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * JSON extraction utilities for parsing LLM responses.
3
+ */
4
+ /**
5
+ * Regex pattern for extracting JSON from markdown code blocks.
6
+ * Handles ```json ... ``` and ``` ... ``` blocks.
7
+ */
8
+ const JSON_BLOCK_PATTERN = /```(?:json)?\s*\n?([\s\S]*?)\n?```/i;
9
+ /**
10
+ * Extract JSON from LLM response, handling markdown code blocks.
11
+ *
12
+ * Robust extraction that handles:
13
+ * - ```json ... ``` blocks
14
+ * - ``` ... ``` blocks (no language specifier)
15
+ * - Plain JSON arrays or objects (no code block)
16
+ * - Multiple code blocks (returns first one)
17
+ *
18
+ * @param content - Raw LLM response content
19
+ * @returns Extracted JSON string, stripped of whitespace
20
+ */
21
+ export function extractJsonFromResponse(content) {
22
+ if (!content) {
23
+ return "";
24
+ }
25
+ // Try to extract from code block using regex
26
+ const match = JSON_BLOCK_PATTERN.exec(content);
27
+ if (match?.[1]) {
28
+ return match[1].trim();
29
+ }
30
+ // No code block found — try to find the outermost JSON array or object
31
+ // by matching balanced brackets/braces
32
+ const arrayJson = extractBalanced(content, "[", "]");
33
+ if (arrayJson)
34
+ return arrayJson;
35
+ const objectJson = extractBalanced(content, "{", "}");
36
+ if (objectJson)
37
+ return objectJson;
38
+ // Fallback: return trimmed content as-is
39
+ return content.trim();
40
+ }
41
+ /**
42
+ * Find the outermost balanced pair of open/close characters in content.
43
+ * Respects JSON string literals to avoid counting brackets inside strings.
44
+ */
45
+ function extractBalancedFrom(content, open, close, startIdx) {
46
+ let depth = 0;
47
+ let inString = false;
48
+ let escaped = false;
49
+ for (let i = startIdx; i < content.length; i++) {
50
+ const ch = content[i];
51
+ if (escaped) {
52
+ escaped = false;
53
+ continue;
54
+ }
55
+ if (ch === "\\") {
56
+ escaped = true;
57
+ continue;
58
+ }
59
+ if (ch === '"') {
60
+ inString = !inString;
61
+ continue;
62
+ }
63
+ if (inString)
64
+ continue;
65
+ if (ch === open) {
66
+ depth++;
67
+ }
68
+ else if (ch === close) {
69
+ depth--;
70
+ if (depth === 0) {
71
+ return content.slice(startIdx, i + 1);
72
+ }
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ /**
78
+ * Find the outermost balanced pair of open/close characters in content.
79
+ * Tries each candidate occurrence and returns the first that parses as valid JSON.
80
+ * Falls back to the first balanced extraction if none parse.
81
+ */
82
+ function extractBalanced(content, open, close) {
83
+ let firstMatch = null;
84
+ let searchFrom = 0;
85
+ while (searchFrom < content.length) {
86
+ const idx = content.indexOf(open, searchFrom);
87
+ if (idx === -1)
88
+ break;
89
+ const candidate = extractBalancedFrom(content, open, close, idx);
90
+ if (!candidate) {
91
+ searchFrom = idx + 1;
92
+ continue;
93
+ }
94
+ if (!firstMatch)
95
+ firstMatch = candidate;
96
+ try {
97
+ JSON.parse(candidate);
98
+ return candidate; // Valid JSON — use it
99
+ }
100
+ catch {
101
+ // Not valid JSON, try next occurrence
102
+ }
103
+ searchFrom = idx + 1;
104
+ }
105
+ return firstMatch;
106
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Prompt building utilities for personas, scenarios, and datapoints.
3
+ *
4
+ * These are the TypeScript equivalents of:
5
+ * - Python Persona.to_system_prompt()
6
+ * - Python Scenario.to_user_context()
7
+ * - Python Datapoint.generate() / Datapoint._build_system_prompt()
8
+ */
9
+ import type { Datapoint, Persona, Scenario } from "../types.js";
10
+ /**
11
+ * Convert a persona to a system prompt for the user simulator.
12
+ *
13
+ * Mirrors Python `Persona.to_system_prompt()`.
14
+ */
15
+ export declare function buildPersonaSystemPrompt(persona: Persona): string;
16
+ /**
17
+ * Convert a scenario to context for the user simulator.
18
+ *
19
+ * Mirrors Python `Scenario.to_user_context()`.
20
+ */
21
+ export declare function buildScenarioUserContext(scenario: Scenario): string;
22
+ /**
23
+ * Build the combined system prompt from persona and scenario.
24
+ *
25
+ * Mirrors Python `Datapoint._build_system_prompt()`.
26
+ */
27
+ export declare function buildDatapointSystemPrompt(persona: Persona, scenario: Scenario): string;
28
+ /**
29
+ * Generate a datapoint from persona and scenario.
30
+ *
31
+ * Mirrors Python `Datapoint.generate()`.
32
+ */
33
+ export declare function generateDatapoint(persona: Persona, scenario: Scenario, firstMessage?: string): Datapoint;
34
+ //# sourceMappingURL=prompt-builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-builders.d.ts","sourceRoot":"","sources":["../../../../../src/lib/integrations/simulation/utils/prompt-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAahE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAwDjE;AAcD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA6CnE;AAMD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,YAAY,SAAK,GAChB,SAAS,CAQX"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Prompt building utilities for personas, scenarios, and datapoints.
3
+ *
4
+ * These are the TypeScript equivalents of:
5
+ * - Python Persona.to_system_prompt()
6
+ * - Python Scenario.to_user_context()
7
+ * - Python Datapoint.generate() / Datapoint._build_system_prompt()
8
+ */
9
+ import { CULTURAL_CONTEXT_INSTRUCTIONS, EMOTIONAL_ARC_INSTRUCTIONS, INPUT_FORMAT_INSTRUCTIONS, STRATEGY_INSTRUCTIONS, } from "../types.js";
10
+ import { delimit } from "./sanitize.js";
11
+ // ---------------------------------------------------------------------------
12
+ // Persona → system prompt
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Convert a persona to a system prompt for the user simulator.
16
+ *
17
+ * Mirrors Python `Persona.to_system_prompt()`.
18
+ */
19
+ export function buildPersonaSystemPrompt(persona) {
20
+ const patienceDesc = persona.patience < 0.3
21
+ ? "very impatient"
22
+ : persona.patience > 0.7
23
+ ? "patient"
24
+ : "moderately patient";
25
+ const assertiveDesc = persona.assertiveness > 0.7
26
+ ? "very assertive and direct"
27
+ : persona.assertiveness < 0.3
28
+ ? "passive"
29
+ : "balanced";
30
+ const politeDesc = persona.politeness < 0.3
31
+ ? "rude and curt"
32
+ : persona.politeness > 0.7
33
+ ? "very polite"
34
+ : "neutral in tone";
35
+ const techDesc = persona.technical_level < 0.3
36
+ ? "a complete novice"
37
+ : persona.technical_level > 0.7
38
+ ? "a technical expert"
39
+ : "somewhat technical";
40
+ let arcText = "";
41
+ const arcKey = persona.emotional_arc ?? "stable";
42
+ const arcInstruction = EMOTIONAL_ARC_INSTRUCTIONS[arcKey];
43
+ if (arcInstruction) {
44
+ arcText = `\n\nEmotional Arc: ${arcInstruction}`;
45
+ }
46
+ let culturalText = "";
47
+ const culturalKey = persona.cultural_context ?? "neutral";
48
+ const culturalInstruction = CULTURAL_CONTEXT_INSTRUCTIONS[culturalKey];
49
+ if (culturalInstruction) {
50
+ culturalText = `\n\nCultural Communication Style: ${culturalInstruction}`;
51
+ }
52
+ return `You are simulating a user with the following characteristics:
53
+
54
+ Name: ${delimit(persona.name)}
55
+ Patience: You are ${patienceDesc}
56
+ Assertiveness: You are ${assertiveDesc}
57
+ Politeness: You are ${politeDesc}
58
+ Technical Level: You are ${techDesc}
59
+ Communication Style: ${delimit(persona.communication_style)}
60
+
61
+ Background: ${delimit(persona.background)}
62
+ ${arcText}${culturalText}
63
+ Stay in character throughout the conversation. Your responses should reflect these traits consistently.
64
+ Do not break character or acknowledge that you are a simulation.`;
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Scenario → user context
68
+ // ---------------------------------------------------------------------------
69
+ const EMOTION_INSTRUCTIONS = {
70
+ neutral: "You approach this conversation calmly.",
71
+ frustrated: "You are frustrated and may express irritation.",
72
+ confused: "You are confused and may ask for clarification.",
73
+ happy: "You are in a good mood and friendly.",
74
+ urgent: "This is urgent and you need a quick resolution.",
75
+ };
76
+ /**
77
+ * Convert a scenario to context for the user simulator.
78
+ *
79
+ * Mirrors Python `Scenario.to_user_context()`.
80
+ */
81
+ export function buildScenarioUserContext(scenario) {
82
+ let criteriaText = "";
83
+ if (scenario.criteria && scenario.criteria.length > 0) {
84
+ const mustHappen = scenario.criteria
85
+ .filter((c) => c.type === "must_happen")
86
+ .map((c) => delimit(c.description));
87
+ const mustNot = scenario.criteria
88
+ .filter((c) => c.type === "must_not_happen")
89
+ .map((c) => delimit(c.description));
90
+ if (mustHappen.length > 0) {
91
+ criteriaText += `\n\nYou expect the agent to: ${mustHappen.join(", ")}`;
92
+ }
93
+ if (mustNot.length > 0) {
94
+ criteriaText += `\n\nYou would be dissatisfied if: ${mustNot.join(", ")}`;
95
+ }
96
+ }
97
+ let strategyText = "";
98
+ const strategyKey = scenario.conversation_strategy ?? "cooperative";
99
+ const strategyInstruction = STRATEGY_INSTRUCTIONS[strategyKey];
100
+ if (strategyInstruction) {
101
+ strategyText = `\n\nConversation Strategy: ${strategyInstruction}`;
102
+ }
103
+ let formatText = "";
104
+ const formatKey = scenario.input_format ?? "plain_text";
105
+ const formatInstruction = INPUT_FORMAT_INSTRUCTIONS[formatKey];
106
+ if (formatInstruction) {
107
+ formatText = `\n\nMessage Format: ${formatInstruction}`;
108
+ }
109
+ const emotionText = EMOTION_INSTRUCTIONS[scenario.starting_emotion ?? "neutral"] ?? "";
110
+ return `Scenario: ${delimit(scenario.name)}
111
+
112
+ Your Goal: ${delimit(scenario.goal)}
113
+
114
+ Context: ${delimit(scenario.context ?? "")}
115
+
116
+ Emotional State: ${emotionText}
117
+ ${criteriaText}${strategyText}${formatText}
118
+
119
+ Work towards your goal naturally. React authentically based on how the agent responds.`;
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Datapoint helpers
123
+ // ---------------------------------------------------------------------------
124
+ /**
125
+ * Build the combined system prompt from persona and scenario.
126
+ *
127
+ * Mirrors Python `Datapoint._build_system_prompt()`.
128
+ */
129
+ export function buildDatapointSystemPrompt(persona, scenario) {
130
+ const personaPrompt = buildPersonaSystemPrompt(persona);
131
+ const scenarioContext = buildScenarioUserContext(scenario);
132
+ return `${personaPrompt}\n\n---\n\n${scenarioContext}`;
133
+ }
134
+ /**
135
+ * Generate a datapoint from persona and scenario.
136
+ *
137
+ * Mirrors Python `Datapoint.generate()`.
138
+ */
139
+ export function generateDatapoint(persona, scenario, firstMessage = "") {
140
+ return {
141
+ id: `dp_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}`,
142
+ persona,
143
+ scenario,
144
+ user_system_prompt: buildDatapointSystemPrompt(persona, scenario),
145
+ first_message: firstMessage,
146
+ };
147
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Input sanitization utilities for prompt injection prevention.
3
+ */
4
+ /**
5
+ * Wrap user-controlled text in delimiters to prevent prompt injection.
6
+ *
7
+ * Uses XML-like data tags to clearly separate user content from
8
+ * system instructions in LLM prompts. The closing tag in the input
9
+ * is escaped to prevent breakout.
10
+ *
11
+ * @param text - User-controlled text to wrap
12
+ * @returns Delimited text safe for prompt interpolation
13
+ */
14
+ export declare function delimit(text: string): string;
15
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../../../src/lib/integrations/simulation/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Input sanitization utilities for prompt injection prevention.
3
+ */
4
+ /**
5
+ * Wrap user-controlled text in delimiters to prevent prompt injection.
6
+ *
7
+ * Uses XML-like data tags to clearly separate user content from
8
+ * system instructions in LLM prompts. The closing tag in the input
9
+ * is escaped to prevent breakout.
10
+ *
11
+ * @param text - User-controlled text to wrap
12
+ * @returns Delimited text safe for prompt interpolation
13
+ */
14
+ export function delimit(text) {
15
+ const sanitized = text
16
+ .replace(/&/g, "&amp;") // must be first
17
+ .replace(/<data>/gi, "&lt;data&gt;")
18
+ .replace(/<\/data>/gi, "&lt;/data&gt;");
19
+ return `<data>${sanitized}</data>`;
20
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Wraps the simulation framework as an evaluatorq Job.
3
+ *
4
+ * Follows the same pattern as wrapAISdkAgent() and wrapLangChainAgent().
5
+ */
6
+ import type { Job } from "../../types.js";
7
+ import type { ChatMessage } from "./types.js";
8
+ /**
9
+ * Options for creating a simulation job.
10
+ */
11
+ export interface SimulationJobOptions {
12
+ /** Display name for this job in results. Defaults to "simulation". */
13
+ name?: string;
14
+ /** Target agent callback — receives messages and returns a response string. */
15
+ targetCallback?: (messages: ChatMessage[]) => string | Promise<string>;
16
+ /** Orq deployment key — used if targetCallback is not provided. */
17
+ agentKey?: string;
18
+ /** Maximum conversation turns per simulation. Defaults to 10. */
19
+ maxTurns?: number;
20
+ /** Model used for user simulator and judge agents. Defaults to "azure/gpt-4o-mini". */
21
+ model?: string;
22
+ /** Built-in evaluator names to apply to results. Defaults to ["goal_achieved", "criteria_met"]. */
23
+ evaluators?: string[];
24
+ }
25
+ /**
26
+ * Creates an evaluatorq Job that runs agent simulations.
27
+ *
28
+ * Each DataPoint should have inputs containing simulation data:
29
+ * - `persona` (Persona object) and `scenario` (Scenario object), or
30
+ * - `datapoint` (full Datapoint object), or
31
+ * - `personas` (Persona[]) and `scenarios` (Scenario[]) for batch generation
32
+ *
33
+ * The job:
34
+ * 1. Extracts persona/scenario/datapoint from data.inputs
35
+ * 2. Runs simulate() with the target agent
36
+ * 3. Converts the first result to OpenResponses format
37
+ * 4. Returns { name, output: ResponseResource }
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { wrapSimulationAgent } from "@orq-ai/evaluatorq/simulation";
42
+ *
43
+ * const job = wrapSimulationAgent({
44
+ * targetCallback: async (messages) => {
45
+ * // Your agent logic here
46
+ * return "Agent response";
47
+ * },
48
+ * maxTurns: 5,
49
+ * });
50
+ *
51
+ * await evaluatorq("simulation-eval", {
52
+ * data: [
53
+ * {
54
+ * inputs: {
55
+ * persona: { name: "Impatient User", patience: 0.2, ... },
56
+ * scenario: { name: "Refund Request", goal: "Get a refund", ... },
57
+ * },
58
+ * },
59
+ * ],
60
+ * jobs: [job],
61
+ * });
62
+ * ```
63
+ */
64
+ export declare function wrapSimulationAgent(options: SimulationJobOptions): Job;
65
+ //# sourceMappingURL=wrap-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-agent.d.ts","sourceRoot":"","sources":["../../../../src/lib/integrations/simulation/wrap-agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAa,GAAG,EAAU,MAAM,gBAAgB,CAAC;AAI7D,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,GAAG,CAkGtE"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Wraps the simulation framework as an evaluatorq Job.
3
+ *
4
+ * Follows the same pattern as wrapAISdkAgent() and wrapLangChainAgent().
5
+ */
6
+ import { fromOrqDeployment } from "./adapters.js";
7
+ import { toOpenResponses } from "./convert.js";
8
+ import { simulate } from "./simulation/index.js";
9
+ /**
10
+ * Creates an evaluatorq Job that runs agent simulations.
11
+ *
12
+ * Each DataPoint should have inputs containing simulation data:
13
+ * - `persona` (Persona object) and `scenario` (Scenario object), or
14
+ * - `datapoint` (full Datapoint object), or
15
+ * - `personas` (Persona[]) and `scenarios` (Scenario[]) for batch generation
16
+ *
17
+ * The job:
18
+ * 1. Extracts persona/scenario/datapoint from data.inputs
19
+ * 2. Runs simulate() with the target agent
20
+ * 3. Converts the first result to OpenResponses format
21
+ * 4. Returns { name, output: ResponseResource }
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { wrapSimulationAgent } from "@orq-ai/evaluatorq/simulation";
26
+ *
27
+ * const job = wrapSimulationAgent({
28
+ * targetCallback: async (messages) => {
29
+ * // Your agent logic here
30
+ * return "Agent response";
31
+ * },
32
+ * maxTurns: 5,
33
+ * });
34
+ *
35
+ * await evaluatorq("simulation-eval", {
36
+ * data: [
37
+ * {
38
+ * inputs: {
39
+ * persona: { name: "Impatient User", patience: 0.2, ... },
40
+ * scenario: { name: "Refund Request", goal: "Get a refund", ... },
41
+ * },
42
+ * },
43
+ * ],
44
+ * jobs: [job],
45
+ * });
46
+ * ```
47
+ */
48
+ export function wrapSimulationAgent(options) {
49
+ const { name = "simulation", targetCallback, agentKey, maxTurns = 10, model, evaluators, } = options;
50
+ return async (data, _row) => {
51
+ // Resolve the target callback
52
+ let resolvedCallback = targetCallback;
53
+ if (!resolvedCallback && agentKey) {
54
+ resolvedCallback = fromOrqDeployment(agentKey);
55
+ }
56
+ if (!resolvedCallback) {
57
+ throw new Error("wrapSimulationAgent requires either targetCallback or agentKey");
58
+ }
59
+ // Extract simulation inputs from DataPoint
60
+ const inputs = data.inputs;
61
+ let datapoints;
62
+ let personas;
63
+ let scenarios;
64
+ if (inputs.datapoint) {
65
+ const dp = inputs.datapoint;
66
+ validateShape(dp, "datapoint", ["persona", "scenario", "first_message"]);
67
+ datapoints = [dp];
68
+ }
69
+ else if (inputs.datapoints) {
70
+ const dps = inputs.datapoints;
71
+ if (!Array.isArray(dps)) {
72
+ throw new Error("Expected 'datapoints' to be an array");
73
+ }
74
+ for (const dp of dps) {
75
+ validateShape(dp, "datapoints[]", [
76
+ "persona",
77
+ "scenario",
78
+ "first_message",
79
+ ]);
80
+ }
81
+ datapoints = dps;
82
+ }
83
+ else if (inputs.persona && inputs.scenario) {
84
+ validateShape(inputs.persona, "persona", ["name"]);
85
+ validateShape(inputs.scenario, "scenario", ["name", "goal"]);
86
+ personas = [inputs.persona];
87
+ scenarios = [inputs.scenario];
88
+ }
89
+ else if (inputs.personas && inputs.scenarios) {
90
+ if (!Array.isArray(inputs.personas) || !Array.isArray(inputs.scenarios)) {
91
+ throw new Error("Expected 'personas' and 'scenarios' to be arrays");
92
+ }
93
+ for (const p of inputs.personas)
94
+ validateShape(p, "personas[]", ["name"]);
95
+ for (const s of inputs.scenarios)
96
+ validateShape(s, "scenarios[]", ["name", "goal"]);
97
+ personas = inputs.personas;
98
+ scenarios = inputs.scenarios;
99
+ }
100
+ else {
101
+ throw new Error("Expected data.inputs to contain 'persona' + 'scenario', 'datapoint', 'datapoints', or 'personas' + 'scenarios'");
102
+ }
103
+ // Run simulation
104
+ const results = await simulate({
105
+ evaluationName: name,
106
+ targetCallback: resolvedCallback,
107
+ datapoints,
108
+ personas,
109
+ scenarios,
110
+ maxTurns,
111
+ model,
112
+ evaluators,
113
+ });
114
+ // Convert first result to OpenResponses format
115
+ const result = results[0];
116
+ if (!result) {
117
+ throw new Error("Simulation produced no results");
118
+ }
119
+ if (results.length > 1) {
120
+ console.warn(`wrapSimulationAgent: ${results.length} simulations ran but only the first result is returned. ` +
121
+ "Use simulate() directly to collect all results.");
122
+ }
123
+ const openResponsesOutput = toOpenResponses(result, model);
124
+ return {
125
+ name,
126
+ output: openResponsesOutput,
127
+ };
128
+ };
129
+ }
130
+ /** Lightweight runtime check that an object has the expected keys. */
131
+ function validateShape(value, label, requiredKeys) {
132
+ if (typeof value !== "object" || value === null) {
133
+ throw new Error(`Expected '${label}' to be an object, got ${typeof value}`);
134
+ }
135
+ for (const key of requiredKeys) {
136
+ if (!(key in value)) {
137
+ throw new Error(`Invalid '${label}': missing required field '${key}'`);
138
+ }
139
+ }
140
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"send-results.d.ts","sourceRoot":"","sources":["../../src/lib/send-results.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGtE,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QACL,KAAK,EACD,MAAM,GACN,OAAO,GACP,MAAM,GACN;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC;QACrD,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,yBAAyB,EAAE,CAAC;CACtC;AAWD,eAAO,MAAM,sBAAsB,GACjC,QAAQ,MAAM,EACd,gBAAgB,MAAM,EACtB,uBAAuB,MAAM,GAAG,SAAS,EACzC,WAAW,MAAM,GAAG,SAAS,EAC7B,SAAS,gBAAgB,EACzB,WAAW,IAAI,EACf,SAAS,IAAI,EACb,MAAM,MAAM,GAAG,SAAS,KACvB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAoG/B,CAAC"}
1
+ {"version":3,"file":"send-results.d.ts","sourceRoot":"","sources":["../../src/lib/send-results.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGtE,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QACL,KAAK,EACD,MAAM,GACN,OAAO,GACP,MAAM,GACN;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC;QACrD,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,yBAAyB,EAAE,CAAC;CACtC;AAmCD,eAAO,MAAM,sBAAsB,GACjC,QAAQ,MAAM,EACd,gBAAgB,MAAM,EACtB,uBAAuB,MAAM,GAAG,SAAS,EACzC,WAAW,MAAM,GAAG,SAAS,EAC7B,SAAS,gBAAgB,EACzB,WAAW,IAAI,EACf,SAAS,IAAI,EACb,MAAM,MAAM,GAAG,SAAS,KACvB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CA2G/B,CAAC"}
@@ -1,4 +1,16 @@
1
1
  import { Effect } from "effect";
2
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ const isEvaluationResultCell = (value) => isRecord(value) && typeof value.type === "string" && isRecord(value.value);
4
+ const serializeScoreValue = (value) => {
5
+ if (isRecord(value) && !isEvaluationResultCell(value)) {
6
+ return JSON.stringify(value);
7
+ }
8
+ return value;
9
+ };
10
+ const isResponseResource = (value) => isRecord(value) && value.object === "response";
11
+ const serializeOutput = (output) => isRecord(output) && !isResponseResource(output)
12
+ ? JSON.stringify(output)
13
+ : output;
2
14
  export const sendResultsToOrqEffect = (apiKey, evaluationName, evaluationDescription, datasetId, results, startTime, endTime, path) => Effect.gen(function* (_) {
3
15
  // Convert Error objects to strings for JSON serialization
4
16
  const serializedResults = results.map((result) => ({
@@ -6,11 +18,14 @@ export const sendResultsToOrqEffect = (apiKey, evaluationName, evaluationDescrip
6
18
  error: result.error ? String(result.error) : undefined,
7
19
  jobResults: result.jobResults?.map((jobResult) => ({
8
20
  jobName: jobResult.jobName,
9
- output: jobResult.output,
21
+ output: serializeOutput(jobResult.output),
10
22
  error: jobResult.error ? String(jobResult.error) : undefined,
11
23
  evaluatorScores: jobResult.evaluatorScores?.map((score) => ({
12
24
  evaluatorName: score.evaluatorName,
13
- score: score.score,
25
+ score: {
26
+ ...score.score,
27
+ value: serializeScoreValue(score.score.value),
28
+ },
14
29
  error: score.error ? String(score.error) : undefined,
15
30
  })),
16
31
  })),
@@ -12,7 +12,7 @@ type EvaluationResult<T> = {
12
12
  };
13
13
  export interface EvaluatorScore {
14
14
  evaluatorName: string;
15
- score: EvaluationResult<number | boolean | string | EvaluationResultCell>;
15
+ score: EvaluationResult<number | boolean | string | EvaluationResultCell | Record<string, unknown>>;
16
16
  error?: Error;
17
17
  }
18
18
  export interface JobResult {
@@ -84,6 +84,6 @@ export type ScorerParameter = {
84
84
  data: DataPoint;
85
85
  output: Output;
86
86
  };
87
- export type Scorer = (params: ScorerParameter) => Promise<EvaluationResult<string | number | boolean | EvaluationResultCell>>;
87
+ export type Scorer = (params: ScorerParameter) => Promise<EvaluationResult<string | number | boolean | EvaluationResultCell | Record<string, unknown>>>;
88
88
  export {};
89
89
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,MAAM,MAAM,GACd,MAAM,GACN,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,IAAI,CAAC;AAET,MAAM,MAAM,yBAAyB,GACjC,MAAM,GACN,MAAM,GACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;CAClD,CAAC;AAEF,KAAK,gBAAgB,CAAC,CAAC,IAAI;IACzB,KAAK,EAAE,CAAC,CAAC;IACT,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,oBAAoB,CAAC,CAAC;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GAAG,eAAe,EAAE,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,GAAG,GAAG,CAChB,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,KACR,OAAO,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EACA;QACE,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,GACD,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CACnB,MAAM,EAAE,eAAe,KACpB,OAAO,CACV,gBAAgB,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,oBAAoB,CAAC,CACnE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,MAAM,MAAM,MAAM,GACd,MAAM,GACN,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,IAAI,CAAC;AAET,MAAM,MAAM,yBAAyB,GACjC,MAAM,GACN,MAAM,GACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;CAClD,CAAC;AAEF,KAAK,gBAAgB,CAAC,CAAC,IAAI;IACzB,KAAK,EAAE,CAAC,CAAC;IACT,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CACrB,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3E,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GAAG,eAAe,EAAE,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,GAAG,GAAG,CAChB,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,KACR,OAAO,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EACA;QACE,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,GACD,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CACnB,MAAM,EAAE,eAAe,KACpB,OAAO,CACV,gBAAgB,CACd,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3E,CACF,CAAC"}