agentops-accelerator 0.3.0__py3-none-any.whl

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 (142) hide show
  1. agentops/__init__.py +10 -0
  2. agentops/__main__.py +6 -0
  3. agentops/agent/__init__.py +12 -0
  4. agentops/agent/_legacy_ids.py +92 -0
  5. agentops/agent/analyzer.py +207 -0
  6. agentops/agent/checks/__init__.py +1 -0
  7. agentops/agent/checks/catalog.py +880 -0
  8. agentops/agent/checks/errors.py +279 -0
  9. agentops/agent/checks/foundry_config.py +75 -0
  10. agentops/agent/checks/latency.py +84 -0
  11. agentops/agent/checks/opex.py +157 -0
  12. agentops/agent/checks/opex_workspace.py +874 -0
  13. agentops/agent/checks/posture.py +36 -0
  14. agentops/agent/checks/posture_rules/__init__.py +53 -0
  15. agentops/agent/checks/posture_rules/content_filter.py +59 -0
  16. agentops/agent/checks/posture_rules/diagnostics.py +74 -0
  17. agentops/agent/checks/posture_rules/local_auth.py +55 -0
  18. agentops/agent/checks/posture_rules/managed_identity.py +59 -0
  19. agentops/agent/checks/posture_rules/network.py +68 -0
  20. agentops/agent/checks/regression.py +78 -0
  21. agentops/agent/checks/release_readiness.py +182 -0
  22. agentops/agent/checks/safety.py +247 -0
  23. agentops/agent/checks/spec_conformance.py +375 -0
  24. agentops/agent/cockpit.py +5159 -0
  25. agentops/agent/config.py +240 -0
  26. agentops/agent/findings.py +113 -0
  27. agentops/agent/history.py +142 -0
  28. agentops/agent/knowledge/__init__.py +182 -0
  29. agentops/agent/knowledge/waf-checklist.csv +39 -0
  30. agentops/agent/llm_assist/__init__.py +16 -0
  31. agentops/agent/llm_assist/_base.py +124 -0
  32. agentops/agent/llm_assist/_bundle_rule.py +154 -0
  33. agentops/agent/llm_assist/_client.py +347 -0
  34. agentops/agent/llm_assist/_dataset_rules.py +191 -0
  35. agentops/agent/llm_assist/_engine.py +106 -0
  36. agentops/agent/llm_assist/_prompt_rules.py +291 -0
  37. agentops/agent/llm_assist/_spec_rules.py +235 -0
  38. agentops/agent/production_telemetry.py +430 -0
  39. agentops/agent/report.py +207 -0
  40. agentops/agent/server/__init__.py +1 -0
  41. agentops/agent/server/app.py +84 -0
  42. agentops/agent/server/auth.py +94 -0
  43. agentops/agent/server/chat.py +44 -0
  44. agentops/agent/server/protocol.py +72 -0
  45. agentops/agent/sources/__init__.py +1 -0
  46. agentops/agent/sources/azure_monitor.py +523 -0
  47. agentops/agent/sources/azure_resources.py +602 -0
  48. agentops/agent/sources/foundry_control.py +174 -0
  49. agentops/agent/sources/results_history.py +494 -0
  50. agentops/agent/sources/spec_detectors/__init__.py +42 -0
  51. agentops/agent/sources/spec_detectors/_base.py +58 -0
  52. agentops/agent/sources/spec_detectors/agents_md.py +75 -0
  53. agentops/agent/sources/spec_detectors/spec_kit.py +172 -0
  54. agentops/agent/time_range.py +117 -0
  55. agentops/cli/__init__.py +1 -0
  56. agentops/cli/app.py +4823 -0
  57. agentops/core/__init__.py +1 -0
  58. agentops/core/agentops_config.py +592 -0
  59. agentops/core/config_loader.py +22 -0
  60. agentops/core/evaluators.py +480 -0
  61. agentops/core/release_evidence.py +56 -0
  62. agentops/core/results.py +117 -0
  63. agentops/mcp/__init__.py +10 -0
  64. agentops/mcp/server.py +232 -0
  65. agentops/pipeline/__init__.py +8 -0
  66. agentops/pipeline/cloud_results.py +189 -0
  67. agentops/pipeline/cloud_runner.py +901 -0
  68. agentops/pipeline/comparison.py +108 -0
  69. agentops/pipeline/diagnostics.py +51 -0
  70. agentops/pipeline/invocations.py +535 -0
  71. agentops/pipeline/official_eval.py +414 -0
  72. agentops/pipeline/orchestrator.py +775 -0
  73. agentops/pipeline/prompt_deploy.py +377 -0
  74. agentops/pipeline/publisher.py +121 -0
  75. agentops/pipeline/reporter.py +202 -0
  76. agentops/pipeline/runtime.py +409 -0
  77. agentops/pipeline/thresholds.py +84 -0
  78. agentops/services/__init__.py +1 -0
  79. agentops/services/cicd.py +720 -0
  80. agentops/services/eval_analysis.py +848 -0
  81. agentops/services/evidence_pack.py +757 -0
  82. agentops/services/initializer.py +86 -0
  83. agentops/services/preflight.py +470 -0
  84. agentops/services/setup_wizard.py +709 -0
  85. agentops/services/skills.py +643 -0
  86. agentops/services/trace_promotion.py +300 -0
  87. agentops/services/workflow_analysis.py +1129 -0
  88. agentops/templates/.gitignore +15 -0
  89. agentops/templates/__init__.py +1 -0
  90. agentops/templates/agent-server/Dockerfile +23 -0
  91. agentops/templates/agent-server/README.md +61 -0
  92. agentops/templates/agent-server/main.bicep +94 -0
  93. agentops/templates/agent.yaml +87 -0
  94. agentops/templates/agentops.yaml +58 -0
  95. agentops/templates/foundry.svg +71 -0
  96. agentops/templates/icon.png +0 -0
  97. agentops/templates/pipelines/azuredevops/agentops-deploy-dev-azd.yml +118 -0
  98. agentops/templates/pipelines/azuredevops/agentops-deploy-dev.yml +73 -0
  99. agentops/templates/pipelines/azuredevops/agentops-deploy-prod-azd.yml +141 -0
  100. agentops/templates/pipelines/azuredevops/agentops-deploy-prod.yml +94 -0
  101. agentops/templates/pipelines/azuredevops/agentops-deploy-prompt-agent.yml +167 -0
  102. agentops/templates/pipelines/azuredevops/agentops-deploy-qa-azd.yml +118 -0
  103. agentops/templates/pipelines/azuredevops/agentops-deploy-qa.yml +68 -0
  104. agentops/templates/pipelines/azuredevops/agentops-pr-prompt-agent.yml +210 -0
  105. agentops/templates/pipelines/azuredevops/agentops-pr.yml +155 -0
  106. agentops/templates/pipelines/azuredevops/agentops-watchdog.yml +106 -0
  107. agentops/templates/project.gitignore +36 -0
  108. agentops/templates/sample-traces.jsonl +3 -0
  109. agentops/templates/skills/agentops-agent/SKILL.md +137 -0
  110. agentops/templates/skills/agentops-config/SKILL.md +113 -0
  111. agentops/templates/skills/agentops-dataset/SKILL.md +84 -0
  112. agentops/templates/skills/agentops-eval/SKILL.md +189 -0
  113. agentops/templates/skills/agentops-report/SKILL.md +71 -0
  114. agentops/templates/skills/agentops-workflow/SKILL.md +471 -0
  115. agentops/templates/smoke.jsonl +3 -0
  116. agentops/templates/waf-checklist.README.md +84 -0
  117. agentops/templates/waf-checklist.csv +22 -0
  118. agentops/templates/workflows/agentops-deploy-dev-azd.yml +166 -0
  119. agentops/templates/workflows/agentops-deploy-dev.yml +187 -0
  120. agentops/templates/workflows/agentops-deploy-prod-azd.yml +183 -0
  121. agentops/templates/workflows/agentops-deploy-prod.yml +171 -0
  122. agentops/templates/workflows/agentops-deploy-prompt-agent.yml +197 -0
  123. agentops/templates/workflows/agentops-deploy-qa-azd.yml +156 -0
  124. agentops/templates/workflows/agentops-deploy-qa.yml +145 -0
  125. agentops/templates/workflows/agentops-pr-prompt-agent.yml +210 -0
  126. agentops/templates/workflows/agentops-pr.yml +148 -0
  127. agentops/templates/workflows/agentops-watchdog.yml +122 -0
  128. agentops/utils/__init__.py +1 -0
  129. agentops/utils/azd_env.py +435 -0
  130. agentops/utils/azure_endpoints.py +62 -0
  131. agentops/utils/colors.py +47 -0
  132. agentops/utils/dotenv_loader.py +105 -0
  133. agentops/utils/foundry_discovery.py +229 -0
  134. agentops/utils/logging.py +59 -0
  135. agentops/utils/telemetry.py +554 -0
  136. agentops/utils/yaml.py +36 -0
  137. agentops_accelerator-0.3.0.dist-info/METADATA +278 -0
  138. agentops_accelerator-0.3.0.dist-info/RECORD +142 -0
  139. agentops_accelerator-0.3.0.dist-info/WHEEL +5 -0
  140. agentops_accelerator-0.3.0.dist-info/entry_points.txt +2 -0
  141. agentops_accelerator-0.3.0.dist-info/licenses/LICENSE +21 -0
  142. agentops_accelerator-0.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,414 @@
1
+ """Prepare Microsoft Foundry AI Agent Evaluation inputs from AgentOps config."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import os
8
+ from dataclasses import dataclass
9
+ from pathlib import Path
10
+ from typing import Any, Iterable, Mapping, Sequence
11
+
12
+ from agentops.core.agentops_config import AgentOpsConfig, classify_agent
13
+ from agentops.core.config_loader import load_agentops_config
14
+ from agentops.core.evaluators import EvaluatorPreset, detect_dataset_shape, select_evaluators
15
+
16
+
17
+ OFFICIAL_EVAL_RUNNER = "official-ai-agent-evaluation"
18
+ OFFICIAL_EVAL_ACTION = "microsoft/ai-agent-evals@v3-beta"
19
+ OFFICIAL_EVAL_ADO_TASK = "AIAgentEvaluation@2"
20
+ OFFICIAL_EVAL_ACTION_ENV = "AGENTOPS_OFFICIAL_EVAL_ACTION"
21
+ OFFICIAL_EVAL_ADO_TASK_ENV = "AGENTOPS_OFFICIAL_EVAL_ADO_TASK"
22
+ AGENTOPS_LOCAL_RUNNER = "agentops-local"
23
+ AGENTOPS_CLOUD_RUNNER = "agentops-cloud"
24
+
25
+ _LATENCY_PRESET = "avg_latency_seconds"
26
+ _OFFICIAL_EVALUATORS: dict[str, str] = {
27
+ "CoherenceEvaluator": "builtin.coherence",
28
+ "FluencyEvaluator": "builtin.fluency",
29
+ "SimilarityEvaluator": "builtin.text_similarity",
30
+ "F1ScoreEvaluator": "builtin.f1_score",
31
+ "GroundednessEvaluator": "builtin.groundedness",
32
+ "RelevanceEvaluator": "builtin.relevance",
33
+ "RetrievalEvaluator": "builtin.retrieval",
34
+ "ResponseCompletenessEvaluator": "builtin.response_completeness",
35
+ "ToolCallAccuracyEvaluator": "builtin.tool_call_accuracy",
36
+ "IntentResolutionEvaluator": "builtin.intent_resolution",
37
+ "TaskAdherenceEvaluator": "builtin.task_adherence",
38
+ }
39
+ _GROUND_TRUTH_EVALUATORS = {
40
+ "builtin.text_similarity",
41
+ "builtin.f1_score",
42
+ "builtin.response_completeness",
43
+ }
44
+
45
+
46
+ def official_eval_action_ref() -> str:
47
+ """Return the GitHub Action ref used for Microsoft Foundry eval workflows."""
48
+
49
+ return os.getenv(OFFICIAL_EVAL_ACTION_ENV, OFFICIAL_EVAL_ACTION)
50
+
51
+
52
+ def official_eval_ado_task_ref() -> str:
53
+ """Return the Azure DevOps task ref used for Microsoft Foundry eval workflows."""
54
+
55
+ return os.getenv(OFFICIAL_EVAL_ADO_TASK_ENV, OFFICIAL_EVAL_ADO_TASK)
56
+
57
+
58
+ class OfficialEvalUnsupported(ValueError):
59
+ """Raised when an AgentOps config cannot use Microsoft Foundry AI Agent Evaluation."""
60
+
61
+
62
+ @dataclass(frozen=True)
63
+ class OfficialEvalSupport:
64
+ """Eligibility result for the Microsoft Foundry evaluation runner."""
65
+
66
+ eligible: bool
67
+ runner: str
68
+ reasons: tuple[str, ...]
69
+ warnings: tuple[str, ...]
70
+ official_evaluators: tuple[str, ...]
71
+ agent_ids: str | None
72
+ data_path: Path | None
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class OfficialEvalPreparation:
77
+ """Prepared Microsoft Foundry evaluation input and metadata."""
78
+
79
+ data_path: Path
80
+ metadata_path: Path
81
+ agent_ids: str
82
+ deployment_name: str
83
+ official_evaluators: tuple[str, ...]
84
+ warnings: tuple[str, ...]
85
+
86
+
87
+ @dataclass(frozen=True)
88
+ class _EvalPlan:
89
+ config: AgentOpsConfig
90
+ config_path: Path
91
+ dataset_path: Path
92
+ agent_ids: str
93
+ official_evaluators: tuple[str, ...]
94
+ skipped_agentops_evaluators: tuple[str, ...]
95
+ warnings: tuple[str, ...]
96
+
97
+
98
+ def analyze_official_eval_support(config_path: Path) -> OfficialEvalSupport:
99
+ """Report whether ``config_path`` can use the Microsoft Foundry eval runner."""
100
+
101
+ try:
102
+ plan = _build_plan(config_path)
103
+ except OfficialEvalUnsupported as exc:
104
+ return OfficialEvalSupport(
105
+ eligible=False,
106
+ runner=AGENTOPS_LOCAL_RUNNER,
107
+ reasons=(str(exc),),
108
+ warnings=(),
109
+ official_evaluators=(),
110
+ agent_ids=None,
111
+ data_path=None,
112
+ )
113
+ except Exception as exc:
114
+ return OfficialEvalSupport(
115
+ eligible=False,
116
+ runner=AGENTOPS_LOCAL_RUNNER,
117
+ reasons=(f"agentops.yaml cannot be prepared for Microsoft Foundry eval: {exc}",),
118
+ warnings=(),
119
+ official_evaluators=(),
120
+ agent_ids=None,
121
+ data_path=None,
122
+ )
123
+
124
+ return OfficialEvalSupport(
125
+ eligible=True,
126
+ runner=OFFICIAL_EVAL_RUNNER,
127
+ reasons=(
128
+ "Agent target is a Foundry prompt agent (`name:version`).",
129
+ "Dataset columns are compatible with Microsoft Foundry eval.",
130
+ ),
131
+ warnings=plan.warnings,
132
+ official_evaluators=plan.official_evaluators,
133
+ agent_ids=plan.agent_ids,
134
+ data_path=plan.dataset_path,
135
+ )
136
+
137
+
138
+ def recommended_eval_runner(directory: Path) -> str:
139
+ """Return the safest evaluation runner for generated CI/CD workflows."""
140
+
141
+ support = analyze_official_eval_support(directory / "agentops.yaml")
142
+ return AGENTOPS_CLOUD_RUNNER if support.eligible else AGENTOPS_LOCAL_RUNNER
143
+
144
+
145
+ def prepare_official_eval(
146
+ config_path: Path,
147
+ output_path: Path,
148
+ *,
149
+ deployment_name: str | None = None,
150
+ ) -> OfficialEvalPreparation:
151
+ """Convert AgentOps JSONL config into Microsoft Foundry AI Agent Evaluation JSON."""
152
+
153
+ plan = _build_plan(config_path)
154
+ deployment = _resolve_deployment_name(deployment_name)
155
+ payload = _build_payload(plan)
156
+
157
+ output_path.parent.mkdir(parents=True, exist_ok=True)
158
+ output_path.write_text(
159
+ json.dumps(payload, indent=2, ensure_ascii=False) + "\n",
160
+ encoding="utf-8",
161
+ )
162
+
163
+ metadata_path = output_path.with_name("metadata.json")
164
+ metadata = {
165
+ "runner": OFFICIAL_EVAL_RUNNER,
166
+ "action": official_eval_action_ref(),
167
+ "azure_devops_task": official_eval_ado_task_ref(),
168
+ "agent_ids": plan.agent_ids,
169
+ "deployment_name": deployment,
170
+ "data_path": str(output_path),
171
+ "items_total": len(payload.get("data", [])),
172
+ "official_evaluators": list(plan.official_evaluators),
173
+ "skipped_agentops_evaluators": list(plan.skipped_agentops_evaluators),
174
+ "machine_readable_thresholds": False,
175
+ "warnings": list(plan.warnings),
176
+ }
177
+ metadata_path.write_text(
178
+ json.dumps(metadata, indent=2, ensure_ascii=False) + "\n",
179
+ encoding="utf-8",
180
+ )
181
+
182
+ return OfficialEvalPreparation(
183
+ data_path=output_path,
184
+ metadata_path=metadata_path,
185
+ agent_ids=plan.agent_ids,
186
+ deployment_name=deployment,
187
+ official_evaluators=plan.official_evaluators,
188
+ warnings=plan.warnings,
189
+ )
190
+
191
+
192
+ def _build_plan(config_path: Path) -> _EvalPlan:
193
+ config_path = config_path.resolve()
194
+ if not config_path.exists():
195
+ raise OfficialEvalUnsupported(
196
+ "agentops.yaml was not found; use AgentOps local eval until a release "
197
+ "config exists."
198
+ )
199
+
200
+ config = load_agentops_config(config_path)
201
+ target = classify_agent(config.agent, config.protocol)
202
+ if target.kind != "foundry_prompt":
203
+ raise OfficialEvalUnsupported(
204
+ "Microsoft Foundry AI Agent Evaluation only evaluates Foundry prompt agents "
205
+ "(`agent: name:version`); use AgentOps local eval for hosted endpoints, "
206
+ "HTTP agents, and model targets."
207
+ )
208
+
209
+ dataset_path = _resolve_dataset_path(config_path, config.dataset)
210
+ shape = detect_dataset_shape(dataset_path)
211
+ overrides = [item.name for item in config.evaluators or []] or None
212
+ presets = select_evaluators(
213
+ target,
214
+ shape,
215
+ overrides=overrides,
216
+ threshold_metrics=config.thresholds.keys(),
217
+ )
218
+ official_evaluators, skipped, warnings = _map_evaluators(presets)
219
+ if not official_evaluators:
220
+ raise OfficialEvalUnsupported(
221
+ "no AgentOps evaluators could be mapped to Microsoft Foundry evaluators."
222
+ )
223
+
224
+ _validate_dataset_for_official_runner(dataset_path, official_evaluators)
225
+
226
+ return _EvalPlan(
227
+ config=config,
228
+ config_path=config_path,
229
+ dataset_path=dataset_path,
230
+ agent_ids=config.agent,
231
+ official_evaluators=tuple(official_evaluators),
232
+ skipped_agentops_evaluators=tuple(skipped),
233
+ warnings=tuple(warnings),
234
+ )
235
+
236
+
237
+ def _map_evaluators(
238
+ presets: Sequence[EvaluatorPreset],
239
+ ) -> tuple[list[str], list[str], list[str]]:
240
+ official: list[str] = []
241
+ skipped: list[str] = []
242
+ warnings: list[str] = []
243
+
244
+ for preset in presets:
245
+ if preset.name == _LATENCY_PRESET:
246
+ skipped.append(preset.name)
247
+ continue
248
+
249
+ official_name = _OFFICIAL_EVALUATORS.get(preset.name)
250
+ if official_name is None:
251
+ raise OfficialEvalUnsupported(
252
+ f"AgentOps evaluator {preset.name!r} has no official Foundry "
253
+ "mapping yet."
254
+ )
255
+ if official_name not in official:
256
+ official.append(official_name)
257
+
258
+ return official, skipped, warnings
259
+
260
+
261
+ def _build_payload(plan: _EvalPlan) -> dict[str, Any]:
262
+ rows = list(_convert_rows(plan.dataset_path))
263
+ payload: dict[str, Any] = {
264
+ "name": _dataset_name(plan.config_path, plan.dataset_path),
265
+ "evaluators": list(plan.official_evaluators),
266
+ "data": rows,
267
+ }
268
+ if "builtin.text_similarity" in plan.official_evaluators:
269
+ payload["openai_graders"] = {
270
+ "builtin.text_similarity": {
271
+ "evaluation_metric": "fuzzy_match",
272
+ "input": "{{sample.output_text}}",
273
+ "reference": "{{item.ground_truth}}",
274
+ }
275
+ }
276
+ return payload
277
+
278
+
279
+ def _convert_rows(dataset_path: Path) -> Iterable[dict[str, Any]]:
280
+ with dataset_path.open("r", encoding="utf-8") as handle:
281
+ for line_number, line in enumerate(handle, start=1):
282
+ stripped = line.strip()
283
+ if not stripped:
284
+ continue
285
+ try:
286
+ row = json.loads(stripped)
287
+ except json.JSONDecodeError as exc:
288
+ raise ValueError(
289
+ f"{dataset_path}: invalid JSON on line {line_number}: {exc}"
290
+ ) from exc
291
+ if not isinstance(row, dict):
292
+ raise ValueError(f"{dataset_path}: line {line_number} is not a JSON object")
293
+
294
+ query = row.get("query", row.get("input"))
295
+ if not isinstance(query, str) or not query.strip():
296
+ raise ValueError(
297
+ f"{dataset_path}: line {line_number} must include a non-empty "
298
+ "`input` or `query` string."
299
+ )
300
+
301
+ converted = dict(row)
302
+ converted["query"] = query
303
+ if "ground_truth" not in converted and row.get("expected") is not None:
304
+ converted["ground_truth"] = row["expected"]
305
+ yield converted
306
+
307
+
308
+ def _validate_dataset_for_official_runner(
309
+ dataset_path: Path,
310
+ official_evaluators: Sequence[str],
311
+ ) -> None:
312
+ needs_ground_truth = any(
313
+ evaluator in _GROUND_TRUTH_EVALUATORS for evaluator in official_evaluators
314
+ )
315
+
316
+ for line_number, row in enumerate(_convert_rows(dataset_path), start=1):
317
+ if needs_ground_truth and not row.get("ground_truth"):
318
+ raise OfficialEvalUnsupported(
319
+ f"{dataset_path}: line {line_number} needs `expected` or "
320
+ "`ground_truth` for the selected Microsoft Foundry evaluators."
321
+ )
322
+
323
+
324
+ def _resolve_dataset_path(config_path: Path, dataset: Path) -> Path:
325
+ dataset_path = dataset
326
+ if not dataset_path.is_absolute():
327
+ dataset_path = config_path.parent / dataset_path
328
+ return dataset_path.resolve()
329
+
330
+
331
+ def _resolve_deployment_name(value: str | None) -> str:
332
+ deployment = (
333
+ value
334
+ or os.getenv("AZURE_OPENAI_DEPLOYMENT")
335
+ or os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME")
336
+ or ""
337
+ ).strip()
338
+ if not deployment:
339
+ raise ValueError(
340
+ "deployment name is required. Pass --deployment-name or set "
341
+ "AZURE_OPENAI_DEPLOYMENT."
342
+ )
343
+ return deployment
344
+
345
+
346
+ def _dataset_name(config_path: Path, dataset_path: Path) -> str:
347
+ parts = [
348
+ config_path.parent.name or "workspace",
349
+ dataset_path.stem or "dataset",
350
+ ]
351
+ raw = "-".join(parts)
352
+ safe = "".join(ch.lower() if ch.isalnum() else "-" for ch in raw)
353
+ return "-".join(part for part in safe.split("-") if part) or "agentops-eval"
354
+
355
+
356
+ def _append_github_output(path: Path, outputs: Mapping[str, str]) -> None:
357
+ with path.open("a", encoding="utf-8") as handle:
358
+ for key, value in outputs.items():
359
+ handle.write(f"{key}={value}\n")
360
+
361
+
362
+ def _emit_ado_output(outputs: Mapping[str, str]) -> None:
363
+ variables = {
364
+ "data_path": "officialDataPath",
365
+ "agent_ids": "officialAgentIds",
366
+ "deployment_name": "officialDeploymentName",
367
+ "metadata_path": "officialMetadataPath",
368
+ }
369
+ for key, variable_name in variables.items():
370
+ print(f"##vso[task.setvariable variable={variable_name};isOutput=true]{outputs[key]}")
371
+
372
+
373
+ def _command_prepare(args: argparse.Namespace) -> int:
374
+ prepared = prepare_official_eval(
375
+ Path(args.config),
376
+ Path(args.out),
377
+ deployment_name=args.deployment_name,
378
+ )
379
+ outputs = {
380
+ "data_path": str(prepared.data_path),
381
+ "agent_ids": prepared.agent_ids,
382
+ "deployment_name": prepared.deployment_name,
383
+ "metadata_path": str(prepared.metadata_path),
384
+ }
385
+ if args.github_output:
386
+ _append_github_output(Path(args.github_output), outputs)
387
+ if args.ado_output:
388
+ _emit_ado_output(outputs)
389
+ if args.print_json:
390
+ print(json.dumps(outputs, indent=2))
391
+ return 0
392
+
393
+
394
+ def main(argv: Sequence[str] | None = None) -> int:
395
+ parser = argparse.ArgumentParser(
396
+ description="Prepare official Microsoft Foundry AI Agent Evaluation inputs."
397
+ )
398
+ subparsers = parser.add_subparsers(dest="command", required=True)
399
+
400
+ prepare_parser = subparsers.add_parser("prepare")
401
+ prepare_parser.add_argument("--config", default="agentops.yaml")
402
+ prepare_parser.add_argument("--out", required=True)
403
+ prepare_parser.add_argument("--deployment-name")
404
+ prepare_parser.add_argument("--github-output")
405
+ prepare_parser.add_argument("--ado-output", action="store_true")
406
+ prepare_parser.add_argument("--print-json", action="store_true")
407
+ prepare_parser.set_defaults(func=_command_prepare)
408
+
409
+ args = parser.parse_args(argv)
410
+ return int(args.func(args))
411
+
412
+
413
+ if __name__ == "__main__": # pragma: no cover
414
+ raise SystemExit(main())