Skip to content

feat(datadog): extend to 40 tools and align every operation with the published OpenAPI specs - #6745

Merged
waleedlatif1 merged 13 commits into
stagingfrom
feat/datadog-depth
Aug 16, 2026
Merged

feat(datadog): extend to 40 tools and align every operation with the published OpenAPI specs#6745
waleedlatif1 merged 13 commits into
stagingfrom
feat/datadog-depth

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

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_downtime was rejected by the API on its default path. DowntimeCreateRequestAttributes requires monitor_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.timezone is illegal on a one-time downtime schedule (additionalProperties: false). Moved to the attribute-level display_timezone, where it actually belongs.
  • List downtimes passed a monitor_id query param the endpoint does not support.
  • disabled was an invented field — it exists nowhere in the downtime schema.
  • Downtime id was 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 that transformResponse already returned but outputs omitted (monitor options/creator, downtime timezone/created/modified, log attributes/tags, signal type, and the query_timeseries series item shape).

Needs a maintainer decision

datadog_mute_monitor posts 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.com renders client-side, and inferring from it produced invented field names — which is how the disabled field got in originally.

Type of Change

  • Bug fix
  • New feature

Testing

Validated statically against the published OpenAPI specs — every endpoint, parameter, and response field. Not exercised against a live Datadog key; the mute_monitor item above is the one that needs it.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…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
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 16, 2026 1:48am

Request Review

@cursor

cursor Bot commented Aug 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Large operational surface (muting, downtimes, SLO/dashboard deletes, incident and security-signal writes) can affect production monitoring if misconfigured; changes are mostly additive with targeted API-alignment fixes rather than auth/core platform changes.

Overview
Expands the Datadog workflow block and docs from 12 operations to 41, covering incidents, SLOs, dashboards, Synthetic tests, Cloud SIEM signals/rules, APM span search, and service catalog listing, with matching sub-blocks, param wiring, and integration metadata.

Fixes several pre-existing downtime and API-shape bugs so create/list downtime calls match the v2 spec (monitor_identifier, display_timezone, UUID IDs, pagination), and tightens shared parsing/error handling across tools (metric types, SLO update merge, incident partial updates, monitor options JSON).

Adds Unmute Monitor, log/signal/span cursors, and richer output schemas; introduces Vitest coverage for the critical request-body and error-path behavior. datadog_mute_monitor remains registered but may not exist in the published v1 OpenAPI—worth validating against a live key.

Reviewed by Cursor Bugbot for commit 5b15235. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR expands the Datadog integration to 40 operations and aligns request, response, registration, generated metadata, and documentation contracts with Datadog’s published specifications.

  • Adds incident, SLO, dashboard, Synthetic Monitoring, Cloud SIEM, and APM span operations.
  • Corrects existing downtime request fields, target selection, pagination, identifiers, and output shapes.
  • Adds regression coverage for mutually exclusive downtime targets and whitespace-only monitor IDs.

Confidence Score: 5/5

The 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.

Important Files Changed

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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Fixed in c798506 — the P1 was real, and it was worse than "options ignored".

create_downtime had no sub-blocks at all for monitorTags, timezone, or muteFirstRecoveryNotification, so the mapping had nothing to forward. The consequence is the monitor-targeting one: with no tags reaching the tool, the request builder always took its * fallback, so a downtime intended for one team's monitors muted every monitor in scope. Added the three advanced sub-blocks and wired them through the mapping and inputs.

Auditing that bug class turned up one more: list_downtimes.currentOnly was mapped raw from a switch. 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 went through toSwitchBoolean; this was the last raw one.

I also swept the remaining 38 operations for dropped params. The rest (query_logs.sort/indexes, list_monitors.groupStates/monitorTags/withDowntimes/page/pageSize, get_monitor.groupStates/withDowntimes, create_event.host/aggregationKey/sourceTypeName/dateHappened, list_slos.isDeleted) have no sub-block either, but unlike the downtime case they are optional filters and pagination that default sensibly — nothing is silently discarded because there is no input to discard. Leaving those out of this PR rather than growing the diff; happy to add them if you'd prefer.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/datadog.ts
Comment thread apps/sim/blocks/blocks/datadog.ts Outdated
Comment thread apps/sim/blocks/blocks/datadog.ts
Comment thread apps/sim/tools/datadog/create_downtime.ts Outdated
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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

# Conflicts:
#	apps/sim/tools/generated/tool-ids.ts
#	apps/sim/tools/generated/tool-metadata.ts
#	apps/sim/tools/generated/tool-outputs.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/datadog.ts
Comment thread apps/sim/blocks/blocks/datadog.ts
…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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/datadog/create_downtime.ts
…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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

Comment thread apps/sim/tools/datadog/create_downtime.ts Outdated
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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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
@waleedlatif1
waleedlatif1 merged commit cabd2e2 into staging Aug 16, 2026
28 checks passed
@waleedlatif1
waleedlatif1 deleted the feat/datadog-depth branch August 16, 2026 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant