Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6168848
Merge pull request #19505 from getsentry/master
github-actions[bot] Feb 24, 2026
8c7932b
chore(lint): Remove junit report file (#19491)
chargome Feb 24, 2026
218ad4f
chore(ci): Validate alert id (#19499)
chargome Feb 25, 2026
cce0029
chore(triage-issue): Fix Linear idempotency check to match actual rep…
chargome Feb 25, 2026
60969fc
feat(nextjs): Use `not: foreign` condition in turbopack loaders (#19502)
chargome Feb 25, 2026
5bbba8a
fix(nestjs): Improve control flow exception filtering (#19524)
nicohrubec Feb 25, 2026
89b437f
fix(tanstackstart-react): Flush events in server entry point for serv…
nicohrubec Feb 25, 2026
17b7532
test(consola): Restructure tests (e.g. changing `cases.forEach()` to …
s1gr1d Feb 26, 2026
d245097
chore(agents): Consolidate SDK dev rules into `AGENTS.md` (#19521)
chargome Feb 26, 2026
ab883e7
fix(core): Improve message truncation for multimodal content and norm…
RulaKhaled Feb 26, 2026
4ff6738
chore: updating minimatch (#19434)
isaacs Feb 26, 2026
1204c6a
chore(agents): Add `dotagents` (#19526)
chargome Feb 26, 2026
03ea6dd
chore(tanstackstart): Fix leftover formatting issue (#19536)
andreiborza Feb 26, 2026
50d1d2f
chore(svelte,sveltekit): Use version range for magic-string (#19520)
JPeer264 Feb 26, 2026
e0b23a8
chore(deps): Bump rollup to 4.59.0 to fix path traversal vulnerabilit…
chargome Feb 26, 2026
311cf29
fix(consola): Normalize extra keys from consola (#19511)
s1gr1d Feb 26, 2026
0e741cb
fix(vue): Avoid triggering deprecated next callback from router instr…
YevheniiKotyrlo Feb 26, 2026
92694c1
chore: Add external contributor to CHANGELOG.md (#19548)
javascript-sdk-gitflow[bot] Feb 26, 2026
07b66ff
feat(deps): bump rxjs from 7.8.1 to 7.8.2 (#19545)
dependabot[bot] Feb 26, 2026
619e8be
chore(agents): Migrate repo-wide cursor rules to skills (#19549)
chargome Feb 27, 2026
5b0c6bd
feat(nextjs): Experimental support for `thirdPartyErrorFilterIntegrat…
chargome Feb 27, 2026
7dabfcf
fix(langchain): use runName argument in handleChainStart to fix unkno…
priscilawebdev Feb 27, 2026
7a6cf97
chore(agents): Add nested `AGENTS.md` for browser (#19551)
chargome Feb 27, 2026
1ea3c10
chore(agents): Add nested `AGENTS.md` for nextjs (#19556)
chargome Feb 27, 2026
8b0e265
Merge branch 'develop' into fix/langchain-handlechainstart-runname
priscilawebdev Feb 27, 2026
fede250
chore(agents): Remove stale cursor commands (#19560)
chargome Feb 27, 2026
2b79e29
Merge pull request #19554 from getsentry/fix/langchain-handlechainsta…
priscilawebdev Feb 27, 2026
0c3b071
test(node): Test runName parameter in handleChainStart for langchain …
RulaKhaled Feb 27, 2026
6707fd3
feat(react-router): Include middleware function names and indices (#1…
onurtemizkan Feb 27, 2026
43be7b0
fix(deps): Bump transitive rollup deps to patch CVE-2026-27606 (#19565)
chargome Feb 27, 2026
88078a0
feat(core,cloudflare,deno): Add instrumentPostgresJsSql instrumentati…
andreiborza Feb 27, 2026
9d3ae61
feat(core,cloudflare): Add dispose to the client for proper cleanup (…
JPeer264 Mar 2, 2026
93e3c30
fix(core): Strip inline media from multimodal content before stringif…
RulaKhaled Mar 2, 2026
dc44fe4
meta(changelog): Update changelog for 10.41.0
andreiborza Mar 2, 2026
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
121 changes: 121 additions & 0 deletions .agents/skills/add-ai-integration/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
name: add-ai-integration
description: Add a new AI provider integration to the Sentry JavaScript SDK. Use when contributing a new AI instrumentation (OpenAI, Anthropic, Vercel AI, LangChain, etc.) or modifying an existing one.
argument-hint: <provider-name>
---

# Adding a New AI Integration

## Decision Tree

```
Does the AI SDK have native OpenTelemetry support?
|- YES -> Does it emit OTel spans automatically?
| |- YES (like Vercel AI) -> Pattern 1: OTel Span Processors
| +- NO -> Pattern 2: OTel Instrumentation (wrap client)
+- NO -> Does the SDK provide hooks/callbacks?
|- YES (like LangChain) -> Pattern 3: Callback/Hook Based
+- NO -> Pattern 4: Client Wrapping
```

## Runtime-Specific Placement

If an AI SDK only works in one runtime, code lives exclusively in that runtime's package. Do NOT add it to `packages/core/`.

- **Node.js-only** -> `packages/node/src/integrations/tracing/{provider}/`
- **Cloudflare-only** -> `packages/cloudflare/src/integrations/tracing/{provider}.ts`
- **Browser-only** -> `packages/browser/src/integrations/tracing/{provider}/`
- **Multi-runtime** -> shared core in `packages/core/src/tracing/{provider}/` with runtime-specific wrappers

## Span Hierarchy

- `gen_ai.invoke_agent` — parent/pipeline spans (chains, agents, orchestration)
- `gen_ai.chat`, `gen_ai.generate_text`, etc. — child spans (actual LLM calls)

## Shared Utilities (`packages/core/src/tracing/ai/`)

- `gen-ai-attributes.ts` — OTel Semantic Convention attribute constants. **Always use these, never hardcode.**
- `utils.ts` — `setTokenUsageAttributes()`, `getTruncatedJsonString()`, `truncateGenAiMessages()`, `buildMethodPath()`
- Only use attributes from [Sentry Gen AI Conventions](https://getsentry.github.io/sentry-conventions/attributes/gen_ai/).

## Streaming

- **Non-streaming:** `startSpan()`, set attributes from response
- **Streaming:** `startSpanManual()`, accumulate state via async generator or event listeners, set `GEN_AI_RESPONSE_STREAMING_ATTRIBUTE: true`, call `span.end()` in finally block
- Detect via `params.stream === true`
- References: `openai/streaming.ts` (async generator), `anthropic-ai/streaming.ts` (event listeners)

## Token Accumulation

- **Child spans:** Set tokens directly from API response via `setTokenUsageAttributes()`
- **Parent spans (`invoke_agent`):** Accumulate from children using event processor (see `vercel-ai/`)

## Pattern 1: OTel Span Processors

**Use when:** SDK emits OTel spans automatically (Vercel AI)

1. **Core:** Create `add{Provider}Processors()` in `packages/core/src/tracing/{provider}/index.ts` — registers `spanStart` listener + event processor
2. **Node.js:** Add `callWhenPatched()` optimization in `packages/node/src/integrations/tracing/{provider}/index.ts` — defers registration until package is imported
3. **Edge:** Direct registration in `packages/cloudflare/src/integrations/tracing/{provider}.ts` — no OTel, call processors immediately

Reference: `packages/node/src/integrations/tracing/vercelai/`

## Pattern 2: OTel Instrumentation (Client Wrapping)

**Use when:** SDK has no native OTel support (OpenAI, Anthropic, Google GenAI)

1. **Core:** Create `instrument{Provider}Client()` in `packages/core/src/tracing/{provider}/index.ts` — Proxy to wrap client methods, create spans manually
2. **Node.js `instrumentation.ts`:** Patch module exports, wrap client constructor. Check `_INTERNAL_shouldSkipAiProviderWrapping()` for LangChain compatibility.
3. **Node.js `index.ts`:** Export integration function using `generateInstrumentOnce()` helper

Reference: `packages/node/src/integrations/tracing/openai/`

## Pattern 3: Callback/Hook Based

**Use when:** SDK provides lifecycle hooks (LangChain, LangGraph)

1. **Core:** Create `create{Provider}CallbackHandler()` — implement SDK's callback interface, create spans in callbacks
2. **Node.js `instrumentation.ts`:** Auto-inject callbacks by patching runnable methods. Disable underlying AI provider wrapping.

Reference: `packages/node/src/integrations/tracing/langchain/`

## Auto-Instrumentation (Node.js)

**Mandatory** for Node.js AI integrations. OTel only patches when the package is imported (zero cost if unused).

### Steps

1. **Add to `getAutoPerformanceIntegrations()`** in `packages/node/src/integrations/tracing/index.ts` — LangChain MUST come first
2. **Add to `getOpenTelemetryInstrumentationToPreload()`** for OTel-based integrations
3. **Export from `packages/node/src/index.ts`**: integration function + options type
4. **Add 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}/`

## Key Rules

1. Respect `sendDefaultPii` for `recordInputs`/`recordOutputs`
2. Set `SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'auto.ai.{provider}'` (alphanumerics, `_`, `.` only)
3. Truncate large data with helper functions from `utils.ts`
4. `gen_ai.invoke_agent` for parent ops, `gen_ai.chat` for child ops

## Checklist

- [ ] Runtime-specific code placed 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
- [ ] E2E tests added and verifying auto-instrumentation
- [ ] 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)
- [ ] Verified OTel only patches when package imported (Node.js)

## Reference Implementations

- **Pattern 1 (Span Processors):** `packages/node/src/integrations/tracing/vercelai/`
- **Pattern 2 (Client Wrapping):** `packages/node/src/integrations/tracing/openai/`
- **Pattern 3 (Callback/Hooks):** `packages/node/src/integrations/tracing/langchain/`

**When in doubt, follow the pattern of the most similar existing integration.**
80 changes: 80 additions & 0 deletions .agents/skills/dotagents/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: dotagents
description: Manage agent skill dependencies with dotagents. Use when asked to "add a skill", "install skills", "remove a skill", "update skills", "dotagents init", "agents.toml", "agents.lock", "sync skills", "list skills", "set up dotagents", "configure trust", "add MCP server", "add hook", "wildcard skills", "user scope", or any dotagents-related task.
---

Manage agent skill dependencies declared in `agents.toml`. dotagents resolves, installs, and symlinks skills so multiple agent tools (Claude Code, Cursor, Codex, VS Code, OpenCode) discover them from `.agents/skills/`.

## References

Read the relevant reference when the task requires deeper detail:

| Document | Read When |
| ---------------------------------------------------------- | ------------------------------------------------------------------------- |
| [references/cli-reference.md](references/cli-reference.md) | Full command options, flags, examples |
| [references/configuration.md](references/configuration.md) | Editing agents.toml, source formats, trust, MCP, hooks, wildcards, scopes |
| [references/config-schema.md](references/config-schema.md) | Exact field names, types, and defaults |

## Quick Start

```bash
# Initialize a new project (interactive TUI)
dotagents init

# Add a skill from GitHub
dotagents add getsentry/skills find-bugs

# Add multiple skills at once
dotagents add getsentry/skills find-bugs code-review commit

# Add all skills from a repo
dotagents add getsentry/skills --all

# Add a pinned skill
dotagents add getsentry/warden@v1.0.0

# Install all dependencies from agents.toml
dotagents install

# List installed skills
dotagents list
```

## Commands

| Command | Description |
| --------------------------- | ------------------------------------------------------------------ |
| `dotagents init` | Initialize `agents.toml` and `.agents/` directory |
| `dotagents install` | Install all skills from `agents.toml` |
| `dotagents add <specifier>` | Add a skill dependency |
| `dotagents remove <name>` | Remove a skill |
| `dotagents update [name]` | Update skills to latest versions |
| `dotagents sync` | Reconcile state (adopt orphans, repair symlinks, verify integrity) |
| `dotagents list` | Show installed skills and their status |
| `dotagents mcp` | Add, remove, or list MCP server declarations |

All commands accept `--user` to operate on user scope (`~/.agents/`) instead of the current project.

For full options and flags, read [references/cli-reference.md](references/cli-reference.md).

## Source Formats

| Format | Example | Description |
| ---------------- | -------------------------------------- | ------------------------------------- |
| GitHub shorthand | `getsentry/skills` | Owner/repo (resolves to GitHub HTTPS) |
| GitHub pinned | `getsentry/warden@v1.0.0` | With tag, branch, or commit |
| GitHub SSH | `git@github.com:owner/repo.git` | SSH clone URL |
| GitHub HTTPS | `https://github.com/owner/repo` | Full HTTPS URL |
| Git URL | `git:https://git.corp.dev/team/skills` | Any non-GitHub git remote |
| Local path | `path:./my-skills/custom` | Relative to project root |

## Key Concepts

- **`.agents/skills/`** is the canonical home for all installed skills
- **`agents.toml`** declares dependencies; **`agents.lock`** pins exact commits and integrity hashes
- **Symlinks**: `.claude/skills/`, `.cursor/skills/` point to `.agents/skills/`
- **Wildcards**: `name = "*"` installs all skills from a source, with optional `exclude` list
- **Trust**: Optional `[trust]` section restricts which sources are allowed
- **Hooks**: `[[hooks]]` declarations write tool-event hooks to each agent's config
- **Gitignore**: When `gitignore = true`, managed skills are gitignored; custom in-place skills are tracked
- **User scope**: `--user` flag manages skills in `~/.agents/` shared across all projects
Loading
Loading