Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions .cursor/rules/adding-a-new-ai-integration.mdc
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,32 @@ Multi-runtime considerations:
- Edge (Cloudflare/Vercel): No OTel, processors only or manual wrapping
```

**IMPORTANT - Runtime-Specific Placement:**

If an AI SDK only works in a specific runtime, the integration code should live exclusively in that runtime's package. Do NOT add it to `packages/core/` or attempt to make it work in other runtimes where it cannot function.

**Runtime-specific integration structures:**

**Node.js-only SDKs** → `packages/node/`

- Core logic: `packages/node/src/integrations/tracing/{provider}/index.ts`
- OTel instrumentation: `packages/node/src/integrations/tracing/{provider}/instrumentation.ts`
- Use when SDK only work with Node.js-specific APIs

**Cloudflare Workers-only SDKs** → `packages/cloudflare/`

- Single file: `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- Use when SDK only works with Cloudflare Workers APIs or Cloudflare AI

**Browser-only SDKs** → `packages/browser/`

- Core logic: `packages/browser/src/integrations/tracing/{provider}/index.ts`
- Use when SDK requires browser-specific APIs (DOM, WebAPIs, etc.)

**For all runtime-specific SDKs:** DO NOT create `packages/core/src/tracing/{provider}/` - keep everything in the runtime package.

**Multi-runtime SDKs:** If the SDK works across multiple runtimes (Node.js, browser, edge), follow the standard pattern with shared core logic in `packages/core/` and runtime-specific wrappers/instrumentation in each package where needed.

---

## Span Hierarchy
Expand DownExpand Up@@ -139,6 +165,10 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!
- `GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE` - Token counts
- `GEN_AI_OPERATION_NAME_ATTRIBUTE` - 'chat', 'embeddings', etc.

**CRITICAL - Attribute Usage:**

Only use attributes explicitly listed in the [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/). Do NOT create custom attributes or use undocumented ones. If you need a new attribute, it MUST be documented in the conventions first before implementation.

### `utils.ts`

- `setTokenUsageAttributes()` - Set token usage on span
Expand DownExpand Up@@ -213,6 +243,8 @@ OpenTelemetry Semantic Convention attribute names. **Always use these constants!

## Auto-Instrumentation (Out-of-the-Box Support)

**MANDATORY**

**RULE:** AI SDKs should be auto-enabled in Node.js runtime if possible.

✅ **Auto-enable if:**
Expand DownExpand Up@@ -269,12 +301,26 @@ export type { {Provider}Options } from './integrations/tracing/{provider}';
export { {provider}Integration } from './integrations/tracing/{provider}';
```

**4. Add E2E test** in `packages/node-integration-tests/suites/{provider}/`
**4. Add E2E tests**

For Node.js integrations, add tests in `dev-packages/node-integration-tests/suites/tracing/{provider}/`:

- Verify spans created automatically (no manual setup)
- Test `recordInputs` and `recordOutputs` options
- Test integration can be disabled

For Cloudflare Workers integrations, add tests in `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}`:

- Create a new worker test app with the AI SDK
- Verify manual instrumentation creates spans correctly
- Test in actual Cloudflare Workers runtime (use `wrangler dev` or `miniflare`)

For Browser integrations, add tests in `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`:

- Create a new test suite with Playwright
- Verify manual instrumentation creates spans correctly in the browser
- Test with actual browser runtime

---

## Directory Structure
Expand DownExpand Up@@ -307,15 +353,17 @@ packages/

## Key Best Practices

1. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
2. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode)
3. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
sentry[bot] marked this conversation as resolved.
4. **Truncate large data**: Use helper functions from `utils.ts`
5. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
6. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
7. **Token accumulation**: Direct on child spans, accumulate on parent from children
8. **Performance**: Use `callWhenPatched()` for Pattern 1
9. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2
1. **Auto-instrumentation is mandatory** - All integrations MUST auto-detect and instrument automatically in Node.js runtime
2. **Runtime-specific placement** - If SDK only works in one runtime, code lives only in that package
3. **Respect `sendDefaultPii`** for recordInputs/recordOutputs
4. **Use semantic attributes** from `gen-ai-attributes.ts` (never hardcode) - Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
5. **Set Sentry origin**: `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.openai'` (use provider name: `openai`, `anthropic`, `vercelai`, etc. - only alphanumerics, `_`, and `.` allowed)
6. **Truncate large data**: Use helper functions from `utils.ts`
7. **Correct span operations**: `gen_ai.invoke_agent` for parent, `gen_ai.chat` for children
8. **Streaming**: Use `startSpanManual()`, accumulate state, call `span.end()`
9. **Token accumulation**: Direct on child spans, accumulate on parent from children
10. **Performance**: Use `callWhenPatched()` for Pattern 1
11. **LangChain**: Check `_INTERNAL_shouldSkipAiProviderWrapping()` in Pattern 2

---

Expand All@@ -329,16 +377,20 @@ packages/

## Auto-Instrumentation Checklist

- [ ] Added to `getAutoPerformanceIntegrations()` in correct order
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()`
- [ ] Exported from `packages/node/src/index.ts`
- [ ] **If browser-compatible:** Exported from `packages/browser/src/index.ts`
- [ ] Added E2E test in `packages/node-integration-tests/suites/{provider}/`
- [ ] E2E test verifies auto-instrumentation
- [ ] If runtime-specific, placed code only in that runtime's package
- [ ] Added to `getAutoPerformanceIntegrations()` in correct order (Node.js)
- [ ] Added to `getOpenTelemetryInstrumentationToPreload()` (Node.js with OTel)
- [ ] Exported from appropriate package index (`packages/node/src/index.ts`, `packages/cloudflare/src/index.ts`, etc.)
- [ ] Added E2E tests:
- [ ] Node.js: `dev-packages/node-integration-tests/suites/tracing/{provider}/`
- [ ] Cloudflare: `dev-packages/cloudflare-integration-tests/suites/tracing/{provider}/`
- [ ] Browser: `dev-packages/browser-integration-tests/suites/tracing/ai-providers/{provider}/`
- [ ] E2E test verifies auto-instrumentation (no manual setup required)
- [ ] Only used attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/)
- [ ] JSDoc says "enabled by default" or "not enabled by default"
- [ ] Documented how to disable (if auto-enabled)
- [ ] Documented limitations clearly
- [ ] Verified OTel only patches when package imported
- [ ] Verified OTel only patches when package imported (Node.js)

---

Expand Down
Loading