@microsoft/m365-copilot-eval 1.2.1-preview.1 → 1.4.0-preview.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 (44) hide show
  1. package/README.md +140 -101
  2. package/package.json +7 -4
  3. package/schema/CHANGELOG.md +8 -0
  4. package/schema/v1/eval-document.schema.json +256 -8
  5. package/schema/v1/examples/invalid/multi-turn-empty-turns.json +8 -0
  6. package/schema/v1/examples/invalid/multi-turn-has-both-prompt-and-turns.json +13 -0
  7. package/schema/v1/examples/invalid/multi-turn-missing-prompt.json +12 -0
  8. package/schema/v1/examples/invalid/multi-turn-typo-in-turn.json +13 -0
  9. package/schema/v1/examples/invalid/multi-turn-unknown-evaluator.json +15 -0
  10. package/schema/v1/examples/valid/comprehensive.json +27 -2
  11. package/schema/v1/examples/valid/mixed-single-and-multi-turn.json +30 -0
  12. package/schema/v1/examples/valid/multi-turn-output.json +59 -0
  13. package/schema/v1/examples/valid/multi-turn-simple.json +21 -0
  14. package/schema/v1/examples/valid/multi-turn-with-evaluators.json +34 -0
  15. package/schema/version.json +2 -2
  16. package/src/clients/cli/api_clients/A2A/__init__.py +3 -0
  17. package/src/clients/cli/api_clients/A2A/a2a_client.py +456 -0
  18. package/src/clients/cli/api_clients/REST/__init__.py +3 -0
  19. package/src/clients/cli/api_clients/REST/sydney_client.py +204 -0
  20. package/src/clients/cli/api_clients/__init__.py +3 -0
  21. package/src/clients/cli/api_clients/base_agent_client.py +78 -0
  22. package/src/clients/cli/cli_logging/__init__.py +0 -0
  23. package/src/clients/cli/cli_logging/console_diagnostics.py +107 -0
  24. package/src/clients/cli/cli_logging/logging_utils.py +144 -0
  25. package/src/clients/cli/common.py +62 -0
  26. package/src/clients/cli/custom_evaluators/CitationsEvaluator.py +3 -3
  27. package/src/clients/cli/custom_evaluators/ExactMatchEvaluator.py +11 -11
  28. package/src/clients/cli/custom_evaluators/PartialMatchEvaluator.py +1 -11
  29. package/src/clients/cli/evaluator_resolver.py +150 -0
  30. package/src/clients/cli/generate_report.py +347 -184
  31. package/src/clients/cli/main.py +1288 -481
  32. package/src/clients/cli/parallel_executor.py +57 -0
  33. package/src/clients/cli/readme.md +14 -7
  34. package/src/clients/cli/requirements.txt +1 -1
  35. package/src/clients/cli/response_extractor.py +30 -14
  36. package/src/clients/cli/retry_policy.py +52 -0
  37. package/src/clients/cli/samples/multiturn_example.json +35 -0
  38. package/src/clients/cli/throttle_gate.py +82 -0
  39. package/src/clients/node-js/bin/runevals.js +134 -41
  40. package/src/clients/node-js/config/default.js +5 -1
  41. package/src/clients/node-js/lib/agent-id.js +12 -0
  42. package/src/clients/node-js/lib/env-loader.js +11 -16
  43. package/src/clients/node-js/lib/eula-manager.js +78 -0
  44. package/src/clients/node-js/lib/progress.js +13 -11
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://raw.githubusercontent.com/microsoft/M365-Copilot-Agent-Evals/refs/heads/main/schema/v1/eval-document.schema.json",
4
4
  "title": "M365 Copilot Eval Document",
5
- "description": "Schema for evaluation documents used by M365 Copilot Agent Evals CLI. Version 1.0.0.",
5
+ "description": "Schema for evaluation documents used by M365 Copilot Agent Evals CLI. Supports single-turn and multi-turn evaluations.",
6
6
  "type": "object",
7
7
  "required": ["schemaVersion", "items"],
8
8
  "additionalProperties": true,
@@ -21,12 +21,19 @@
21
21
  "metadata": {
22
22
  "$ref": "#/$defs/DocumentMetadata"
23
23
  },
24
+ "default_evaluators": {
25
+ "$ref": "#/$defs/EvaluatorMap",
26
+ "description": "File-level default evaluators (overrides system defaults)"
27
+ },
24
28
  "items": {
25
29
  "type": "array",
26
30
  "minItems": 1,
27
- "description": "Array of evaluation items (prompts and optionally responses with scores)",
31
+ "description": "Array of evaluation items: single-turn evaluations or multi-turn threads",
28
32
  "items": {
29
- "$ref": "#/$defs/EvalItem"
33
+ "oneOf": [
34
+ { "$ref": "#/$defs/SingleTurnEvaluation" },
35
+ { "$ref": "#/$defs/MultiTurnThread" }
36
+ ]
30
37
  }
31
38
  }
32
39
  },
@@ -56,7 +63,7 @@
56
63
  "evaluatedAt": {
57
64
  "type": "string",
58
65
  "format": "date-time",
59
- "description": "ISO 8601 timestamp when evaluation was performed (output documents)"
66
+ "description": "ISO 8601 timestamp when evaluation was performed"
60
67
  },
61
68
  "tags": {
62
69
  "type": "array",
@@ -69,6 +76,14 @@
69
76
  "type": "string",
70
77
  "description": "M365 Agent ID this evaluation targets"
71
78
  },
79
+ "agentName": {
80
+ "type": "string",
81
+ "description": "Name of the M365 agent this evaluation targets"
82
+ },
83
+ "cliVersion": {
84
+ "type": "string",
85
+ "description": "Version of the M365 Copilot Agent Evals CLI that produced this document"
86
+ },
72
87
  "extensions": {
73
88
  "type": "object",
74
89
  "additionalProperties": true,
@@ -76,11 +91,11 @@
76
91
  }
77
92
  }
78
93
  },
79
- "EvalItem": {
94
+ "SingleTurnEvaluation": {
80
95
  "type": "object",
81
- "description": "A single evaluation item containing a prompt and optionally a response with scores",
96
+ "description": "A standalone single-turn prompt-response evaluation",
82
97
  "required": ["prompt"],
83
- "additionalProperties": true,
98
+ "additionalProperties": false,
84
99
  "properties": {
85
100
  "prompt": {
86
101
  "type": "string",
@@ -93,12 +108,22 @@
93
108
  },
94
109
  "response": {
95
110
  "type": "string",
96
- "description": "Actual response from the agent (present in output documents)"
111
+ "description": "Actual response from the agent"
97
112
  },
98
113
  "context": {
99
114
  "type": "string",
100
115
  "description": "Additional context for grounding evaluation"
101
116
  },
117
+ "evaluators": {
118
+ "$ref": "#/$defs/EvaluatorMap",
119
+ "description": "Per-prompt evaluator overrides"
120
+ },
121
+ "evaluators_mode": {
122
+ "type": "string",
123
+ "enum": ["extend", "replace"],
124
+ "default": "extend",
125
+ "description": "How per-prompt evaluators combine with defaults"
126
+ },
102
127
  "citations": {
103
128
  "type": "array",
104
129
  "items": {
@@ -114,6 +139,135 @@
114
139
  "additionalProperties": true,
115
140
  "description": "Extension point for custom item-level fields"
116
141
  }
142
+ },
143
+ "not": {
144
+ "required": ["turns"]
145
+ }
146
+ },
147
+ "MultiTurnThread": {
148
+ "type": "object",
149
+ "description": "A multi-turn conversation thread with ordered turns sharing conversation context",
150
+ "required": ["turns"],
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "name": {
154
+ "type": "string",
155
+ "description": "Human-readable name for the thread"
156
+ },
157
+ "description": {
158
+ "type": "string",
159
+ "description": "Description of what this thread tests"
160
+ },
161
+ "turns": {
162
+ "type": "array",
163
+ "minItems": 1,
164
+ "maxItems": 20,
165
+ "items": { "$ref": "#/$defs/Turn" },
166
+ "description": "Ordered array of conversation turns"
167
+ },
168
+ "conversation_id": {
169
+ "type": "string",
170
+ "description": "Unique identifier for this conversation thread"
171
+ },
172
+ "summary": {
173
+ "$ref": "#/$defs/ThreadSummary",
174
+ "description": "Aggregate statistics for the thread"
175
+ },
176
+ "extensions": {
177
+ "type": "object",
178
+ "additionalProperties": true,
179
+ "description": "Extension point for custom thread-level fields"
180
+ }
181
+ },
182
+ "not": {
183
+ "required": ["prompt"]
184
+ }
185
+ },
186
+ "Turn": {
187
+ "type": "object",
188
+ "description": "A single turn within a multi-turn thread",
189
+ "required": ["prompt"],
190
+ "additionalProperties": false,
191
+ "properties": {
192
+ "prompt": {
193
+ "type": "string",
194
+ "minLength": 1,
195
+ "description": "The user message for this turn"
196
+ },
197
+ "expected_response": {
198
+ "type": "string",
199
+ "description": "Expected agent response for this turn"
200
+ },
201
+ "response": {
202
+ "type": "string",
203
+ "description": "Actual agent response"
204
+ },
205
+ "context": {
206
+ "type": "string",
207
+ "description": "Additional context for grounding evaluation"
208
+ },
209
+ "evaluators": {
210
+ "$ref": "#/$defs/EvaluatorMap",
211
+ "description": "Per-turn evaluator overrides"
212
+ },
213
+ "evaluators_mode": {
214
+ "type": "string",
215
+ "enum": ["extend", "replace"],
216
+ "default": "extend",
217
+ "description": "How per-turn evaluators combine with defaults"
218
+ },
219
+ "citations": {
220
+ "type": "array",
221
+ "items": {
222
+ "$ref": "#/$defs/Citation"
223
+ },
224
+ "description": "Citations included in the response"
225
+ },
226
+ "scores": {
227
+ "$ref": "#/$defs/ScoreCollection"
228
+ },
229
+ "status": {
230
+ "type": "string",
231
+ "enum": ["pass", "fail", "error"],
232
+ "description": "Overall status of this turn"
233
+ },
234
+ "error": {
235
+ "type": "string",
236
+ "description": "Error message if status is 'error'"
237
+ },
238
+ "extensions": {
239
+ "type": "object",
240
+ "additionalProperties": true,
241
+ "description": "Extension point for custom turn-level fields"
242
+ }
243
+ }
244
+ },
245
+ "ThreadSummary": {
246
+ "type": "object",
247
+ "description": "Aggregate statistics for a thread",
248
+ "required": ["turns_total", "turns_passed", "turns_failed", "overall_status"],
249
+ "additionalProperties": false,
250
+ "properties": {
251
+ "turns_total": {
252
+ "type": "integer",
253
+ "minimum": 1,
254
+ "description": "Total number of turns executed"
255
+ },
256
+ "turns_passed": {
257
+ "type": "integer",
258
+ "minimum": 0,
259
+ "description": "Number of turns where all evaluators passed"
260
+ },
261
+ "turns_failed": {
262
+ "type": "integer",
263
+ "minimum": 0,
264
+ "description": "Number of turns where any evaluator failed"
265
+ },
266
+ "overall_status": {
267
+ "type": "string",
268
+ "enum": ["pass", "partial", "fail"],
269
+ "description": "pass: all turns passed, partial: some failed, fail: all failed or error"
270
+ }
117
271
  }
118
272
  },
119
273
  "ScoreCollection": {
@@ -140,6 +294,14 @@
140
294
  "citations": {
141
295
  "$ref": "#/$defs/CitationScore",
142
296
  "description": "Citation evaluation results"
297
+ },
298
+ "exactMatch": {
299
+ "$ref": "#/$defs/ExactMatchScore",
300
+ "description": "Exact match evaluation result"
301
+ },
302
+ "partialMatch": {
303
+ "$ref": "#/$defs/PartialMatchScore",
304
+ "description": "Partial match evaluation result"
143
305
  }
144
306
  }
145
307
  },
@@ -211,6 +373,92 @@
211
373
  }
212
374
  }
213
375
  },
376
+ "ExactMatchScore": {
377
+ "type": "object",
378
+ "description": "Exact match evaluation result",
379
+ "required": ["match", "result"],
380
+ "additionalProperties": true,
381
+ "properties": {
382
+ "match": {
383
+ "type": "boolean",
384
+ "description": "Whether response exactly matches expected_response (trimmed; case-insensitive by default)"
385
+ },
386
+ "result": {
387
+ "type": "string",
388
+ "enum": ["pass", "fail"],
389
+ "description": "Pass when match is true, fail otherwise"
390
+ },
391
+ "reason": {
392
+ "type": "string",
393
+ "description": "Explanation of the match result"
394
+ }
395
+ }
396
+ },
397
+ "PartialMatchScore": {
398
+ "type": "object",
399
+ "description": "Partial match evaluation result",
400
+ "required": ["score", "result", "threshold"],
401
+ "additionalProperties": true,
402
+ "properties": {
403
+ "score": {
404
+ "type": "number",
405
+ "minimum": 0,
406
+ "maximum": 1,
407
+ "description": "Match score from 0.0 (no match) to 1.0 (full match)"
408
+ },
409
+ "result": {
410
+ "type": "string",
411
+ "enum": ["pass", "fail"],
412
+ "description": "Pass/fail based on score vs threshold"
413
+ },
414
+ "threshold": {
415
+ "type": "number",
416
+ "minimum": 0,
417
+ "maximum": 1,
418
+ "description": "Minimum score required for pass (default: 0.5)"
419
+ },
420
+ "reason": {
421
+ "type": "string",
422
+ "description": "Explanation of the match result"
423
+ }
424
+ }
425
+ },
426
+ "EvaluatorMap": {
427
+ "type": "object",
428
+ "description": "Map of evaluator names to their configuration options",
429
+ "propertyNames": {
430
+ "enum": ["Relevance", "Coherence", "Groundedness", "ToolCallAccuracy", "Citations", "ExactMatch", "PartialMatch"]
431
+ },
432
+ "additionalProperties": {
433
+ "$ref": "#/$defs/EvaluatorOptions"
434
+ }
435
+ },
436
+ "EvaluatorOptions": {
437
+ "type": "object",
438
+ "description": "Evaluator configuration options. Use empty object {} for defaults.",
439
+ "additionalProperties": false,
440
+ "properties": {
441
+ "threshold": {
442
+ "type": "number",
443
+ "description": "Pass/fail threshold. Range depends on evaluator type: 1-5 for LLM evaluators (default: 3), >= 1 integer for Citations (min citation count, default: 1), 0.0-1.0 for PartialMatch (min match ratio, default: 0.5). Validated per-evaluator at runtime."
444
+ },
445
+ "citation_format": {
446
+ "type": "string",
447
+ "examples": ["oai_unicode", "bracket", "mixed"],
448
+ "description": "Citation format for detection. 'oai_unicode': new OAI unicode format, 'bracket': legacy [^i^] bracket format, 'mixed': auto-detect both formats. Default: oai_unicode."
449
+ },
450
+ "case_sensitive": {
451
+ "type": "boolean",
452
+ "default": false,
453
+ "description": "Case-sensitive matching for ExactMatch/PartialMatch"
454
+ },
455
+ "options": {
456
+ "type": "object",
457
+ "additionalProperties": true,
458
+ "description": "Evaluator-specific configuration"
459
+ }
460
+ }
461
+ },
214
462
  "Citation": {
215
463
  "type": "object",
216
464
  "description": "A single citation reference",
@@ -0,0 +1,8 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "turns": []
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "prompt": "This item has both prompt and turns",
6
+ "turns": [
7
+ {
8
+ "prompt": "Turn 1"
9
+ }
10
+ ]
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "turns": [
6
+ {
7
+ "expected_response": "This turn is missing a prompt."
8
+ }
9
+ ]
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "turns": [
6
+ {
7
+ "prompt": "Hello",
8
+ "expeceted_response": "Typo in field name"
9
+ }
10
+ ]
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "turns": [
6
+ {
7
+ "prompt": "Hello",
8
+ "evaluators": {
9
+ "TaskCompletionEvaluator": {}
10
+ }
11
+ }
12
+ ]
13
+ }
14
+ ]
15
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/microsoft/M365-Copilot-Agent-Evals/refs/heads/main/schema/v1/eval-document.schema.json",
3
- "schemaVersion": "1.0.0",
3
+ "schemaVersion": "1.1.0",
4
4
  "metadata": {
5
5
  "name": "Graph API Evaluation Set",
6
6
  "description": "Test prompts for Microsoft Graph API knowledge",
@@ -9,11 +9,17 @@
9
9
  "evaluatedAt": "2026-01-20T10:30:00Z",
10
10
  "tags": ["graph", "api", "authentication"],
11
11
  "agentId": "12345678-1234-1234-1234-123456789abc",
12
+ "agentName": "Graph Knowledge Agent",
13
+ "cliVersion": "1.2.0",
12
14
  "extensions": {
13
15
  "com.contoso.department": "engineering",
14
16
  "com.contoso.priority": "high"
15
17
  }
16
18
  },
19
+ "default_evaluators": {
20
+ "Relevance": {},
21
+ "Coherence": {}
22
+ },
17
23
  "items": [
18
24
  {
19
25
  "prompt": "What is Microsoft Graph API?",
@@ -86,7 +92,26 @@
86
92
  },
87
93
  {
88
94
  "prompt": "How do I authenticate with Microsoft Graph?",
89
- "expected_response": "You can authenticate using OAuth 2.0 or client credentials flow."
95
+ "expected_response": "You can authenticate using OAuth 2.0 or client credentials flow.",
96
+ "evaluators": {
97
+ "ExactMatch": { "case_sensitive": false },
98
+ "PartialMatch": { "threshold": 0.5 }
99
+ },
100
+ "evaluators_mode": "replace",
101
+ "response": "You can authenticate using OAuth 2.0 or client credentials flow.",
102
+ "scores": {
103
+ "exactMatch": {
104
+ "match": true,
105
+ "result": "pass",
106
+ "reason": "Exact match found"
107
+ },
108
+ "partialMatch": {
109
+ "score": 1.0,
110
+ "result": "pass",
111
+ "threshold": 0.5,
112
+ "reason": "Match score: 1.000"
113
+ }
114
+ }
90
115
  }
91
116
  ]
92
117
  }
@@ -0,0 +1,30 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "default_evaluators": {
4
+ "Relevance": {},
5
+ "Coherence": {}
6
+ },
7
+ "items": [
8
+ {
9
+ "prompt": "What is Microsoft Graph API?",
10
+ "expected_response": "Microsoft Graph API is a unified endpoint for accessing Microsoft services."
11
+ },
12
+ {
13
+ "name": "Canadian Employee HR Inquiry",
14
+ "turns": [
15
+ {
16
+ "prompt": "I'm a Canadian employee based in Toronto.",
17
+ "expected_response": "Got it! I can help with Canada-specific HR questions."
18
+ },
19
+ {
20
+ "prompt": "Is July 4th a holiday for me?",
21
+ "expected_response": "July 4th is not a statutory holiday in Canada. However, July 1st (Canada Day) is."
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "prompt": "How do I authenticate with Microsoft Graph?",
27
+ "expected_response": "You can authenticate using OAuth 2.0 or client credentials flow."
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "metadata": {
4
+ "evaluatedAt": "2026-03-30T10:00:00Z",
5
+ "agentName": "Travel Assistant",
6
+ "cliVersion": "1.3.0"
7
+ },
8
+ "items": [
9
+ {
10
+ "name": "Context Persistence Test",
11
+ "turns": [
12
+ {
13
+ "prompt": "I'm based in Seattle.",
14
+ "expected_response": "Got it! I can help with Seattle-specific questions.",
15
+ "response": "Understood! I can assist with Seattle-related queries.",
16
+ "scores": {
17
+ "relevance": {
18
+ "score": 4.0,
19
+ "result": "pass",
20
+ "threshold": 3,
21
+ "reason": "Response acknowledges Seattle context."
22
+ },
23
+ "coherence": {
24
+ "score": 5.0,
25
+ "result": "pass",
26
+ "threshold": 3
27
+ }
28
+ },
29
+ "status": "pass"
30
+ },
31
+ {
32
+ "prompt": "What's the weather like here?",
33
+ "expected_response": "Seattle weather is typically mild with rain.",
34
+ "response": "Seattle generally has mild temperatures with frequent rain, especially in fall and winter.",
35
+ "scores": {
36
+ "relevance": {
37
+ "score": 5.0,
38
+ "result": "pass",
39
+ "threshold": 3
40
+ },
41
+ "coherence": {
42
+ "score": 4.0,
43
+ "result": "pass",
44
+ "threshold": 3
45
+ }
46
+ },
47
+ "status": "pass"
48
+ }
49
+ ],
50
+ "conversation_id": "conv-abc-123",
51
+ "summary": {
52
+ "turns_total": 2,
53
+ "turns_passed": 2,
54
+ "turns_failed": 0,
55
+ "overall_status": "pass"
56
+ }
57
+ }
58
+ ]
59
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "items": [
4
+ {
5
+ "turns": [
6
+ {
7
+ "prompt": "I'm traveling to Seattle next week for a conference.",
8
+ "expected_response": "I can help with travel-related questions."
9
+ },
10
+ {
11
+ "prompt": "What's the weather usually like?",
12
+ "expected_response": "Seattle weather is typically mild with some rain."
13
+ },
14
+ {
15
+ "prompt": "Should I bring a rain jacket?",
16
+ "expected_response": "Yes, Seattle is known for rain. A rain jacket is recommended."
17
+ }
18
+ ]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "schemaVersion": "1.2.0",
3
+ "default_evaluators": {
4
+ "Relevance": {},
5
+ "Coherence": {}
6
+ },
7
+ "items": [
8
+ {
9
+ "name": "Expense Policy Flow",
10
+ "description": "Test that agent handles expense policy questions across turns",
11
+ "turns": [
12
+ {
13
+ "prompt": "I'm traveling to Seattle next week for a conference.",
14
+ "expected_response": "I can help with travel-related questions."
15
+ },
16
+ {
17
+ "prompt": "My dinner last night was $250. Is that okay?",
18
+ "expected_response": "The per-diem meal allowance is a maximum of $200.",
19
+ "evaluators": {
20
+ "Groundedness": { "threshold": 4 }
21
+ }
22
+ },
23
+ {
24
+ "prompt": "What should I do about the overage?",
25
+ "expected_response": "For expenses exceeding the policy limit, you'll need manager approval.",
26
+ "evaluators": {
27
+ "ExactMatch": { "case_sensitive": false }
28
+ },
29
+ "evaluators_mode": "replace"
30
+ }
31
+ ]
32
+ }
33
+ ]
34
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.0.0",
3
- "releaseDate": "2026-02-19",
2
+ "version": "1.2.0",
3
+ "releaseDate": "2026-04-02",
4
4
  "schemaId": "https://raw.githubusercontent.com/microsoft/M365-Copilot-Agent-Evals/refs/heads/main/schema/v1/eval-document.schema.json",
5
5
  "description": "M365 Copilot Eval Document Schema"
6
6
  }
@@ -0,0 +1,3 @@
1
+ from .a2a_client import A2AClient
2
+
3
+ __all__ = ["A2AClient"]