All notable changes to this project will be documented in this file. This format follows Keep a Changelog and adheres to Semantic Versioning.
- The Cockpit can be deployed as an authenticated, read-only Azure App
Service.
agentops cockpit deploydefaults to the current workspace Foundry project, requires an infrastructure/RBAC/federation preview before mutation, reuses an existing single-tenant app registration, and preserves a recovery journal for safe reruns after partial failures. - Observe can aggregate multiple Foundry resources and projects with truthful source attribution and coverage. Shared filters drive Overview, Agents, Models and usage, and Telemetry coverage views while bounded queries preserve partial results and distinguish missing evidence from numeric zero.
- Aggregate telemetry and protected generative-AI content use separate
identities. The hosted UAMI receives only Reader and Log Analytics Reader;
explicit
AppGenAIContentreads use the signed-in user's delegated Azure Monitor permission through OBO, returnno-store, and never enter shared caches, URLs, browser persistence, telemetry, diagnostics, or deployment artifacts.
- Hosted Cockpit deployment preview now works with Windows Azure CLI shims
and the live App Service name API. Command execution resolves wrappers such
as
az.cmd, and hostname checks use the active subscription's documentedSiteavailability contract before any Azure mutation. - Hosted Cockpit delegated consent now targets the Log Analytics API.
Deployment preflight resolves the
Data.Readscope from the correct resource application, allowing tenant administrators to grant the required permission. - Developer installs include the hosted Cockpit test dependencies. The standard development environment can collect and run the FastAPI integration tests used by CI.
- Evaluations can load JSONL datasets directly from Azure Blob Storage and
ADLS Gen2. The existing scalar
datasetsetting accepts canonical Blob and DFS HTTPS object URLs. AgentOps resolves one read-only snapshot of up to 100 MiB for local, cloud, official-evaluation, and readiness-analysis flows while preserving the original source URI in reports and lineage.
- Remote datasets use only the Azure identity already running AgentOps.
Local runs reuse
az login; automated runs reuse their federated, workload, managed, or service-principal identity. SAS URLs, dataset-specific tokens, account keys, connection strings, query strings, and embedded credentials are rejected. The identity needsStorage Blob Data Readerand any applicable ADLS path ACLs.
- The AgentOps Cockpit now focuses on five release-readiness sections. The page renders only the readiness and Doctor ship verdicts, Foundry and GitHub connections, the 13-item observability checklist, the latest Doctor findings, and prioritized next actions. Date-window and auto-refresh controls were removed because the remaining sections describe current configuration and the latest analysis rather than time-series dashboards.
- Observability readiness now distinguishes native Foundry tracing from optional custom spans. Hosted agents and prompt agents are recognized as natively instrumented, while repository OpenTelemetry spans are reported as optional extensions. App Insights linkage, rubric evaluators, alert definitions, and tracing evidence are resolved independently so unknown state is no longer presented as a failure.
- Project-managed Application Insights connections now work throughout
Doctor and Cockpit. AgentOps discovers the attached Application Insights
ARM resource from credential-free Foundry connection metadata and queries it
with
LogsQueryClient.query_resource, avoiding false missing-telemetry findings when no API-key connection string exists. agentops agent registernow derives hosted-agent names from Foundry target URLs. A command that supplies only--sponsorcorrectly resolves names such ashelpdeskbot, matching the fallback promised by--help.
- The experimental AgentOps telemetry import and custom Operations Dashboard have been removed. The public telemetry command group, Log Analytics workbook deployment, bundled workbook/KQL assets, and dashboard-specific posture rule are no longer shipped while native product observability support is reviewed.
- Pre-flight now validates Foundry project reachability independently from
Application Insights credential discovery. Projects whose attached
Application Insights connection uses
ProjectManagedIdentityno longer produce a false Foundry warning or require API Key credentials, while an explicitAPPLICATIONINSIGHTS_CONNECTION_STRINGstill takes precedence.
- Agents can now carry a first-class Microsoft Entra identity that travels
from registration through traces into release evidence. Before this, a
trace could tell you what an agent did but not which registered agent did it,
so nothing in the evidence pack tied runtime behaviour back to an accountable
owner in the tenant. Three pieces close that loop.
agentops agent registercreates or adopts an agent identity blueprint in Microsoft Entra (idempotent, sponsor required,--dry-runsupported) and records the resolved id under.agentops/identity/agent-identity.json. AgentOps then stamps that id on every span it emits as the OpenTelemetry resource attributegen_ai.agent.id, omitting the attribute entirely when no identity is registered so presence is a meaningful filter. Finally, the release evidence pack publishes anagent_identitysection reporting the id and its source. A read-only Doctor check reports registration posture, contacting Microsoft Graph only whenidentity.verifyis enabled inagentops.yaml.agentops.yamlaccepts a new optionalidentityblock (display_name,sponsor,verify).
- The official evaluation runner now honours the agent version override.
prepare_official_evalread the agent name and version straight fromagentops.yamland ignored both the--agentflag and theAGENTOPS_AGENTenvironment variable, so a pipeline that pinned a specific agent version still evaluated whatever version the config happened to carry. The override is now resolved in one place (resolve_agent_override), applied byofficial_eval.py, and forwarded by the generated GitHub Actions and Azure DevOps workflows. An unexpanded CI token such as$(AGENTOPS_AGENT)is treated as absent instead of being parsed as an agent name.
- The release cut logic moved out of
cut-release.ymland intoscripts/check_changelog.py cut. The workflow used to carry the transformation as an inline Python heredoc, which no test could import, so a regression in it was only visible when a release was already being cut. That is exactly how the 0.8.6 cut broke. The same code now backs both the workflow and the unit tests, and the subcommand is idempotent: re-running it for a version already present in the file is a no-op.
-
CI now fails a pull request that changes shipped code without a CHANGELOG entry.
cut-release.ymlnever generates changelog content. It inserts a## [X.Y.Z] - <date>heading beneath## [Unreleased]and stops there, so a release cycle where no PR wrote anything under[Unreleased]publishes an empty section with a green pipeline. Releases 0.8.4 and 0.8.5 both shipped that way and were backfilled by hand, between them hiding six user-visible bug fixes and six dependency bumps.A new
changelogjob runsscripts/check_changelog.pyon every PR todevelop. It asks for an entry only when the diff touches a file that ships and the PR title reads as user-visible (feat,fix,perf,revert, a breaking-change marker, or no conventional-commit type at all). Changes confined todocs/,tests/,.github/workflows/,.github/ISSUE_TEMPLATE/, or the top-level markdown files are never asked for one, and neither are PRs typeddocs:,test:,ci:,chore:,build:,style:, orrefactor:. The check resolves each added line to the section it lands in, so a bullet written under an already-released heading fails the same as no bullet, which matches whatcut-releasewill actually promote. Apply theno-changeloglabel to bypass it. Dependabot is exempt because a bot cannot respond to a red check.The same script guards the release itself.
cut-release.ymland both localcut-releasescripts now abort before creating the release branch when[Unreleased]is empty, so a cycle that wrote nothing at all cannot reach a published tag. That is a non-emptiness check, not per-change coverage: one bullet from any PR satisfies it. -
Both local
cut-releasescripts inserted the new version heading in the wrong place.scripts/cut-release.shandscripts/cut-release.ps1anchored the insertion on the "adheres to [Semantic Versioning]" line, which sits above## [Unreleased]. Cutting a release locally therefore produced an empty## [X.Y.Z]section and left every accumulated entry stranded under[Unreleased], where the next cycle would silently absorb it. Both scripts now anchor on## [Unreleased]and insert beneath it, matching whatcut-release.ymlhas always done, and both abort if that heading is missing. -
agentops eval runaccepts an explicit agent target. The eval target was only ever read fromagentops.yaml, so retargeting a run meant editing tracked config.--agentnow overrides it, falling back to theAGENTOPS_AGENTenvironment variable when the flag is absent. A bare number (--agent 12) replaces just the version segment of the configured target; a full agent reference (endpoint URL,name:version, ormodel:<deployment>) replaces the target outright. Unset means unchanged, so every existing run behaves exactly as before.RunOptions.agent_overridealready existed in the orchestrator and was already consumed by all three execution backends, but nothing set it. This connects the CLI to that seam and forwardsAGENTOPS_AGENTinto every generated eval step on GitHub Actions and Azure DevOps, so a future pipeline change can retarget the gate without rewritingagentops.yamlmid-run. Nothing in the shipped pipelines assigns a value yet, and the injected expressions read same-job scope, which cannot see a prior job's output. Wiring a producer needs declared job outputs on GitHub Actions orstageDependencieson Azure DevOps; see issue #388.Azure DevOps leaves
$(NAME)in the environment verbatim when a variable is undefined, so an unexpanded token is treated as "no override" rather than as an agent expression. An empty or unexpanded value falls back to the configured agent instead of failing, because every pipeline generated today passes exactly that.agentops workflow analyzereports the pinned agent version as a signal when the repo also has a generated deploy pipeline, which is the only place a later deploy step could move the target underneath the gate. Eval-only repos see nothing.
-
The eval gate installed
azdbut never gave it credentials, on both GitHub Actions and Azure DevOps. When a project uses the azd evaluation backend, the generated pipeline runsagentops eval run, which shells out toazd ai agent eval run. Both platforms installed the pinnedazure.ai.agentsextension and then invoked the binary with no credentials, so the eval gate failed before reaching Foundry.This is the issue #379 trap in a job nobody had exercised. The fix differs by platform because the surrounding authentication differs. On Azure DevOps every azd call runs inside
AzureCLI@2, which completes the service-connection handshake and leaves the Azure CLI authenticated, butazdkeeps a separate credential store and ignores that session unlessauth.useAzCliAuthis set; the eval stage now sets it, matching the provision and deploy stages in the same pipeline. On GitHub Actionsazure/login@v3authenticates only the Azure CLI, so the eval job now runsazd auth login --federated-credential-provider githubwith the samevars.AZURE_CLIENT_IDandvars.AZURE_TENANT_IDthe provision and deploy jobs already use. Every generated job that installs the azd extension now also authenticates it. -
The generated Azure DevOps PR pipeline was not valid YAML. The report-comment step embedded a multi-line
python -csnippet whose continuation lines started at column 0. A column-0 line terminates the surroundingbash: |block scalar, so Azure DevOps rejected the file with a parse error before running anything. The continuation lines are now indented into the block; the trailing backslashes still join them into a single logical line, so the Python behaviour is unchanged. A regression test parses every generated ADO pipeline across all eval-runner variants and rejects any stray column-0 line. -
Publishing a release never rebuilt the documentation site. The site is built from the
docsbranch, and theDeploy Documentationworkflow that builds it declares arelease: publishedtrigger. That trigger could never fire, because the workflow file existed only ondocs, and GitHub Actions resolves workflows for non-pushevents from the default branch. Four consecutive releases published while the home page kept advertisingv0.8.1, since the version string is baked into the HTML at build time. The workflow now also lives on the default branch so release events can reach it. It still checks outdocsexplicitly, so the published content is unchanged, andpushevents continue to resolve from the pushed commit, so there is no duplicate run. -
The contributor setup command in
how-it-works.mdinstalled nothing. It suggestedpip install -e ".[dev]", butdevis a PEP 735 dependency group rather than an extra, so pip warned about an unknown extra and skipped every development dependency. The next documented step, running pytest, then failed on a missing module. The page now usesuv sync --group dev, which is what all eleven CI invocations already use.
-
Generated
azdworkflows failed at the provision and deploy steps. Everyazd-based CI template ranazd provisionandazd deploywithout first installing theazure.ai.agentsextension and without authenticating theazdCLI itself, so the provision job stopped withERROR: Auto-installation is not supported in CI/CD environments.Two separate gaps caused this. First,
azdrefuses to auto-install extensions in CI, so the extension has to be installed explicitly. Second,azure/login@v3authenticates the Azure CLI, notazd;azdkeeps its own credential store and needs its ownazd auth login --federated-credential-provider github. Theevaljob was unaffected and passed, which made the failure look intermittent:agentopsitself usesazure-identity, which happily reads the Azure CLI session, so only the jobs that shell out to theazdbinary broke.Both steps are now emitted into the provision and deploy jobs of every
azdtemplate, on GitHub Actions and Azure DevOps alike. The extension version is read from the same source the CLI uses rather than hardcoded, so it cannot drift. -
execution: cloudstill emittedazdsetup into the eval job. With cloud execution the evaluation runs server-side in Foundry and never invokesazd, but the generated workflow installed and authenticated it anyway. That is dead setup work on every run, and it made the eval job fail for a reason unrelated to evaluation wheneverazdauth was not configured.workflow analyzeand the eval-runner recommendation now both take the configured execution mode into account. -
Generated workflows installed a package extra that does not exist. Templates and two tutorials asked for
agentops-accelerator[foundry,agent]. There is nofoundryextra; the real ones aremcpandagent. Corrected in 10 GitHub Actions templates, 8 Azure DevOps templates, and the tutorials. -
The eval job ignored the deployment environment. Dev and QA workflows declared
environment:on provision and deploy but not on eval, so the eval job could not read the environment-scoped variables it needs and fell back to whatever happened to be set at repository scope. The productionsafety-evaljob intentionally keeps noenvironment:, because gating it would force a human to approve the run before seeing any results. -
eval analyzelabelled agent targets asmodel quality. The scenario hint inspected only dataset column names, so any dataset carrying anexpectedcolumn was reported as a model-quality scenario. That is correct for a rawmodel:<deployment>target compared against a reference answer, but wrong for an agent answeringinputwith a free-form reply, which is conversational. Foundry hosted and prompt agents were both affected. The hint now agrees withcore/evaluators.py, which already branched on the target kind when picking the actual evaluators.--format textalso leaked the raw kind string (Project: foundry_hosted evaluation setup); both renderers now share one label table so they cannot drift apart again. -
workflow analyzehardcoded "Foundry prompt agent" as the target. The Foundry eval checklist printed that label regardless of the real target, so a hosted-agent project was told it had a prompt agent. The rows now render the reasons the analysis actually produced.
- OIDC docs now cover
sub_claim_prefix. Accounts configured with an immutable-ID subject claim receive a subject built from numeric account and repository IDs rather than the plain names, so a federated credential matching onlyrepo:<owner>/<repo>:environment:<env>is never matched and the workflow fails withAADSTS700213. The setup guide now explains how to read the prefix fromrepos/<owner>/<repo>/actions/oidc/customization/suband register the second credential. Note that theuse_defaultanduse_immutable_subjectbooleans in that response are not reliable indicators; read thesub_claim_prefixstring itself. - Release documentation corrected.
docs/release-process.mdand the release-management skill described a manual approval gate protecting the PyPI publish that does not exist: both environments have emptyprotection_rules, so pushing the tag publishes immediately and irreversibly. The same files also documentedVSCE_PATas an environment secret when it is a repository secret. Themain→developsync step, previously easy to skip, is now called out explicitly.
mcp1.27.1 → 1.28.1, with the floor raised tomcp>=1.28.1,<2. The proposed<3widening was rejected:mcp2.0.0 renamesFastMCPtoMCPServerand is a breaking rewrite. CI reported green on that change only becauseuv sync --group devnever installs themcpextra, so the MCP tests skip.cryptography48.0.1 → 50.0.0. The breaking changes in 49 and 50 concern FFDH deprecation and stricter DER/SCT/OCSP/CRL/PKCS#7 parsing; the only direct consumer,agent/server/auth.py, is EC-only over a PEM public key.aiohttp3.14.1 → 3.14.3,nltk3.9.4 → 3.10.0,actions/setup-node6 → 7,actions/setup-python6 → 7.
- Generated CI pinned an
azdextension version that was never published. The templates asked forazure.ai.agentsversion1.0.0, which does not exist in the azd extension registry, so every generated pipeline targeting a Foundry hosted agent stopped atInstall pinned azd AI agents extensionwithERROR: no extensions found, on both GitHub Actions and Azure DevOps. Pinned to1.0.0-beta.9, the highest version actually published.
-
execution: cloudnow works with a Foundry hosted agent. Settingexecution: cloudon a hosted agent endpoint failed withexecution: cloud only supports Foundry prompt agents, so hosted-agent users had no way to run a server-side evaluation and see the results in the New Foundry Evaluations panel. Their only option wasexecution: local, which keeps everything on the client and publishes nothing.This was an artificial restriction, not an API limit. The Foundry Evals API identifies its target with
{"type": "azure_ai_agent", "name": ..., "version": ...}, and a hosted agent URL already carries both values in its path (/agents/<name>/versions/<version>). The problem was thatclassify_agent()never extracted them: it returned afoundry_hostedtarget withnameandversionleft asNone, so the cloud path had nothing to send and rejected the target up front.classify_agent()now parses the agent name and version out of a hosted endpoint URL, tolerating trailing path segments (/responses), query strings, and fragments. The guards inpipeline/cloud_runner.pyandpipeline/orchestrator.pyacceptfoundry_hostedalongsidefoundry_prompt. A hosted URL with no/versions/<version>segment is still rejected, because there is no version to pin the run to, but the error now names the missing segment instead of rejecting the whole target kind.execution: localremains the default for every target kind, so this change adds an option without altering existing behavior. -
CI:
Install from TestPyPIno longer fails on a healthy build. After a dev, staging, or release build uploaded a distribution to TestPyPI and received200 OK, the verification step immediately tried to install it and gave up after 5 attempts spaced 30 s apart (~2 min). TestPyPI serves its simple index through a CDN, so propagation regularly takes longer than that, and the job failed withNo matching distribution found for agentops-accelerator==<version>for a package that had in fact been published successfully. The retry window is now 12 attempts (~6 min), andpip installruns with--no-cache-dirso a negative index response from an earlier attempt is not reused within the same job. Applied toci.yml(verify-dev),staging.yml, andrelease.yml— inrelease.ymlthis step gates publication to PyPI, so a false negative there blocked the release entirely.
-
protocol: responsesnow works against a Foundry hosted agent. Every invocation failed withHTTP 400 ... Missing required query parameter: api-version, because the hosted-agent path built the request URL by string-concatenating/responsesonto the configured URL. That had three consequences:- Any existing query string was corrupted, because
/responseswas appended after it (.../responses?api-version=v1became.../responses?api-version=v1/responses). - The required
api-versionquery parameter was never added, so the Foundry data plane rejected the request outright. - A Foundry agent identity URL
(
/api/projects/<project>/agents/<name>/versions/<n>) was accepted even though it is not an invocable route; the invocable route is/agents/<name>/endpoint/protocols/openai/responses.
The URL is now parsed rather than concatenated: the path and the query string are handled separately, an agent identity URL is normalized onto the protocol route, and
api-versiondefaults tov1for Foundry protocol routes only. When the configured URL pins a version, the version is preserved by sending anagent_referencein the request body (the same mechanism_invoke_foundry_promptalready uses), so pinning semantics are not lost. URLs that already point at a/responsesroute and non-Foundry HTTP endpoints are left untouched. - Any existing query string was corrupted, because
agentops doctorno longer prints noisy non-fatal errors to the console. Three low-level probes that already degrade gracefully were leaking their transport errors to the screen during readiness checks:- The LLM judge called the Foundry project OpenAI client on the legacy
/openai/route, which returns HTTP 404 for chat completions, printingWARNING: llm_assist: judge call failed: Error code: 404. The client is now normalized to the stable/openai/v1/route (with the injectedapi-versionquery parameter cleared) using the same reused credential and token refresh, so the judge runs instead of 404ing. Non-Foundry endpoints are left untouched. - The OpenAI data-plane RBAC check built an ARM role-assignment filter
(
atScopeAndAbove() and assignedTo('<oid>')) that ARM rejects withUnsupportedQuery. It now sends the supportedassignedTo('<oid>')filter, which already returns assignments at the target scope and every ancestor scope, so the check runs instead of skipping with a console error. - The Application Insights REST probe caught only
urllib.error.URLError, so a read timeout (asocket.timeout, which is anOSErrorbut not aURLError) escaped and surfacedINFO: Rate-limit App Insights probe failed (non-fatal): The read operation timed out. It now catchesOSError(covering both) and the request timeout was raised from 10s to 30s, so a slow App Insights degrades quietly.
- The LLM judge called the Foundry project OpenAI client on the legacy
- Add a read-only Agent behavior tab to the Foundry operations Azure Monitor
workbook, with versioned
AppEvents/customEventsnormalization, explicit data and freshness states, separate invocation / evaluated-trace / evaluation-event counts, scale-safe per-evaluator trends, and trace IDs for Foundry investigation. Human trace annotations are the documentedgen_ai.evaluation.resultproducer; automated trace-evaluation event export remains validation-dependent.
agentops telemetry dashboard deploynow works. The generated ARM template set the workbooklocationtoglobal, whichMicrosoft.Insights/workbooksrejects (LocationNotAvailableForResourceType), so the v0.7.0 deploy always failed. The workbook now deploys to the target resource group's region ([resourceGroup().location]) by default; an explicit region override is still honored. Verified with a live deploy against Azure.
- Bumped
idnato3.18andpytestto9.1.1inuv.lockto clear two moderate Dependabot alerts. The high-severitynltkadvisory (GHSA-p4gq-832x-fm9v) has no upstream fix yet and remains open until a patched release is available.
- Foundry operations dashboard. A new Azure Monitor Workbook
(
agentops telemetry dashboard) surfaces Azure OpenAI capacity (PTU utilization, rate-limit, spillover), traffic and tokens, latency percentiles (TTFT, TBT, TTLT, tokens/sec), and errors and throttling for a given Azure OpenAI resource and Log Analytics workspace. The workbook JSON, its per-metric KQL queries, and an authoring README ship as package data. Three commands manage it:deploy(RBAC + diagnostic-settings preflight, then deploy theMicrosoft.Insights/workbooksARM resource, with--dry-runto emit the template),open(build the portal deep link and open a browser,--print-urlfor non-interactive shells), andexport(copy the packaged workbook JSON to a local path).agentops telemetry dashboard deployis the first CLI command that creates an Azure resource; it is scoped to a single workbook. - Doctor check for Azure OpenAI usage telemetry. A new WAF-AI Operational
Excellence posture rule (
waf.observability.aoai_diagnostic_categories) warns when the Azure OpenAI account is not emitting theRequestResponseandAzureOpenAIRequestUsagediagnostic log categories to a Log Analytics workspace, and prints the exactaz monitor diagnostic-settings createfix. Doctor stays read-only.
- Cockpit redesign answers "can I ship?" first. The Cockpit now opens with
three consolidated status cards (Readiness, Doctor, Eval gate) that expand
their detail sections on click, promotes "Next actions" to second position,
and collapses the detailed sections by default. The former "Eval gate
summary" and "Quality gate summary" are merged into a single "Eval gates"
section with two subgroups. The Foundry launchpad footer adds a "Foundry
operations dashboard" tile (the same workbook portal URL used by
agentops telemetry dashboard open) next to "Operate overview", folds the single-tile "Azure Monitor" group into the Foundry project group, and removes the duplicated App Insights CTA from the Production signal section. Cockpit remains read-only.
- Retrieval telemetry can now be imported as evaluation datasets. The new
telemetry_importsconfig contract andagentops telemetry validate,agentops telemetry preview, andagentops telemetry importcommands let teams turn reviewed retrieval telemetry into dataset-backed eval rows withresponse_source: dataset. Grey-box HTTP agents can mapresponse_fieldsfrom$response.context, and the evaluation docs now cover the import workflow and contract.
- Updated the AgentOps CLI tagline to use
Operateinstead ofOwnfor clearer operator-focused positioning. - Prompt-agent PR validation now uses sandbox instead of dev. Generated GitHub and Azure DevOps PR workflows stage prompt-agent candidates in the sandbox Foundry environment, keeping dev for deployed-of-record versions.
- VS Code extension is back on the Marketplace. The 0.5.2 release published to
PyPI, but the Marketplace (VSIX) publish was blocked by an expired publisher
token, so the VS Code extension never updated to 0.5.2. Release 0.5.3 ships the
same toolkit as 0.5.2 with a refreshed Marketplace credential, so
agentops-acceleratoron PyPI and the AgentOps extension on the Marketplace are back in sync. No functional changes to the CLI or the extension.
- Per-evaluator input remapping via
evaluators[].input_mapping. Evaluator overrides inagentops.yamlnow accept an optionalinput_mappingmap that is merged onto the preset's default inputs, so you only list the keys you want to change. This is what lets a grey-box HTTP/JSON target point a RAG evaluator at the live retrieved context captured byresponse_fields, for examplecontext: $response.contextonGroundednessEvaluatorandRetrievalEvaluator. The mapping applies to both explicitly listed overrides and auto-selected presets. A bare evaluator name string (- GroundednessEvaluator) is still accepted as shorthand for{ name: GroundednessEvaluator }, so existing configs are unchanged.
- Rendered gate results in GitHub Actions job summaries. When AgentOps runs
inside GitHub Actions (
GITHUB_STEP_SUMMARYset),agentops eval runnow appends the full renderedreport.mdto the workflow run summary, andagentops assert run/agentops redteam runappend a concise pass/fail summary (suite, cases, pass rate, per-dimension and per-risk-category breakdowns). Reviewers can read the report directly on the run page without downloading the uploaded artifacts. Writes are best-effort and a no-op outside GitHub Actions, so local runs are unaffected.
- Generated workflows use Node24-ready action versions. The prompt-agent and
watchdog workflow templates now pin
actions/download-artifact@v7(instead of the Node20@v4), so generated pipelines no longer emit the "Node.js 20 actions are deprecated" warning. A regression guard checks every workflow template against the known Node20 action majors.
- Grey-box retrieval capture for HTTP JSON targets. An HTTP target can now
capture extra named fields from a JSON response via a
response_fieldsmap (name -> dot-path). Captured values are exposed to evaluatorinput_mappingas$response.<name>(for example$response.context,$response.retrieved_documents), and dataset columns can be referenced with$row.<name>(for example$row.qrels). This lets RAG evaluators such as Groundedness, Retrieval, and Document Retrieval score the retrieval actually used at eval time instead of static dataset context. The primary prediction (response_field) and single-field behavior are unchanged whenresponse_fieldsis not set.
- Governance gates for HTTP agents (ASSERT and Red Team).
agentops assert runandagentops redteam runnow work against a live HTTP orchestrator endpoint, not only model/deployment targets. Red Team wraps the HTTP endpoint as an SDK-compatible target and reuses the AgentOps HTTP mapping (request_field,response_mode,stream, custom headers). ASSERT resolvesassert-aiinside the active virtual environment, accepts non-secret values fromassert.env, can request an AAD token from the Azure CLI for local auth-disabled Azure AI resources, injects the GPT-5max_completion_tokensshim only when configured, and materializes a runtime ASSERT config so committed configs no longer need absolute artifact paths. - Generated workflows run the ASSERT and Red Team gates.
agentops workflow generatenow installs the optional ASSERT/Red Team dependencies, runs those gates whenassert:orredteam:is present inagentops.yaml, uploads their artifacts, and emits the corrected Red Team command quoting.
- Reasoning-model judges no longer fail the eval gate in CI. The generated
GitHub Actions and Azure DevOps eval and Red Team steps now forward
AZURE_OPENAI_MODEL_NAME, so AgentOps detects reasoning models (such asgpt-5-nano) and usesmax_completion_tokensinstead ofmax_tokens. This removes the judge400error that could break the eval gate when the judge deployment is a reasoning model.
- Streaming HTTP targets. The
http_jsontarget now understands streaming responses so AgentOps can evaluate SSE/streaming agents (such as the gpt-rag-orchestrator/orchestratorendpoint) directly, without a manual adapter. A newresponse_mode: json|sse|textfield selects the response parser (jsonis the default and preserves the existing single-json.loadsbehavior exactly). Forsse/text, an optionalstreamblock configures aggregation:text_field(dotted path to the token text when each SSEdata:line is JSON),done_marker(stop token, e.g.[DONE]), andstrip_leading_token(drop the leading whitespace-delimited token, e.g. the orchestrator'sconversation_idprefix). The auth header is now configurable viaauth_header_name(defaultAuthorization) andauth_value_template(defaultBearer {token}, where{token}is replaced by theauth_header_envvalue), so targets gated by a shared secret such asX-API-KEYare supported without hardcoding the secret inagentops.yaml. Streaming uses the same stdlib (urllib) transport and 3-try backoff as the JSON path. When a JSON parse fails on atext/event-streamresponse, the error now suggests settingresponse_mode: sse|text.
- Prompt-agent tutorials no longer require manual portal copy/paste.
agentops prompt pullreads the configured Foundry prompt agent (agent: name:version), validates that the Foundry definition is actually a prompt agent, and writes the reviewed Sandbox instructions to.agentops/prompts/<agent-name>.prompt.mdby default. Before writing, the CLI prints the resolved agent, endpoint, endpoint source, and destination file so operators can catch the wrong environment early. Changed prompt files are protected by default and require--forceto overwrite reviewed local edits. The command updatesprompt_fileinagentops.yamlunless--no-update-configis passed, and it can resolve the endpoint from--project-endpoint,agentops.yaml,AZURE_AI_FOUNDRY_PROJECT_ENDPOINT, or the active.azure/<env>/.env. The prompt-agent tutorial and packagedagentops-evalskill now use this command instead of a manual here-string. (#322)
agentops eval initnow recommends evaluators from the agent and dataset shape. The azd bootstrap path now reuses the same AgentOps evaluator catalog asagentops eval run: free-form answer datasets get answer-quality checks, RAG-shaped datasets get groundedness / relevance / retrieval checks, and tool-use datasets get tool-call / intent / task-adherence checks while avoiding literal-answer similarity metrics. Explicitevaluators:entries inagentops.yamlstill win. The CLI prints the recommendation source, detected signals, and selected azd built-ins before reporting the generatedeval.yaml, so users can see why those evaluators were chosen. (#323)
agentops eval initnow works with both old and newazure.ai.agentsazd extensions. Version 0.1.40 of the extension renamed the eval subcommand fromazd ai agent eval inittoazd ai agent eval generate, which madeagentops eval inithard-fail withCommand "init" is deprecated, use 'azd ai agent eval generate' instead. AgentOps now invokesgeneratefirst and transparently falls back to the legacyinitsubcommand when an older extension does not recognisegenerate. The fallback only triggers on subcommand-name/deprecation errors; genuine failures (authentication, project endpoint, timeouts) are still surfaced immediately and unchanged. All previously passed flags (--project-endpoint,--agent,--gen-instruction-file,--eval-model,--dataset,--evaluator) and the recipe discovery/persistence behaviour are preserved.
- PR-stage Foundry prompt-agent versions are now tagged at the source. When
agentops.pipeline.prompt_deploy stageruns in a PR context (GitHub Actionspull_requestevent or Azure DevOpsBUILD_REASON=PullRequest), the version it creates in the dev Foundry project carries metadataagentops:candidate=true,agentops:pr=<number>, andagentops:created_at=<ISO timestamp>. Portal viewers can filter the Versions tab onagentops:candidateto separate abandoned PR candidates from deployed-of-record versions, and downstream consumers that resolve "latest" can refuse to pick up candidates. Deployed-of-record versions (push tomain/develop/release/**orworkflow_dispatch) are not tagged, so absence ofagentops:candidateis the deployed-of-record signal. The PR/deploy workflow templates and the prompt-agent quickstart tutorial are updated to describe the new contract. (#214)
-
Clean installs now include the pager dependency used by explain commands.
agentops explain,agentops init explain, andagentops doctor explainimport Click directly to render long manual output, soclick>=8.1,<9is now declared as a runtime dependency instead of relying on transitive installs. -
agentops eval initnow works with both old and newazure.ai.agentsazd extensions. Version 0.1.40 of the extension renamed the eval subcommand fromazd ai agent eval inittoazd ai agent eval generate, which madeagentops eval inithard-fail withCommand "init" is deprecated, use 'azd ai agent eval generate' instead. AgentOps now invokesgeneratefirst and transparently falls back to the legacyinitsubcommand when an older extension does not recognisegenerate. The fallback only triggers on subcommand-name/deprecation errors; genuine failures (authentication, project endpoint, timeouts) are still surfaced immediately and unchanged. All previously passed flags (--project-endpoint,--agent,--gen-instruction-file,--eval-model,--dataset,--evaluator) and the recipe discovery/persistence behaviour are preserved.
agentops doctornow detects missing OpenAI data-plane RBAC on the Foundry resource. A newsecurity.missing_openai_data_plane_rbaccheck resolves the signed-in principal (via theoidclaim of the access token used byDefaultAzureCredential) and lists role assignments at the Foundry account scope usingazure-mgmt-authorization. When none of Cognitive Services OpenAI User, Cognitive Services OpenAI Contributor or Cognitive Services Contributor is present (directly or inherited), Doctor surfaces an actionable WARNING that includes the exactaz role assignment createcommand for Cognitive Services OpenAI User scoped to the Foundry account. The check is read-only and skips silently when the SDK, principal or scope cannot be resolved. (#228)
agentops-prworkflow templates now auto-detect a committed baseline. Both the GitHub Actions (.github/workflows/agentops-pr.yml) and Azure DevOps (.azuredevops/pipelines/agentops-pr.yml) PR templates emitted byagentops workflow generatewrapagentops eval runwith a small bash guard. When.agentops/baseline/results.jsonexists in the consumer repo, the step automatically passes--baseline .agentops/baseline/results.json; without the file the behaviour is unchanged. Aligns shipped templates with thetutorial-baseline-comparison.md"drop a file in your repo" promise. Deploy templates (dev/qa/prod) are untouched. (#155)
agentops skills install --platformhelp text now listscursor. The CLI option help was advertising onlycopilotandclaudeeven though thecursorplatform is fully implemented (registers rules in.cursor/rules/agentops.mdc). Updated toTarget platform(s): copilot, claude, cursor.so users discover the supported value from--help. (#157)
agentops-governanceskill now scaffolds a validassert-ai 0.1.0config. The previous skeleton invented top-level keys (dimensions:,num_cases_per_dimension:,target.type:,suite_id:/run_id:) thatassert-ai runrejects withconfig has unsupported field(s). The skill and tutorial step 12 now generate the real pipeline schema (suite/run/behavior.preset/default_model/pipeline.{systematize,test_set,inference, judge}) using the built-intravel_plannerbehavior preset shipped withassert-ai, plus asafety-core+alignmentjudge combo. Added a troubleshooting note explaining the LiteLLM-style Azure env vars (AZURE_API_KEY/AZURE_API_BASE/AZURE_API_VERSION) thatassert-aineeds at runtime.
- E2E agent container dependencies no longer resolve vulnerable Starlette or
mem0ai versions. The sample FastAPI service now pins patched FastAPI and
Agent Framework releases and adds an explicit
mem0aipin so Dependabot no longer reports the transitive Starlette host-header / file-response advisories or the mem0ai unsafe deserialization advisory on the default branch.
agentops-workflowskill now verifies OIDC tenant, branch upstream tracking, and trace-sampling RBAC before wiring CI. The packaged skill instructs agents to treatAZURE_TENANT_IDas the tenant that owns the Entra app registration / federated credential (not the subscription tenant), to set and verify the local trunk branch upstream (git branch -vvmust show[origin/main]), and to grant Reader on Application Insights (and its backing Log Analytics workspace) to the Foundry project managed identity for trace-to-dataset flows.
- Prompt-agent, hosted-agent, and end-to-end tutorials hardened end to end.
OIDC setup calls out the app-registration tenant; observability steps require
App Insights Reader for trace sampling and cover workspace-backed App Insights;
the telemetry step queries
gen_ai.evaluationresults fromAppEvents(table-safe, no hard-coded dates); the evidence step explains expected production-telemetry criticals and where the Doctor thresholds live (.agentops/agent.yaml); and the Cockpit step is now a concrete walkthrough (exacthttp://127.0.0.1:8090URL, read-only note, per-section checks, and azd-env switching instead of a non-existent URL switch).
agentops-governanceskill can now scaffold the ASSERT and Red Team runners (installassert-ai/azure-ai-evaluation[redteam], create./assert/eval_config.yaml, append theassert:/redteam:block toagentops.yaml). Previously the skill only drafted reviewable evidence skeletons.
execution: azdreports no longer ship emptyDataset:lines and empty## Rowstables. Theeval.yamlparser now recognizes thedataset_file:field thatazd ai agent eval initemits, soreport.mdshows the actual dataset path. When azd returns aggregate metrics only (the normal case), the reporter omits the row tables entirely and instead emits a## Per-row breakdownsection that links to the Foundry run for the per-sample view.agentops eval runprints a clickable Foundry deep link on success. After a successful azd run, the CLI now emits aFoundry run: <url>line alongside theresults.json/report.mdpaths so users can jump straight to the per-sample table and rubric drill-downs in the Foundry portal.
- Shorter azd backend log line. Replaced the verbose
Running azd backend: azd --no-prompt ai agent eval run --config <long path> --output jsonline with a conciseRunning azd backend: azd ai agent eval run; the full command remains captured in the per-failure debug logs introduced in 0.3.18. execution: azdstartup line uses a workspace-relative recipe path so the "delegating to azd ai agent eval" message stays readable on long Windows paths.
agentops eval runsurfaces real azd failures instead of swallowing them behind a spinner line. Whenexecution: azdfails, the error now includes the full command, exit code, and both stderr and stdout (truncated defensively). Raw streams are also persisted to.agentops/results/<ts>/azd_eval_run_stdout.logand_stderr.log(and the matchingazd_eval_show_*files whenazd ai agent eval showfails) so the underlying cause is always recoverable from disk. Previously the CLI printed only the active azd spinner step (e.g. "Resolving eval context..."), leaving users with no actionable diagnostic.
agentops assert runorchestrates the open-source ASSERT framework. AgentOps now invokes theassert-aiCLI as an active CI step instead of only consuming pre-generated artifacts viaassert_path:. A newassert:block inagentops.yaml(config,results_dir,suite,run_id,fail_on_violations) drives subprocess invocation, locates the run output under<results_dir>/<suite>/<run>/, parsesmetrics.jsonandscores.jsonl, and writes a normalized summary at.agentops/assert/latest.jsonthat the release evidence pack ingests automatically. Exit code 2 when any policy dimension reports violations.agentops redteam runorchestrates Foundry's AI Red Teaming agent (PyRIT). AgentOps now invokesazure.ai.evaluation.red_team.RedTeamagainst the configured target (Azure OpenAI deployment, Foundry prompt agent, or HTTP endpoint) and normalizes the per-category and per-strategy attack outcomes. A newredteam:block inagentops.yaml(target,risk_categories,attack_strategies,num_objectives,fail_on_attack_success_rate) controls the scan; results land at.agentops/redteam/latest.jsonso the evidence pack picks them up viaredteam_path:automatically. Exit code 2 when attack-success-rate exceeds the configured threshold.
- Quickstart rubrics no longer block azd eval runs with placeholder evidence. The Travel Agent hardening flow now defaults to multi-turn dataset coverage and treats rubric evaluators as advanced opt-in only after Foundry / azd emits real metric names, while AgentOps preserves rubric metadata without failing a normal azd result solely because matching rubric metrics were not emitted.
- Foundry observability readiness now spans eval, Doctor, Cockpit, and release evidence.
agentops.yamlsupportsdataset_kind,rubrics, andobservabilitymetadata for multi-turn coverage, rubric evaluator gates, trace sampling, and replay/evaluation/dataset links. Doctor and Cockpit surface the readiness state without mutating cloud resources, and release evidence records the same signals for reviewers. - Trace promotion preserves evaluation lineage.
agentops eval promote-tracesnow carries operation/span IDs, source system, agent version, replay/evaluation URLs, sampling policy, and multi-turn message fields into candidate datasets and their manifest.
- Rubric evaluators are executed through the azd backend. When
rubrics:is configured,agentops eval initincludes those evaluator names in the azd recipe andagentops eval runfails closed outsideexecution: azd, so rubric scores cannot be treated as evidence unless Foundry / azd actually ran them. - Tutorials now carry rubric and observability proof into evaluation and CI/CD. The Travel Agent flow keeps the existing smoke recording through step 10, then upgrades the gate to multi-turn dataset rows, rubric thresholds, trace sampling/replay lineage, and CI/CD workflows that reuse the same eval contract.
- Local AI-assisted evaluators now support reasoning-model graders. When
AZURE_OPENAI_DEPLOYMENTpoints atgpt-5*,o1*,o3*, oro4*, AgentOps marks the Azure AI Evaluation evaluator model as reasoning-capable so the SDK sendsmax_completion_tokensinstead of the unsupportedmax_tokens. agentops eval runno longer hides interactive azd prompts while appearing to hang. The azd backend now runsazd ai agent eval runand the follow-upshowcommand with--no-promptand a closed stdin, so any missing authentication/configuration fails visibly instead of waiting indefinitely.agentops eval initnow bootstraps the minimal azd prompt-agent context. For Foundry prompt-agent configs, the command creates missingazure.yamlandsrc/<agent>/agent.yamlfiles, enriches the active.azure/<env>/.envwith Foundry project metadata when it can resolve the project resource, and then generates the azd eval recipe. The prompt-agent quickstart now keeps the main path toagentops eval initfollowed byagentops eval run, while still usingazd ai agent evalunder the hood.agentops workflow analyzenow tells azd eval users to runagentops eval initfirst. When an azd eval recipe is selected, the recommended commands and next steps now explicitly create or reuse the recipe before telling users to run the local eval gate.agentops eval runnow prints heartbeat feedback while azd is running. Longazd ai agent eval runcalls now show an immediate waiting message and periodic elapsed-time updates instead of leaving the terminal silent while Foundry completes the native evaluation.
- Prompt-agent tutorial now uses
azd ai agent evalas the standard eval path. Step 10 creates the minimal azd service context, records Foundry project metadata in the active.azure/<env>/.env, runsagentops eval init, and verifies the native azd eval backend withagentops eval run. agentops eval initnow prepares azd-compatible inputs for prompt-agent datasets. The wrapper writes an azd JSONL copy withqueryvalues derived from AgentOpsinput, passes absolute paths for azd service-project resolution, uses stable built-in evaluators by default, and decodes azd output safely on Windows.- AgentOps now normalizes the current azd preview eval output. The azd
runner reads text run IDs, exports details with
azd ai agent eval show --out-file, and converts per-criteria pass counts into aggregate metrics for the AgentOps threshold gate.
- AgentOps can now delegate Foundry eval execution to
azd ai agent eval. Projects with an azdeval.yamlrecipe can setexecution: azdandeval_recipe: eval.yaml; AgentOps invokes azd, normalizes emitted metrics intoresults.json, binds thresholds including Rubric/custom dimensions, and fails closed when configured thresholds do not map to emitted metrics. - Governance evidence support for ASSERT, ACS, and red-team readiness.
agentops.yamlcan referenceassert_path,acs_path, andredteam_path. Doctor, Cockpit, and release evidence record path, SHA-256 hash, status, and ACS checkpoint coverage without executing ASSERT, applying ACS controls, or exposing red-team payload text. agentops-governancecoding-agent skill. The new skill drafts safe evidence templates for ASSERT policies, ACS contracts, Guided Guardrail review notes, and red-team readiness plans while explicitly refusing offensive payload generation.
- Prompt-agent tutorial now explicitly verifies the Travel Agent dataset path
after
agentops init. Step 7 now tells users to confirmagentops.yamlpoints at.agentops/data/travel-smoke.jsonland provides a repair command if the wizard left the starter.agentops/data/smoke.jsonl. agentops eval initnow reuses configured prompt-agent inputs and avoids hidden azd prompts. When--datasetis omitted, the command passes the existingagentops.yamldataset toazd ai agent eval init. It also runs azd with--no-prompt, passes the configured Foundry project endpoint, agent name, prompt file, and bootstrap model, and prints a progress line before the potentially long Foundry initialization.- Prompt-agent tutorial guidance now keeps azd eval recipes advanced-only.
Step 10 now follows
workflow analyzefor the quickstart's AgentOps cloud eval path and explains thatagentops eval initrequires a full azd AI agent project context beforeazd ai agent eval runcan resolve the Foundry project. agentops eval initnow prints safely on Windows terminals without Unicode support. The CLI falls back to an ASCII updated marker instead of raising aUnicodeEncodeErroron cp1252 consoles after it wiresexecution: azdandeval_recipe.- Foundry RBAC preflight now prevents the portal build-agent permission
block. The prompt-agent, hosted-agent, and end-to-end tutorials plus the
packaged
agentops-evalskill now grantFoundry UserandCognitive Services OpenAI Useron the parent AI Services account using stable role IDs. This covers the Foundry UI's "You don't have permission to build agents" failure as well as the evaluator chat-completions data-plane failure, while still assigning the OpenAI role to Foundry/Azure AI managed identities used by server-side graders.
agentops initnow handles blank required wizard values gracefully. If the user presses Enter without an existing Foundry endpoint or agent default, the wizard explains that AgentOps needs the missing value and re-prompts instead of proceeding to a later persistence failure. Scripted blank flags such as--agent ""now exit with the same friendly message and no traceback.agentops initno longer depends on undeclared PyYAML. The setup wizard now reads and writesagentops.yamlthrough the repository'sruamel.yamlhelpers, fixing the uglyNo module named 'yaml'traceback seen in clean installs.
- AgentOps brand tagline sequence now reads
Evaluate :: Ship :: Observe :: Own. The startup/explain banner now matches the intended product story order.
- RBAC preflight now covers Foundry/Azure AI managed identities, not only
the signed-in user. Cloud evaluations run server-side and some agent or
grader calls authenticate as the managed identities on the backing AI
Services account and child Foundry project. Granting
Cognitive Services OpenAI Useronly to the user still allowed intermittent graderAuthenticationErrorfailures and the v0.3.6 execution warning. The prompt-agent, hosted-agent, and end-to-end tutorials plus theagentops-evalskill now assign the same data-plane role to every managed identity in the Foundry resource group, preventing the warning/failure path beforeagentops eval run.
agentops eval runnow distinguishes a grader execution failure from a quality-gate failure. When evaluator workers error out on a subset of rows (auth/RBAC/timeout), no row has every grader return a score, soitems_passed_allis0and the run reportsThreshold status: FAILEDeven though every threshold that could be computed passed. The CLI now detects this case (errored graders combined with all thresholds passing) and prints aWarningexplaining that this is an execution error, not a quality regression, names the most common cause (data-plane RBAC granted moments earlier that is still propagating to the evaluator workers), surfaces the first underlying grader error, and advises waiting a few minutes before re-running. The exit-code contract is unchanged. Added the_grader_error_summaryhelper plus focused unit tests.- Corrected the RBAC propagation guidance in the tutorials and the
agentops-evalskill. Data-plane role assignments on Cognitive Services accounts can take several minutes (not 30-120 seconds) to reach the independent, per-row evaluator workers, which can produce an intermittentFAILEDwith otherwise-green thresholds on the first run after granting access. The prompt-agent, hosted-agent, and end-to-end tutorials and the skill now describe this symptom and tell readers to wait and re-run rather than lower thresholds.
agentops-evalcoding-agent skill now preflights the data-plane RBAC step that the Foundry portal does not assign by default. Creating a Foundry project through the portal only grants the userFoundry Userat the project scope, which does not coverMicrosoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/actionon the parent AI Services account where chat completions actually live. SubscriptionOwneris also insufficient because the built-inOwnerrole definition hasactions: ["*"]butdataActions: []. The firstagentops eval runagainst a fresh workspace therefore failed withPermissionDeniedon every AI-assisted evaluator and every cloud-eval grader. The skill's new Step 0.5 - Ensure data-plane RBAC on the AI Services account resolves the Foundry project endpoint from.azure/<env>/.envor.agentops/.env, looks up the backing AI Services account + resource group withaz cognitiveservices account list, fetches the signed-in object ID withaz ad signed-in-user show, and runs an idempotentaz role assignment createforCognitive Services OpenAI Userat the resource-group scope before handing off toagentops eval analyze. This keeps the skill experience consistent with the new manual instructions added to the prompt-agent, hosted-agent, and end-to-end tutorials, so users running the skill against a fresh Foundry project no longer hit the same 401 the manual tutorials previously hid.
agentops eval runin local execution mode no longer fails withMissing environment variables: AZURE_OPENAI_ENDPOINTwhen only the Foundry project endpoint is configured.CONTRIBUTING.mdand the user-facing env-var docs both stated thatAZURE_OPENAI_ENDPOINTis "auto-derived from the project endpoint when absent", butpipeline/runtime.py::_model_configonly read the explicitAZURE_OPENAI_ENDPOINTenv var with no fallback — so a fresh workspace created byagentops init(which writesAZURE_AI_FOUNDRY_PROJECT_ENDPOINTbut notAZURE_OPENAI_ENDPOINT) would always trip the missing-env error the first time AI-assisted evaluators tried to run locally. The new helperagentops.utils.azure_endpoints.derive_openai_endpoint_from_projecttrims the trailing/api/projects/<name>segment from a Foundry project URL (covering bothservices.ai.azure.comand the legacycognitiveservices.azure.comhosts) to recover the AI Services account base URL, which is exactly what theopenaiandazure-ai-evaluationSDKs want._model_confignow uses the derived value as a fallback wheneverAZURE_OPENAI_ENDPOINTis unset, so the documented behavior finally matches the runtime. WhenAZURE_OPENAI_DEPLOYMENTis the only thing missing, the error message now points users at the deployment list in the Foundry portal and mentions theexecution: cloudescape hatch inagentops.yamlso the next step is obvious without leaving the terminal.
-
Runtime dependencies now have upper bounds so a future SDK major release cannot silently break installs.
pyproject.tomlpreviously declared every Azure-SDK dependency with only a lower bound (e.g.azure-ai-projects>=2.0.1), sopip install agentops-acceleratorcould resolveazure-ai-projects 3.xthe day after that ships and break the agent-definition serialization (the exact failure mode that produced theinvalid_payload — Required properties ["kind"] are not presentregression below). Each Azure SDK dependency (azure-ai-projects,azure-ai-evaluation,azure-identity,azure-monitor-*,azure-mgmt-*) is now constrained to its current major.pandas,fastapi,uvicorn,httpx, andmarkdownare similarly capped to their next major.cryptographyis intentionally left unbounded so security patches can flow through without a coordinated AgentOps release. Lift any of these bounds via an explicit PR that exercises the new SDK againsttests/. -
agentops workflow generatenow stamps the installed agentops version into generated CI/CD templates instead of always installing fromgit+...@main. Every generatedagentops-pr.yml,agentops-deploy-*.yml,agentops-watchdog.yml(and their Azure DevOps pipeline equivalents) used to containpip install "agentops-accelerator[...] @ git+https://github.com/Azure/agentops.git@main", with no version pin and a stale "NOTE: pinned to GitHub main until the next package release" comment. User CI runs were therefore non-reproducible: the same workflow file pulled different agentops snapshots day to day, which is how PO's recorded tutorial took a hard SDK regression mid-record. The generator now writes a literal==X.Y.Zpin derived from the agentops version currently installed on the machine runningagentops workflow generate— so a user who generates workflows against AgentOps0.3.3always installsagentops-accelerator==0.3.3on every CI run, andagentops-acceleratorbrings exact-major Azure SDKs along (per the upper bounds above). Editable installs (versions carrying a local segment like+gabcdefor marked.devN) keep the@mainfallback so contributors testing template changes still get a resolvable install. Existing user workflows are unaffected until the user re-runsagentops workflow generate --forceagainst a release of AgentOps that ships this change.
- Doctor regression check no longer flags the previous PR run as "current"
in CI. The results-history loader (
agent/sources/results_history.py) was reading the wrong fields fromresults.jsonand excluding.agentops/results/latest/from the candidate list. Three coordinated schema-alignment fixes restore correctness:_summarizenow reads top-levelaggregate_metricsfirst (the field the orchestrator actually writes, percore/results.py), then falls back to legacymetrics/run_metrics. Previously the loader looked only at the legacy fields, so every freshly-written localRunSummaryhadmetrics = {}and the regression check could never see the current run's metrics._summarizenow readssummary.overall_passedfirst when deriving therun_passflag, then falls back to the legacysummary.run_pass/metrics.run_passshapes._summarizenow orders runs bytimestamp→finished_at→started_at→created_at→summary.timestamp. The previous list omittedfinished_at/started_at, which are the two fieldsresults.jsonactually contains, so every loaded run defaulted to epoch-zero ordering._collect_local_runsnow includes.agentops/results/latest/when it is the only local results directory. In CI, generated workflows runagentops eval run --output .agentops/results/latestand write nowhere else; the old loader unconditionally skippedlatest/for dev-mode dedup, so in CIlocal_runswas always empty. With cloud listing trailing behind by seconds (eventual consistency), the regression check would then computelatest = previous_runand blame the just-completed candidate's coherence/groundedness on the prior PR. Dev-mode dedup is preserved: when a timestamped sibling exists,latest/is still skipped.
- Prompt-agent deploy:
stageno longer fails withRequired properties ["kind"] are not presentagainstazure-ai-projects2.x._copy_definitionpreviously called.copy()on the typedPromptAgentDefinitionreturned byget_version. In SDK 1.x that preserved the typed model so the body serialized as a flat{"kind": "prompt", "model": ..., "instructions": ...}. In SDK 2.x the same.copy()returns a stripped baseModelwhose JSON shape is{"_data": {"kind": "prompt", ...}}, and.get("kind")returnsNone— so the request body that reached the Foundry Agents service containeddefinition: {"_data": {...}}with no top-levelkind, and the service rejected it withinvalid_payload. This regression only fired on thecreatedaction path (i.e. when the user's prompt differed from the seed); thereusedand bootstrap paths were unaffected because they don't round-trip the typed model through.copy()._copy_definitionnow normalizes any SDK definition object to a plaindictbefore mutation, and_create_agent_versionno longer puts a root-levelkindon the request body (the new API treatskindstrictly as the discriminator insidedefinition). - Tutorial: prompt-agent step 13 now shows the steady-state
foundry-agent.json(action: reused) instead of the bootstrap edge case. The example JSON in step 13 previously showedaction: bootstrappedwithcandidate_agent: "travel-agent:1"and a "the two numbers are expected to differ until the environment has caught up to the seed" explanation. In practice the merge-triggered deploy is almost never the run that bootstraps — by the time the user reaches step 13, the skill's verification dispatch in step 12 plus the first PR run have already settled dev totravel-agent:2, so the merge deploy reportsaction: reusedwithcandidate_agent: "travel-agent:2"(matchingsource_agent). The example now shows the steady-state shape (taken from a real recording), uses the runner-resolved absolute paths the user actually sees (/home/runner/work/<your-repo>/...), and uses a real 64-charprompt_sha256+ a real ISO timestamp. The three-outcome list (reused/created/bootstrapped) below the JSON keeps the bootstrap case as the documented edge condition. - Tutorial: prompt-agent step 13 now matches what the workflow skill actually does (dispatches both workflows).
PR #211 mistakenly narrowed the step 13 callout to say the workflow
skill only dispatches
agentops-pr.ymlas a verification run, based on incorrect reasoning aboutpush:triggers (the skill actually usesworkflow_dispatch, which works against any branch regardless of the workflow'spush:block). In practice — verified against a live recording — the skill dispatches bothagentops-pr.ymlandagentops-deploy-dev.ymlend-to-end as part of CI verification, asking the user to approve first per SKILL.md rule #14. The step 13 callout now reflects this and explains the expected outcome (both runs may exitthreshold_failedon first contact with an empty dev project because the bootstrap path produces a freshtravel-agent:1that has not been measured against the seed thresholds yet — by design, not a CI wiring failure). The "What you should see in the first PR workflow run" section also updates from the "dev is still empty" assumption (which becomes false after the skill's verification dispatch) to the three possible outcomes (reused/created/bootstrapped) you can actually see at this point. The "After the merge" paragraph now calls out that the merge-triggered deploy is the second deploy-dev run for the repo, not the first. - Tutorials: end-to-end audit caught misleading dist URLs, phantom CLI commands, missing JSON fields, and stale Doctor advisory text.
All three tutorials previously installed the development build from a
personal fork URL (
git+https://github.com/placerda/agentops.git@develop); they now point at the canonicalgit+https://github.com/Azure/agentops.git@develop. The prompt-agent tutorial referenced a non-existentprompt_deploy recordsubcommand in two places — the actual command isprompt_deploy summarize, matchingsrc/agentops/pipeline/prompt_deploy.pyand the deploy template'sMark candidate as deployedstep. The same tutorial'sfoundry-agent.jsonsample was missing theeval_configfield that the code writes atsrc/agentops/pipeline/prompt_deploy.py:186. The step 12 skill prompt and the step 13 prose did not tell the reader to rewrite the dev-deploy trigger fromdeveloptomainfor this trunk-on-maintutorial; the generator's stock default isdevelop, which would silently no-op after the first merge. Step 12 now instructs the skill to do the rewrite (and the bullet list of skill actions calls it out as a required step, with a manual-edit fallback). Step 13's "deploy fires automatically onmain" sentence now states the dependency on the step 12 rewrite explicitly, and the placeholder phrase "your trunk branch" is now disambiguated as "mainin this tutorial". The end-to-end tutorial's step 5 and step 9 Doctor descriptions still read as if Doctor were advisory-only in PR workflows — that text predates the--doctor-gate criticaldefault; both blocks now describe the actual behavior (critical findings block the PR by default; warning/info are evidence-only).
- Tutorials: skip-if-skill callouts now state the skill's outcome directly and accurately.
The
step 13callout indocs/tutorial-prompt-agent-quickstart.mdand the baseline-run paragraph indocs/tutorial-end-to-end.mdpreviously opened with "if you used the workflow skill, this is already done…" plus a manual-fallback block. That conditional framing was confusing because the preceding step (step 12of the prompt-agent tutorial,step 5of the end-to-end tutorial) only documents the workflow-skill path — there is no alternative wired-by-hand path the reader could have taken. Both callouts now state the skill's outcome directly, and the redundantgit add/commit/pushandgh workflow run agentops-pr.yml --ref mainblocks have been removed (the skill already triggers the first run). A smallgh run list/gh run watchsnippet remains as an opt-in way to wait on the run from the terminal instead of the Actions UI. The previous wording also over-claimed that the skill triggered verification runs of bothagentops-pr.ymlandagentops-deploy-dev.yml; the skill only dispatches the PR workflow as a sanity check (workflow_dispatch), whileagentops-deploy-dev.ymltriggers on the first real merge into the trunk branch. The callout now reflects this accurately and notes that the deploy-dev run happens at the end of the section, not during the skill's setup.
- Tutorials now flag the workflow skill's setup actions as redundant in the manual follow-up steps.
When users run the
agentops-workflowskill in the CI-wiring step of either the prompt-agent tutorial (step 12) or the end-to-end tutorial (step 5, the same skill invocation that precedes the baseline-run step), the skill already commits the workspace, pushesmainto GitHub, and triggers a first verification run ofagentops-pr.yml(andagentops-deploy-dev.ymlfor the prompt-agent flow). The next step previously asked users to repeat all three actions, which was a no-op at best and confusing at worst (thegit addwould find nothing to commit, thegit pushwould report up-to-date, the dispatched PR run would be the second one, not the first). Step 13 ofdocs/tutorial-prompt-agent-quickstart.mdand the baseline-run paragraph indocs/tutorial-end-to-end.mdnow open with an explicit "if you used the workflow skill above, this is already done" callout and reframe the manual commands as a fallback for users who skipped the skill or wired CI by hand. The deliberate baseline-PR step that follows (open a feature branch, open a PR, merge once green) is unchanged — it must still go through a real pull request, which the skill does not do for you, so that the rolling Doctor history is seeded. - Tutorial wording: "quickstart" → "tutorial", "workshop" → "tutorial".
The three documentation entries that were labeled "Prompt Agent quickstart",
"Hosted Agent quickstart", and "End-to-end workshop" now read as "Foundry
Prompt Agent tutorial", "Hosted or HTTP Agent tutorial", and "End-to-end
tutorial" across
README.md,plugins/agentops/README.md,AGENTS.md,docs/concepts.md,docs/doctor-explained.md, theagentops-workflowskill (both synced copies), and the H1s + cross-references inside each tutorial doc. The README description for the end-to-end tutorial now also states explicitly that it extends either of the type-specific tutorials (sandbox → dev → qa → prod plus Foundry red-team scans plus trace-to-regression promotion) so the difference between the three is obvious at a glance. The "quickstart" framing no longer fits doc bodies that grew past 1000 lines covering multi-environment promotion, regression injection, Doctor evidence, and Cockpit. The tutorial filenames are intentionally preserved (tutorial-*-quickstart.md) to keep inbound links and bookmarks stable. - Skill + tutorial guidance now require
Cognitive Services OpenAI Useras a prerequisite RBAC role. Theagentops-workflowskill,tutorial-prompt-agent-quickstart.md,tutorial-end-to-end.md, anddocs/ci-github-actions.mdnow instruct users to grant the OIDC/CI service principal both Foundry User on the Foundry project and Cognitive Services OpenAI User on the underlying Azure AI Services account that hosts the evaluator model deployment. Foundryazure_ai_evaluatorgraders impersonate the OIDC principal to call OpenAI; without the OpenAI User role they fail with a 401PermissionDeniedand every cloud eval metric returnsnull, blocking the first PR run. The skill now emits the matchingaz role assignment createcommands for both roles (role ids53ca6127-db72-4b80-b1b0-d745d6d5456dand5e0bd9bd-7b93-4f28-af87-19fc36ad61bd) before dispatching the workflow.
agentops init --azd-env <name>no longer pre-fills the endpoint from a different env. When the user explicitly targets a new azd env (e.g.--azd-env devwhile the active env issandbox), the wizard now refuses to pre-fillAZURE_AI_FOUNDRY_PROJECT_ENDPOINTfrom sources that don't match the targeted env — process environment, legacy top-levelproject_endpoint:inagentops.yaml, or a different.azure/<env>/.envfile. Instead it prompts with no default and prints a short note explaining where the suspect default came from (e.g. "the active azd envsandbox's.azure/sandbox/.env"). This stops the silent sandbox→dev endpoint leak that surfaced when users ran the multi-env tutorials; values picked up from the targeted env's own.azure/<env>/.envare still honored. The strict check only fires when--azd-envis passed explicitly — bareagentops initkeeps its existing best-effort default behavior.- Cloud eval surfaces grader execution errors instead of silent nulls.
When a Foundry
azure_ai_evaluatorgrader fails to execute (most commonly because the evaluator service principal lacksCognitive Services OpenAI Useron the target model deployment), the per-metricscorecomes backnulland the real cause is buried inresult.sample.error.message. The cloud-results parser now lifts that message intoRowMetric.error(including the errorcodeprefix when present), so the actionable error appears inresults.jsonandreport.mdinstead of operators only seeingactual=missingin the threshold table. The orchestrator's "0 usable metric scores" warning also quotes the first grader error so CI logs carry the signal without operators having to download the raw artifact.
cloud_output_items.jsonis now uploaded as a CI artifact. Generated PR and deploy workflows (GitHub Actions and Azure DevOps) include.agentops/results/latest/cloud_output_items.jsonin theagentops-*-resultsartifact bundle alongsideresults.json,report.md, andcloud_evaluation.json. Pairs with the "0 usable scores" warning so operators can diagnose unrecognized Foundry grader shapes without re-running locally.cloud_output_items.jsonraw dump. Every cloud eval run now writes the rawoutput_itemsit received from Foundry to<output_dir>/cloud_output_items.json, in addition to the parsedresults.json. When a future grader / SDK upgrade changes the on-the- wire shape and the parser stops finding scores, the artifact bundle alone is enough to triage the issue. The orchestrator also emits an explicit warning to the progress channel when a cloud run yields zero usable metric scores despite returning rows, pointing the user at the new dump file..gitattributespinning*.yml/*.yaml/*.sh/*.md/*.pyto LF line endings, preventing future CRLF↔LF churn from Windows clones withcore.autocrlf=true. Normalizes the existing_build.ymlandci.yml(previously CRLF) to LF so all files in.github/workflows/share a single line-ending convention.
- Retired tombstone publish jobs from CI. The
agentops-toolkit→agentops-acceleratordeprecation tombstones were one-shot publishes for v0.3.0 / v0.3.1; thebuild-pypi-tombstone,publish-tombstone-testpypi,verify-tombstone-testpypi,publish-tombstone-pypi, andpublish-tombstone-vsix(-prerelease)jobs (plus theircut-release.ymlplugin-version sync steps) have been removed fromrelease.yml,staging.yml, andcut-release.yml. Thegithub-releasejob now depends only onpublish-pypiandpublish-vsix(both required), and the deadalways()guard has been dropped. Future releases ship onlyagentops-acceleratoron PyPI and theAgentOpsAccelerator.agentops-acceleratorVSIX. The orphanedscripts/verify_tombstones.pyharness anddocs/verifying-tombstones.mdchecklist (both one-shot tools whose CI counterpart no longer exists) have been removed, along with the now-unusedtombstones/pypi/package source and thetombstones/vscode/extension source — onlytombstones/vscode/CDN_DEPRECATION_REQUEST.mdsurvives as the template for the still-pending Microsoft CDN deprecation request.
- Cloud-eval parser no longer returns null scores for Foundry
azure_ai_evaluatorgraders. The parser now probes a wider set of score-carrier keys (score,value,result,metric_value,rating,grader_score,numeric_value), falls back topassed(bool) and thenlabel("pass"/"fail"strings), and descends intosample/detailsas a final resort. Treatsscore: 0as a legitimate value (was previously coerced toNonein some paths). Without this fix, every metric in a Foundry cloud run came backvalue: nullagainst the real on-the-wire shape — thereport.mdthreshold table showed every metric asactual=missingand exit code 2 fired withThreshold status: FAILEDeven when the run itself succeeded.
- Auto-bootstrap empty Foundry projects on first deploy. New optional
prompt_agent_bootstrapblock inagentops.yamllets the prompt-agent deploy workflow create the first version of an agent in a dev / qa / prod Foundry project that does not yet have one. When the stage step looks up the seed agent and gets a 404, it reads the model deployment (required) plus optionaldescription,model_parameters, andtoolsfromprompt_agent_bootstrap, combines them withprompt_file, and creates the first version automatically. The deployment artifact records the newaction: "bootstrapped"for that first run; subsequent deploys follow the normal reuse / next-version flow. Eliminates the previous per-environment manual seeding step.agentops workflow analyzenow warns when a prompt-agent workspace is missing this block. Authentication (401 / 403) and other non-404 errors continue to propagate — the bootstrap path only triggers on a genuine "agent does not exist" 404. --doctor-gateflag onagentops workflow generate. New option--doctor-gate critical|warning|nonecontrols the Doctor severity floor in the PR workflow template. Default iscritical, which makes the PR Doctor step block on critical Doctor findings (notably theregression.<metric>checks that fire when an evaluator metric drops meaningfully from the rolling baseline). This catches drift such as groundedness moving from 5.0 to 4.0 even when the configured eval thresholds technically still pass.--doctor-gate warningblocks on warnings or higher;--doctor-gate nonerestores the pre-1.x advisory behavior. Only the PR template is affected — deploy templates continue to run with--severity-fail criticalregardless.- Stage-then-eval PR workflow for Foundry prompt agents. When
--deploy-mode prompt-agentis in effect,agentops workflow generate --kinds prnow emits a PR workflow (and Azure DevOps pipeline) that stages an ephemeral Foundry candidate prompt-agent version fromprompt_filein the dev Foundry project, then evaluates that exact candidate (instead of the seed agent pinned inagentops.yaml). This makes the PR gate meaningful for prompt-agent flows: regressions are caught at PR time, not after merge. Candidates accumulate in the dev project across PRs and may need periodic cleanup.
-
Renamed PyPI distribution and VS Code publisher. The PyPI distribution name changed from
agentops-toolkittoagentops-accelerator, and the VS Code Marketplace publisher changed fromAgentOpsToolkittoAgentOpsAccelerator. The resulting extension ID flips fromAgentOpsToolkit.agentops-toolkittoAgentOpsAccelerator.agentops-accelerator. The Python import (import agentops) and CLI command (agentops ...) are unchanged — only the install/distribution identifier changed. Install withpip install agentops-acceleratororuv pip install agentops-accelerator. Two deprecation tombstones are published atomically with this release so existing users are guided to the new identifiers:- PyPI tombstone:
pip install agentops-toolkitkeeps working via a metapackage attombstones/pypi/that pinsagentops-accelerator>=0.3.0(no shadow code, no auto-discovery). The package long-description on PyPI links to the migration instructions. - VS Code Marketplace tombstone: a final
AgentOpsToolkit.agentops-toolkitextension attombstones/vscode/activates with a one-time prompt offering to installAgentOpsAccelerator.agentops-accelerator(or open the Marketplace page in a browser). A per-install storage sentinel prevents re-prompts after the user resolves it.
The release tag (
v0.3.0) drives all four publishes (agentops-accelerator + agentops-toolkit on PyPI, plus the new and legacy VSIX publishers) through gated jobs inrelease.yml. The tombstones are gated AFTER the corresponding main publish jobs so the worst-case failure mode is "tombstone delayed, recoverable in v0.3.1" — never "tombstone-without-new". (#181) - PyPI tombstone:
-
Default PR Doctor behavior is now blocking. Generating workflows without
--doctor-gateproduces a PR template that blocks on critical Doctor findings. Existing workflows continue to work unchanged; only re-generated workflows pick up the new default. To opt back into the previous advisory behavior, runagentops workflow generate --doctor-gate none --force. -
--deploy-mode prompt-agentnow changes the generated PR workflow. Re-runningagentops workflow generate --deploy-mode prompt-agent --kinds pr,dev,qa,prod --forceproduces a different PR template than before (it now stages a Foundry candidate before evaluating). Other modes (auto,placeholder,azd) continue to produce the previous generic PR template. -
Prompt and hosted agent eval defaults now use judge-based response completeness instead of token-overlap F1, keeping F1 as the default for exact-reference
model:<deployment>checks or explicit evaluator overrides.
- Editable install cleanup after rebrand. Developers with an
existing local editable install (
uv pip install -e .orpip install -e .) may have a stalesrc/agentops_toolkit.egg-info/directory or staleimportlib.metadataentries pointing to the old distribution name after pulling this release. Clean up with:rm -rf src/*.egg-info && uv pip install -e .(orrm -rf src/*.egg-info && pip install -e .for pip). This is a one-time, dev-only step; CI runs are unaffected because they create fresh virtual environments, and end users installing from PyPI are unaffected because wheels carry the newdist-infodirectory directly. (#181)
- Release workflow verification. Release builds now pin package versions from the release tag, assert the generated distribution matches that version, and fail TestPyPI verification immediately when the expected package is not available.
- Consolidated the tutorial set into two quickstarts plus one end-to-end Foundry + AgentOps workshop, with the quickstarts now covering the broader Foundry build/debug/evaluate/observe journey before AgentOps readiness.
- Made the quickstarts self-contained around a Travel Agent example, including prompt-agent creation, hosted HTTP endpoint creation, and travel-specific eval datasets without local workspace install paths.
- Updated the tutorials to prefer the interactive
agentops initwizard, explain evaluator deployment separately from initialization, and include forced regression/fix loops for prompt and hosted agent paths. - Re-ask starter
agentanddatasetvalues during the first interactiveagentops initrun so tutorial users replacemy-agent:1with their target. - Removed the interactive App Insights question from
agentops init; runtime commands discover it from the Foundry project when possible, and--appinsights-connection-stringremains available for explicit setup. - Made
workflow analyzeoutput use a lighter PowerShell-friendly summary, Markdown tables, and user-facing Foundry eval labels; also removed a non-actionable latency warning from the normal analysis output. - Made
workflow generatenext steps gentler for PowerShell and tutorial users: PR/watchdog-only output now asks for only thedevenvironment, explains that deploy setup can wait, and points users to Copilot-assisted GitHub/OIDC setup.
- Doctor App Insights discovery. The
azure_monitorsource now falls back to an App InsightsApplicationIdfromAPPLICATIONINSIGHTS_CONNECTION_STRINGor Foundry project telemetry discovery, so Doctor no longer reports runtime telemetry as unconfigured when Cockpit can already resolve App Insights.
- Release evidence packs. Added the release evidence schema and Doctor evidence-pack writer so teams can produce review-ready production promotion artifacts from existing readiness signals.
- Trace promotion workflow. Added trace export promotion into reviewable dataset candidates so production learnings can become future regression coverage.
- Workflow analysis and prompt-agent deployment templates. Added CI/CD analysis plus GitHub Actions and Azure DevOps templates for prompt-agent deployment paths.
- Production readiness guidance. Added the production readiness tutorial and release-readiness Doctor checks to connect evaluation gates, evidence, and deployment readiness.
- Pre-flight checks for
agentops eval run- detects common issues (missingazure-identityorazure-ai-evaluationpackages, missing env vars for AI-assisted/safety evaluators, Azure credential failures, unreachable endpoints) before backend execution. All detectable issues are reported at once with actionable error messages andpip installhints. --dry-run/-nflag oneval run- runs pre-flight checks without executing the evaluation. Exits 0 if all checks pass, 1 otherwise. Useful for CI gating and fast feedback.- Credential warm-up in pre-flight - acquires and caches the MSAL token once during pre-flight so subsequent evaluator calls don't each cold-start
az.cmd.
- AgentOps 1.0 workspace and documentation refresh. Updated the CLI,
templates, skills, examples, and docs around the flat
agentops.yamlworkflow, azd-compatible initialization, Doctor/Cockpit readiness, and production evaluation loops. AZURE_OPENAI_ENDPOINTis now auto-normalized. When the env var includes the portal-style inference-path suffix (e.g.https://<resource>.openai.azure.com/openai/v1,/openai/,/openai/deployments), AgentOps strips it before passing the value to theazure-ai-evaluationSDK and theopenaiclient. Trailing slashes are also trimmed. The user can paste whichever URL the Foundry portal showed and the eval pipeline now works transparently.- Doctor categories aligned to WAF-AI pillars (breaking). The
genaiopscategory was renamed tooperational_excellenceto match the Microsoft Well-Architected Framework for AI pillar names. Every doctor finding id with thegenaiops.prefix was renamed toopex.(the WAF checklist, cockpit rows, report grouping, and CLI--categoriesflag are now all named consistently). Thechecks/mlops.pymodule was renamed tochecks/opex_workspace.pyand its functionrun_mlops_checktorun_opex_workspace_check. A read-only legacy-id shim (agentops/agent/_legacy_ids.py) rewrites legacygenaiops.*rule ids inchecks.llm_assist.rulesand legacy--categories genaiopsflags in memory at load time with a one-shot deprecation warning; update your config to the canonical names - the legacy aliases will be removed in a future release. - Azure CLI credential timeout raised to 30s - all
DefaultAzureCredentialinstantiation sites (eval_engine.py,foundry_backend.py) now passprocess_timeout=30. Default (10s) is insufficient for Windowsaz.cmdcold starts and was causing intermittentAzureCliCredential: Failed to invoke the Azure CLIerrors.
- Single source of truth for skills (closes #87) -
src/agentops/templates/skills/is now the canonical location. Addedscripts/sync-skills.shandscripts/sync-skills.ps1to propagate changes toplugins/agentops/skills/. CI testtest_skills_sync.pyfails if the two directories diverge. - Optional unit test generation -
agentops-evalskill (Step 1) now offers to generate unit tests for agent code when no existing tests are detected. Generatespytest+unittest.mocktests covering endpoint handlers, response parsing, and error handling. Opt-in only - skips silently if tests already exist or user declines.
- Cross-platform subprocess handling in generated scripts -
agentops-evalandagentops-datasetskills now instruct generatedrag_context.pyscripts to useshutil.which()+shell=(sys.platform == "win32")when calling external CLIs, preventingFileNotFoundErroron Windows. - Auth detection carrythrough to callable adapter -
agentops-evalskill Step 5.5 now explicitly wires the auth pattern detected in Step 2 into the adapter using genericAGENT_AUTH_HEADERandAGENT_AUTH_TOKENenv vars. Updatedcallable_adapter.pytemplate to use the same generic auth mechanism. Prevents 401 errors on first smoke test. - azd environment validation -
agentops-eval(Step 4) andagentops-config(Step 3) skills now validate azd environments before trusting.azure/<env>/.envvalues: checksazd env list, verifies resource group exists viaaz group exists, and warns on stale environments. - Enhanced smoke test diagnostics -
agentops-evalskill Step 6 smoke test now checks for empty responses, response length, response format mismatches (JSON vs SSE), unexpected prefixes (UUIDs), and HTML error pages. Expanded troubleshooting table with specific remediation steps. - Updated CONTRIBUTING.md - added single-source-of-truth rule for skills and sync script instructions.
- Unified changelog - removed separate
plugins/agentops/CHANGELOG.md; CI now copies the root changelog into the VSIX package. Single source of truth for both CLI and extension. - Removed
[Unreleased]changelog pattern - changelog entries are now added directly under versioned sections. - Configured Dependabot - added
.github/dependabot.ymltargetingdevelopfor pip, GitHub Actions, and npm ecosystems.
- Make release pipeline resilient to VSIX version conflicts - add
continue-on-erroron VSIX publish and decouple GitHub Release from VSIX publish result, preventing staging pre-release "already exists" failures from blocking the release. - Resolve 31 mypy type errors and enforce mypy in CI - strict type checking added to the
lintjob (mypy --strict src/), fixing errors acrossfoundry_backend.py,eval_engine.py,reporter.py,runner.py,comparison.py, andbrowse.py. - Resolve 18 ruff lint errors (F401 unused imports, F811 redefinition, F841 unused variables) across 6 source and test files.
- Fix UV cache race condition in CI - disable UV cache on non-matrix jobs (lint, coverage, publish-dev) that shared cache keys with the test matrix, eliminating
Failed to save: Unable to reserve cachewarnings.
- Upgrade GitHub Actions to Node.js 24 runtimes - update
actions/checkoutto v6,actions/setup-pythonto v5,astral-sh/setup-uvto v7,actions/upload-artifactanddownload-artifactto v7 across all CI/CD workflows. - Apply ruff-format across source and workflows - normalize code style and whitespace across backends, services, CLI, tests, and workflow YAML files.
- Resolve all 37 mypy type errors across 6 source files (
foundry_backend.py,config_loader.py,reporter.py,browse.py,comparison.py,runner.py). - Fix VSIX version derivation in CI/CD workflows - use global tag sort (
git tag -l --sort=-v:refname) instead ofgit describewhich misses tags not reachable from the current branch.
- Auto-registration of skills in coding agent instruction files -
agentops skills installnow registers installed skills in the coding agent's instruction file so AI assistants discover them automatically. For Copilot: appends an idempotent marker-delimited block to.github/copilot-instructions.mdwith a skill discovery table. For Cursor: writes a managed.cursor/rules/agentops.mdcfile withalwaysApply: true. Repeated runs update the block in place (no duplicates). - Cursor platform detection -
detect_platforms()now recognises.cursor/rules/directory or.cursorrulesfile as Cursor indicators. Cursor skills are installed to.github/skills/(shared with Copilot) and registered via.cursor/rules/agentops.mdc. - Underscore Copilot filename detection -
detect_platforms()now silently acceptscopilot_instructions.md(underscore variant) as a valid Copilot signal alongside the standardcopilot-instructions.md. agentops skills installcommand - Installs packaged coding agent skills into consumer projects. Supports GitHub Copilot (.github/skills/), Cursor (.github/skills/), and Claude Code (.claude/commands/). Auto-detects platforms; falls back to GitHub Copilot silently. Pass--promptto ask before installing when no platform is detected. Pass--platformfor explicit platform selection.- Packaged skill templates under
src/agentops/templates/skills/for distribution viapip install. - Extend Foundry cloud evaluation to support 22 built-in evaluators (up from 8), covering quality, agent, safety, RAG, tool, and NLP evaluator categories.
- Add dynamic
item_schemabuilding - automatically includestool_definitionsandcontextfields when the enabled evaluators require them. - Fix NLP evaluator names in frozensets to match
_to_builtin_evaluator_nameconversion (bleu_score,rouge_score,gleu_score,meteor_scoreinstead ofbleu,rouge,gleu,meteor). - Add default
initialization_parametersforRougeScoreEvaluator(rouge_type: rouge1). - Add optional OTLP tracing for evaluation runs - set
AGENTOPS_OTLP_ENDPOINTto emit OpenTelemetry spans.- Three-layer schema: CICD semconv (pipeline run/task), GenAI semconv (agent invocation), and
agentops.eval.*(evaluator scores/thresholds). - Per-row item spans with evaluator child spans showing score, threshold, and pass/fail.
- Zero overhead when
AGENTOPS_OTLP_ENDPOINTis unset; graceful no-op whenopentelemetry-sdkis not installed.
- Three-layer schema: CICD semconv (pipeline run/task), GenAI semconv (agent invocation), and
- Browse commands:
agentops bundle list,agentops bundle show,agentops run list,agentops run showfor workspace inspection.
- Skills optimized for weaker models - Rewrote all 8 SKILL.md files to reduce cognitive load and token usage. Key changes: replaced prose paragraphs with numbered single-action steps and tables, removed boilerplate ("Before You Start", "When to Use", "Purpose" sections), inlined decision logic into steps (no disconnected decision trees), provided one copy-paste callable adapter template instead of multiple variants, consolidated rules into a single section per skill. Size reductions:
agentops-eval613→275 lines (−55%),agentops-config229→170 (−26%),agentops-report−35%,agentops-regression−35%,agentops-monitor−53%,agentops-trace−55%,agentops-workflow−38%,agentops-dataset−11%. - Skills discovery improvements -
agentops-evalandagentops-configskills now auto-discover container app URLs (az containerapp list) and webapp URLs (az webapp list), detect auth patterns from codebase (Dapr, API key, Bearer), pre-warm Azure CLI tokens to prevent intermittentAzureCliCredential.get_token failederrors, and present all discovered values as a confirmation table instead of asking each one separately. - Report readability improvements -
report.mdand HTML reports now include: evaluator descriptions ("What It Measures" column), human-readable metric names (CamelCase split,_→ spaces), ✅/❌ visual indicators for pass/fail, merged threshold columns (>= 0.80instead of separate Criteria/Expected), clean number formatting (drop unnecessary decimal zeros), per-row score tables in Row Details, retrieved context display for RAG evaluations (truncated at 500 chars), "How Pass/Fail Is Determined" section, and one-sentence descriptions after each section heading. RowMetricsResultmodel updated - Added optionalcontextfield toRowMetricsResultfor RAG evaluation context display. All three backends (Foundry, HTTP, local adapter) now populate this field from dataset rows.- README restructured - Simplified Quickstart from 6 steps to 3. Moved evaluation scenarios, configuration model, and run config examples to new
docs/concepts.mdpage with ASCII architecture diagram. Removed Project Structure and Copilot Skills sections from README (available in CONTRIBUTING.md and tutorial-copilot-skills.md respectively).
docs/concepts.md- new conceptual overview page with ASCII evaluation flow diagram, core concept definitions (workspace, run config, bundle, dataset, evaluator, backend), evaluation scenarios table, and configuration model summary.
- CLI refactored to entity-verb pattern - All CLI commands now follow a consistent
<entity> <verb>structure:agentops report→agentops report generateagentops config cicd→agentops workflow generate(newworkflowentity)agentops monitor cockpit→agentops monitor showagentops monitor alert→agentops monitor configure
- Skills refactored into modular skills - 8 single-responsibility skills with
agentops-prefix:/agentops-eval(run evaluations),/agentops-config(infer scenario + generate run.yaml),/agentops-dataset(generate JSONL + YAML datasets),/agentops-report(interpret and regenerate reports),/agentops-regression(investigate score drops),/agentops-trace(tracing stub),/agentops-monitor(monitoring stub),/agentops-workflow(CI/CD setup). Decomposed the monolithicevalsskill into 4 focused skills. Each follows a standardized structure: Purpose, When to Use, Before You Start, Steps, Guardrails, Outputs. - Run config model - The configuration model uses an orthogonal
target/hosting/execution_modemodel. Configs missing aversionfield or containing a legacybackendkey are rejected with an actionable error message.targetsection withtype(agent|model),hosting(local|foundry|aks|containerapps),execution_mode(local|remote).- Remote endpoints configured via
target.endpointwithkind: foundry_agentorkind: http. - Local adapter configured via
target.local.adapter. - Bundle and dataset references support both
name(convention-based) andpath(explicit). executionsection withconcurrencyandtimeout_seconds.runsection for optionalnameanddescriptionmetadata.
- Backend resolution based on
execution_mode+endpoint.kind. BackendRunContextcarries fullRunConfig.publish_foundry_evaluation()takesendpoint_config: TargetEndpointConfig.
- Callable adapter mode for
LocalAdapterBackend- users can now specify a Python function (module:function) viatarget.local.callableinstead of spawning a subprocess. The function receives(input_text: str, context: dict) -> dictand must return{"response": "..."}. - Shared evaluation engine (
backends/eval_engine.py) - evaluator loading, instantiation, execution, scoring, and dataset utilities extracted fromfoundry_backend.pyinto a standalone module shared by all backends. - Starter templates:
callable_adapter.py(example callable function) andrun-callable.yaml(run config using callable mode), created byagentops init. - Starter conversational dataset:
smoke-conversational.yaml+smoke-conversational.jsonl, created byagentops init. - Tutorials:
tutorial-conversational-agent.md(Agent Framework conversational) andtutorial-agent-workflow.md(Agent Framework workflow with tools). LocalAdapterConfignow acceptsadapter(subprocess) XORcallable(module:function) - both backward-compatible and validated.- Local adapter backend (
local_adapter_backend.py) - uses a stdin/stdout JSON protocol per dataset row. TargetEndpointConfig,LocalAdapterConfig,TargetConfig,BundleRef,DatasetRef,ExecutionConfig,RunMetadata,OutputConfigPydantic models.- Bundle/dataset name-based resolution:
resolve_bundle_ref()andresolve_dataset_ref()inconfig_loader.py. - Config validation with actionable error messages for missing
versionor legacybackendkey. tests/fixtures/fake_adapter.py- stdin/stdout JSON echo adapter for integration tests.
SubprocessBackend(replaced byLocalAdapterBackend).agent_http_baselinebundle (replaced by scenario-specific bundles with HTTP runs).
- Evaluation bundles refactored - renamed to outcome-focused names and added explicit evaluator configs:
model_direct_baseline→model_quality_baseline- with explicitconfig(kind, class_name, input_mapping, score_keys) for all evaluators.rag_retrieval_baseline→rag_quality_baseline- with explicit evaluator config.agent_tools_baseline→agent_workflow_baseline- with explicit evaluator config.
- All run templates updated to reference new bundle names.
conversational_agent_baselinebundle - CoherenceEvaluator, FluencyEvaluator, RelevanceEvaluator, SimilarityEvaluator for chatbots and Q&A agents.safe_agent_baselinebundle - ViolenceEvaluator, SexualEvaluator, SelfHarmEvaluator, HateUnfairnessEvaluator, ProtectedMaterialEvaluator for content safety and responsible AI. Usesazure_ai_project(auto-injected fromAZURE_AI_FOUNDRY_PROJECT_ENDPOINT).- Safety evaluator backend support - auto-injects
azure_ai_projectfor safety evaluator classes, cloud evaluation data mapping, and default input mappings. docs/bundles.md- comprehensive bundle documentation with per-bundle sections, input mapping variables, and threshold reference.
-
HTTP backend (
type: http) - new evaluation backend for agents deployed outside Microsoft Foundry Agent Service, such as LangGraph, LangChain, OpenAI SaaS, Microsoft Agent Framework applications on Azure Container Apps (ACA), or any custom REST endpoint.- Calls the agent endpoint row by row via HTTP POST.
- Configurable via
url(inline) orurl_env(env var, recommended for CI). - Supports
request_field(prompt key, defaultmessage),response_field(response key with dot-path support, defaulttext),auth_header_env(Bearer token), andheaders(static headers). - Supports
tool_calls_fieldto extract tool call data from HTTP responses for agent-with-tools evaluators. - Supports
extra_fieldsto forward additional JSONL row fields (e.g.,session_id) in the request body. - Runs local evaluators (
exact_match,latency_seconds,avg_latency_seconds) and AI-assisted foundry evaluators (viaAZURE_OPENAI_ENDPOINT/AZURE_AI_MODEL_DEPLOYMENT_NAME). - All three scenarios (model-direct, RAG, agent-with-tools) supported via HTTP.
- No Foundry Agent Service dependency - works for multi-agent scenarios where the orchestrator exposes an HTTP endpoint.
-
Add
TargetEndpointConfigfields for HTTP:url,url_env,request_field,response_field,auth_header_env,headers,tool_calls_field,extra_fields. -
Enriched evaluation bundles with comprehensive predefined evaluators:
model_quality_baseline-SimilarityEvaluator,CoherenceEvaluator,FluencyEvaluator,F1ScoreEvaluator.rag_quality_baseline-GroundednessEvaluator,RelevanceEvaluator,RetrievalEvaluator,ResponseCompletenessEvaluator,CoherenceEvaluator.agent_workflow_baseline-TaskCompletionEvaluator,ToolCallAccuracyEvaluator,IntentResolutionEvaluator,TaskAdherenceEvaluator,ToolSelectionEvaluator,ToolInputAccuracyEvaluator.
-
Expanded cloud evaluator mappings:
_EVALUATORS_NEEDING_CONTEXTnow includesrelevanceandretrieval;_EVALUATORS_NEEDING_TOOL_CALLSnow includestool_selection,tool_input_accuracy,tool_output_utilization,tool_call_success. -
Added default input mappings for all new evaluators in
_default_foundry_input_mapping(). -
agentops initnow scaffolds HTTP scenario starter files:run-http-model.yaml- HTTP model-direct run config.run-http-rag.yaml- HTTP RAG run config.run-http-agent-tools.yaml- HTTP agent-with-tools run config (withtool_calls_field).bundles/agent_http_baseline.yamlremoved (replaced by scenario-specific bundles).
-
Add
docs/tutorial-http-agent.md- end-to-end tutorial for the Agent Framework / ACA scenario. -
Add unit tests for
HttpBackend(tests/unit/test_http_backend.py): URL resolution, request field, dot-path response extraction, latency metrics, auth header,backend_metrics.jsonschema. -
Implement
agentops eval compare --runs <baseline>,<current>for baseline comparison of evaluation runs.- Produces
comparison.json(structured metric deltas, threshold flips, item-level changes) andcomparison.md(human-readable report). - Exits with code
0(no regressions),2(regressions detected), or1(error). - Supports run IDs by timestamped folder name,
latestkeyword, or absolute/relative paths.
- Produces
-
Add Pydantic models for comparison output:
ComparisonResult,MetricDelta,ThresholdDelta,ItemDelta,ComparisonSummary. -
Add comparison service (
services/comparison.py) with run discovery and structured diff logic. -
Update
agentops-regressionandagentops-evalCopilot skills to reference the new compare command. -
Add distributable Copilot skills under
.github/plugins/agentops/skills/for GitHub-based installation (agentops-eval,agentops-config,agentops-dataset,agentops-report,agentops-regression,agentops-trace,agentops-monitor,agentops-workflow). -
Fix cloud evaluation to use the Foundry Project Evals API (
api-version=2025-11-15-preview) withazure_ai_evaluatortesting criteria, replacing the OpenAI SDK-based path that was incompatible. -
Fix metric polarity in comparison: lower-is-better metrics (e.g.
avg_latency_secondswith<=threshold) now correctly show "improved" when they decrease. -
Align
azure-ai-projectsversion references across all files to>=2.0.1.
- Migrate versioning from static
pyproject.tomlfield tosetuptools-scm- version is now derived automatically from git tags. - Redesign release pipeline into three workflow files:
_build.yml- reusable build workflow (test + package via setuptools-scm)staging.yml-release/*branch pushes publish to TestPyPI and verify installrelease.yml-v*tag pushes publish to TestPyPI, then PyPI (with approval gate), then create GitHub Release
- Add CLI smoke test in staging/release verify step (
agentops --version,agentops --help,agentops init). - Fix secret reference from
PIPY_TOKENtoPYPI_TOKEN; addTEST_PYPI_TOKENfor TestPyPI. - Add consistent workflow index header across all CI/CD workflow files.
- Add VSIX extension packaging and publishing to CI/CD pipeline; include Copilot skills in the VS Code Marketplace extension.
DatasetFormat.context_field- optional field to declare the JSONL column holding retrieved context documents; used byGroundednessEvaluatorin both cloud and local evaluation modes.TaskCompletionEvaluatorsupport in the Foundry backend: defaultinput_mappingand clouddata_mappingfor both cloud and local modes.ToolCallAccuracyEvaluatorsupport in the Foundry backend:_EVALUATORS_NEEDING_TOOL_CALLSset, clouddata_mapping(mapstool_callsfrom{{sample.tool_calls}}andtool_definitionsfrom{{item.tool_definitions}}), and localinput_mapping.agent_workflow_baselinebundle upgraded fromSimilarityEvaluatorplaceholder toTaskCompletionEvaluator+ToolCallAccuracyEvaluatorwith matching thresholds.smoke-agent-tools.jsonlenriched withtool_definitionsandtool_callsfields for all 5 rows.- Unit tests covering
_cloud_evaluator_data_mapping(context_field, task_completion, tool_call_accuracy) and_default_foundry_input_mapping(GroundednessEvaluator, TaskCompletionEvaluator, ToolCallAccuracyEvaluator).
GroundednessEvaluatorin cloud mode now mapscontextto{{item.<context_field>}}whencontext_fieldis set in the dataset format, instead of incorrectly using theexpected_fieldcolumn.GroundednessEvaluatorin local mode now mapscontextto$row.context(the retrieved documents column) instead of$expected(the ground truth answer).smoke-rag.yamldataset config now declarescontext_field: contextto correctly wire thecontextJSONL column to groundedness evaluation.
- Split
agentops initdataset seeds into.agentops/datasets/for YAML definitions and.agentops/data/for JSONL rows, and updated docs/examples to use the new layout. - Expanded
agentops initrun-config seeds to include scenario-specific examples:.agentops/run-rag.yamland.agentops/run-agent.yamlin addition to the default.agentops/run.yaml. - Removed the runtime fallback to
gpt-5-miniin the Foundry backend; model-direct mode now requires an explicit deployment viabackend.modelorAZURE_AI_MODEL_DEPLOYMENT_NAME. - Added planned CLI command stubs with friendly "not implemented in this release" messages, and documented command availability/status in README and architecture docs.
- Reworked
README.mdinto a walkthrough-oriented structure with a clearer overview, step-by-step onboarding flow, command status table, and documentation map. - Refined
README.mdmessaging to position AgentOps as a broader operations foundation (evaluation + planned CI/CD, tracing, observability, and monitoring capabilities), and renamed the onboarding section toQuickstart.
- Align README quickstart workspace tree and starter bundle table with current
agentops inittemplates (model_quality_baseline,rag_quality_baseline,conversational_agent_baseline,agent_workflow_baseline, and smoke datasets).
- CLI command surface with Typer stubs:
agentops initagentops eval run --config <run.yaml> [--output <dir>]agentops report --in <results.json> [--out <report.md>]
- Unit tests for models, YAML/config loading, and workspace initialization behavior.
- Initial documentation including generic quickstart and test running guide.