From a0f10ffa191eca409c58ec4a55d404007a6a7509 Mon Sep 17 00:00:00 2001 From: Kenan Yildirim Date: Fri, 12 Sep 2025 10:35:57 -0400 Subject: [PATCH 1/2] pangea-node-sdk: update prompt_messages typing --- packages/pangea-node-sdk/CHANGELOG.md | 4 + .../pangea-node-sdk/src/services/ai_guard.ts | 6 +- packages/pangea-node-sdk/src/types.ts | 2 +- .../tests/testdata/ai-guard.openapi.json | 295 ++++++++++++++++-- 4 files changed, 283 insertions(+), 24 deletions(-) diff --git a/packages/pangea-node-sdk/CHANGELOG.md b/packages/pangea-node-sdk/CHANGELOG.md index bc341acc2..cf5e5fc86 100644 --- a/packages/pangea-node-sdk/CHANGELOG.md +++ b/packages/pangea-node-sdk/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - AI Guard: `onlyRelevantContent` parameter which allows for sending only relevant messages to AI Guard. +## Changed + +- AI Guard: `prompt_messages` field is now more specific. + ## 5.3.0 - 2025-08-25 ### Added diff --git a/packages/pangea-node-sdk/src/services/ai_guard.ts b/packages/pangea-node-sdk/src/services/ai_guard.ts index 0594d64cf..eb0c2712c 100644 --- a/packages/pangea-node-sdk/src/services/ai_guard.ts +++ b/packages/pangea-node-sdk/src/services/ai_guard.ts @@ -160,13 +160,13 @@ export class AIGuardService extends BaseService { } ); if (response.success && response.result.prompt_messages) { - const transformedMessages = response.result - .prompt_messages as unknown as MessageLike[]; + const transformedMessages = response.result.prompt_messages; + // @ts-expect-error Input `role` is optional, but on output it's required? response.result.prompt_messages = patchMessages( originalMessages, originalIndices, transformedMessages - ) as unknown as Record; + ); } return response; } diff --git a/packages/pangea-node-sdk/src/types.ts b/packages/pangea-node-sdk/src/types.ts index a78cd0bf7..c6dd2cbe4 100644 --- a/packages/pangea-node-sdk/src/types.ts +++ b/packages/pangea-node-sdk/src/types.ts @@ -479,7 +479,7 @@ export namespace AIGuard { prompt_text?: string; /** Updated structured prompt, if applicable. */ - prompt_messages?: { [key: string]: unknown }; + prompt_messages?: { role: string; content: string }[]; /** Whether or not the prompt triggered a block detection. */ blocked?: boolean; diff --git a/packages/pangea-node-sdk/tests/testdata/ai-guard.openapi.json b/packages/pangea-node-sdk/tests/testdata/ai-guard.openapi.json index 5ae8d84da..8a0345e8d 100644 --- a/packages/pangea-node-sdk/tests/testdata/ai-guard.openapi.json +++ b/packages/pangea-node-sdk/tests/testdata/ai-guard.openapi.json @@ -410,8 +410,21 @@ "description": "Updated prompt text, if applicable." }, "prompt_messages": { - "type": "object", - "description": "Updated structured prompt, if applicable." + "type": "array", + "description": "Updated structured prompt, if applicable.", + "items": { + "type": "object", + "required": ["role", "content"], + "properties": { + "role": { + "type": "string" + }, + "content": { + "type": "string" + } + }, + "additionalProperties": false + } }, "blocked": { "type": "boolean", @@ -896,6 +909,240 @@ "tags": ["ai-guard"] } }, + "/v1beta/guard_async": { + "post": { + "operationId": "ai_guard_post_v1beta_guard_async", + "summary": "Guard LLM input and output", + "description": "Analyze and redact content to avoid manipulation of the model, addition of malicious content, and other undesirable data transfers.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/multimodal-guard" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/pangea-response" + }, + { + "properties": { + "result": { + "type": "object", + "required": ["detectors"], + "properties": { + "output": { + "type": "object", + "description": "Updated structured prompt." + }, + "blocked": { + "type": "boolean", + "description": "Whether or not the prompt triggered a block detection." + }, + "transformed": { + "type": "boolean", + "description": "Whether or not the original input was transformed." + }, + "recipe": { + "type": "string", + "description": "The Recipe that was used." + }, + "detectors": { + "type": "object", + "description": "Result of the recipe analyzing and input prompt.", + "properties": { + "malicious_prompt": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Malicious Prompt was detected." + }, + "data": { + "type": "object", + "description": "Details about the analyzers.", + "$ref": "#/components/schemas/prompt-injection-result" + } + } + }, + "confidential_and_pii_entity": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the PII Entities were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected entities.", + "$ref": "#/components/schemas/redact-entity-result" + } + } + }, + "malicious_entity": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Malicious Entities were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected entities.", + "$ref": "#/components/schemas/malicious-entity-result" + } + } + }, + "custom_entity": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Custom Entities were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected entities.", + "$ref": "#/components/schemas/redact-entity-result" + } + } + }, + "secret_and_key_entity": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Secret Entities were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected entities.", + "$ref": "#/components/schemas/redact-entity-result" + } + } + }, + "competitors": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Competitors were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected entities.", + "$ref": "#/components/schemas/single-entity-result" + } + } + }, + "prompt_hardening": { + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Details about the detected languages.", + "$ref": "#/components/schemas/hardening-result" + } + } + }, + "language": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Languages were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected languages.", + "$ref": "#/components/schemas/language-result" + } + } + }, + "topic": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Topics were detected." + }, + "data": { + "type": "object", + "description": "Details about the detected topics.", + "$ref": "#/components/schemas/topic-result" + } + } + }, + "code": { + "type": "object", + "properties": { + "detected": { + "type": "boolean", + "description": "Whether or not the Code was detected." + }, + "data": { + "type": "object", + "description": "Details about the detected code.", + "$ref": "#/components/schemas/language-result" + } + } + } + } + }, + "access_rules": { + "$ref": "#/components/schemas/access-rules-response" + }, + "fpe_context": { + "type": "string", + "format": "base64", + "description": "If an FPE redaction method returned results, this will be the context passed to unredact." + }, + "input_token_count": { + "type": "number", + "description": "Number of tokens counted in the input" + }, + "output_token_count": { + "type": "number", + "description": "Number of tokens counted in the output" + } + } + } + } + } + ] + } + } + }, + "description": "No description provided" + }, + "400": { + "description": "Validation errors", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/pangea-response" + }, + { + "$ref": "#/components/schemas/pangea-validation-errors" + } + ] + } + } + } + } + }, + "tags": ["ai-guard"] + } + }, "/request/{requestId}": { "get": { "operationId": "get_async_request", @@ -1372,11 +1619,11 @@ }, "app_id": { "type": "string", - "description": "Id of source application." + "description": "Id of source application/agent" }, "actor_id": { "type": "string", - "description": "User/Service account id." + "description": "User/Service account id/service account" }, "llm_provider": { "type": "string", @@ -1413,12 +1660,18 @@ "event_type": { "type": "string", "description": "(AIDR) Event Type.", - "enum": ["input", "output"], + "enum": [ + "input", + "output", + "tool_input", + "tool_output", + "tool_listing" + ], "default": "input" }, - "sensor_instance_id": { + "collector_instance_id": { "type": "string", - "description": "(AIDR) sensor instance id." + "description": "(AIDR) collector instance id." }, "extra_info": { "type": "object", @@ -1426,19 +1679,19 @@ "properties": { "app_name": { "type": "string", - "description": "Name of source application." + "description": "Name of source application/agent." }, "app_group": { "type": "string", - "description": "The group of source application." + "description": "The group of source application/agent." }, "app_version": { "type": "string", - "description": "Version of the source application." + "description": "Version of the source application/agent." }, "actor_name": { "type": "string", - "description": "Name of subject actor." + "description": "Name of subject actor/service account." }, "actor_group": { "type": "string", @@ -1448,17 +1701,19 @@ "type": "string", "description": "Geographic region or data center." }, - "data_sensitivity": { + "sub_tenant": { "type": "string", - "description": "Sensitivity level of data involved" + "description": "Sub tenant of the user or organization" }, - "customer_tier": { - "type": "string", - "description": "Tier of the user or organization" - }, - "use_case": { - "type": "string", - "description": "Business-specific use case" + "mcp_tools": { + "type": "array", + "title": "List of MCP tools", + "description": "Each item is :", + "uniqueItems": true, + "items": { + "type": "string", + "description": "Formatted mcp service and tools name :" + } } }, "additionalProperties": true From 0b6c2d3c76603b334545e695e2dd9a3c3ba67ffd Mon Sep 17 00:00:00 2001 From: Kenan Yildirim Date: Fri, 12 Sep 2025 10:36:55 -0400 Subject: [PATCH 2/2] pangea-node-sdk: publish v5.4.0 --- packages/pangea-node-sdk/CHANGELOG.md | 2 ++ packages/pangea-node-sdk/package.json | 2 +- packages/pangea-node-sdk/src/config.ts | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/pangea-node-sdk/CHANGELOG.md b/packages/pangea-node-sdk/CHANGELOG.md index cf5e5fc86..911a12892 100644 --- a/packages/pangea-node-sdk/CHANGELOG.md +++ b/packages/pangea-node-sdk/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## 5.4.0 - 2025-09-12 + ## Added - AI Guard: `onlyRelevantContent` parameter which allows for sending only diff --git a/packages/pangea-node-sdk/package.json b/packages/pangea-node-sdk/package.json index c8589ba6d..b808846ac 100644 --- a/packages/pangea-node-sdk/package.json +++ b/packages/pangea-node-sdk/package.json @@ -1,6 +1,6 @@ { "name": "pangea-node-sdk", - "version": "5.3.0", + "version": "5.4.0", "type": "commonjs", "main": "./dist/index.cjs", "types": "./dist/index.d.cts", diff --git a/packages/pangea-node-sdk/src/config.ts b/packages/pangea-node-sdk/src/config.ts index da3134526..6462b8a21 100644 --- a/packages/pangea-node-sdk/src/config.ts +++ b/packages/pangea-node-sdk/src/config.ts @@ -1,4 +1,4 @@ -export const version = "5.3.0"; +export const version = "5.4.0"; /** Configuration for a Pangea service client. */ class PangeaConfig {