feat(datadog): extend to 40 tools and align every operation with the published OpenAPI specs - #6745
Conversation
…M, and APM tools Extends the Datadog block from 12 to 39 operations, all verified against Datadog's published OpenAPI specs: - Incidents (v2, public beta): list, get, create, update, add todo - SLOs (v1): list, get, create, update, delete, history - Dashboards (v1): list, get, create, delete - Synthetics (v1): list tests, get test, latest results, trigger, pause/resume - Cloud SIEM (v2): search signals, get signal, update triage state, assign, list detection rules - APM: search spans (v2), list Service Catalog definitions (v2) Adds tools/datadog/utils.ts so every tool builds its URL from the configured site/region and shares the JSON:API-aware error extraction, and handles the v1 flat vs v2 envelope shapes and cursor pagination per endpoint.
Validated all 39 shipped operations (plus the 12 pre-existing ones that had never been spec-checked) against the DataDog v1 and v2 OpenAPI schemas. - `POST /api/v2/downtime` requires `monitor_identifier`, so a downtime created without a monitor id was rejected. Default to the `*` monitor tag. - A one-time downtime schedule declares `additionalProperties: false` and accepts only `start`/`end`; the timezone moves to `display_timezone`. - `GET /api/v2/downtime` has no `monitor_id` filter, and the response carries no `disabled` attribute. Downtime ids are UUID strings, not numbers. - Drop scaffold types for operations that do not exist (metric metadata, event query, monitor update/delete/unmute, host listing) along with their fields. - Note that monitor mute is no longer published in the v1 specification. - Add browser Synthetic test results, which the browser-specific endpoint returns with its own camelCase step-count shape. - Replace every `any` with a spec-derived interface, keeping the polymorphic service-definition schema opaque.
…utput field Replace the six surviving `Record<string, any>` request-body and response-cast sites with concrete spec-derived shapes, and declare the output fields that transformResponse already returned but outputs omitted: - create_downtime / list_downtimes: timezone, created, modified - create_monitor / get_monitor: options, creator - list_monitors: message, priority, options, created, modified, creator - query_logs: content.attributes, content.tags - update_security_signal_state / _assignee: type; assignee also gained the archiveReason/archiveComment pair its sibling already declared - query_timeseries: series gained the items shape it never described
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Fixes several pre-existing downtime and API-shape bugs so create/list downtime calls match the v2 spec ( Adds Unmute Monitor, log/signal/span cursors, and richer output schemas; introduces Vitest coverage for the critical request-body and error-path behavior. Reviewed by Cursor Bugbot for commit 5b15235. Configure here. |
Greptile SummaryThe PR expands the Datadog integration to 40 operations and aligns request, response, registration, generated metadata, and documentation contracts with Datadog’s published specifications.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the prior downtime mapping and whitespace-conflict issues are addressed by the current parameter forwarding, parsed-value guard, and regression coverage.
|
| Filename | Overview |
|---|---|
| apps/sim/blocks/blocks/datadog.ts | Registers the expanded operation set and now forwards the previously omitted downtime options to their matching tool parameters. |
| apps/sim/tools/datadog/create_downtime.ts | Builds the v2 downtime payload with parsed, mutually exclusive monitor targets and correctly handles whitespace-only monitor IDs. |
| apps/sim/tools/datadog/datadog.test.ts | Adds focused request-shape and regression coverage, including target conflicts, wildcard fallback, numeric IDs, and whitespace handling. |
| apps/sim/tools/datadog/types.ts | Defines specification-derived request and response shapes shared across the expanded Datadog tools. |
| apps/sim/tools/registry.ts | Registers the newly added Datadog operations for runtime lookup. |
| apps/docs/content/docs/en/integrations/datadog.mdx | Documents the expanded operation catalog and corrected Datadog input and output contracts. |
Reviews (9): Last reviewed commit: "fix(datadog): compare downtime targets a..." | Re-trigger Greptile
…pping create_downtime accepts monitorTags, timezone and muteFirstRecoveryNotification, but the block exposed no inputs for them and never forwarded them. Monitor-tag targeting silently fell back to the `*` tag, so a downtime meant for one team's monitors muted every monitor in scope. Adds the three advanced sub-blocks and wires them through. Also routes list_downtimes' currentOnly through toSwitchBoolean. A switch yields the strings 'true'/'false', and 'false' is truthy, so turning the toggle off still sent current_only=true. Every other switch in the block already used the helper; this was the last raw one.
|
Fixed in c798506 — the P1 was real, and it was worse than "options ignored".
Auditing that bug class turned up one more: I also swept the remaining 38 operations for dropped params. The rest ( |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c798506. Configure here.
…rop unpublished mute
Independent re-validation of all 39 operations against the DataDog/datadog-api-client-go
generator specs (v1 and v2 openapi.yaml) rather than the client-rendered docs site.
Correctness:
- submit_metrics sent inverted MetricIntakeType codes (gauge as 0/unspecified, rate as 1/count,
count as 2/rate), silently changing how Datadog aggregated every submitted series. The spec
enum is 0 unspecified, 1 count, 2 rate, 3 gauge; an unrecognized type is now omitted so
Datadog infers it. Also stops stamping an invented `resources: [{name:'host'}]` default and
now forwards `interval`, which Datadog requires for count and rate metrics.
- update_slo replaced the whole SLO with only the fields the caller filled in, so editing one
field erased description, tags, query, monitor_ids, groups, thresholds, and timeframe.
PUT /api/v1/slo/{slo_id} is a full replacement, so the stored SLO is now read first and the
supplied edits are overlaid onto it, with the read-only fields stripped.
- update_incident admitted empty strings, so a blank input could blank a stored incident title
or fail as an invalid date-time.
- query_timeseries reported a failed query as success: Datadog returns 200 with a non-ok
`status` and the reason in `error`.
- create_monitor swallowed malformed options JSON and created a monitor with no thresholds.
- send_logs rebuilt each entry from a fixed field list, discarding the custom attributes
Datadog accepts as additionalProperties, and padded absent optional fields with empty strings.
Removed:
- mute_monitor. /api/v1/monitor/{monitor_id}/mute is absent from the v1 spec entirely, there is
no unmute counterpart to reverse it, and downtimes are the supported mechanism.
Contract accuracy:
- Security signal search advertised relative times ("now-1h"); the spec types filter.from/to as
format: date-time. Descriptions, placeholders, and wand prompts now produce ISO-8601.
- list_incidents advertised an `include` value ("integrations") that is not in the spec enum,
and neither incident tool trimmed the comma-separated list, so "users, attachments" 400d.
- Invalid "ok" group state dropped from both monitor descriptions.
- time_slice removed from SLO create input, which cannot build one without an SLI specification.
- DatadogSite gains ap2, uk1, and us2.ddog-gov.com.
Pagination and errors:
- list_downtimes silently truncated at Datadog's default 30 with no way to page; adds
page[limit]/page[offset] and surfaces totalCount.
- query_logs returned a cursor it had no way to accept back.
- Error extraction consolidated onto datadogErrorMessage, which now also reads the
dictionary-shaped errors of the SLO delete conflict. Ten tools were reading `.detail` off
plain strings or the raw entry off objects, degrading every failure to a bare status line.
- Debug logging removed from list_monitors.
Adds 29 regression tests, each verified to fail when its fix is reverted.
# Conflicts: # apps/sim/tools/generated/tool-ids.ts # apps/sim/tools/generated/tool-metadata.ts # apps/sim/tools/generated/tool-outputs.ts
|
@cursor review |
…ut defaults - The severity dropdown omitted SEV-0, which IncidentSeverity allows and both incident tool descriptions already advertised. - Page-size descriptions now state Datadog's documented default of 10 and cap of 100 instead of an arbitrary example, so an agent does not request an out-of-range page. - trigger_synthetics_tests emitted an explicit null for a string-typed optional output, and update_synthetics_status reported 'live' on the error path regardless of what the caller actually requested.
|
@cursor review |
Reverses the removal in the previous commit. Absence from the datadog-api-client-go
generator spec showed the endpoint is unpublished there, not that it is retired:
Datadog's official Python client still implements it on master as
`Monitor.mute(id, scope=, end=)` and `Monitor.unmute(id, scope=, all_scopes=)`
(datadogpy datadog/api/monitors.py), which `_trigger_class_action` resolves to
`POST /api/v1/monitor/{id}/mute` and `/unmute` with exactly those body fields.
mute_monitor has also been in the block since #2175 in December, so dropping it would
have broken existing workflows for an endpoint that two independent sources agree is live.
The genuine defect was that muting was a one-way trapdoor: Sim could mute a monitor but
had no way to reverse it. Adds datadog_unmute_monitor, sharing the monitor ID and scope
inputs with mute, so the operation is recoverable from the same block.
Also: mute no longer discards the response body (it now reports the monitor id, name, and
state), routes errors through datadogErrorMessage, encodes the monitor ID in the path, and
stops dropping an explicit `end` of 0.
|
@cursor review |
# Conflicts: # apps/sim/tools/generated/tool-ids.ts # apps/sim/tools/generated/tool-metadata.ts # apps/sim/tools/generated/tool-outputs.ts
|
@cursor review |
…ination from the block Addresses the review findings on the previous round. - create_downtime accepted both a monitor ID and monitor tags but `monitor_identifier` is a oneOf, so it silently kept the ID and dropped the tags, muting a different set of monitors than the caller asked for. It now rejects the ambiguous combination. - create_downtime ran Number.parseInt on the monitor ID with no validation, so a non-numeric value became NaN and serialized as null inside monitor_identifier. It now uses the same parseMonitorIds guard the SLO path already had, naming the offending value. - list_downtimes gained limit/offset in the tool but the block exposed neither, so no block-driven call could page past Datadog's default. Adds the two sub-blocks and wires them through the params mapper. - The block did not declare the totalCount the tool now returns, so nothing downstream could bind to it.
|
@cursor review |
…te subblock ids Both defects were introduced by this branch. - splitCommaList called .split on its argument, so routing create_downtime's monitorId through it turned a legitimate numeric input into a TypeError before the request was built. A <Block.output> reference to get_monitor or list_monitors resolves to a number, and an LLM tool call can pass a number or an array, so the helper now normalizes all three shapes. The previous Number.parseInt path had accepted a number by coercion. - Adding the unmute operation renamed the mute subblock ids scope/end to muteScope/muteEnd. Workflow state is persisted by subblock id, so every existing Mute Monitor block would have kept the old keys and silently lost its scope and end time. Restored the shipped ids; both are still unique block-wide and no operation reads another operation's value.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 769d986. Configure here.
A whitespace-only Monitor ID is truthy as a raw string but parses to no monitor, so the oneOf conflict guard rejected a valid tag-targeted downtime whenever the untouched Monitor ID field carried blank text. Both sides are now compared after parsing.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5b15235. Configure here.
# Conflicts: # apps/sim/tools/generated/tool-ids.ts # apps/sim/tools/generated/tool-metadata.ts # apps/sim/tools/generated/tool-outputs.ts
Summary
Extends the Datadog block from 12 to 40 tools (incidents, SLOs, dashboards, synthetics, Cloud SIEM, APM spans), then validates all 40 against the published OpenAPI specs.
The notable result: all five real defects were in the 12 pre-existing tools, not the 27 new ones.
create_downtimewas rejected by the API on its default path.DowntimeCreateRequestAttributesrequiresmonitor_identifier, but the tool only sent one when an optional advanced subblock was filled in. It now always sends one, falling back to the*monitor tag — Datadog's way of expressing "every monitor in scope".schedule.timezoneis illegal on a one-time downtime schedule (additionalProperties: false). Moved to the attribute-leveldisplay_timezone, where it actually belongs.monitor_idquery param the endpoint does not support.disabledwas an invented field — it exists nowhere in the downtime schema.idwas typed as a number. In v2 it is a UUID string.Also removed nine dead scaffold type groups that no tool referenced.
Follow-up in the same branch: removed the six surviving
Record<string, any>sites in favor of spec-derived shapes, and declared the output fields thattransformResponsealready returned butoutputsomitted (monitoroptions/creator, downtimetimezone/created/modified, logattributes/tags, signaltype, and thequery_timeseriesseries item shape).Needs a maintainer decision
datadog_mute_monitorposts to/api/v1/monitor/{monitor_id}/mute, which does not exist anywhere in the v1 spec. I left it registered with a description marking it legacy/unpublished and pointing at downtimes as the supported path. If it 404s against a live key, it should be dropped.Verification method
Every field was extracted individually from
datadog-api-client-go's generator specs.docs.datadoghq.comrenders client-side, and inferring from it produced invented field names — which is how thedisabledfield got in originally.Type of Change
Testing
Validated statically against the published OpenAPI specs — every endpoint, parameter, and response field. Not exercised against a live Datadog key; the
mute_monitoritem above is the one that needs it.Checklist