@brizz/sdk 0.1.28 → 0.1.30

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/README.md CHANGED
@@ -190,9 +190,22 @@ The SDK automatically instruments:
190
190
  - **LangChain** - `langchain` and `@langchain/*` packages
191
191
  - **LlamaIndex** - `llamaindex` package
192
192
  - **AWS Bedrock** - `@aws-sdk/client-bedrock-runtime`
193
- - **Google Vertex AI** - `@google-cloud/vertexai`
194
193
  - **Vector Databases** - Pinecone, Qdrant, ChromaDB
195
- - **HTTP/Fetch** - Automatic network request tracing
194
+
195
+ ### Optional Instrumentations
196
+
197
+ A few instrumentations ship as **optional peer dependencies** so they're only
198
+ pulled in when you need them. Install the matching package(s) to enable them:
199
+
200
+ | To trace | Install |
201
+ | --- | --- |
202
+ | **Google Vertex AI** (`@google-cloud/vertexai`) | `npm install @traceloop/instrumentation-vertexai` |
203
+ | **MCP** (Model Context Protocol) | `npm install @arizeai/openinference-instrumentation-mcp @modelcontextprotocol/sdk` |
204
+
205
+ If a package isn't installed, the SDK keeps working and simply skips that
206
+ instrumentation. On the automatic path the skip is a quiet `debug` log; when you
207
+ opt in explicitly via `instrumentModules`, a missing package is logged at `error`
208
+ so the misconfiguration is visible.
196
209
 
197
210
  ### Vercel AI SDK Integration
198
211
 
@@ -331,6 +344,20 @@ await startSession('session-456', async (session) => {
331
344
  });
332
345
  ```
333
346
 
347
+ **External link example:**
348
+
349
+ ```typescript
350
+ import { addExternalLink, startSession } from '@brizz/sdk';
351
+
352
+ startSession('session-123', (session) => {
353
+ // Top-level function — resolves the active session from context.
354
+ addExternalLink('https://app.datadoghq.com/trace/abc', { title: 'Datadog trace' });
355
+ });
356
+
357
+ // Outside a session — pass the id explicitly.
358
+ addExternalLink('https://sentry.io/issues/456', { sessionId: 'session-123', linkType: 'sentry' });
359
+ ```
360
+
334
361
  ### Session Title Generation
335
362
 
336
363
  If you use an LLM call to generate session titles, wrap it so those spans don't appear as part of
@@ -0,0 +1,158 @@
1
+ // src/internal/logger.ts
2
+ import { DiagLogLevel } from "@opentelemetry/api";
3
+ import pino from "pino";
4
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
5
+ LogLevel2[LogLevel2["NONE"] = 0] = "NONE";
6
+ LogLevel2[LogLevel2["ERROR"] = 1] = "ERROR";
7
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
8
+ LogLevel2[LogLevel2["INFO"] = 3] = "INFO";
9
+ LogLevel2[LogLevel2["DEBUG"] = 4] = "DEBUG";
10
+ return LogLevel2;
11
+ })(LogLevel || {});
12
+ var DEFAULT_LOG_LEVEL = 2 /* WARN */;
13
+ var PinoLogger = class {
14
+ _level = DEFAULT_LOG_LEVEL;
15
+ _pinoLogger = null;
16
+ debug = (msg, ...meta) => {
17
+ if (this._level >= 4 /* DEBUG */) {
18
+ this.ensurePinoLogger().debug(this.formatMeta(meta), msg);
19
+ }
20
+ };
21
+ info = (msg, ...meta) => {
22
+ if (this._level >= 3 /* INFO */) {
23
+ this.ensurePinoLogger().info(this.formatMeta(meta), msg);
24
+ }
25
+ };
26
+ warn = (msg, ...meta) => {
27
+ if (this._level >= 2 /* WARN */) {
28
+ this.ensurePinoLogger().warn(this.formatMeta(meta), msg);
29
+ }
30
+ };
31
+ error = (msg, ...meta) => {
32
+ if (this._level >= 1 /* ERROR */) {
33
+ this.ensurePinoLogger().error(this.formatMeta(meta), msg);
34
+ }
35
+ };
36
+ constructor() {
37
+ const envLevel = this.getLogLevelFromEnv();
38
+ this._level = envLevel;
39
+ }
40
+ /**
41
+ * Lazy initialization of Pino logger to ensure it's created AFTER Jest spies
42
+ * are set up during tests. This prevents the pino-pretty transport from
43
+ * bypassing stdout/stderr spies.
44
+ */
45
+ ensurePinoLogger() {
46
+ if (!this._pinoLogger) {
47
+ this._pinoLogger = pino({
48
+ name: "Brizz",
49
+ level: this.logLevelToPino(this._level),
50
+ // Disable transport in test environment to allow proper spy capture
51
+ transport: this.isProduction() || this.isTest() ? void 0 : {
52
+ target: "pino-pretty",
53
+ options: {
54
+ singleLine: true,
55
+ colorize: true,
56
+ translateTime: "HH:MM:ss",
57
+ ignore: "pid,hostname",
58
+ messageFormat: "[{name}] {msg}"
59
+ }
60
+ }
61
+ });
62
+ }
63
+ return this._pinoLogger;
64
+ }
65
+ isProduction() {
66
+ return process.env["NODE_ENV"] === "production";
67
+ }
68
+ isTest() {
69
+ return process.env["NODE_ENV"] === "test";
70
+ }
71
+ getLogLevelFromEnv() {
72
+ const envLevel = process.env["BRIZZ_LOG_LEVEL"];
73
+ return envLevel ? parseLogLevel(envLevel) : DEFAULT_LOG_LEVEL;
74
+ }
75
+ logLevelToPino(level) {
76
+ switch (level) {
77
+ case 4 /* DEBUG */:
78
+ return "debug";
79
+ case 3 /* INFO */:
80
+ return "info";
81
+ case 2 /* WARN */:
82
+ return "warn";
83
+ case 1 /* ERROR */:
84
+ return "error";
85
+ default:
86
+ return "silent";
87
+ }
88
+ }
89
+ formatMeta(meta) {
90
+ if (meta.length === 0) {
91
+ return {};
92
+ }
93
+ if (meta.length === 1 && typeof meta[0] === "object" && meta[0] !== null) {
94
+ return meta[0];
95
+ }
96
+ return { metadata: meta };
97
+ }
98
+ setLevel(level) {
99
+ this._level = level;
100
+ if (this._pinoLogger) {
101
+ this._pinoLogger.level = this.logLevelToPino(level);
102
+ }
103
+ }
104
+ getLevel() {
105
+ return this._level;
106
+ }
107
+ };
108
+ function parseLogLevel(level) {
109
+ if (!level) {
110
+ return DEFAULT_LOG_LEVEL;
111
+ }
112
+ const normalizedLevel = level.toLowerCase().trim();
113
+ switch (normalizedLevel) {
114
+ case "debug":
115
+ return 4 /* DEBUG */;
116
+ case "info":
117
+ return 3 /* INFO */;
118
+ case "warn":
119
+ case "warning":
120
+ return 2 /* WARN */;
121
+ case "error":
122
+ return 1 /* ERROR */;
123
+ case "none":
124
+ case "off":
125
+ case "silent":
126
+ return 0 /* NONE */;
127
+ default: {
128
+ const numLevel = Math.trunc(Number(normalizedLevel));
129
+ if (!Number.isNaN(numLevel) && numLevel >= 0 && numLevel <= 4) {
130
+ return numLevel;
131
+ }
132
+ return DEFAULT_LOG_LEVEL;
133
+ }
134
+ }
135
+ }
136
+ var logger = new PinoLogger();
137
+ function setLogLevel(level) {
138
+ const resolvedLevel = typeof level === "string" ? parseLogLevel(level) : level;
139
+ logger.setLevel(resolvedLevel);
140
+ }
141
+ function getLogLevel() {
142
+ return logger.getLevel();
143
+ }
144
+
145
+ // src/internal/version.ts
146
+ function getSDKVersion() {
147
+ return "0.1.30";
148
+ }
149
+
150
+ export {
151
+ LogLevel,
152
+ DEFAULT_LOG_LEVEL,
153
+ parseLogLevel,
154
+ logger,
155
+ setLogLevel,
156
+ getLogLevel,
157
+ getSDKVersion
158
+ };