shield360 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +310 -0
- package/dist/__tests__/manual-trace.test.d.ts +1 -0
- package/dist/__tests__/manual-trace.test.js +118 -0
- package/dist/__tests__/manual-trace.test.js.map +1 -0
- package/dist/__tests__/register.test.d.ts +0 -0
- package/dist/__tests__/register.test.js +90 -0
- package/dist/__tests__/register.test.js.map +1 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/constant.d.ts +6 -0
- package/dist/constant.js +14 -0
- package/dist/constant.js.map +1 -0
- package/dist/evals/__tests__/offline.test.d.ts +1 -0
- package/dist/evals/__tests__/offline.test.js +427 -0
- package/dist/evals/__tests__/offline.test.js.map +1 -0
- package/dist/evals/index.d.ts +2 -0
- package/dist/evals/index.js +15 -0
- package/dist/evals/index.js.map +1 -0
- package/dist/evals/offline.d.ts +6 -0
- package/dist/evals/offline.js +350 -0
- package/dist/evals/offline.js.map +1 -0
- package/dist/evals/types.d.ts +74 -0
- package/dist/evals/types.js +23 -0
- package/dist/evals/types.js.map +1 -0
- package/dist/features/__tests__/rule-engine.test.d.ts +1 -0
- package/dist/features/__tests__/rule-engine.test.js +146 -0
- package/dist/features/__tests__/rule-engine.test.js.map +1 -0
- package/dist/features/base.d.ts +8 -0
- package/dist/features/base.js +15 -0
- package/dist/features/base.js.map +1 -0
- package/dist/features/prompt-hub.d.ts +4 -0
- package/dist/features/prompt-hub.js +66 -0
- package/dist/features/prompt-hub.js.map +1 -0
- package/dist/features/rule-engine.d.ts +6 -0
- package/dist/features/rule-engine.js +60 -0
- package/dist/features/rule-engine.js.map +1 -0
- package/dist/features/vault.d.ts +4 -0
- package/dist/features/vault.js +63 -0
- package/dist/features/vault.js.map +1 -0
- package/dist/guard/__tests__/findings.test.d.ts +1 -0
- package/dist/guard/__tests__/findings.test.js +79 -0
- package/dist/guard/__tests__/findings.test.js.map +1 -0
- package/dist/guard/__tests__/integration.test.d.ts +1 -0
- package/dist/guard/__tests__/integration.test.js +215 -0
- package/dist/guard/__tests__/integration.test.js.map +1 -0
- package/dist/guard/__tests__/pii.test.d.ts +1 -0
- package/dist/guard/__tests__/pii.test.js +131 -0
- package/dist/guard/__tests__/pii.test.js.map +1 -0
- package/dist/guard/__tests__/pipeline.test.d.ts +1 -0
- package/dist/guard/__tests__/pipeline.test.js +162 -0
- package/dist/guard/__tests__/pipeline.test.js.map +1 -0
- package/dist/guard/__tests__/prompt-injection.test.d.ts +1 -0
- package/dist/guard/__tests__/prompt-injection.test.js +92 -0
- package/dist/guard/__tests__/prompt-injection.test.js.map +1 -0
- package/dist/guard/__tests__/report.test.d.ts +1 -0
- package/dist/guard/__tests__/report.test.js +50 -0
- package/dist/guard/__tests__/report.test.js.map +1 -0
- package/dist/guard/base.d.ts +79 -0
- package/dist/guard/base.js +136 -0
- package/dist/guard/base.js.map +1 -0
- package/dist/guard/custom.d.ts +19 -0
- package/dist/guard/custom.js +46 -0
- package/dist/guard/custom.js.map +1 -0
- package/dist/guard/findings.d.ts +31 -0
- package/dist/guard/findings.js +156 -0
- package/dist/guard/findings.js.map +1 -0
- package/dist/guard/index.d.ts +24 -0
- package/dist/guard/index.js +42 -0
- package/dist/guard/index.js.map +1 -0
- package/dist/guard/integration.d.ts +44 -0
- package/dist/guard/integration.js +363 -0
- package/dist/guard/integration.js.map +1 -0
- package/dist/guard/moderation.d.ts +18 -0
- package/dist/guard/moderation.js +61 -0
- package/dist/guard/moderation.js.map +1 -0
- package/dist/guard/pii.d.ts +17 -0
- package/dist/guard/pii.js +114 -0
- package/dist/guard/pii.js.map +1 -0
- package/dist/guard/pipeline.d.ts +26 -0
- package/dist/guard/pipeline.js +139 -0
- package/dist/guard/pipeline.js.map +1 -0
- package/dist/guard/prompt-injection.d.ts +21 -0
- package/dist/guard/prompt-injection.js +70 -0
- package/dist/guard/prompt-injection.js.map +1 -0
- package/dist/guard/report.d.ts +34 -0
- package/dist/guard/report.js +182 -0
- package/dist/guard/report.js.map +1 -0
- package/dist/guard/schema.d.ts +20 -0
- package/dist/guard/schema.js +99 -0
- package/dist/guard/schema.js.map +1 -0
- package/dist/guard/sensitive-topic.d.ts +23 -0
- package/dist/guard/sensitive-topic.js +89 -0
- package/dist/guard/sensitive-topic.js.map +1 -0
- package/dist/guard/topic-restriction.d.ts +22 -0
- package/dist/guard/topic-restriction.js +54 -0
- package/dist/guard/topic-restriction.js.map +1 -0
- package/dist/helpers.d.ts +246 -0
- package/dist/helpers.js +903 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation/__tests__/ai21-rag-trace-comparison.test.d.ts +13 -0
- package/dist/instrumentation/__tests__/ai21-rag-trace-comparison.test.js +176 -0
- package/dist/instrumentation/__tests__/ai21-rag-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/ai21-trace-comparison.test.d.ts +10 -0
- package/dist/instrumentation/__tests__/ai21-trace-comparison.test.js +203 -0
- package/dist/instrumentation/__tests__/ai21-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.js +284 -0
- package/dist/instrumentation/__tests__/anthropic-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/assemblyai-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/assemblyai-wrapper.test.js +284 -0
- package/dist/instrumentation/__tests__/assemblyai-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/astra-trace-comparison.test.d.ts +7 -0
- package/dist/instrumentation/__tests__/astra-trace-comparison.test.js +160 -0
- package/dist/instrumentation/__tests__/astra-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.js +171 -0
- package/dist/instrumentation/__tests__/base-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/bedrock-trace-comparison.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/bedrock-trace-comparison.test.js +422 -0
- package/dist/instrumentation/__tests__/bedrock-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/browser-use-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/browser-use-wrapper.test.js +284 -0
- package/dist/instrumentation/__tests__/browser-use-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/cache-pricing.test.d.ts +15 -0
- package/dist/instrumentation/__tests__/cache-pricing.test.js +155 -0
- package/dist/instrumentation/__tests__/cache-pricing.test.js.map +1 -0
- package/dist/instrumentation/__tests__/chroma-trace-comparison.test.d.ts +18 -0
- package/dist/instrumentation/__tests__/chroma-trace-comparison.test.js +209 -0
- package/dist/instrumentation/__tests__/chroma-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.js +256 -0
- package/dist/instrumentation/__tests__/cohere-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/elevenlabs-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/elevenlabs-wrapper.test.js +282 -0
- package/dist/instrumentation/__tests__/elevenlabs-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/firecrawl-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/firecrawl-wrapper.test.js +238 -0
- package/dist/instrumentation/__tests__/firecrawl-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/google-ai-trace-comparison.test.d.ts +4 -0
- package/dist/instrumentation/__tests__/google-ai-trace-comparison.test.js +229 -0
- package/dist/instrumentation/__tests__/google-ai-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/gpu-collector.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/gpu-collector.test.js +247 -0
- package/dist/instrumentation/__tests__/gpu-collector.test.js.map +1 -0
- package/dist/instrumentation/__tests__/gradient-trace-comparison.test.d.ts +11 -0
- package/dist/instrumentation/__tests__/gradient-trace-comparison.test.js +391 -0
- package/dist/instrumentation/__tests__/gradient-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/groq-trace-comparison.test.d.ts +7 -0
- package/dist/instrumentation/__tests__/groq-trace-comparison.test.js +687 -0
- package/dist/instrumentation/__tests__/groq-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/helpers-genai.test.d.ts +14 -0
- package/dist/instrumentation/__tests__/helpers-genai.test.js +347 -0
- package/dist/instrumentation/__tests__/helpers-genai.test.js.map +1 -0
- package/dist/instrumentation/__tests__/huggingface-trace-comparison.test.d.ts +7 -0
- package/dist/instrumentation/__tests__/huggingface-trace-comparison.test.js +529 -0
- package/dist/instrumentation/__tests__/huggingface-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/langchain-role-map.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/langchain-role-map.test.js +19 -0
- package/dist/instrumentation/__tests__/langchain-role-map.test.js.map +1 -0
- package/dist/instrumentation/__tests__/langchain-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/langchain-wrapper.test.js +282 -0
- package/dist/instrumentation/__tests__/langchain-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/letta-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/letta-wrapper.test.js +285 -0
- package/dist/instrumentation/__tests__/letta-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/mem0-trace-comparison.test.d.ts +13 -0
- package/dist/instrumentation/__tests__/mem0-trace-comparison.test.js +208 -0
- package/dist/instrumentation/__tests__/mem0-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/milvus-trace-comparison.test.d.ts +17 -0
- package/dist/instrumentation/__tests__/milvus-trace-comparison.test.js +206 -0
- package/dist/instrumentation/__tests__/milvus-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/mistral-trace-comparison.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/mistral-trace-comparison.test.js +345 -0
- package/dist/instrumentation/__tests__/mistral-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.js +179 -0
- package/dist/instrumentation/__tests__/openai-wrapper.test.js.map +1 -0
- package/dist/instrumentation/__tests__/pg-trace-comparison.test.d.ts +21 -0
- package/dist/instrumentation/__tests__/pg-trace-comparison.test.js +455 -0
- package/dist/instrumentation/__tests__/pg-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/qdrant-trace-comparison.test.d.ts +17 -0
- package/dist/instrumentation/__tests__/qdrant-trace-comparison.test.js +182 -0
- package/dist/instrumentation/__tests__/qdrant-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/replicate-trace-comparison.test.d.ts +8 -0
- package/dist/instrumentation/__tests__/replicate-trace-comparison.test.js +346 -0
- package/dist/instrumentation/__tests__/replicate-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/together-trace-comparison.test.d.ts +4 -0
- package/dist/instrumentation/__tests__/together-trace-comparison.test.js +289 -0
- package/dist/instrumentation/__tests__/together-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/trace-comparison-utils.d.ts +67 -0
- package/dist/instrumentation/__tests__/trace-comparison-utils.js +255 -0
- package/dist/instrumentation/__tests__/trace-comparison-utils.js.map +1 -0
- package/dist/instrumentation/__tests__/transformers-trace-comparison.test.d.ts +11 -0
- package/dist/instrumentation/__tests__/transformers-trace-comparison.test.js +214 -0
- package/dist/instrumentation/__tests__/transformers-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/vercel-ai-trace-comparison.test.d.ts +8 -0
- package/dist/instrumentation/__tests__/vercel-ai-trace-comparison.test.js +446 -0
- package/dist/instrumentation/__tests__/vercel-ai-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/vertexai-trace-comparison.test.d.ts +6 -0
- package/dist/instrumentation/__tests__/vertexai-trace-comparison.test.js +409 -0
- package/dist/instrumentation/__tests__/vertexai-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/__tests__/vllm-trace-comparison.test.d.ts +1 -0
- package/dist/instrumentation/__tests__/vllm-trace-comparison.test.js +519 -0
- package/dist/instrumentation/__tests__/vllm-trace-comparison.test.js.map +1 -0
- package/dist/instrumentation/ai21/index.d.ts +11 -0
- package/dist/instrumentation/ai21/index.js +67 -0
- package/dist/instrumentation/ai21/index.js.map +1 -0
- package/dist/instrumentation/ai21/wrapper.d.ts +54 -0
- package/dist/instrumentation/ai21/wrapper.js +511 -0
- package/dist/instrumentation/ai21/wrapper.js.map +1 -0
- package/dist/instrumentation/anthropic/index.d.ts +11 -0
- package/dist/instrumentation/anthropic/index.js +45 -0
- package/dist/instrumentation/anthropic/index.js.map +1 -0
- package/dist/instrumentation/anthropic/wrapper.d.ts +34 -0
- package/dist/instrumentation/anthropic/wrapper.js +426 -0
- package/dist/instrumentation/anthropic/wrapper.js.map +1 -0
- package/dist/instrumentation/assemblyai/index.d.ts +12 -0
- package/dist/instrumentation/assemblyai/index.js +91 -0
- package/dist/instrumentation/assemblyai/index.js.map +1 -0
- package/dist/instrumentation/assemblyai/wrapper.d.ts +35 -0
- package/dist/instrumentation/assemblyai/wrapper.js +238 -0
- package/dist/instrumentation/assemblyai/wrapper.js.map +1 -0
- package/dist/instrumentation/astra/index.d.ts +11 -0
- package/dist/instrumentation/astra/index.js +87 -0
- package/dist/instrumentation/astra/index.js.map +1 -0
- package/dist/instrumentation/astra/wrapper.d.ts +39 -0
- package/dist/instrumentation/astra/wrapper.js +349 -0
- package/dist/instrumentation/astra/wrapper.js.map +1 -0
- package/dist/instrumentation/azure-ai-inference/index.d.ts +11 -0
- package/dist/instrumentation/azure-ai-inference/index.js +76 -0
- package/dist/instrumentation/azure-ai-inference/index.js.map +1 -0
- package/dist/instrumentation/azure-ai-inference/wrapper.d.ts +55 -0
- package/dist/instrumentation/azure-ai-inference/wrapper.js +580 -0
- package/dist/instrumentation/azure-ai-inference/wrapper.js.map +1 -0
- package/dist/instrumentation/base-wrapper.d.ts +16 -0
- package/dist/instrumentation/base-wrapper.js +139 -0
- package/dist/instrumentation/base-wrapper.js.map +1 -0
- package/dist/instrumentation/bedrock/index.d.ts +11 -0
- package/dist/instrumentation/bedrock/index.js +52 -0
- package/dist/instrumentation/bedrock/index.js.map +1 -0
- package/dist/instrumentation/bedrock/wrapper.d.ts +41 -0
- package/dist/instrumentation/bedrock/wrapper.js +494 -0
- package/dist/instrumentation/bedrock/wrapper.js.map +1 -0
- package/dist/instrumentation/browser-use/index.d.ts +11 -0
- package/dist/instrumentation/browser-use/index.js +98 -0
- package/dist/instrumentation/browser-use/index.js.map +1 -0
- package/dist/instrumentation/browser-use/wrapper.d.ts +12 -0
- package/dist/instrumentation/browser-use/wrapper.js +706 -0
- package/dist/instrumentation/browser-use/wrapper.js.map +1 -0
- package/dist/instrumentation/chroma/index.d.ts +11 -0
- package/dist/instrumentation/chroma/index.js +70 -0
- package/dist/instrumentation/chroma/index.js.map +1 -0
- package/dist/instrumentation/chroma/wrapper.d.ts +10 -0
- package/dist/instrumentation/chroma/wrapper.js +127 -0
- package/dist/instrumentation/chroma/wrapper.js.map +1 -0
- package/dist/instrumentation/claude-agent-sdk/index.d.ts +23 -0
- package/dist/instrumentation/claude-agent-sdk/index.js +83 -0
- package/dist/instrumentation/claude-agent-sdk/index.js.map +1 -0
- package/dist/instrumentation/claude-agent-sdk/wrapper.d.ts +13 -0
- package/dist/instrumentation/claude-agent-sdk/wrapper.js +1123 -0
- package/dist/instrumentation/claude-agent-sdk/wrapper.js.map +1 -0
- package/dist/instrumentation/cohere/index.d.ts +11 -0
- package/dist/instrumentation/cohere/index.js +53 -0
- package/dist/instrumentation/cohere/index.js.map +1 -0
- package/dist/instrumentation/cohere/wrapper.d.ts +50 -0
- package/dist/instrumentation/cohere/wrapper.js +452 -0
- package/dist/instrumentation/cohere/wrapper.js.map +1 -0
- package/dist/instrumentation/cursor-sdk/index.d.ts +21 -0
- package/dist/instrumentation/cursor-sdk/index.js +58 -0
- package/dist/instrumentation/cursor-sdk/index.js.map +1 -0
- package/dist/instrumentation/cursor-sdk/wrapper.d.ts +17 -0
- package/dist/instrumentation/cursor-sdk/wrapper.js +789 -0
- package/dist/instrumentation/cursor-sdk/wrapper.js.map +1 -0
- package/dist/instrumentation/elevenlabs/index.d.ts +12 -0
- package/dist/instrumentation/elevenlabs/index.js +92 -0
- package/dist/instrumentation/elevenlabs/index.js.map +1 -0
- package/dist/instrumentation/elevenlabs/wrapper.d.ts +34 -0
- package/dist/instrumentation/elevenlabs/wrapper.js +280 -0
- package/dist/instrumentation/elevenlabs/wrapper.js.map +1 -0
- package/dist/instrumentation/firecrawl/index.d.ts +13 -0
- package/dist/instrumentation/firecrawl/index.js +115 -0
- package/dist/instrumentation/firecrawl/index.js.map +1 -0
- package/dist/instrumentation/firecrawl/wrapper.d.ts +22 -0
- package/dist/instrumentation/firecrawl/wrapper.js +378 -0
- package/dist/instrumentation/firecrawl/wrapper.js.map +1 -0
- package/dist/instrumentation/google-adk/index.d.ts +57 -0
- package/dist/instrumentation/google-adk/index.js +371 -0
- package/dist/instrumentation/google-adk/index.js.map +1 -0
- package/dist/instrumentation/google-adk/utils.d.ts +45 -0
- package/dist/instrumentation/google-adk/utils.js +663 -0
- package/dist/instrumentation/google-adk/utils.js.map +1 -0
- package/dist/instrumentation/google-adk/wrapper.d.ts +11 -0
- package/dist/instrumentation/google-adk/wrapper.js +391 -0
- package/dist/instrumentation/google-adk/wrapper.js.map +1 -0
- package/dist/instrumentation/google-ai/index.d.ts +11 -0
- package/dist/instrumentation/google-ai/index.js +48 -0
- package/dist/instrumentation/google-ai/index.js.map +1 -0
- package/dist/instrumentation/google-ai/wrapper.d.ts +52 -0
- package/dist/instrumentation/google-ai/wrapper.js +466 -0
- package/dist/instrumentation/google-ai/wrapper.js.map +1 -0
- package/dist/instrumentation/gpu/index.d.ts +38 -0
- package/dist/instrumentation/gpu/index.js +233 -0
- package/dist/instrumentation/gpu/index.js.map +1 -0
- package/dist/instrumentation/gradient/index.d.ts +12 -0
- package/dist/instrumentation/gradient/index.js +74 -0
- package/dist/instrumentation/gradient/index.js.map +1 -0
- package/dist/instrumentation/gradient/utils.d.ts +14 -0
- package/dist/instrumentation/gradient/utils.js +119 -0
- package/dist/instrumentation/gradient/utils.js.map +1 -0
- package/dist/instrumentation/gradient/wrapper.d.ts +76 -0
- package/dist/instrumentation/gradient/wrapper.js +584 -0
- package/dist/instrumentation/gradient/wrapper.js.map +1 -0
- package/dist/instrumentation/groq/index.d.ts +11 -0
- package/dist/instrumentation/groq/index.js +43 -0
- package/dist/instrumentation/groq/index.js.map +1 -0
- package/dist/instrumentation/groq/wrapper.d.ts +35 -0
- package/dist/instrumentation/groq/wrapper.js +442 -0
- package/dist/instrumentation/groq/wrapper.js.map +1 -0
- package/dist/instrumentation/huggingface/index.d.ts +13 -0
- package/dist/instrumentation/huggingface/index.js +110 -0
- package/dist/instrumentation/huggingface/index.js.map +1 -0
- package/dist/instrumentation/huggingface/wrapper.d.ts +54 -0
- package/dist/instrumentation/huggingface/wrapper.js +514 -0
- package/dist/instrumentation/huggingface/wrapper.js.map +1 -0
- package/dist/instrumentation/index.d.ts +7 -0
- package/dist/instrumentation/index.js +176 -0
- package/dist/instrumentation/index.js.map +1 -0
- package/dist/instrumentation/langchain/index.d.ts +16 -0
- package/dist/instrumentation/langchain/index.js +91 -0
- package/dist/instrumentation/langchain/index.js.map +1 -0
- package/dist/instrumentation/langchain/wrapper.d.ts +41 -0
- package/dist/instrumentation/langchain/wrapper.js +1235 -0
- package/dist/instrumentation/langchain/wrapper.js.map +1 -0
- package/dist/instrumentation/langgraph/index.d.ts +12 -0
- package/dist/instrumentation/langgraph/index.js +99 -0
- package/dist/instrumentation/langgraph/index.js.map +1 -0
- package/dist/instrumentation/langgraph/wrapper.d.ts +20 -0
- package/dist/instrumentation/langgraph/wrapper.js +620 -0
- package/dist/instrumentation/langgraph/wrapper.js.map +1 -0
- package/dist/instrumentation/letta/index.d.ts +10 -0
- package/dist/instrumentation/letta/index.js +122 -0
- package/dist/instrumentation/letta/index.js.map +1 -0
- package/dist/instrumentation/letta/utils.d.ts +24 -0
- package/dist/instrumentation/letta/utils.js +343 -0
- package/dist/instrumentation/letta/utils.js.map +1 -0
- package/dist/instrumentation/letta/wrapper.d.ts +37 -0
- package/dist/instrumentation/letta/wrapper.js +180 -0
- package/dist/instrumentation/letta/wrapper.js.map +1 -0
- package/dist/instrumentation/llamaindex/index.d.ts +36 -0
- package/dist/instrumentation/llamaindex/index.js +221 -0
- package/dist/instrumentation/llamaindex/index.js.map +1 -0
- package/dist/instrumentation/llamaindex/wrapper.d.ts +36 -0
- package/dist/instrumentation/llamaindex/wrapper.js +811 -0
- package/dist/instrumentation/llamaindex/wrapper.js.map +1 -0
- package/dist/instrumentation/mcp/index.d.ts +20 -0
- package/dist/instrumentation/mcp/index.js +282 -0
- package/dist/instrumentation/mcp/index.js.map +1 -0
- package/dist/instrumentation/mcp/wrapper.d.ts +72 -0
- package/dist/instrumentation/mcp/wrapper.js +571 -0
- package/dist/instrumentation/mcp/wrapper.js.map +1 -0
- package/dist/instrumentation/mem0/index.d.ts +17 -0
- package/dist/instrumentation/mem0/index.js +113 -0
- package/dist/instrumentation/mem0/index.js.map +1 -0
- package/dist/instrumentation/mem0/wrapper.d.ts +37 -0
- package/dist/instrumentation/mem0/wrapper.js +298 -0
- package/dist/instrumentation/mem0/wrapper.js.map +1 -0
- package/dist/instrumentation/milvus/index.d.ts +11 -0
- package/dist/instrumentation/milvus/index.js +67 -0
- package/dist/instrumentation/milvus/index.js.map +1 -0
- package/dist/instrumentation/milvus/wrapper.d.ts +15 -0
- package/dist/instrumentation/milvus/wrapper.js +219 -0
- package/dist/instrumentation/milvus/wrapper.js.map +1 -0
- package/dist/instrumentation/mistral/index.d.ts +11 -0
- package/dist/instrumentation/mistral/index.js +66 -0
- package/dist/instrumentation/mistral/index.js.map +1 -0
- package/dist/instrumentation/mistral/wrapper.d.ts +49 -0
- package/dist/instrumentation/mistral/wrapper.js +482 -0
- package/dist/instrumentation/mistral/wrapper.js.map +1 -0
- package/dist/instrumentation/ollama/index.d.ts +11 -0
- package/dist/instrumentation/ollama/index.js +72 -0
- package/dist/instrumentation/ollama/index.js.map +1 -0
- package/dist/instrumentation/ollama/wrapper.d.ts +73 -0
- package/dist/instrumentation/ollama/wrapper.js +629 -0
- package/dist/instrumentation/ollama/wrapper.js.map +1 -0
- package/dist/instrumentation/openai/index.d.ts +11 -0
- package/dist/instrumentation/openai/index.js +79 -0
- package/dist/instrumentation/openai/index.js.map +1 -0
- package/dist/instrumentation/openai/wrapper.d.ts +80 -0
- package/dist/instrumentation/openai/wrapper.js +1121 -0
- package/dist/instrumentation/openai/wrapper.js.map +1 -0
- package/dist/instrumentation/openai-agents/index.d.ts +20 -0
- package/dist/instrumentation/openai-agents/index.js +174 -0
- package/dist/instrumentation/openai-agents/index.js.map +1 -0
- package/dist/instrumentation/openai-agents/processor.d.ts +35 -0
- package/dist/instrumentation/openai-agents/processor.js +249 -0
- package/dist/instrumentation/openai-agents/processor.js.map +1 -0
- package/dist/instrumentation/openai-agents/utils.d.ts +20 -0
- package/dist/instrumentation/openai-agents/utils.js +624 -0
- package/dist/instrumentation/openai-agents/utils.js.map +1 -0
- package/dist/instrumentation/pg/index.d.ts +20 -0
- package/dist/instrumentation/pg/index.js +74 -0
- package/dist/instrumentation/pg/index.js.map +1 -0
- package/dist/instrumentation/pg/wrapper.d.ts +66 -0
- package/dist/instrumentation/pg/wrapper.js +441 -0
- package/dist/instrumentation/pg/wrapper.js.map +1 -0
- package/dist/instrumentation/pinecone/index.d.ts +11 -0
- package/dist/instrumentation/pinecone/index.js +79 -0
- package/dist/instrumentation/pinecone/index.js.map +1 -0
- package/dist/instrumentation/pinecone/wrapper.d.ts +14 -0
- package/dist/instrumentation/pinecone/wrapper.js +198 -0
- package/dist/instrumentation/pinecone/wrapper.js.map +1 -0
- package/dist/instrumentation/qdrant/index.d.ts +11 -0
- package/dist/instrumentation/qdrant/index.js +67 -0
- package/dist/instrumentation/qdrant/index.js.map +1 -0
- package/dist/instrumentation/qdrant/wrapper.d.ts +14 -0
- package/dist/instrumentation/qdrant/wrapper.js +213 -0
- package/dist/instrumentation/qdrant/wrapper.js.map +1 -0
- package/dist/instrumentation/replicate/index.d.ts +11 -0
- package/dist/instrumentation/replicate/index.js +57 -0
- package/dist/instrumentation/replicate/index.js.map +1 -0
- package/dist/instrumentation/replicate/wrapper.d.ts +28 -0
- package/dist/instrumentation/replicate/wrapper.js +242 -0
- package/dist/instrumentation/replicate/wrapper.js.map +1 -0
- package/dist/instrumentation/strands/index.d.ts +21 -0
- package/dist/instrumentation/strands/index.js +83 -0
- package/dist/instrumentation/strands/index.js.map +1 -0
- package/dist/instrumentation/strands/processor.d.ts +51 -0
- package/dist/instrumentation/strands/processor.js +625 -0
- package/dist/instrumentation/strands/processor.js.map +1 -0
- package/dist/instrumentation/strands/utils.d.ts +24 -0
- package/dist/instrumentation/strands/utils.js +373 -0
- package/dist/instrumentation/strands/utils.js.map +1 -0
- package/dist/instrumentation/together/index.d.ts +11 -0
- package/dist/instrumentation/together/index.js +43 -0
- package/dist/instrumentation/together/index.js.map +1 -0
- package/dist/instrumentation/together/wrapper.d.ts +48 -0
- package/dist/instrumentation/together/wrapper.js +409 -0
- package/dist/instrumentation/together/wrapper.js.map +1 -0
- package/dist/instrumentation/transformers/index.d.ts +35 -0
- package/dist/instrumentation/transformers/index.js +119 -0
- package/dist/instrumentation/transformers/index.js.map +1 -0
- package/dist/instrumentation/transformers/wrapper.d.ts +49 -0
- package/dist/instrumentation/transformers/wrapper.js +472 -0
- package/dist/instrumentation/transformers/wrapper.js.map +1 -0
- package/dist/instrumentation/vercel-ai/index.d.ts +10 -0
- package/dist/instrumentation/vercel-ai/index.js +59 -0
- package/dist/instrumentation/vercel-ai/index.js.map +1 -0
- package/dist/instrumentation/vercel-ai/wrapper.d.ts +50 -0
- package/dist/instrumentation/vercel-ai/wrapper.js +539 -0
- package/dist/instrumentation/vercel-ai/wrapper.js.map +1 -0
- package/dist/instrumentation/vertexai/index.d.ts +11 -0
- package/dist/instrumentation/vertexai/index.js +70 -0
- package/dist/instrumentation/vertexai/index.js.map +1 -0
- package/dist/instrumentation/vertexai/wrapper.d.ts +67 -0
- package/dist/instrumentation/vertexai/wrapper.js +530 -0
- package/dist/instrumentation/vertexai/wrapper.js.map +1 -0
- package/dist/instrumentation/vllm/index.d.ts +13 -0
- package/dist/instrumentation/vllm/index.js +67 -0
- package/dist/instrumentation/vllm/index.js.map +1 -0
- package/dist/instrumentation/vllm/wrapper.d.ts +60 -0
- package/dist/instrumentation/vllm/wrapper.js +482 -0
- package/dist/instrumentation/vllm/wrapper.js.map +1 -0
- package/dist/llm/anthropic.d.ts +5 -0
- package/dist/llm/anthropic.js +39 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/index.d.ts +10 -0
- package/dist/llm/index.js +93 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/openai.d.ts +6 -0
- package/dist/llm/openai.js +52 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/providers.d.ts +7 -0
- package/dist/llm/providers.js +10 -0
- package/dist/llm/providers.js.map +1 -0
- package/dist/manual-trace.d.ts +40 -0
- package/dist/manual-trace.js +103 -0
- package/dist/manual-trace.js.map +1 -0
- package/dist/otel/__tests__/metrics.test.d.ts +1 -0
- package/dist/otel/__tests__/metrics.test.js +40 -0
- package/dist/otel/__tests__/metrics.test.js.map +1 -0
- package/dist/otel/events.d.ts +11 -0
- package/dist/otel/events.js +74 -0
- package/dist/otel/events.js.map +1 -0
- package/dist/otel/metrics.d.ts +35 -0
- package/dist/otel/metrics.js +219 -0
- package/dist/otel/metrics.js.map +1 -0
- package/dist/otel/tracing.d.ts +12 -0
- package/dist/otel/tracing.js +93 -0
- package/dist/otel/tracing.js.map +1 -0
- package/dist/otel/utils.d.ts +11 -0
- package/dist/otel/utils.js +34 -0
- package/dist/otel/utils.js.map +1 -0
- package/dist/pricing.json +951 -0
- package/dist/prompt-hub.d.ts +4 -0
- package/dist/prompt-hub.js +66 -0
- package/dist/prompt-hub.js.map +1 -0
- package/dist/register.d.ts +4 -0
- package/dist/register.js +52 -0
- package/dist/register.js.map +1 -0
- package/dist/score/__tests__/score.test.d.ts +1 -0
- package/dist/score/__tests__/score.test.js +143 -0
- package/dist/score/__tests__/score.test.js.map +1 -0
- package/dist/score/index.d.ts +2 -0
- package/dist/score/index.js +6 -0
- package/dist/score/index.js.map +1 -0
- package/dist/score/score.d.ts +15 -0
- package/dist/score/score.js +135 -0
- package/dist/score/score.js.map +1 -0
- package/dist/semantic-convention.d.ts +555 -0
- package/dist/semantic-convention.js +630 -0
- package/dist/semantic-convention.js.map +1 -0
- package/dist/types.d.ts +131 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +136 -0
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OTEL_ASSISTANT_ROLE = exports.LANGCHAIN_ROLE_MAP = void 0;
|
|
7
|
+
exports.isFrameworkLlmActive = isFrameworkLlmActive;
|
|
8
|
+
exports.runWithFrameworkLlm = runWithFrameworkLlm;
|
|
9
|
+
exports.setFrameworkLlmActive = setFrameworkLlmActive;
|
|
10
|
+
exports.resetFrameworkLlmActive = resetFrameworkLlmActive;
|
|
11
|
+
exports.getCurrentAgentVersion = getCurrentAgentVersion;
|
|
12
|
+
exports.setAgentVersion = setAgentVersion;
|
|
13
|
+
exports.resetAgentVersion = resetAgentVersion;
|
|
14
|
+
exports.runWithAgentVersion = runWithAgentVersion;
|
|
15
|
+
exports.isLangGraphActive = isLangGraphActive;
|
|
16
|
+
exports.runWithLangGraph = runWithLangGraph;
|
|
17
|
+
exports.isCreateAgentActive = isCreateAgentActive;
|
|
18
|
+
exports.runWithCreateAgent = runWithCreateAgent;
|
|
19
|
+
exports.getLangGraphConversationId = getLangGraphConversationId;
|
|
20
|
+
exports.runWithLangGraphConversationId = runWithLangGraphConversationId;
|
|
21
|
+
exports.getFrameworkParentContext = getFrameworkParentContext;
|
|
22
|
+
exports.setFrameworkParentContext = setFrameworkParentContext;
|
|
23
|
+
exports.clearFrameworkParentContext = clearFrameworkParentContext;
|
|
24
|
+
exports.getServerAddressForProvider = getServerAddressForProvider;
|
|
25
|
+
exports.mapLangChainRole = mapLangChainRole;
|
|
26
|
+
exports.applyCustomSpanAttributes = applyCustomSpanAttributes;
|
|
27
|
+
exports.getMergedCustomAttributes = getMergedCustomAttributes;
|
|
28
|
+
exports.injectAdditionalAttributes = injectAdditionalAttributes;
|
|
29
|
+
exports.usingAttributes = usingAttributes;
|
|
30
|
+
const pricing_json_1 = __importDefault(require("./pricing.json"));
|
|
31
|
+
const js_tiktoken_1 = require("js-tiktoken");
|
|
32
|
+
const crypto_1 = require("crypto");
|
|
33
|
+
const api_1 = require("@opentelemetry/api");
|
|
34
|
+
const api_logs_1 = require("@opentelemetry/api-logs");
|
|
35
|
+
const async_hooks_1 = require("async_hooks");
|
|
36
|
+
const semantic_convention_1 = __importDefault(require("./semantic-convention"));
|
|
37
|
+
const events_1 = __importDefault(require("./otel/events"));
|
|
38
|
+
const config_1 = __importDefault(require("./config"));
|
|
39
|
+
/**
|
|
40
|
+
* AsyncLocalStorage for context-scoped custom span attributes.
|
|
41
|
+
* Mirrors Python's ContextVar _custom_span_attributes, used by
|
|
42
|
+
* usingAttributes() and injectAdditionalAttributes().
|
|
43
|
+
*/
|
|
44
|
+
const _customSpanAttributes = new async_hooks_1.AsyncLocalStorage();
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Framework LLM span suppression flags (mirrors Python SDK ContextVars)
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
const _frameworkLlmActive = new async_hooks_1.AsyncLocalStorage();
|
|
49
|
+
/**
|
|
50
|
+
* Returns true when a framework instrumentor (LangChain, LiteLLM, etc.)
|
|
51
|
+
* owns the current LLM span. Provider-level wrappers (OpenAI, Anthropic, …)
|
|
52
|
+
* must skip their own span creation when this returns true.
|
|
53
|
+
*/
|
|
54
|
+
function isFrameworkLlmActive() {
|
|
55
|
+
return _frameworkLlmActive.getStore() === true;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Run `fn` with the framework-LLM-active flag set. All provider wrappers
|
|
59
|
+
* invoked inside `fn` will see `isFrameworkLlmActive() === true`.
|
|
60
|
+
*/
|
|
61
|
+
function runWithFrameworkLlm(fn) {
|
|
62
|
+
return _frameworkLlmActive.run(true, fn);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Set framework-LLM-active flag in the current execution context.
|
|
66
|
+
* Used by SpanProcessor-based instrumentations (Strands) where
|
|
67
|
+
* the processor observes spans rather than controlling execution.
|
|
68
|
+
* Mirrors Python's ContextVar.set(True) in Strands processor.
|
|
69
|
+
*/
|
|
70
|
+
function setFrameworkLlmActive() {
|
|
71
|
+
_frameworkLlmActive.enterWith(true);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Reset framework-LLM-active flag in the current execution context.
|
|
75
|
+
* Mirrors Python's ContextVar.reset(token) in Strands processor.
|
|
76
|
+
*/
|
|
77
|
+
function resetFrameworkLlmActive() {
|
|
78
|
+
_frameworkLlmActive.enterWith(false);
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// User-supplied agent version label (mirrors Python's _current_agent_version)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
const _currentAgentVersion = new async_hooks_1.AsyncLocalStorage();
|
|
84
|
+
/**
|
|
85
|
+
* Returns the user-supplied agent version label set via
|
|
86
|
+
* `Shield360.setAgentVersion()` / `runWithAgentVersion()`, if any.
|
|
87
|
+
*
|
|
88
|
+
* Provider wrappers stamp this on `gen_ai.agent.version` so the server-side
|
|
89
|
+
* materializer can group traces by the user's preferred label in addition to
|
|
90
|
+
* the auto-computed `shield360.agent.version_hash` fingerprint.
|
|
91
|
+
*/
|
|
92
|
+
function getCurrentAgentVersion() {
|
|
93
|
+
return _currentAgentVersion.getStore();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Set the agent version label for the current execution context.
|
|
97
|
+
*
|
|
98
|
+
* IMPORTANT: this uses `AsyncLocalStorage.enterWith` which permanently
|
|
99
|
+
* mutates the current async resource. Sequential requests handled on the
|
|
100
|
+
* same Node worker (or reused thread/connection) will inherit the label
|
|
101
|
+
* until something overwrites or clears it. **Always pair with a matching
|
|
102
|
+
* `resetAgentVersion()` in a `finally` block**, or prefer
|
|
103
|
+
* `runWithAgentVersion(label, fn)` which guarantees scoped cleanup.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* try {
|
|
107
|
+
* setAgentVersion('hotfix-2026-05-12');
|
|
108
|
+
* await runAgent();
|
|
109
|
+
* } finally {
|
|
110
|
+
* resetAgentVersion();
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // Preferred — automatic scope cleanup, no leak risk:
|
|
115
|
+
* await runWithAgentVersion('hotfix-2026-05-12', () => runAgent());
|
|
116
|
+
*/
|
|
117
|
+
function setAgentVersion(version) {
|
|
118
|
+
if (typeof version !== 'string' || version.length === 0)
|
|
119
|
+
return;
|
|
120
|
+
_currentAgentVersion.enterWith(version);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Clear the agent version label set by `setAgentVersion()`. No-op if no
|
|
124
|
+
* label is active. See the `setAgentVersion` docstring for the leak
|
|
125
|
+
* scenario this guards against.
|
|
126
|
+
*/
|
|
127
|
+
function resetAgentVersion() {
|
|
128
|
+
_currentAgentVersion.enterWith(undefined);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Run `fn` with the given agent version label bound to the current async
|
|
132
|
+
* scope. Mirrors `shield360.agent_version_context()` in Python and is the
|
|
133
|
+
* recommended way to attach a label — the store is automatically restored
|
|
134
|
+
* when `fn` resolves so there is no risk of leaking the label across
|
|
135
|
+
* subsequent requests.
|
|
136
|
+
*/
|
|
137
|
+
function runWithAgentVersion(version, fn) {
|
|
138
|
+
return _currentAgentVersion.run(version, fn);
|
|
139
|
+
}
|
|
140
|
+
const _langGraphActive = new async_hooks_1.AsyncLocalStorage();
|
|
141
|
+
/**
|
|
142
|
+
* Returns true when a LangGraph wrapper is controlling execution.
|
|
143
|
+
* LangChain's callback handler skips its own invoke_workflow span when true.
|
|
144
|
+
*/
|
|
145
|
+
function isLangGraphActive() {
|
|
146
|
+
return _langGraphActive.getStore() === true;
|
|
147
|
+
}
|
|
148
|
+
function runWithLangGraph(fn) {
|
|
149
|
+
return _langGraphActive.run(true, fn);
|
|
150
|
+
}
|
|
151
|
+
const _createAgentActive = new async_hooks_1.AsyncLocalStorage();
|
|
152
|
+
/**
|
|
153
|
+
* Returns true when a create_agent span is already being handled
|
|
154
|
+
* (prevents duplicate spans between LangChain and LangGraph).
|
|
155
|
+
*/
|
|
156
|
+
function isCreateAgentActive() {
|
|
157
|
+
return _createAgentActive.getStore() === true;
|
|
158
|
+
}
|
|
159
|
+
function runWithCreateAgent(fn) {
|
|
160
|
+
return _createAgentActive.run(true, fn);
|
|
161
|
+
}
|
|
162
|
+
const _langGraphConversationId = new async_hooks_1.AsyncLocalStorage();
|
|
163
|
+
/**
|
|
164
|
+
* Propagate conversation ID from invoke_workflow to child node spans.
|
|
165
|
+
* Mirrors Python's set_langgraph_conversation_id / get_langgraph_conversation_id.
|
|
166
|
+
*/
|
|
167
|
+
function getLangGraphConversationId() {
|
|
168
|
+
return _langGraphConversationId.getStore();
|
|
169
|
+
}
|
|
170
|
+
function runWithLangGraphConversationId(conversationId, fn) {
|
|
171
|
+
return _langGraphConversationId.run(conversationId, fn);
|
|
172
|
+
}
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// Framework parent context propagation (mirrors Python context_api.attach)
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
const _frameworkParentContext = new async_hooks_1.AsyncLocalStorage();
|
|
177
|
+
/**
|
|
178
|
+
* Returns the OTel context set by a framework processor (OpenAI Agents, etc.)
|
|
179
|
+
* so that provider wrappers can create spans as children of framework spans.
|
|
180
|
+
* Mirrors Python's context_api.attach(set_span_in_context(span)).
|
|
181
|
+
*/
|
|
182
|
+
function getFrameworkParentContext() {
|
|
183
|
+
return _frameworkParentContext.getStore() || undefined;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Set the OTel parent context for provider span creation.
|
|
187
|
+
* Called by processor-based frameworks that cannot use context.with().
|
|
188
|
+
*/
|
|
189
|
+
function setFrameworkParentContext(ctx) {
|
|
190
|
+
_frameworkParentContext.enterWith(ctx);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Clear the framework parent context.
|
|
194
|
+
*/
|
|
195
|
+
function clearFrameworkParentContext() {
|
|
196
|
+
_frameworkParentContext.enterWith(undefined);
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Provider default endpoints (mirrors Python PROVIDER_DEFAULT_ENDPOINTS)
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
const PROVIDER_DEFAULT_ENDPOINTS = {
|
|
202
|
+
openai: ['api.openai.com', 443],
|
|
203
|
+
anthropic: ['api.anthropic.com', 443],
|
|
204
|
+
google: ['generativelanguage.googleapis.com', 443],
|
|
205
|
+
'gcp.gemini': ['generativelanguage.googleapis.com', 443],
|
|
206
|
+
'gcp.vertex_ai': ['aiplatform.googleapis.com', 443],
|
|
207
|
+
mistral_ai: ['api.mistral.ai', 443],
|
|
208
|
+
groq: ['api.groq.com', 443],
|
|
209
|
+
ai21: ['api.ai21.com', 443],
|
|
210
|
+
digitalocean: ['inference.do-ai.run', 443],
|
|
211
|
+
together: ['api.together.xyz', 443],
|
|
212
|
+
fireworks: ['api.fireworks.ai', 443],
|
|
213
|
+
perplexity: ['api.perplexity.ai', 443],
|
|
214
|
+
deepinfra: ['api.deepinfra.com', 443],
|
|
215
|
+
'aws.bedrock': ['bedrock-runtime.amazonaws.com', 443],
|
|
216
|
+
azure: ['openai.azure.com', 443],
|
|
217
|
+
'azure.ai.openai': ['openai.azure.com', 443],
|
|
218
|
+
'azure.ai.inference': ['inference.ai.azure.com', 443],
|
|
219
|
+
cohere: ['api.cohere.ai', 443],
|
|
220
|
+
ollama: ['localhost', 11434],
|
|
221
|
+
deepseek: ['api.deepseek.com', 443],
|
|
222
|
+
x_ai: ['api.x.ai', 443],
|
|
223
|
+
huggingface: ['api-inference.huggingface.co', 443],
|
|
224
|
+
cursor: ['api2.cursor.sh', 443],
|
|
225
|
+
};
|
|
226
|
+
function getServerAddressForProvider(provider) {
|
|
227
|
+
return PROVIDER_DEFAULT_ENDPOINTS[provider] || ['', 0];
|
|
228
|
+
}
|
|
229
|
+
/** LangChain/LangGraph message type → OTel GenAI role (mirrors Python LANGCHAIN_ROLE_MAPPING). */
|
|
230
|
+
exports.LANGCHAIN_ROLE_MAP = {
|
|
231
|
+
system: 'system',
|
|
232
|
+
human: 'user',
|
|
233
|
+
ai: 'assistant',
|
|
234
|
+
tool: 'tool',
|
|
235
|
+
function: 'tool',
|
|
236
|
+
};
|
|
237
|
+
exports.OTEL_ASSISTANT_ROLE = exports.LANGCHAIN_ROLE_MAP.ai;
|
|
238
|
+
/** Map a raw LangChain message type/role to the OTel GenAI convention value. */
|
|
239
|
+
function mapLangChainRole(rawRole) {
|
|
240
|
+
if (!rawRole) {
|
|
241
|
+
return exports.OTEL_ASSISTANT_ROLE;
|
|
242
|
+
}
|
|
243
|
+
return exports.LANGCHAIN_ROLE_MAP[rawRole] ?? rawRole;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Apply global (from init) and context-scoped (from usingAttributes /
|
|
247
|
+
* injectAdditionalAttributes) custom attributes to a span.
|
|
248
|
+
* Global attributes are applied first; context attributes override on conflict.
|
|
249
|
+
* Matches Python's _apply_custom_span_attributes().
|
|
250
|
+
*/
|
|
251
|
+
function applyCustomSpanAttributes(span) {
|
|
252
|
+
const globalAttrs = config_1.default.customSpanAttributes;
|
|
253
|
+
if (globalAttrs) {
|
|
254
|
+
for (const [key, value] of Object.entries(globalAttrs)) {
|
|
255
|
+
span.setAttribute(key, value);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const contextAttrs = _customSpanAttributes.getStore();
|
|
259
|
+
if (contextAttrs) {
|
|
260
|
+
for (const [key, value] of Object.entries(contextAttrs)) {
|
|
261
|
+
span.setAttribute(key, value);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get merged custom attributes (global + context) for use in events.
|
|
267
|
+
* Returns a flat object; context attributes override global on conflict.
|
|
268
|
+
*/
|
|
269
|
+
function getMergedCustomAttributes() {
|
|
270
|
+
const merged = {};
|
|
271
|
+
const globalAttrs = config_1.default.customSpanAttributes;
|
|
272
|
+
if (globalAttrs) {
|
|
273
|
+
Object.assign(merged, globalAttrs);
|
|
274
|
+
}
|
|
275
|
+
const contextAttrs = _customSpanAttributes.getStore();
|
|
276
|
+
if (contextAttrs) {
|
|
277
|
+
Object.assign(merged, contextAttrs);
|
|
278
|
+
}
|
|
279
|
+
return merged;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Run a function with custom span attributes attached to all
|
|
283
|
+
* auto-instrumented spans created during its execution.
|
|
284
|
+
* Matches Python's shield360.inject_additional_attributes().
|
|
285
|
+
*/
|
|
286
|
+
function injectAdditionalAttributes(fn, attributes) {
|
|
287
|
+
return _customSpanAttributes.run(attributes, fn);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Context wrapper that adds custom attributes to all auto-instrumented
|
|
291
|
+
* spans created within its callback scope.
|
|
292
|
+
* Matches Python's shield360.using_attributes() context manager.
|
|
293
|
+
*
|
|
294
|
+
* Usage:
|
|
295
|
+
* await usingAttributes({"user.id": "u1", "team": "ml"}, async () => {
|
|
296
|
+
* await client.chat.completions.create(...);
|
|
297
|
+
* });
|
|
298
|
+
*/
|
|
299
|
+
function usingAttributes(attributes, fn) {
|
|
300
|
+
return _customSpanAttributes.run(attributes, fn);
|
|
301
|
+
}
|
|
302
|
+
class Shield360Helper {
|
|
303
|
+
static openaiTokens(text, model) {
|
|
304
|
+
try {
|
|
305
|
+
const encoding = (0, js_tiktoken_1.encodingForModel)(model);
|
|
306
|
+
return encoding.encode(text).length;
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
return Shield360Helper.generalTokens(text);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
static generalTokens(text) {
|
|
313
|
+
const encoding = (0, js_tiktoken_1.encodingForModel)('gpt2');
|
|
314
|
+
return encoding.encode(text).length;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Compute chat completion cost, optionally accounting for prompt-cache tokens.
|
|
318
|
+
*
|
|
319
|
+
* When the model's pricing entry defines `cacheReadPrice` / `cacheCreationPrice`,
|
|
320
|
+
* the matching cache tokens are billed at those rates instead of the regular
|
|
321
|
+
* prompt price.
|
|
322
|
+
*
|
|
323
|
+
* Token accounting differs across providers:
|
|
324
|
+
* - Anthropic's native API reports `promptTokens` exclusive of cache tokens,
|
|
325
|
+
* so cache tokens are added on top (keep `promptTokensIncludeCache` false).
|
|
326
|
+
* - OpenAI / LangChain report `promptTokens` inclusive of cache read tokens,
|
|
327
|
+
* so pass `promptTokensIncludeCache: true` to subtract the re-priced cache
|
|
328
|
+
* tokens from the prompt base and avoid billing them twice.
|
|
329
|
+
*
|
|
330
|
+
* Cache tokens are only re-priced (and, when inclusive, only subtracted) when a
|
|
331
|
+
* dedicated cache price exists, so the result is identical to the legacy
|
|
332
|
+
* behaviour for any model without cache pricing configured.
|
|
333
|
+
*/
|
|
334
|
+
static getChatModelCost(model, pricingInfo, promptTokens, completionTokens, cacheReadTokens = 0, cacheCreationTokens = 0, promptTokensIncludeCache = false) {
|
|
335
|
+
try {
|
|
336
|
+
const chatPricing = pricingInfo?.chat;
|
|
337
|
+
if (!chatPricing)
|
|
338
|
+
return 0;
|
|
339
|
+
let modelPricing = chatPricing[model];
|
|
340
|
+
if (modelPricing == null && model.includes('/')) {
|
|
341
|
+
modelPricing = chatPricing[model.split('/', 2)[1]];
|
|
342
|
+
}
|
|
343
|
+
if (modelPricing == null)
|
|
344
|
+
return 0;
|
|
345
|
+
const cacheRead = cacheReadTokens || 0;
|
|
346
|
+
const cacheCreation = cacheCreationTokens || 0;
|
|
347
|
+
let billablePromptTokens = promptTokens;
|
|
348
|
+
let cacheCost = 0;
|
|
349
|
+
if (modelPricing.cacheReadPrice != null) {
|
|
350
|
+
cacheCost += (cacheRead / Shield360Helper.PROMPT_TOKEN_FACTOR) * modelPricing.cacheReadPrice;
|
|
351
|
+
if (promptTokensIncludeCache) {
|
|
352
|
+
billablePromptTokens -= cacheRead;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (modelPricing.cacheCreationPrice != null) {
|
|
356
|
+
cacheCost +=
|
|
357
|
+
(cacheCreation / Shield360Helper.PROMPT_TOKEN_FACTOR) * modelPricing.cacheCreationPrice;
|
|
358
|
+
if (promptTokensIncludeCache) {
|
|
359
|
+
billablePromptTokens -= cacheCreation;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (billablePromptTokens < 0) {
|
|
363
|
+
billablePromptTokens = 0;
|
|
364
|
+
}
|
|
365
|
+
const cost = (billablePromptTokens / Shield360Helper.PROMPT_TOKEN_FACTOR) * modelPricing.promptPrice +
|
|
366
|
+
(completionTokens / Shield360Helper.PROMPT_TOKEN_FACTOR) * modelPricing.completionPrice +
|
|
367
|
+
cacheCost;
|
|
368
|
+
return isNaN(cost) ? 0 : cost;
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
return 0;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
static getEmbedModelCost(model, pricingInfo, promptTokens) {
|
|
375
|
+
try {
|
|
376
|
+
const embedPricing = pricingInfo?.embeddings;
|
|
377
|
+
if (!embedPricing)
|
|
378
|
+
return 0;
|
|
379
|
+
let unitCost = embedPricing[model];
|
|
380
|
+
if (unitCost == null && model.includes('/')) {
|
|
381
|
+
unitCost = embedPricing[model.split('/', 2)[1]];
|
|
382
|
+
}
|
|
383
|
+
if (unitCost == null)
|
|
384
|
+
return 0;
|
|
385
|
+
const cost = (promptTokens / Shield360Helper.PROMPT_TOKEN_FACTOR) * unitCost;
|
|
386
|
+
return isNaN(cost) ? 0 : cost;
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return 0;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
static getImageModelCost(model, pricingInfo, size, quality) {
|
|
393
|
+
try {
|
|
394
|
+
const cost = pricingInfo.images[model][quality][size];
|
|
395
|
+
return isNaN(cost) ? 0 : cost;
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
console.error(`Error in getImageModelCost: ${error}`);
|
|
399
|
+
return 0;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
static getAudioModelCost(model, pricingInfo, prompt, duration) {
|
|
403
|
+
try {
|
|
404
|
+
const rate = pricingInfo?.audio?.[model];
|
|
405
|
+
if (typeof rate !== 'number') {
|
|
406
|
+
return 0;
|
|
407
|
+
}
|
|
408
|
+
if (prompt) {
|
|
409
|
+
const cost = (prompt.length / Shield360Helper.PROMPT_TOKEN_FACTOR) * rate;
|
|
410
|
+
return isNaN(cost) ? 0 : cost;
|
|
411
|
+
}
|
|
412
|
+
const durationSeconds = typeof duration === 'number' && Number.isFinite(duration) ? duration : 0;
|
|
413
|
+
const cost = durationSeconds * rate;
|
|
414
|
+
return isNaN(cost) ? 0 : cost;
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
console.error(`Error in getAudioModelCost: ${error}`);
|
|
418
|
+
return 0;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
static async fetchPricingInfo(pricingJson) {
|
|
422
|
+
// SHIELD: use the pricing data shipped with the SDK unless a source is given.
|
|
423
|
+
if (!pricingJson) {
|
|
424
|
+
return JSON.parse(JSON.stringify(pricing_json_1.default));
|
|
425
|
+
}
|
|
426
|
+
let pricingUrl = '';
|
|
427
|
+
if (pricingJson) {
|
|
428
|
+
let isUrl = false;
|
|
429
|
+
try {
|
|
430
|
+
isUrl = !!new URL(pricingJson);
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
isUrl = false;
|
|
434
|
+
}
|
|
435
|
+
if (isUrl) {
|
|
436
|
+
pricingUrl = pricingJson;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
try {
|
|
440
|
+
if (typeof pricingJson === 'string') {
|
|
441
|
+
const json = JSON.parse(pricingJson);
|
|
442
|
+
return json;
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
const json = JSON.parse(JSON.stringify(pricingJson));
|
|
446
|
+
return json;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
return {};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
const response = await fetch(pricingUrl);
|
|
456
|
+
if (response.ok) {
|
|
457
|
+
return response.json();
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
throw new Error(`HTTP error occurred while fetching pricing info: ${response.status}`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
console.error(`Unexpected error occurred while fetching pricing info: ${error}`);
|
|
465
|
+
return {};
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Build OTel-spec input messages JSON string from provider messages array.
|
|
470
|
+
* Format: [{"role": "user", "parts": [{"type": "text", "content": "..."}]}]
|
|
471
|
+
*/
|
|
472
|
+
static buildInputMessages(messages, system) {
|
|
473
|
+
try {
|
|
474
|
+
const otelMessages = [];
|
|
475
|
+
if (system) {
|
|
476
|
+
otelMessages.push({ role: 'system', parts: [{ type: 'text', content: system }] });
|
|
477
|
+
}
|
|
478
|
+
for (const msg of messages || []) {
|
|
479
|
+
const role = msg.role || 'user';
|
|
480
|
+
const content = msg.content;
|
|
481
|
+
const parts = [];
|
|
482
|
+
if (typeof content === 'string' && content) {
|
|
483
|
+
parts.push({ type: 'text', content });
|
|
484
|
+
}
|
|
485
|
+
else if (Array.isArray(content)) {
|
|
486
|
+
for (const item of content) {
|
|
487
|
+
const t = item.type;
|
|
488
|
+
if (t === 'text') {
|
|
489
|
+
parts.push({ type: 'text', content: item.text || '' });
|
|
490
|
+
}
|
|
491
|
+
else if (t === 'image_url') {
|
|
492
|
+
const url = item.image_url?.url || '';
|
|
493
|
+
if (url && !url.startsWith('data:')) {
|
|
494
|
+
parts.push({ type: 'uri', modality: 'image', uri: url });
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else if (t === 'image') {
|
|
498
|
+
// Anthropic image format
|
|
499
|
+
const url = item.source?.url || '';
|
|
500
|
+
if (url && !url.startsWith('data:')) {
|
|
501
|
+
parts.push({ type: 'uri', modality: 'image', uri: url });
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
else if (t === 'tool_use') {
|
|
505
|
+
parts.push({ type: 'tool_call', id: item.id || '', name: item.name || '', arguments: item.input || {} });
|
|
506
|
+
}
|
|
507
|
+
else if (t === 'tool_result') {
|
|
508
|
+
parts.push({ type: 'tool_call_response', id: item.tool_use_id || '', response: typeof item.content === 'string' ? item.content : JSON.stringify(item.content || '') });
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Handle tool_calls in message (OpenAI assistant format)
|
|
513
|
+
if (msg.tool_calls && Array.isArray(msg.tool_calls)) {
|
|
514
|
+
for (const tc of msg.tool_calls) {
|
|
515
|
+
let args = tc.function?.arguments || {};
|
|
516
|
+
if (typeof args === 'string') {
|
|
517
|
+
try {
|
|
518
|
+
args = JSON.parse(args);
|
|
519
|
+
}
|
|
520
|
+
catch {
|
|
521
|
+
args = { raw: args };
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
parts.push({ type: 'tool_call', id: tc.id || '', name: tc.function?.name || '', arguments: args });
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (parts.length > 0) {
|
|
528
|
+
otelMessages.push({ role, parts });
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return JSON.stringify(otelMessages);
|
|
532
|
+
}
|
|
533
|
+
catch {
|
|
534
|
+
return '[]';
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Extract system message(s) from a chat-completions messages array.
|
|
539
|
+
* Returns an OTel ``gen_ai.system_instructions`` payload
|
|
540
|
+
* (``[{"type": "text", "content": "..."}]``) JSON-encoded as a string,
|
|
541
|
+
* or ``undefined`` when no system message is present.
|
|
542
|
+
*
|
|
543
|
+
* Mirrors Python's ``build_system_instructions_from_messages``.
|
|
544
|
+
*/
|
|
545
|
+
static buildSystemInstructionsFromMessages(messages) {
|
|
546
|
+
if (!Array.isArray(messages) || messages.length === 0)
|
|
547
|
+
return undefined;
|
|
548
|
+
try {
|
|
549
|
+
const instructions = [];
|
|
550
|
+
for (const msg of messages) {
|
|
551
|
+
if (!msg || msg.role !== 'system')
|
|
552
|
+
continue;
|
|
553
|
+
const content = msg.content;
|
|
554
|
+
if (Array.isArray(content)) {
|
|
555
|
+
for (const part of content) {
|
|
556
|
+
if (part && part.type === 'text' && part.text) {
|
|
557
|
+
instructions.push({ type: 'text', content: String(part.text) });
|
|
558
|
+
}
|
|
559
|
+
else if (typeof part === 'string' && part) {
|
|
560
|
+
instructions.push({ type: 'text', content: part });
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
else if (content) {
|
|
565
|
+
instructions.push({ type: 'text', content: String(content) });
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
if (instructions.length === 0)
|
|
569
|
+
return undefined;
|
|
570
|
+
return JSON.stringify(instructions);
|
|
571
|
+
}
|
|
572
|
+
catch {
|
|
573
|
+
return undefined;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Normalize a request ``tools`` array into the OTel
|
|
578
|
+
* ``gen_ai.tool.definitions`` schema and return it as a JSON string,
|
|
579
|
+
* or ``undefined`` when there is nothing usable.
|
|
580
|
+
*
|
|
581
|
+
* Accepts both the OpenAI-style schema
|
|
582
|
+
* (``{"type": "function", "function": {...}}``) and the flat schema
|
|
583
|
+
* (``{"name": ..., "description": ..., "parameters": ...}``), and
|
|
584
|
+
* Anthropic's ``input_schema`` synonym for ``parameters``.
|
|
585
|
+
*
|
|
586
|
+
* Mirrors Python's ``build_tool_definitions``.
|
|
587
|
+
*/
|
|
588
|
+
static buildToolDefinitions(tools) {
|
|
589
|
+
if (!tools)
|
|
590
|
+
return undefined;
|
|
591
|
+
const list = Array.isArray(tools) ? tools : [];
|
|
592
|
+
if (list.length === 0)
|
|
593
|
+
return undefined;
|
|
594
|
+
try {
|
|
595
|
+
const definitions = [];
|
|
596
|
+
for (const tool of list) {
|
|
597
|
+
if (!tool || typeof tool !== 'object')
|
|
598
|
+
continue;
|
|
599
|
+
try {
|
|
600
|
+
if (tool.type === 'function' && tool.function && typeof tool.function === 'object') {
|
|
601
|
+
const fn = tool.function;
|
|
602
|
+
const name = fn.name ?? '';
|
|
603
|
+
if (!name)
|
|
604
|
+
continue;
|
|
605
|
+
definitions.push({
|
|
606
|
+
type: 'function',
|
|
607
|
+
name,
|
|
608
|
+
description: fn.description ?? '',
|
|
609
|
+
parameters: fn.parameters ?? {},
|
|
610
|
+
});
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (tool.name) {
|
|
614
|
+
definitions.push({
|
|
615
|
+
type: 'function',
|
|
616
|
+
name: tool.name,
|
|
617
|
+
description: tool.description ?? '',
|
|
618
|
+
parameters: tool.parameters ?? tool.input_schema ?? {},
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
catch {
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (definitions.length === 0)
|
|
627
|
+
return undefined;
|
|
628
|
+
return JSON.stringify(definitions);
|
|
629
|
+
}
|
|
630
|
+
catch {
|
|
631
|
+
return undefined;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Compute the canonical agent-version fingerprint.
|
|
636
|
+
*
|
|
637
|
+
* Mirrors `fingerprint()` in
|
|
638
|
+
* `src/client/src/lib/platform/agents/snapshot.ts` so that the SDK stamps
|
|
639
|
+
* `shield360.agent.version_hash` with the same value the server-side
|
|
640
|
+
* materializer derives from `otel_traces`. The hash covers the parts that
|
|
641
|
+
* meaningfully change agent behavior: system prompt, tool set (name +
|
|
642
|
+
* schema), primary model, and sampling config.
|
|
643
|
+
*
|
|
644
|
+
* Accepts the same shapes used by the SDK chat finalizers:
|
|
645
|
+
* - `systemInstructions`: the JSON string emitted on
|
|
646
|
+
* `gen_ai.system_instructions`, the original list of `{type,content}`
|
|
647
|
+
* parts, or a plain string.
|
|
648
|
+
* - `toolDefinitions`: the JSON string emitted on
|
|
649
|
+
* `gen_ai.tool.definitions`, or the original list of
|
|
650
|
+
* `{type, name, description, parameters}` items.
|
|
651
|
+
*/
|
|
652
|
+
static computeAgentVersionHash(args) {
|
|
653
|
+
// This runs on every chat/llm span on the hot path. The hashing code
|
|
654
|
+
// touches user-supplied payloads (tool schemas, runtime configs) and a
|
|
655
|
+
// single odd value historically blew up the whole span. Return '' on
|
|
656
|
+
// any failure so the wrapper falls back to time-window matching and the
|
|
657
|
+
// span still gets exported. Mirrors the Python SDK's defensive
|
|
658
|
+
// try/except in `compute_agent_version_hash`.
|
|
659
|
+
// Process-local LRU memoization. Provider wrappers re-invoke this with
|
|
660
|
+
// identical inputs on every LLM request for the same agent; the cache
|
|
661
|
+
// key uses cheap string coercion so building it is far cheaper than the
|
|
662
|
+
// canonical JSON serialization + SHA1 work we'd otherwise repeat.
|
|
663
|
+
const cacheKey = Shield360Helper._buildAgentVersionCacheKey(args);
|
|
664
|
+
if (cacheKey) {
|
|
665
|
+
const cached = Shield360Helper._versionHashCache.get(cacheKey);
|
|
666
|
+
if (cached !== undefined) {
|
|
667
|
+
// Re-insert to bump recency in JS Map (insertion-order eviction).
|
|
668
|
+
Shield360Helper._versionHashCache.delete(cacheKey);
|
|
669
|
+
Shield360Helper._versionHashCache.set(cacheKey, cached);
|
|
670
|
+
return cached;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
const normalizeWhitespace = (s) => (s || '').replace(/\s+/g, ' ').trim();
|
|
675
|
+
const canonical = (value) => {
|
|
676
|
+
if (Array.isArray(value))
|
|
677
|
+
return value.map(canonical);
|
|
678
|
+
if (value && typeof value === 'object') {
|
|
679
|
+
const sorted = {};
|
|
680
|
+
for (const k of Object.keys(value).sort()) {
|
|
681
|
+
sorted[k] = canonical(value[k]);
|
|
682
|
+
}
|
|
683
|
+
return sorted;
|
|
684
|
+
}
|
|
685
|
+
return value;
|
|
686
|
+
};
|
|
687
|
+
const roundTo3 = (v) => {
|
|
688
|
+
if (v === undefined || v === null)
|
|
689
|
+
return null;
|
|
690
|
+
const n = typeof v === 'number' ? v : Number(v);
|
|
691
|
+
if (!Number.isFinite(n))
|
|
692
|
+
return null;
|
|
693
|
+
return Math.round(n * 1000) / 1000;
|
|
694
|
+
};
|
|
695
|
+
const coerceMaxTokens = (v) => {
|
|
696
|
+
if (v === undefined || v === null)
|
|
697
|
+
return null;
|
|
698
|
+
const n = typeof v === 'number' ? v : Number(v);
|
|
699
|
+
if (!Number.isFinite(n))
|
|
700
|
+
return null;
|
|
701
|
+
return Math.trunc(n);
|
|
702
|
+
};
|
|
703
|
+
const sp = (() => {
|
|
704
|
+
const raw = args.systemInstructions;
|
|
705
|
+
if (raw == null)
|
|
706
|
+
return '';
|
|
707
|
+
if (typeof raw === 'string')
|
|
708
|
+
return raw;
|
|
709
|
+
try {
|
|
710
|
+
return JSON.stringify(raw);
|
|
711
|
+
}
|
|
712
|
+
catch {
|
|
713
|
+
return '';
|
|
714
|
+
}
|
|
715
|
+
})();
|
|
716
|
+
const parsedTools = (() => {
|
|
717
|
+
const raw = args.toolDefinitions;
|
|
718
|
+
if (raw == null)
|
|
719
|
+
return [];
|
|
720
|
+
if (typeof raw === 'string') {
|
|
721
|
+
try {
|
|
722
|
+
const parsed = JSON.parse(raw);
|
|
723
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
724
|
+
}
|
|
725
|
+
catch {
|
|
726
|
+
return [];
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return Array.isArray(raw) ? raw : [];
|
|
730
|
+
})();
|
|
731
|
+
const tools = parsedTools
|
|
732
|
+
.map((t) => {
|
|
733
|
+
if (!t || typeof t !== 'object')
|
|
734
|
+
return null;
|
|
735
|
+
const rec = t;
|
|
736
|
+
const name = typeof rec.name === 'string' ? rec.name : '';
|
|
737
|
+
if (!name)
|
|
738
|
+
return null;
|
|
739
|
+
const schema = rec.parameters !== undefined
|
|
740
|
+
? rec.parameters
|
|
741
|
+
: rec.input_schema !== undefined
|
|
742
|
+
? rec.input_schema
|
|
743
|
+
: rec.schema !== undefined
|
|
744
|
+
? rec.schema
|
|
745
|
+
: null;
|
|
746
|
+
return { n: name, s: canonical(schema) };
|
|
747
|
+
})
|
|
748
|
+
.filter((t) => t !== null)
|
|
749
|
+
// Byte-order (codepoint) sort to stay deterministic across locales
|
|
750
|
+
// and to match the Python SDK's default `tools.sort(key=lambda t: t["n"])`,
|
|
751
|
+
// which also sorts by Unicode codepoint. `localeCompare` is locale-
|
|
752
|
+
// dependent and would diverge from the server fingerprint for
|
|
753
|
+
// non-ASCII tool names.
|
|
754
|
+
.sort((a, b) => (a.n < b.n ? -1 : a.n > b.n ? 1 : 0));
|
|
755
|
+
const providersSorted = [...(args.providers || [])].filter(Boolean).sort();
|
|
756
|
+
const rc = args.runtimeConfig || {};
|
|
757
|
+
const payload = canonical({
|
|
758
|
+
sp: normalizeWhitespace(sp),
|
|
759
|
+
tools,
|
|
760
|
+
model: args.primaryModel || '',
|
|
761
|
+
cfg: {
|
|
762
|
+
temperature: roundTo3(rc.temperature ?? null),
|
|
763
|
+
top_p: roundTo3(rc.top_p ?? null),
|
|
764
|
+
max_tokens: coerceMaxTokens(rc.max_tokens ?? null),
|
|
765
|
+
provider: rc.provider || providersSorted[0] || '',
|
|
766
|
+
},
|
|
767
|
+
});
|
|
768
|
+
const result = (0, crypto_1.createHash)('sha1')
|
|
769
|
+
.update(JSON.stringify(payload))
|
|
770
|
+
.digest('hex')
|
|
771
|
+
.slice(0, 16);
|
|
772
|
+
if (cacheKey) {
|
|
773
|
+
Shield360Helper._versionHashCache.set(cacheKey, result);
|
|
774
|
+
if (Shield360Helper._versionHashCache.size > Shield360Helper._VERSION_HASH_CACHE_MAX) {
|
|
775
|
+
const firstKey = Shield360Helper._versionHashCache.keys().next().value;
|
|
776
|
+
if (firstKey !== undefined)
|
|
777
|
+
Shield360Helper._versionHashCache.delete(firstKey);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
return result;
|
|
781
|
+
}
|
|
782
|
+
catch {
|
|
783
|
+
return '';
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Build a stable, cheap cache key for the version-hash memoization. Uses
|
|
788
|
+
* `JSON.stringify` of inputs (orders-of-magnitude cheaper than the full
|
|
789
|
+
* canonical pass we want to skip on a cache hit). Returns `null` if
|
|
790
|
+
* inputs can't be stringified (circular refs etc.) — the caller falls
|
|
791
|
+
* back to uncached computation.
|
|
792
|
+
*/
|
|
793
|
+
static _buildAgentVersionCacheKey(args) {
|
|
794
|
+
try {
|
|
795
|
+
const si = typeof args.systemInstructions === 'string' || args.systemInstructions == null
|
|
796
|
+
? args.systemInstructions ?? ''
|
|
797
|
+
: JSON.stringify(args.systemInstructions);
|
|
798
|
+
const td = typeof args.toolDefinitions === 'string' || args.toolDefinitions == null
|
|
799
|
+
? args.toolDefinitions ?? ''
|
|
800
|
+
: JSON.stringify(args.toolDefinitions);
|
|
801
|
+
const rc = args.runtimeConfig ? JSON.stringify(args.runtimeConfig) : '';
|
|
802
|
+
const prov = [...(args.providers || [])]
|
|
803
|
+
.filter(Boolean)
|
|
804
|
+
.sort()
|
|
805
|
+
.join(',');
|
|
806
|
+
return `${si}|${td}|${args.primaryModel || ''}|${rc}|${prov}`;
|
|
807
|
+
}
|
|
808
|
+
catch {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Build OTel-spec output messages JSON string from provider response.
|
|
814
|
+
* Format: [{"role": "assistant", "parts": [{"type": "text", "content": "..."}], "finish_reason": "stop"}]
|
|
815
|
+
*/
|
|
816
|
+
static buildOutputMessages(text, finishReason, toolCalls) {
|
|
817
|
+
try {
|
|
818
|
+
const parts = [];
|
|
819
|
+
if (text) {
|
|
820
|
+
parts.push({ type: 'text', content: text });
|
|
821
|
+
}
|
|
822
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
823
|
+
for (const tc of toolCalls) {
|
|
824
|
+
let args = tc.function?.arguments || tc.arguments || {};
|
|
825
|
+
if (typeof args === 'string') {
|
|
826
|
+
try {
|
|
827
|
+
args = JSON.parse(args);
|
|
828
|
+
}
|
|
829
|
+
catch {
|
|
830
|
+
args = { raw: args };
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
parts.push({
|
|
834
|
+
type: 'tool_call',
|
|
835
|
+
id: tc.id || '',
|
|
836
|
+
name: tc.function?.name || tc.name || '',
|
|
837
|
+
arguments: args,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return JSON.stringify([{ role: 'assistant', parts, finish_reason: finishReason || 'stop' }]);
|
|
842
|
+
}
|
|
843
|
+
catch {
|
|
844
|
+
return '[]';
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Emit an inference event via the LoggerProvider, matching Python SDK's
|
|
849
|
+
* gen_ai.client.inference.operation.details event.
|
|
850
|
+
* Falls back to span.addEvent if LoggerProvider is not available.
|
|
851
|
+
*/
|
|
852
|
+
static emitInferenceEvent(span, attrs) {
|
|
853
|
+
const eventAttributes = {};
|
|
854
|
+
const customAttrs = getMergedCustomAttributes();
|
|
855
|
+
for (const [key, value] of Object.entries(customAttrs)) {
|
|
856
|
+
if (value !== undefined && value !== null) {
|
|
857
|
+
eventAttributes[key] = value;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
861
|
+
if (value !== undefined && value !== null) {
|
|
862
|
+
eventAttributes[key] = value;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
if (events_1.default.logger) {
|
|
866
|
+
events_1.default.logger.emit({
|
|
867
|
+
eventName: semantic_convention_1.default.GEN_AI_CLIENT_INFERENCE_OPERATION_DETAILS,
|
|
868
|
+
context: api_1.trace.setSpan(api_1.context.active(), span),
|
|
869
|
+
severityNumber: api_logs_1.SeverityNumber.INFO,
|
|
870
|
+
severityText: 'INFO',
|
|
871
|
+
body: semantic_convention_1.default.GEN_AI_CLIENT_INFERENCE_OPERATION_DETAILS,
|
|
872
|
+
attributes: {
|
|
873
|
+
...eventAttributes,
|
|
874
|
+
'event.name': semantic_convention_1.default.GEN_AI_CLIENT_INFERENCE_OPERATION_DETAILS,
|
|
875
|
+
},
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
span.addEvent(semantic_convention_1.default.GEN_AI_CLIENT_INFERENCE_OPERATION_DETAILS, eventAttributes);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
static handleException(span, error) {
|
|
883
|
+
span.recordException(error);
|
|
884
|
+
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message });
|
|
885
|
+
const errorType = error.constructor?.name || '_OTHER';
|
|
886
|
+
span.setAttribute(semantic_convention_1.default.ERROR_TYPE, errorType);
|
|
887
|
+
}
|
|
888
|
+
static async createStreamProxy(stream, generatorFuncResponse) {
|
|
889
|
+
return new Proxy(stream, {
|
|
890
|
+
get(target, prop, receiver) {
|
|
891
|
+
if (prop === Symbol.asyncIterator) {
|
|
892
|
+
return () => generatorFuncResponse;
|
|
893
|
+
}
|
|
894
|
+
return Reflect.get(target, prop, receiver);
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
Shield360Helper.PROMPT_TOKEN_FACTOR = 1000;
|
|
900
|
+
Shield360Helper._VERSION_HASH_CACHE_MAX = 256;
|
|
901
|
+
Shield360Helper._versionHashCache = new Map();
|
|
902
|
+
exports.default = Shield360Helper;
|
|
903
|
+
//# sourceMappingURL=helpers.js.map
|