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.
- agentops/__init__.py +10 -0
- agentops/__main__.py +6 -0
- agentops/agent/__init__.py +12 -0
- agentops/agent/_legacy_ids.py +92 -0
- agentops/agent/analyzer.py +207 -0
- agentops/agent/checks/__init__.py +1 -0
- agentops/agent/checks/catalog.py +880 -0
- agentops/agent/checks/errors.py +279 -0
- agentops/agent/checks/foundry_config.py +75 -0
- agentops/agent/checks/latency.py +84 -0
- agentops/agent/checks/opex.py +157 -0
- agentops/agent/checks/opex_workspace.py +874 -0
- agentops/agent/checks/posture.py +36 -0
- agentops/agent/checks/posture_rules/__init__.py +53 -0
- agentops/agent/checks/posture_rules/content_filter.py +59 -0
- agentops/agent/checks/posture_rules/diagnostics.py +74 -0
- agentops/agent/checks/posture_rules/local_auth.py +55 -0
- agentops/agent/checks/posture_rules/managed_identity.py +59 -0
- agentops/agent/checks/posture_rules/network.py +68 -0
- agentops/agent/checks/regression.py +78 -0
- agentops/agent/checks/release_readiness.py +182 -0
- agentops/agent/checks/safety.py +247 -0
- agentops/agent/checks/spec_conformance.py +375 -0
- agentops/agent/cockpit.py +5159 -0
- agentops/agent/config.py +240 -0
- agentops/agent/findings.py +113 -0
- agentops/agent/history.py +142 -0
- agentops/agent/knowledge/__init__.py +182 -0
- agentops/agent/knowledge/waf-checklist.csv +39 -0
- agentops/agent/llm_assist/__init__.py +16 -0
- agentops/agent/llm_assist/_base.py +124 -0
- agentops/agent/llm_assist/_bundle_rule.py +154 -0
- agentops/agent/llm_assist/_client.py +347 -0
- agentops/agent/llm_assist/_dataset_rules.py +191 -0
- agentops/agent/llm_assist/_engine.py +106 -0
- agentops/agent/llm_assist/_prompt_rules.py +291 -0
- agentops/agent/llm_assist/_spec_rules.py +235 -0
- agentops/agent/production_telemetry.py +430 -0
- agentops/agent/report.py +207 -0
- agentops/agent/server/__init__.py +1 -0
- agentops/agent/server/app.py +84 -0
- agentops/agent/server/auth.py +94 -0
- agentops/agent/server/chat.py +44 -0
- agentops/agent/server/protocol.py +72 -0
- agentops/agent/sources/__init__.py +1 -0
- agentops/agent/sources/azure_monitor.py +523 -0
- agentops/agent/sources/azure_resources.py +602 -0
- agentops/agent/sources/foundry_control.py +174 -0
- agentops/agent/sources/results_history.py +494 -0
- agentops/agent/sources/spec_detectors/__init__.py +42 -0
- agentops/agent/sources/spec_detectors/_base.py +58 -0
- agentops/agent/sources/spec_detectors/agents_md.py +75 -0
- agentops/agent/sources/spec_detectors/spec_kit.py +172 -0
- agentops/agent/time_range.py +117 -0
- agentops/cli/__init__.py +1 -0
- agentops/cli/app.py +4823 -0
- agentops/core/__init__.py +1 -0
- agentops/core/agentops_config.py +592 -0
- agentops/core/config_loader.py +22 -0
- agentops/core/evaluators.py +480 -0
- agentops/core/release_evidence.py +56 -0
- agentops/core/results.py +117 -0
- agentops/mcp/__init__.py +10 -0
- agentops/mcp/server.py +232 -0
- agentops/pipeline/__init__.py +8 -0
- agentops/pipeline/cloud_results.py +189 -0
- agentops/pipeline/cloud_runner.py +901 -0
- agentops/pipeline/comparison.py +108 -0
- agentops/pipeline/diagnostics.py +51 -0
- agentops/pipeline/invocations.py +535 -0
- agentops/pipeline/official_eval.py +414 -0
- agentops/pipeline/orchestrator.py +775 -0
- agentops/pipeline/prompt_deploy.py +377 -0
- agentops/pipeline/publisher.py +121 -0
- agentops/pipeline/reporter.py +202 -0
- agentops/pipeline/runtime.py +409 -0
- agentops/pipeline/thresholds.py +84 -0
- agentops/services/__init__.py +1 -0
- agentops/services/cicd.py +720 -0
- agentops/services/eval_analysis.py +848 -0
- agentops/services/evidence_pack.py +757 -0
- agentops/services/initializer.py +86 -0
- agentops/services/preflight.py +470 -0
- agentops/services/setup_wizard.py +709 -0
- agentops/services/skills.py +643 -0
- agentops/services/trace_promotion.py +300 -0
- agentops/services/workflow_analysis.py +1129 -0
- agentops/templates/.gitignore +15 -0
- agentops/templates/__init__.py +1 -0
- agentops/templates/agent-server/Dockerfile +23 -0
- agentops/templates/agent-server/README.md +61 -0
- agentops/templates/agent-server/main.bicep +94 -0
- agentops/templates/agent.yaml +87 -0
- agentops/templates/agentops.yaml +58 -0
- agentops/templates/foundry.svg +71 -0
- agentops/templates/icon.png +0 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-dev-azd.yml +118 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-dev.yml +73 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-prod-azd.yml +141 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-prod.yml +94 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-prompt-agent.yml +167 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-qa-azd.yml +118 -0
- agentops/templates/pipelines/azuredevops/agentops-deploy-qa.yml +68 -0
- agentops/templates/pipelines/azuredevops/agentops-pr-prompt-agent.yml +210 -0
- agentops/templates/pipelines/azuredevops/agentops-pr.yml +155 -0
- agentops/templates/pipelines/azuredevops/agentops-watchdog.yml +106 -0
- agentops/templates/project.gitignore +36 -0
- agentops/templates/sample-traces.jsonl +3 -0
- agentops/templates/skills/agentops-agent/SKILL.md +137 -0
- agentops/templates/skills/agentops-config/SKILL.md +113 -0
- agentops/templates/skills/agentops-dataset/SKILL.md +84 -0
- agentops/templates/skills/agentops-eval/SKILL.md +189 -0
- agentops/templates/skills/agentops-report/SKILL.md +71 -0
- agentops/templates/skills/agentops-workflow/SKILL.md +471 -0
- agentops/templates/smoke.jsonl +3 -0
- agentops/templates/waf-checklist.README.md +84 -0
- agentops/templates/waf-checklist.csv +22 -0
- agentops/templates/workflows/agentops-deploy-dev-azd.yml +166 -0
- agentops/templates/workflows/agentops-deploy-dev.yml +187 -0
- agentops/templates/workflows/agentops-deploy-prod-azd.yml +183 -0
- agentops/templates/workflows/agentops-deploy-prod.yml +171 -0
- agentops/templates/workflows/agentops-deploy-prompt-agent.yml +197 -0
- agentops/templates/workflows/agentops-deploy-qa-azd.yml +156 -0
- agentops/templates/workflows/agentops-deploy-qa.yml +145 -0
- agentops/templates/workflows/agentops-pr-prompt-agent.yml +210 -0
- agentops/templates/workflows/agentops-pr.yml +148 -0
- agentops/templates/workflows/agentops-watchdog.yml +122 -0
- agentops/utils/__init__.py +1 -0
- agentops/utils/azd_env.py +435 -0
- agentops/utils/azure_endpoints.py +62 -0
- agentops/utils/colors.py +47 -0
- agentops/utils/dotenv_loader.py +105 -0
- agentops/utils/foundry_discovery.py +229 -0
- agentops/utils/logging.py +59 -0
- agentops/utils/telemetry.py +554 -0
- agentops/utils/yaml.py +36 -0
- agentops_accelerator-0.3.0.dist-info/METADATA +278 -0
- agentops_accelerator-0.3.0.dist-info/RECORD +142 -0
- agentops_accelerator-0.3.0.dist-info/WHEEL +5 -0
- agentops_accelerator-0.3.0.dist-info/entry_points.txt +2 -0
- agentops_accelerator-0.3.0.dist-info/licenses/LICENSE +21 -0
- agentops_accelerator-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# AgentOps - PR evaluation gate (Foundry prompt agent, Azure DevOps)
|
|
2
|
+
#
|
|
3
|
+
# agentops:deploy-mode=prompt-agent
|
|
4
|
+
#
|
|
5
|
+
# For Foundry prompt-agent flows, the PR gate must evaluate the prompt
|
|
6
|
+
# the PR is proposing, not the seed agent version pinned in
|
|
7
|
+
# `agentops.yaml`. So this PR pipeline stages an ephemeral candidate
|
|
8
|
+
# Foundry prompt-agent version in the dev project from the
|
|
9
|
+
# source-controlled `prompt_file`, evaluates that exact candidate, and
|
|
10
|
+
# runs Doctor against it. The merge gate is the eval + Doctor result.
|
|
11
|
+
#
|
|
12
|
+
# Notes:
|
|
13
|
+
# - Each PR run creates or reuses a candidate version in the dev
|
|
14
|
+
# Foundry project. AgentOps deduplicates only when the prompt is
|
|
15
|
+
# byte-identical to the current seed version's instructions; PR
|
|
16
|
+
# candidates can therefore accumulate over time and may need to be
|
|
17
|
+
# cleaned up out-of-band.
|
|
18
|
+
# - Merge is what promotes the candidate via the deploy pipeline.
|
|
19
|
+
# This PR pipeline does not record the candidate as deployed.
|
|
20
|
+
#
|
|
21
|
+
# Setup (one-time):
|
|
22
|
+
# 1. Create a variable group named `agentops` in Pipelines -> Library
|
|
23
|
+
# with: AZURE_AI_FOUNDRY_PROJECT_ENDPOINT, AZURE_OPENAI_ENDPOINT,
|
|
24
|
+
# AZURE_OPENAI_DEPLOYMENT, AGENTOPS_AGENT_PROMPT_FILE (optional).
|
|
25
|
+
# 2. Create a service connection to your Azure subscription named
|
|
26
|
+
# `agentops-azure`.
|
|
27
|
+
# 3. Grant the build service "Contribute to pull requests" permission
|
|
28
|
+
# on the repository so the PR-comment step can post.
|
|
29
|
+
#
|
|
30
|
+
# Generated by `agentops workflow generate --platform azure-devops --deploy-mode prompt-agent`.
|
|
31
|
+
|
|
32
|
+
trigger: none
|
|
33
|
+
|
|
34
|
+
pr:
|
|
35
|
+
branches:
|
|
36
|
+
include:
|
|
37
|
+
- develop
|
|
38
|
+
- release/*
|
|
39
|
+
- main
|
|
40
|
+
|
|
41
|
+
pool:
|
|
42
|
+
vmImage: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
variables:
|
|
45
|
+
- group: agentops
|
|
46
|
+
- name: AZURE_SERVICE_CONNECTION
|
|
47
|
+
value: agentops-azure
|
|
48
|
+
- name: AGENTOPS_CONFIG
|
|
49
|
+
value: agentops.yaml
|
|
50
|
+
- name: TARGET_ENVIRONMENT
|
|
51
|
+
value: __ENV_NAME__
|
|
52
|
+
|
|
53
|
+
stages:
|
|
54
|
+
- stage: stage_candidate
|
|
55
|
+
displayName: Stage Foundry prompt candidate (PR)
|
|
56
|
+
jobs:
|
|
57
|
+
- job: stage_candidate
|
|
58
|
+
steps:
|
|
59
|
+
- checkout: self
|
|
60
|
+
fetchDepth: 1
|
|
61
|
+
|
|
62
|
+
- task: UsePythonVersion@0
|
|
63
|
+
displayName: Set up Python 3.11
|
|
64
|
+
inputs:
|
|
65
|
+
versionSpec: "3.11"
|
|
66
|
+
|
|
67
|
+
- task: AzureCLI@2
|
|
68
|
+
displayName: Create candidate agent version from prompt_file
|
|
69
|
+
inputs:
|
|
70
|
+
azureSubscription: $(AZURE_SERVICE_CONNECTION)
|
|
71
|
+
scriptType: bash
|
|
72
|
+
scriptLocation: inlineScript
|
|
73
|
+
inlineScript: |
|
|
74
|
+
python -m pip install --upgrade pip
|
|
75
|
+
python -m pip install "agentops-accelerator[foundry] @ git+https://github.com/Azure/agentops.git@main"
|
|
76
|
+
python -m agentops.pipeline.prompt_deploy stage \
|
|
77
|
+
--config "$(AGENTOPS_CONFIG)" \
|
|
78
|
+
--environment "$(TARGET_ENVIRONMENT)" \
|
|
79
|
+
--out ".agentops/deployments/foundry-agent.json" \
|
|
80
|
+
--eval-config ".agentops/deployments/agentops.candidate.yaml"
|
|
81
|
+
env:
|
|
82
|
+
AZURE_AI_FOUNDRY_PROJECT_ENDPOINT: $(AZURE_AI_FOUNDRY_PROJECT_ENDPOINT)
|
|
83
|
+
AGENTOPS_AGENT_PROMPT_FILE: $(AGENTOPS_AGENT_PROMPT_FILE)
|
|
84
|
+
|
|
85
|
+
- task: PublishPipelineArtifact@1
|
|
86
|
+
displayName: Upload candidate deployment record
|
|
87
|
+
inputs:
|
|
88
|
+
targetPath: .agentops/deployments
|
|
89
|
+
artifact: foundry-agent-__ENV_KEY__-candidate
|
|
90
|
+
publishLocation: pipeline
|
|
91
|
+
|
|
92
|
+
- stage: eval
|
|
93
|
+
displayName: AgentOps eval (PR candidate gate)
|
|
94
|
+
dependsOn: stage_candidate
|
|
95
|
+
jobs:
|
|
96
|
+
- job: run_eval
|
|
97
|
+
displayName: Eval candidate for $(TARGET_ENVIRONMENT)
|
|
98
|
+
timeoutInMinutes: 45
|
|
99
|
+
steps:
|
|
100
|
+
- checkout: self
|
|
101
|
+
fetchDepth: 1
|
|
102
|
+
|
|
103
|
+
- task: DownloadPipelineArtifact@2
|
|
104
|
+
displayName: Download candidate deployment record
|
|
105
|
+
inputs:
|
|
106
|
+
artifact: foundry-agent-__ENV_KEY__-candidate
|
|
107
|
+
path: .agentops/deployments
|
|
108
|
+
|
|
109
|
+
- task: UsePythonVersion@0
|
|
110
|
+
displayName: Set up Python 3.11
|
|
111
|
+
inputs:
|
|
112
|
+
versionSpec: "3.11"
|
|
113
|
+
|
|
114
|
+
- bash: |
|
|
115
|
+
python -m pip install --upgrade pip
|
|
116
|
+
python -m pip install "agentops-accelerator[foundry,agent] @ git+https://github.com/Azure/agentops.git@main"
|
|
117
|
+
displayName: Install AgentOps Toolkit
|
|
118
|
+
|
|
119
|
+
__EVAL_TASKS__
|
|
120
|
+
|
|
121
|
+
- task: AzureCLI@2
|
|
122
|
+
displayName: Run AgentOps doctor
|
|
123
|
+
condition: always()
|
|
124
|
+
inputs:
|
|
125
|
+
azureSubscription: $(AZURE_SERVICE_CONNECTION)
|
|
126
|
+
scriptType: bash
|
|
127
|
+
scriptLocation: inlineScript
|
|
128
|
+
inlineScript: |
|
|
129
|
+
# Doctor gate severity is configured at workflow
|
|
130
|
+
# generation time via `agentops workflow generate
|
|
131
|
+
# --doctor-gate critical|warning|none`.
|
|
132
|
+
agentops doctor --workspace . --out .agentops/agent/report.md \
|
|
133
|
+
--severity-fail __DOCTOR_GATE__ --evidence-pack
|
|
134
|
+
env:
|
|
135
|
+
AZURE_AI_FOUNDRY_PROJECT_ENDPOINT: $(AZURE_AI_FOUNDRY_PROJECT_ENDPOINT)
|
|
136
|
+
AZURE_OPENAI_ENDPOINT: $(AZURE_OPENAI_ENDPOINT)
|
|
137
|
+
AZURE_OPENAI_DEPLOYMENT: $(AZURE_OPENAI_DEPLOYMENT)
|
|
138
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING: $(APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
139
|
+
|
|
140
|
+
- task: PublishPipelineArtifact@1
|
|
141
|
+
displayName: Upload AgentOps results
|
|
142
|
+
condition: always()
|
|
143
|
+
inputs:
|
|
144
|
+
targetPath: __EVAL_ARTIFACT_TARGET__
|
|
145
|
+
artifact: agentops-pr-results
|
|
146
|
+
publishLocation: pipeline
|
|
147
|
+
|
|
148
|
+
- task: PublishPipelineArtifact@1
|
|
149
|
+
displayName: Upload AgentOps release evidence
|
|
150
|
+
condition: always()
|
|
151
|
+
inputs:
|
|
152
|
+
targetPath: .agentops/release/latest
|
|
153
|
+
artifact: agentops-pr-release-evidence
|
|
154
|
+
publishLocation: pipeline
|
|
155
|
+
|
|
156
|
+
- bash: |
|
|
157
|
+
if [ -f .agentops/results/latest/report.md ]; then
|
|
158
|
+
cat .agentops/results/latest/report.md
|
|
159
|
+
else
|
|
160
|
+
echo "No report.md produced."
|
|
161
|
+
fi
|
|
162
|
+
if [ -f .agentops/release/latest/evidence.md ]; then
|
|
163
|
+
echo
|
|
164
|
+
echo "---"
|
|
165
|
+
echo
|
|
166
|
+
cat .agentops/release/latest/evidence.md
|
|
167
|
+
fi
|
|
168
|
+
displayName: Print report.md to log
|
|
169
|
+
condition: always()
|
|
170
|
+
|
|
171
|
+
- bash: |
|
|
172
|
+
set -euo pipefail
|
|
173
|
+
if [ "$(Build.Reason)" != "PullRequest" ]; then
|
|
174
|
+
echo "Not a PR build; skipping PR comment."
|
|
175
|
+
exit 0
|
|
176
|
+
fi
|
|
177
|
+
if [ ! -f .agentops/results/latest/report.md ]; then
|
|
178
|
+
echo "No report.md produced; skipping PR comment."
|
|
179
|
+
exit 0
|
|
180
|
+
fi
|
|
181
|
+
MARKER='<!-- agentops-pr-report -->'
|
|
182
|
+
BODY="$(printf '%s\n' "$MARKER"; cat .agentops/results/latest/report.md)"
|
|
183
|
+
if [ -f .agentops/release/latest/evidence.md ]; then
|
|
184
|
+
BODY="$(printf '%s\n\n---\n\n%s' "$BODY" "$(cat .agentops/release/latest/evidence.md)")"
|
|
185
|
+
fi
|
|
186
|
+
ORG_URL="$(System.CollectionUri)"
|
|
187
|
+
PROJECT="$(System.TeamProject)"
|
|
188
|
+
REPO_ID="$(Build.Repository.ID)"
|
|
189
|
+
PR_ID="$(System.PullRequest.PullRequestId)"
|
|
190
|
+
API="${ORG_URL}${PROJECT}/_apis/git/repositories/${REPO_ID}/pullRequests/${PR_ID}/threads?api-version=7.1-preview.1"
|
|
191
|
+
AUTH="Authorization: Bearer $(System.AccessToken)"
|
|
192
|
+
|
|
193
|
+
EXISTING=$(curl -s -H "$AUTH" "$API" | python -c "import sys, json; data=json.load(sys.stdin); print(next((t['id'] for t in data.get('value', []) for c in t.get('comments', []) if isinstance(c.get('content'), str) and c['content'].startswith('$MARKER')), ''))")
|
|
194
|
+
|
|
195
|
+
PAYLOAD=$(python -c "import json,sys; print(json.dumps({'content': sys.stdin.read(), 'commentType': 1}))" <<< "$BODY")
|
|
196
|
+
|
|
197
|
+
if [ -n "$EXISTING" ]; then
|
|
198
|
+
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
199
|
+
-d "$PAYLOAD" \
|
|
200
|
+
"${ORG_URL}${PROJECT}/_apis/git/repositories/${REPO_ID}/pullRequests/${PR_ID}/threads/${EXISTING}/comments?api-version=7.1-preview.1" > /dev/null
|
|
201
|
+
else
|
|
202
|
+
THREAD_PAYLOAD=$(python -c "import json,sys; b=sys.stdin.read(); print(json.dumps({'comments':[{'parentCommentId':0,'content':b,'commentType':1}],'status':1}))" <<< "$BODY")
|
|
203
|
+
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
204
|
+
-d "$THREAD_PAYLOAD" \
|
|
205
|
+
"$API" > /dev/null
|
|
206
|
+
fi
|
|
207
|
+
displayName: Comment AgentOps report on PR
|
|
208
|
+
condition: always()
|
|
209
|
+
env:
|
|
210
|
+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# AgentOps — PR evaluation gate (Azure DevOps Pipelines)
|
|
2
|
+
#
|
|
3
|
+
# Runs on pull requests targeting develop, release/**, or main and gates
|
|
4
|
+
# the merge on the AgentOps eval result. Posts the rendered Markdown
|
|
5
|
+
# report as an idempotent PR comment via the Azure DevOps REST API.
|
|
6
|
+
#
|
|
7
|
+
# Setup (one-time):
|
|
8
|
+
# 1. Create a variable group named `agentops` in Pipelines → Library with:
|
|
9
|
+
# AZURE_AI_FOUNDRY_PROJECT_ENDPOINT
|
|
10
|
+
# AZURE_OPENAI_ENDPOINT
|
|
11
|
+
# AZURE_OPENAI_DEPLOYMENT
|
|
12
|
+
# 2. Create a service connection to your Azure subscription named
|
|
13
|
+
# `agentops-azure` (Pipelines → Service connections → New).
|
|
14
|
+
# 3. Grant the build service "Contribute to pull requests" permission
|
|
15
|
+
# on the repository so the PR-comment step can post.
|
|
16
|
+
#
|
|
17
|
+
# Generated by `agentops workflow generate --platform azure-devops`.
|
|
18
|
+
|
|
19
|
+
trigger: none
|
|
20
|
+
|
|
21
|
+
pr:
|
|
22
|
+
branches:
|
|
23
|
+
include:
|
|
24
|
+
- develop
|
|
25
|
+
- release/*
|
|
26
|
+
- main
|
|
27
|
+
|
|
28
|
+
pool:
|
|
29
|
+
vmImage: ubuntu-latest
|
|
30
|
+
|
|
31
|
+
variables:
|
|
32
|
+
- group: agentops
|
|
33
|
+
- name: AZURE_SERVICE_CONNECTION
|
|
34
|
+
value: agentops-azure
|
|
35
|
+
- name: AGENTOPS_CONFIG
|
|
36
|
+
value: agentops.yaml
|
|
37
|
+
|
|
38
|
+
stages:
|
|
39
|
+
- stage: eval
|
|
40
|
+
displayName: AgentOps eval (PR gate)
|
|
41
|
+
jobs:
|
|
42
|
+
- job: run_eval
|
|
43
|
+
displayName: Run AgentOps eval
|
|
44
|
+
timeoutInMinutes: 30
|
|
45
|
+
steps:
|
|
46
|
+
- checkout: self
|
|
47
|
+
fetchDepth: 1
|
|
48
|
+
|
|
49
|
+
- task: UsePythonVersion@0
|
|
50
|
+
displayName: Set up Python 3.11
|
|
51
|
+
inputs:
|
|
52
|
+
versionSpec: "3.11"
|
|
53
|
+
|
|
54
|
+
- bash: |
|
|
55
|
+
python -m pip install --upgrade pip
|
|
56
|
+
# NOTE: pinned to GitHub main until the next package release includes this flow.
|
|
57
|
+
python -m pip install "agentops-accelerator[foundry,agent] @ git+https://github.com/Azure/agentops.git@main"
|
|
58
|
+
displayName: Install AgentOps Toolkit
|
|
59
|
+
|
|
60
|
+
__EVAL_TASKS__
|
|
61
|
+
|
|
62
|
+
- task: AzureCLI@2
|
|
63
|
+
displayName: Run AgentOps doctor
|
|
64
|
+
condition: always()
|
|
65
|
+
inputs:
|
|
66
|
+
azureSubscription: $(AZURE_SERVICE_CONNECTION)
|
|
67
|
+
scriptType: bash
|
|
68
|
+
scriptLocation: inlineScript
|
|
69
|
+
inlineScript: |
|
|
70
|
+
# Doctor gate severity is configured at workflow generation
|
|
71
|
+
# time via `agentops workflow generate
|
|
72
|
+
# --doctor-gate critical|warning|none`.
|
|
73
|
+
agentops doctor --workspace . --out .agentops/agent/report.md \
|
|
74
|
+
--severity-fail __DOCTOR_GATE__ --evidence-pack
|
|
75
|
+
env:
|
|
76
|
+
AZURE_AI_FOUNDRY_PROJECT_ENDPOINT: $(AZURE_AI_FOUNDRY_PROJECT_ENDPOINT)
|
|
77
|
+
AZURE_OPENAI_ENDPOINT: $(AZURE_OPENAI_ENDPOINT)
|
|
78
|
+
AZURE_OPENAI_DEPLOYMENT: $(AZURE_OPENAI_DEPLOYMENT)
|
|
79
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING: $(APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
80
|
+
|
|
81
|
+
- task: PublishPipelineArtifact@1
|
|
82
|
+
displayName: Upload AgentOps results
|
|
83
|
+
condition: always()
|
|
84
|
+
inputs:
|
|
85
|
+
targetPath: __EVAL_ARTIFACT_TARGET__
|
|
86
|
+
artifact: agentops-pr-results
|
|
87
|
+
publishLocation: pipeline
|
|
88
|
+
|
|
89
|
+
- task: PublishPipelineArtifact@1
|
|
90
|
+
displayName: Upload AgentOps release evidence
|
|
91
|
+
condition: always()
|
|
92
|
+
inputs:
|
|
93
|
+
targetPath: .agentops/release/latest
|
|
94
|
+
artifact: agentops-pr-release-evidence
|
|
95
|
+
publishLocation: pipeline
|
|
96
|
+
|
|
97
|
+
- bash: |
|
|
98
|
+
if [ -f .agentops/results/latest/report.md ]; then
|
|
99
|
+
cat .agentops/results/latest/report.md
|
|
100
|
+
else
|
|
101
|
+
echo "No report.md produced."
|
|
102
|
+
fi
|
|
103
|
+
if [ -f .agentops/release/latest/evidence.md ]; then
|
|
104
|
+
echo
|
|
105
|
+
echo "---"
|
|
106
|
+
echo
|
|
107
|
+
cat .agentops/release/latest/evidence.md
|
|
108
|
+
fi
|
|
109
|
+
displayName: Print report.md to log
|
|
110
|
+
condition: always()
|
|
111
|
+
|
|
112
|
+
- bash: |
|
|
113
|
+
set -euo pipefail
|
|
114
|
+
if [ "$(Build.Reason)" != "PullRequest" ]; then
|
|
115
|
+
echo "Not a PR build; skipping PR comment."
|
|
116
|
+
exit 0
|
|
117
|
+
fi
|
|
118
|
+
if [ ! -f .agentops/results/latest/report.md ]; then
|
|
119
|
+
echo "No report.md produced; skipping PR comment."
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
MARKER='<!-- agentops-pr-report -->'
|
|
123
|
+
BODY="$(printf '%s\n' "$MARKER"; cat .agentops/results/latest/report.md)"
|
|
124
|
+
if [ -f .agentops/release/latest/evidence.md ]; then
|
|
125
|
+
BODY="$(printf '%s\n\n---\n\n%s' "$BODY" "$(cat .agentops/release/latest/evidence.md)")"
|
|
126
|
+
fi
|
|
127
|
+
ORG_URL="$(System.CollectionUri)"
|
|
128
|
+
PROJECT="$(System.TeamProject)"
|
|
129
|
+
REPO_ID="$(Build.Repository.ID)"
|
|
130
|
+
PR_ID="$(System.PullRequest.PullRequestId)"
|
|
131
|
+
API="${ORG_URL}${PROJECT}/_apis/git/repositories/${REPO_ID}/pullRequests/${PR_ID}/threads?api-version=7.1-preview.1"
|
|
132
|
+
AUTH="Authorization: Bearer $(System.AccessToken)"
|
|
133
|
+
|
|
134
|
+
EXISTING=$(curl -s -H "$AUTH" "$API" \
|
|
135
|
+
| python -c "import sys, json; data=json.load(sys.stdin); \
|
|
136
|
+
print(next((t['id'] for t in data.get('value', []) \
|
|
137
|
+
for c in t.get('comments', []) \
|
|
138
|
+
if isinstance(c.get('content'), str) and c['content'].startswith('$MARKER')), ''))")
|
|
139
|
+
|
|
140
|
+
PAYLOAD=$(python -c "import json,sys; print(json.dumps({'content': sys.stdin.read(), 'commentType': 1}))" <<< "$BODY")
|
|
141
|
+
|
|
142
|
+
if [ -n "$EXISTING" ]; then
|
|
143
|
+
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
144
|
+
-d "$PAYLOAD" \
|
|
145
|
+
"${ORG_URL}${PROJECT}/_apis/git/repositories/${REPO_ID}/pullRequests/${PR_ID}/threads/${EXISTING}/comments?api-version=7.1-preview.1" > /dev/null
|
|
146
|
+
else
|
|
147
|
+
THREAD_PAYLOAD=$(python -c "import json,sys; b=sys.stdin.read(); print(json.dumps({'comments':[{'parentCommentId':0,'content':b,'commentType':1}],'status':1}))" <<< "$BODY")
|
|
148
|
+
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
149
|
+
-d "$THREAD_PAYLOAD" \
|
|
150
|
+
"$API" > /dev/null
|
|
151
|
+
fi
|
|
152
|
+
displayName: Comment AgentOps report on PR
|
|
153
|
+
condition: always()
|
|
154
|
+
env:
|
|
155
|
+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# AgentOps — Scheduled doctor (Azure DevOps Pipelines)
|
|
2
|
+
#
|
|
3
|
+
# Runs `agentops doctor` on a daily cron. Restores the previous
|
|
4
|
+
# run's history.jsonl from a pipeline artifact so the Doctor cockpit
|
|
5
|
+
# carries trend data across executions.
|
|
6
|
+
#
|
|
7
|
+
# Setup mirrors agentops-pr.yml (variable group `agentops`, service
|
|
8
|
+
# connection `agentops-azure`).
|
|
9
|
+
# If Foundry App Insights auto-discovery is not available in your tenant,
|
|
10
|
+
# add APPLICATIONINSIGHTS_CONNECTION_STRING to the `agentops` variable group.
|
|
11
|
+
#
|
|
12
|
+
# Generated by `agentops workflow generate --platform azure-devops` (kind: doctor).
|
|
13
|
+
|
|
14
|
+
trigger: none
|
|
15
|
+
pr: none
|
|
16
|
+
|
|
17
|
+
schedules:
|
|
18
|
+
- cron: "0 6 * * *"
|
|
19
|
+
displayName: Daily Doctor
|
|
20
|
+
branches:
|
|
21
|
+
include:
|
|
22
|
+
- main
|
|
23
|
+
|
|
24
|
+
pool:
|
|
25
|
+
vmImage: ubuntu-latest
|
|
26
|
+
|
|
27
|
+
variables:
|
|
28
|
+
- group: agentops
|
|
29
|
+
- name: AZURE_SERVICE_CONNECTION
|
|
30
|
+
value: agentops-azure
|
|
31
|
+
|
|
32
|
+
stages:
|
|
33
|
+
- stage: analyze
|
|
34
|
+
displayName: AgentOps doctor
|
|
35
|
+
jobs:
|
|
36
|
+
- job: run_doctor
|
|
37
|
+
displayName: Run AgentOps doctor
|
|
38
|
+
timeoutInMinutes: 30
|
|
39
|
+
steps:
|
|
40
|
+
- checkout: self
|
|
41
|
+
fetchDepth: 1
|
|
42
|
+
|
|
43
|
+
- task: UsePythonVersion@0
|
|
44
|
+
displayName: Set up Python 3.11
|
|
45
|
+
inputs:
|
|
46
|
+
versionSpec: "3.11"
|
|
47
|
+
|
|
48
|
+
- task: DownloadPipelineArtifact@2
|
|
49
|
+
displayName: Restore Doctor history
|
|
50
|
+
continueOnError: true
|
|
51
|
+
inputs:
|
|
52
|
+
source: specific
|
|
53
|
+
project: $(System.TeamProject)
|
|
54
|
+
pipeline: $(System.DefinitionId)
|
|
55
|
+
runVersion: latestFromBranch
|
|
56
|
+
runBranch: $(Build.SourceBranch)
|
|
57
|
+
artifact: agentops-doctor-history
|
|
58
|
+
path: $(Build.SourcesDirectory)/.agentops/agent
|
|
59
|
+
|
|
60
|
+
- task: AzureCLI@2
|
|
61
|
+
displayName: Install AgentOps Toolkit and run Doctor
|
|
62
|
+
inputs:
|
|
63
|
+
azureSubscription: $(AZURE_SERVICE_CONNECTION)
|
|
64
|
+
scriptType: bash
|
|
65
|
+
scriptLocation: inlineScript
|
|
66
|
+
inlineScript: |
|
|
67
|
+
python -m pip install --upgrade pip
|
|
68
|
+
python -m pip install "agentops-accelerator[foundry,agent] @ git+https://github.com/Azure/agentops.git@main"
|
|
69
|
+
agentops doctor --workspace . --out .agentops/agent/report.md \
|
|
70
|
+
--severity-fail critical --evidence-pack
|
|
71
|
+
env:
|
|
72
|
+
AZURE_AI_FOUNDRY_PROJECT_ENDPOINT: $(AZURE_AI_FOUNDRY_PROJECT_ENDPOINT)
|
|
73
|
+
AZURE_OPENAI_ENDPOINT: $(AZURE_OPENAI_ENDPOINT)
|
|
74
|
+
AZURE_OPENAI_DEPLOYMENT: $(AZURE_OPENAI_DEPLOYMENT)
|
|
75
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING: $(APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
76
|
+
|
|
77
|
+
- task: PublishPipelineArtifact@1
|
|
78
|
+
displayName: Publish Doctor history
|
|
79
|
+
condition: always()
|
|
80
|
+
inputs:
|
|
81
|
+
targetPath: .agentops/agent
|
|
82
|
+
artifact: agentops-doctor-history
|
|
83
|
+
publishLocation: pipeline
|
|
84
|
+
|
|
85
|
+
- task: PublishPipelineArtifact@1
|
|
86
|
+
displayName: Publish release evidence
|
|
87
|
+
condition: always()
|
|
88
|
+
inputs:
|
|
89
|
+
targetPath: .agentops/release/latest
|
|
90
|
+
artifact: agentops-doctor-release-evidence
|
|
91
|
+
publishLocation: pipeline
|
|
92
|
+
|
|
93
|
+
- bash: |
|
|
94
|
+
if [ -f .agentops/agent/report.md ]; then
|
|
95
|
+
cat .agentops/agent/report.md
|
|
96
|
+
else
|
|
97
|
+
echo "No report.md produced."
|
|
98
|
+
fi
|
|
99
|
+
if [ -f .agentops/release/latest/evidence.md ]; then
|
|
100
|
+
echo
|
|
101
|
+
echo "---"
|
|
102
|
+
echo
|
|
103
|
+
cat .agentops/release/latest/evidence.md
|
|
104
|
+
fi
|
|
105
|
+
displayName: Print Doctor report
|
|
106
|
+
condition: always()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Generated by `agentops init`
|
|
2
|
+
# Standard Python / virtualenv / IDE noise
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
*$py.class
|
|
6
|
+
*.egg-info/
|
|
7
|
+
.eggs/
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
env/
|
|
13
|
+
ENV/
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# Environment files
|
|
21
|
+
.env
|
|
22
|
+
.env.*
|
|
23
|
+
!.env.example
|
|
24
|
+
|
|
25
|
+
# IDE
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
28
|
+
*.swp
|
|
29
|
+
|
|
30
|
+
# AgentOps runtime artifacts (results are reproducible from the config + dataset)
|
|
31
|
+
.agentops/results/
|
|
32
|
+
.agentops/official-eval/
|
|
33
|
+
.agentops/.resolved/
|
|
34
|
+
|
|
35
|
+
# Local install scratch space (unpacked plugins, VSIX, editor extras)
|
|
36
|
+
.local/
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"operation_Id":"trace-demo-001","timestamp":"2026-05-21T21:40:00Z","customDimensions":{"input":"Answer with exactly this sentence: Paris is the capital of France and one of Europe's major cultural centers.","response":"Paris is the capital of France and one of Europe's major cultural centers."}}
|
|
2
|
+
{"operation_Id":"trace-demo-002","timestamp":"2026-05-21T21:41:00Z","customDimensions":{"input":"Answer with exactly this sentence: Mars is known as the Red Planet because iron-rich dust gives its surface a reddish color.","response":"Mars is known as the Red Planet because iron-rich dust gives its surface a reddish color."}}
|
|
3
|
+
{"operation_Id":"trace-demo-003","timestamp":"2026-05-21T21:42:00Z","customDimensions":{"input":"Answer with exactly this sentence: Water has the chemical formula H2O because each molecule contains two hydrogen atoms and one oxygen atom.","response":"Water has the chemical formula H2O because each molecule contains two hydrogen atoms and one oxygen atom."}}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentops-agent
|
|
3
|
+
description: AgentOps Doctor - surface release-readiness findings, regressions, latency spikes, error rates, and safety hits across AgentOps eval history, Azure Monitor traces, and Foundry control plane.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `agentops-agent` - Doctor skill
|
|
7
|
+
|
|
8
|
+
Use this skill when the user asks any of:
|
|
9
|
+
|
|
10
|
+
- *"Are my agents healthy in production?"*
|
|
11
|
+
- *"Run the doctor"*
|
|
12
|
+
- *"Anything regressed in our last evals?"*
|
|
13
|
+
- *"Show latency / error spikes from Azure Monitor"*
|
|
14
|
+
- *"Open the AgentOps doctor report"*
|
|
15
|
+
|
|
16
|
+
This skill is the front door to `agentops doctor` and the
|
|
17
|
+
`agentops agent serve` Copilot Extension. It does **not** invent
|
|
18
|
+
findings - it shells out to the CLI which reads real data from:
|
|
19
|
+
|
|
20
|
+
1. `.agentops/results/*/results.json` (eval history)
|
|
21
|
+
2. Application Insights traces emitted by Foundry agents
|
|
22
|
+
3. Foundry control plane (`azure-ai-projects`)
|
|
23
|
+
|
|
24
|
+
Doctor and Cockpit are read-only readiness tools. They help answer "can we ship
|
|
25
|
+
it, and where is the proof?" They do not create, deploy, mutate, or delete
|
|
26
|
+
Foundry or Azure resources.
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
### 1. Validate the workspace
|
|
31
|
+
|
|
32
|
+
Look for `.agentops/agent.yaml`. If absent, copy the template:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mkdir -p .agentops
|
|
36
|
+
cp $(python -c "import agentops, os, pathlib;
|
|
37
|
+
print(pathlib.Path(agentops.__file__).parent / 'templates' / 'agent.yaml')") .agentops/agent.yaml
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Edit `app_insights_resource_id` and `project_endpoint_env` if the user
|
|
41
|
+
wants the Azure Monitor / Foundry sources to be live. Without those
|
|
42
|
+
values the sources skip gracefully.
|
|
43
|
+
|
|
44
|
+
### 2. Run the analyzer
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
agentops doctor --severity-fail critical
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The command writes `.agentops/agent/report.md`. Exit codes:
|
|
51
|
+
|
|
52
|
+
- `0` - no findings at or above the configured severity floor
|
|
53
|
+
- `2` - at least one finding meets the severity floor (use this in CI)
|
|
54
|
+
- `1` - runtime / configuration error
|
|
55
|
+
|
|
56
|
+
### 3. Read and summarize
|
|
57
|
+
|
|
58
|
+
Open `.agentops/agent/report.md`. The report has:
|
|
59
|
+
|
|
60
|
+
- **Verdict banner** - overall pass / warning / critical
|
|
61
|
+
- **Summary** - counts by severity
|
|
62
|
+
- **Sources** - which sources ran, which were skipped and why
|
|
63
|
+
- **Findings** - sorted by severity, each with a recommendation
|
|
64
|
+
- **Recent runs** - appendix of the last `lookback_runs` evals
|
|
65
|
+
|
|
66
|
+
When summarising for the user, lead with the verdict, then the top
|
|
67
|
+
3 findings, each with the recommendation. Always cite the finding `id`
|
|
68
|
+
so the user can grep them later.
|
|
69
|
+
|
|
70
|
+
### 4. Drive remediation, do not invent it
|
|
71
|
+
|
|
72
|
+
For each finding the report includes a `Recommendation`. Follow it
|
|
73
|
+
verbatim - for example, if the finding says "compare the latest run
|
|
74
|
+
against the baseline runs in `.agentops/results/`", actually open
|
|
75
|
+
those folders.
|
|
76
|
+
|
|
77
|
+
## Local cockpit (`agentops cockpit`)
|
|
78
|
+
|
|
79
|
+
For a workspace-level operations view the user can open a local
|
|
80
|
+
Cockpit:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install "agentops-accelerator[agent] @ git+https://github.com/Azure/agentops.git@main"
|
|
84
|
+
agentops cockpit
|
|
85
|
+
# → http://127.0.0.1:8090
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Cockpit reads local AgentOps artifacts first: `.agentops/results/`,
|
|
89
|
+
generated reports, `.agentops/agent/history.jsonl`, and workflow files.
|
|
90
|
+
When a Foundry project is configured, it also resolves telemetry
|
|
91
|
+
readiness and links to the matching Foundry and Azure Monitor views.
|
|
92
|
+
It is read-only and bound to localhost.
|
|
93
|
+
|
|
94
|
+
When telemetry is enabled the analyzer **also** emits OpenTelemetry
|
|
95
|
+
spans for the Doctor run with per-severity / per-category counters,
|
|
96
|
+
useful for long-term retention in App Insights or any OTel backend.
|
|
97
|
+
Resolution order:
|
|
98
|
+
|
|
99
|
+
1. `APPLICATIONINSIGHTS_CONNECTION_STRING` (or the AgentOps-prefixed
|
|
100
|
+
variant) - explicit user configuration always wins.
|
|
101
|
+
2. `AGENTOPS_OTLP_ENDPOINT` - generic OTLP/HTTP exporter.
|
|
102
|
+
3. **Auto-discovery** - when `AZURE_AI_FOUNDRY_PROJECT_ENDPOINT` is
|
|
103
|
+
set but no explicit env var is, AgentOps asks the Foundry project
|
|
104
|
+
for the connection string of the Application Insights resource
|
|
105
|
+
attached to it. Zero configuration when the user is already on
|
|
106
|
+
Foundry.
|
|
107
|
+
|
|
108
|
+
## Copilot Extension server
|
|
109
|
+
|
|
110
|
+
If the user wants the Doctor inside Copilot Chat, they can:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pip install "agentops-accelerator[agent] @ git+https://github.com/Azure/agentops.git@main"
|
|
114
|
+
agentops agent serve --no-verify # local dev
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For production, point them at:
|
|
118
|
+
|
|
119
|
+
- `src/agentops/templates/agent-server/Dockerfile`
|
|
120
|
+
- `src/agentops/templates/agent-server/main.bicep`
|
|
121
|
+
- `src/agentops/templates/agent-server/README.md`
|
|
122
|
+
|
|
123
|
+
These are the deploy scaffold for hosting the Doctor as a Copilot
|
|
124
|
+
Extension on Azure Container Apps.
|
|
125
|
+
|
|
126
|
+
## Guardrails
|
|
127
|
+
|
|
128
|
+
- Do **not** fabricate findings, metric values, or recommendations.
|
|
129
|
+
- Do **not** invent CLI flags. The contract is exactly:
|
|
130
|
+
- `agentops doctor [--workspace] [--config] [--out] [--lookback-days] [--severity-fail]`
|
|
131
|
+
- `agentops agent serve [--host] [--port] [--config] [--no-verify] [--workers]`
|
|
132
|
+
- `agentops cockpit [--host] [--port] [--workspace]`
|
|
133
|
+
- If a source is `skipped` or `error`, surface that as the *first*
|
|
134
|
+
thing in the user-facing summary so they know the analyzer ran with
|
|
135
|
+
partial data.
|
|
136
|
+
- Never suggest disabling content-safety checks - recommend filtering
|
|
137
|
+
the offending row or tightening the system prompt instead.
|