From 89ab39aaff64e3067af3a17222502b479d29fa51 Mon Sep 17 00:00:00 2001 From: waleed Date: Mon, 6 Jul 2026 14:30:44 -0700 Subject: [PATCH 1/3] improvement(new-relic): validate integration against NerdGraph docs, surface more entity fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Audited all 4 New Relic tools (nrql_query, search_entities, get_entity, create_deployment_event) plus the block against live NerdGraph API docs; request/response shapes, auth, region endpoints, and GraphQL injection handling all confirmed correct. - Added domain, reporting, alertSeverity, and tags to get_entity and search_entities outputs — stable Entity schema fields we weren't surfacing. Purely additive, no existing fields changed. - Skipped NerdGraph's aiIssues/incidents API; New Relic marks it "unsafe experimental" and requires an opt-in header, not worth the fragility. --- apps/sim/blocks/blocks/new_relic.ts | 12 +++++- apps/sim/tools/new_relic/get_entity.ts | 41 +++++++++++++++++++++ apps/sim/tools/new_relic/search_entities.ts | 29 +++++++++++++++ apps/sim/tools/new_relic/types.ts | 9 +++++ 4 files changed, 89 insertions(+), 2 deletions(-) diff --git a/apps/sim/blocks/blocks/new_relic.ts b/apps/sim/blocks/blocks/new_relic.ts index f8912cd08ca..92640b31aaa 100644 --- a/apps/sim/blocks/blocks/new_relic.ts +++ b/apps/sim/blocks/blocks/new_relic.ts @@ -345,9 +345,17 @@ Return ONLY the numeric timestamp - no explanations, no extra text.`, resultCount: { type: 'number', description: 'Number of NRQL result rows' }, count: { type: 'number', description: 'Number of matching entities' }, query: { type: 'string', description: 'Entity search query New Relic executed' }, - entities: { type: 'json', description: 'Matching New Relic entities (guid, name, entityType)' }, + entities: { + type: 'json', + description: + 'Matching New Relic entities (guid, name, entityType, domain, reporting, alertSeverity, tags)', + }, nextCursor: { type: 'string', description: 'Cursor for the next entity search page' }, - entity: { type: 'json', description: 'New Relic entity details (guid, name, entityType)' }, + entity: { + type: 'json', + description: + 'New Relic entity details (guid, name, entityType, domain, reporting, alertSeverity, tags)', + }, event: { type: 'json', description: 'Created change tracking event metadata' }, messages: { type: 'json', description: 'New Relic change tracking messages' }, }, diff --git a/apps/sim/tools/new_relic/get_entity.ts b/apps/sim/tools/new_relic/get_entity.ts index 4e839a04f3b..810d7e3d0e2 100644 --- a/apps/sim/tools/new_relic/get_entity.ts +++ b/apps/sim/tools/new_relic/get_entity.ts @@ -12,6 +12,10 @@ interface GetEntityData { entity?: { name?: string | null entityType?: string | null + domain?: string | null + reporting?: boolean | null + alertSeverity?: string | null + tags?: { key?: string | null; values?: string[] | null }[] | null } | null } | null } @@ -54,6 +58,13 @@ export const newRelicGetEntityTool: ToolConfig ({ + key: tag.key ?? null, + values: tag.values ?? [], + })) ?? [], } : null, }, @@ -87,6 +106,28 @@ export const newRelicGetEntityTool: ToolConfig Date: Mon, 6 Jul 2026 14:49:01 -0700 Subject: [PATCH 2/3] fix(new-relic): normalize search_entities output, share entity normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit search_entities passed raw NerdGraph entities straight through, so tags/ domain/reporting/alertSeverity could arrive as null/undefined at runtime despite the non-nullable NewRelicEntity type contract — a .map() on a null tags array would throw. get_entity already normalized these fields correctly. Extracted the normalization into a shared normalizeNewRelicEntity() in utils.ts and reuse it from both tools, so the two can't drift again. --- apps/sim/tools/new_relic/get_entity.ts | 25 ++++---------------- apps/sim/tools/new_relic/search_entities.ts | 7 +++--- apps/sim/tools/new_relic/utils.ts | 26 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/apps/sim/tools/new_relic/get_entity.ts b/apps/sim/tools/new_relic/get_entity.ts index 810d7e3d0e2..b45eafddd30 100644 --- a/apps/sim/tools/new_relic/get_entity.ts +++ b/apps/sim/tools/new_relic/get_entity.ts @@ -2,21 +2,16 @@ import type { NewRelicGetEntityParams, NewRelicGetEntityResponse } from '@/tools import { getNerdGraphEndpoint, gqlString, + type NewRelicRawEntity, newRelicHeaders, + normalizeNewRelicEntity, parseNerdGraphResponse, } from '@/tools/new_relic/utils' import type { ToolConfig } from '@/tools/types' interface GetEntityData { actor?: { - entity?: { - name?: string | null - entityType?: string | null - domain?: string | null - reporting?: boolean | null - alertSeverity?: string | null - tags?: { key?: string | null; values?: string[] | null }[] | null - } | null + entity?: NewRelicRawEntity | null } | null } @@ -79,19 +74,7 @@ export const newRelicGetEntityTool: ToolConfig ({ - key: tag.key ?? null, - values: tag.values ?? [], - })) ?? [], - } + ? { ...normalizeNewRelicEntity(entity), guid: params?.guid ?? null } : null, }, } diff --git a/apps/sim/tools/new_relic/search_entities.ts b/apps/sim/tools/new_relic/search_entities.ts index b8adcfce0a7..974877190b9 100644 --- a/apps/sim/tools/new_relic/search_entities.ts +++ b/apps/sim/tools/new_relic/search_entities.ts @@ -1,11 +1,12 @@ import type { - NewRelicEntity, NewRelicSearchEntitiesParams, NewRelicSearchEntitiesResponse, } from '@/tools/new_relic/types' import { getNerdGraphEndpoint, + type NewRelicRawEntity, newRelicHeaders, + normalizeNewRelicEntity, parseNerdGraphResponse, } from '@/tools/new_relic/utils' import type { ToolConfig } from '@/tools/types' @@ -17,7 +18,7 @@ interface SearchEntitiesData { query?: string results?: { nextCursor?: string | null - entities?: NewRelicEntity[] + entities?: NewRelicRawEntity[] } | null } | null } | null @@ -101,7 +102,7 @@ export const newRelicSearchEntitiesTool: ToolConfig< if (!entitySearch) { throw new Error('New Relic did not return entity search data') } - const entities = entitySearch?.results?.entities ?? [] + const entities = (entitySearch?.results?.entities ?? []).map(normalizeNewRelicEntity) return { success: true, diff --git a/apps/sim/tools/new_relic/utils.ts b/apps/sim/tools/new_relic/utils.ts index 032ae1263f1..c34b2198b52 100644 --- a/apps/sim/tools/new_relic/utils.ts +++ b/apps/sim/tools/new_relic/utils.ts @@ -1,9 +1,19 @@ -import type { NewRelicRegion } from '@/tools/new_relic/types' +import type { NewRelicEntity, NewRelicRegion } from '@/tools/new_relic/types' interface GraphQLError { message?: string } +export interface NewRelicRawEntity { + guid?: string | null + name?: string | null + entityType?: string | null + domain?: string | null + reporting?: boolean | null + alertSeverity?: string | null + tags?: ({ key?: string | null; values?: string[] | null } | null)[] | null +} + interface GraphQLResponse { data?: TData errors?: GraphQLError[] @@ -40,3 +50,17 @@ export const cleanOptionalString = (value?: string): string | undefined => { const trimmed = value?.trim() return trimmed ? trimmed : undefined } + +export const normalizeNewRelicEntity = (entity: NewRelicRawEntity): NewRelicEntity => ({ + guid: entity.guid ?? null, + name: entity.name ?? null, + entityType: entity.entityType ?? null, + domain: entity.domain ?? null, + reporting: entity.reporting ?? null, + alertSeverity: entity.alertSeverity ?? null, + tags: + entity.tags?.map((tag) => ({ + key: tag?.key ?? null, + values: tag?.values ?? [], + })) ?? [], +}) From 77295994853757a1df3487c5bcd53effa93ff1a4 Mon Sep 17 00:00:00 2001 From: waleed Date: Mon, 6 Jul 2026 15:16:40 -0700 Subject: [PATCH 3/3] fix(new-relic): gate alertSeverity behind required GraphQL interface fragments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit alertSeverity isn't a direct field on New Relic's Entity/EntityOutline types — it only exists on the AlertableEntity/AlertableEntityOutline sub-interfaces, and NerdGraph rejects the query outright without the inline fragment. get_entity.ts (entity(guid), returns Entity) now uses `... on AlertableEntity { alertSeverity }`; search_entities.ts (entitySearch, returns EntityOutline) now uses `... on AlertableEntityOutline { alertSeverity }`. Confirmed against New Relic's live NerdGraph entities API docs. --- apps/sim/tools/new_relic/get_entity.ts | 4 +++- apps/sim/tools/new_relic/search_entities.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/new_relic/get_entity.ts b/apps/sim/tools/new_relic/get_entity.ts index b45eafddd30..52f4ce4c5b9 100644 --- a/apps/sim/tools/new_relic/get_entity.ts +++ b/apps/sim/tools/new_relic/get_entity.ts @@ -55,7 +55,9 @@ export const newRelicGetEntityTool: ToolConfig