@raindrop-ai/ai-sdk 0.0.34 → 0.0.35

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.
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
 
3
- // ../core/dist/chunk-U5HUTMR5.js
3
+ // ../core/dist/chunk-SK6EJEO7.js
4
4
  function getCrypto() {
5
5
  const c = globalThis.crypto;
6
6
  return c;
@@ -397,6 +397,25 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
397
397
  ).catch(() => {
398
398
  });
399
399
  }
400
+ var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
401
+ var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
402
+ function isValidProjectIdSlug(value) {
403
+ return PROJECT_ID_SLUG_PATTERN.test(value);
404
+ }
405
+ function normalizeProjectId(raw, opts) {
406
+ if (typeof raw !== "string") return void 0;
407
+ const trimmed = raw.trim();
408
+ if (!trimmed) return void 0;
409
+ if (!isValidProjectIdSlug(trimmed) && opts.debug) {
410
+ console.warn(
411
+ `${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
412
+ );
413
+ }
414
+ return trimmed;
415
+ }
416
+ function projectIdHeaders(projectId) {
417
+ return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
418
+ }
400
419
  var SHUTDOWN_DEADLINE_MS = 1e4;
401
420
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
402
421
  function mergePatches(target, source) {
@@ -431,6 +450,10 @@ var EventShipper = class {
431
450
  if (this.debug && this.localDebuggerUrl) {
432
451
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
433
452
  }
453
+ this.projectId = normalizeProjectId(opts.projectId, {
454
+ debug: this.debug,
455
+ prefix: this.prefix
456
+ });
434
457
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
435
458
  this.context = {
436
459
  library: {
@@ -449,6 +472,9 @@ var EventShipper = class {
449
472
  authHeaders() {
450
473
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
451
474
  }
475
+ requestHeaders() {
476
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
477
+ }
452
478
  /**
453
479
  * Build the retry/timeout options for one POST, honoring the shutdown
454
480
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -578,7 +604,7 @@ var EventShipper = class {
578
604
  return;
579
605
  }
580
606
  try {
581
- await postJson(url, body, this.authHeaders(), opts);
607
+ await postJson(url, body, this.requestHeaders(), opts);
582
608
  } catch (err) {
583
609
  const msg = err instanceof Error ? err.message : String(err);
584
610
  rateLimitedLog(
@@ -614,7 +640,7 @@ var EventShipper = class {
614
640
  return;
615
641
  }
616
642
  try {
617
- await postJson(url, body, this.authHeaders(), opts);
643
+ await postJson(url, body, this.requestHeaders(), opts);
618
644
  } catch (err) {
619
645
  const msg = err instanceof Error ? err.message : String(err);
620
646
  rateLimitedLog(
@@ -710,7 +736,7 @@ var EventShipper = class {
710
736
  if (!isPending) this.sticky.delete(eventId);
711
737
  return;
712
738
  }
713
- const p = postJson(url, payload, this.authHeaders(), opts);
739
+ const p = postJson(url, payload, this.requestHeaders(), opts);
714
740
  this.inFlight.add(p);
715
741
  try {
716
742
  try {
@@ -857,6 +883,10 @@ var TraceShipper = class {
857
883
  if (this.debug && this.localDebuggerUrl) {
858
884
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
859
885
  }
886
+ this.projectId = normalizeProjectId(opts.projectId, {
887
+ debug: this.debug,
888
+ prefix: this.prefix
889
+ });
860
890
  this.transformSpanHook = opts.transformSpan;
861
891
  this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
862
892
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
@@ -933,6 +963,9 @@ var TraceShipper = class {
933
963
  authHeaders() {
934
964
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
935
965
  }
966
+ requestHeaders() {
967
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
968
+ }
936
969
  startSpan(args) {
937
970
  var _a, _b;
938
971
  const ids = createSpanIds(args.parent);
@@ -1064,7 +1097,7 @@ var TraceShipper = class {
1064
1097
  endpoint: url
1065
1098
  });
1066
1099
  }
1067
- const p = postJson(url, body, this.authHeaders(), opts);
1100
+ const p = postJson(url, body, this.requestHeaders(), opts);
1068
1101
  this.inFlight.add(p);
1069
1102
  try {
1070
1103
  try {
@@ -5014,7 +5047,7 @@ function extractNestedTokens(usage, key) {
5014
5047
  // package.json
5015
5048
  var package_default = {
5016
5049
  name: "@raindrop-ai/ai-sdk",
5017
- version: "0.0.34"};
5050
+ version: "0.0.35"};
5018
5051
 
5019
5052
  // src/internal/version.ts
5020
5053
  var libraryName = package_default.name;
@@ -5124,6 +5157,7 @@ function createRaindropAISDK(opts) {
5124
5157
  enabled: eventsEnabled,
5125
5158
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
5126
5159
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
5160
+ projectId: opts.projectId,
5127
5161
  localDebuggerUrl
5128
5162
  });
5129
5163
  const traceShipper = new TraceShipper2({
@@ -5135,6 +5169,7 @@ function createRaindropAISDK(opts) {
5135
5169
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
5136
5170
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
5137
5171
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
5172
+ projectId: opts.projectId,
5138
5173
  localDebuggerUrl,
5139
5174
  transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
5140
5175
  disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
@@ -83,6 +83,13 @@ type EventShipperOptions = {
83
83
  * Pass `null` to opt out of all mirroring (including auto-detect).
84
84
  */
85
85
  localDebuggerUrl?: string | null;
86
+ /**
87
+ * Optional project slug. When set, every outbound cloud request includes an
88
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
89
+ * values are ignored. Slug format is validated on construction but never
90
+ * throws — the backend returns 400 on invalid values.
91
+ */
92
+ projectId?: string;
86
93
  /**
87
94
  * Per-field character cap applied to event input/output BEFORE buffering
88
95
  * or serialization, so oversized payloads cost the cap — not the payload —
@@ -101,6 +108,7 @@ declare class EventShipper$1 {
101
108
  private sdkName;
102
109
  private prefix;
103
110
  private defaultEventName;
111
+ private projectId;
104
112
  private context;
105
113
  private buffers;
106
114
  private sticky;
@@ -124,6 +132,7 @@ declare class EventShipper$1 {
124
132
  constructor(opts: EventShipperOptions);
125
133
  isDebugEnabled(): boolean;
126
134
  private authHeaders;
135
+ private requestHeaders;
127
136
  /**
128
137
  * Build the retry/timeout options for one POST, honoring the shutdown
129
138
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -254,6 +263,13 @@ type TraceShipperOptions = {
254
263
  * Pass `null` to opt out of all mirroring (including auto-detect).
255
264
  */
256
265
  localDebuggerUrl?: string | null;
266
+ /**
267
+ * Optional project slug. When set, every OTLP trace export includes an
268
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
269
+ * values are ignored. Slug format is validated on construction but never
270
+ * throws — the backend returns 400 on invalid values.
271
+ */
272
+ projectId?: string;
257
273
  /**
258
274
  * Per-span hook that fires for every OTLP span right before the span is
259
275
  * shipped (both to the Raindrop API and to a local debugger). Lets callers
@@ -311,6 +327,7 @@ declare class TraceShipper$1 {
311
327
  private flushIntervalMs;
312
328
  private maxBatchSize;
313
329
  private maxQueueSize;
330
+ private projectId;
314
331
  private queue;
315
332
  private timer;
316
333
  private inFlight;
@@ -361,6 +378,7 @@ declare class TraceShipper$1 {
361
378
  private redactSpan;
362
379
  isDebugEnabled(): boolean;
363
380
  private authHeaders;
381
+ private requestHeaders;
364
382
  startSpan(args: {
365
383
  name: string;
366
384
  parent?: {
@@ -899,6 +917,12 @@ type RaindropAISDKOptions = {
899
917
  */
900
918
  writeKey?: string;
901
919
  endpoint?: string;
920
+ /**
921
+ * Optional Raindrop project slug. When set, every outbound cloud request
922
+ * carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
923
+ * resolves to `default` server-side; byte-identical to prior behavior).
924
+ */
925
+ projectId?: string;
902
926
  /**
903
927
  * Force-enable (or opt out of) Workshop / local-debugger mirroring.
904
928
  *
@@ -83,6 +83,13 @@ type EventShipperOptions = {
83
83
  * Pass `null` to opt out of all mirroring (including auto-detect).
84
84
  */
85
85
  localDebuggerUrl?: string | null;
86
+ /**
87
+ * Optional project slug. When set, every outbound cloud request includes an
88
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
89
+ * values are ignored. Slug format is validated on construction but never
90
+ * throws — the backend returns 400 on invalid values.
91
+ */
92
+ projectId?: string;
86
93
  /**
87
94
  * Per-field character cap applied to event input/output BEFORE buffering
88
95
  * or serialization, so oversized payloads cost the cap — not the payload —
@@ -101,6 +108,7 @@ declare class EventShipper$1 {
101
108
  private sdkName;
102
109
  private prefix;
103
110
  private defaultEventName;
111
+ private projectId;
104
112
  private context;
105
113
  private buffers;
106
114
  private sticky;
@@ -124,6 +132,7 @@ declare class EventShipper$1 {
124
132
  constructor(opts: EventShipperOptions);
125
133
  isDebugEnabled(): boolean;
126
134
  private authHeaders;
135
+ private requestHeaders;
127
136
  /**
128
137
  * Build the retry/timeout options for one POST, honoring the shutdown
129
138
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -254,6 +263,13 @@ type TraceShipperOptions = {
254
263
  * Pass `null` to opt out of all mirroring (including auto-detect).
255
264
  */
256
265
  localDebuggerUrl?: string | null;
266
+ /**
267
+ * Optional project slug. When set, every OTLP trace export includes an
268
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
269
+ * values are ignored. Slug format is validated on construction but never
270
+ * throws — the backend returns 400 on invalid values.
271
+ */
272
+ projectId?: string;
257
273
  /**
258
274
  * Per-span hook that fires for every OTLP span right before the span is
259
275
  * shipped (both to the Raindrop API and to a local debugger). Lets callers
@@ -311,6 +327,7 @@ declare class TraceShipper$1 {
311
327
  private flushIntervalMs;
312
328
  private maxBatchSize;
313
329
  private maxQueueSize;
330
+ private projectId;
314
331
  private queue;
315
332
  private timer;
316
333
  private inFlight;
@@ -361,6 +378,7 @@ declare class TraceShipper$1 {
361
378
  private redactSpan;
362
379
  isDebugEnabled(): boolean;
363
380
  private authHeaders;
381
+ private requestHeaders;
364
382
  startSpan(args: {
365
383
  name: string;
366
384
  parent?: {
@@ -899,6 +917,12 @@ type RaindropAISDKOptions = {
899
917
  */
900
918
  writeKey?: string;
901
919
  endpoint?: string;
920
+ /**
921
+ * Optional Raindrop project slug. When set, every outbound cloud request
922
+ * carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
923
+ * resolves to `default` server-side; byte-identical to prior behavior).
924
+ */
925
+ projectId?: string;
902
926
  /**
903
927
  * Force-enable (or opt out of) Workshop / local-debugger mirroring.
904
928
  *
@@ -83,6 +83,13 @@ type EventShipperOptions = {
83
83
  * Pass `null` to opt out of all mirroring (including auto-detect).
84
84
  */
85
85
  localDebuggerUrl?: string | null;
86
+ /**
87
+ * Optional project slug. When set, every outbound cloud request includes an
88
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
89
+ * values are ignored. Slug format is validated on construction but never
90
+ * throws — the backend returns 400 on invalid values.
91
+ */
92
+ projectId?: string;
86
93
  /**
87
94
  * Per-field character cap applied to event input/output BEFORE buffering
88
95
  * or serialization, so oversized payloads cost the cap — not the payload —
@@ -101,6 +108,7 @@ declare class EventShipper$1 {
101
108
  private sdkName;
102
109
  private prefix;
103
110
  private defaultEventName;
111
+ private projectId;
104
112
  private context;
105
113
  private buffers;
106
114
  private sticky;
@@ -124,6 +132,7 @@ declare class EventShipper$1 {
124
132
  constructor(opts: EventShipperOptions);
125
133
  isDebugEnabled(): boolean;
126
134
  private authHeaders;
135
+ private requestHeaders;
127
136
  /**
128
137
  * Build the retry/timeout options for one POST, honoring the shutdown
129
138
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -254,6 +263,13 @@ type TraceShipperOptions = {
254
263
  * Pass `null` to opt out of all mirroring (including auto-detect).
255
264
  */
256
265
  localDebuggerUrl?: string | null;
266
+ /**
267
+ * Optional project slug. When set, every OTLP trace export includes an
268
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
269
+ * values are ignored. Slug format is validated on construction but never
270
+ * throws — the backend returns 400 on invalid values.
271
+ */
272
+ projectId?: string;
257
273
  /**
258
274
  * Per-span hook that fires for every OTLP span right before the span is
259
275
  * shipped (both to the Raindrop API and to a local debugger). Lets callers
@@ -311,6 +327,7 @@ declare class TraceShipper$1 {
311
327
  private flushIntervalMs;
312
328
  private maxBatchSize;
313
329
  private maxQueueSize;
330
+ private projectId;
314
331
  private queue;
315
332
  private timer;
316
333
  private inFlight;
@@ -361,6 +378,7 @@ declare class TraceShipper$1 {
361
378
  private redactSpan;
362
379
  isDebugEnabled(): boolean;
363
380
  private authHeaders;
381
+ private requestHeaders;
364
382
  startSpan(args: {
365
383
  name: string;
366
384
  parent?: {
@@ -899,6 +917,12 @@ type RaindropAISDKOptions = {
899
917
  */
900
918
  writeKey?: string;
901
919
  endpoint?: string;
920
+ /**
921
+ * Optional Raindrop project slug. When set, every outbound cloud request
922
+ * carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
923
+ * resolves to `default` server-side; byte-identical to prior behavior).
924
+ */
925
+ projectId?: string;
902
926
  /**
903
927
  * Force-enable (or opt out of) Workshop / local-debugger mirroring.
904
928
  *
@@ -83,6 +83,13 @@ type EventShipperOptions = {
83
83
  * Pass `null` to opt out of all mirroring (including auto-detect).
84
84
  */
85
85
  localDebuggerUrl?: string | null;
86
+ /**
87
+ * Optional project slug. When set, every outbound cloud request includes an
88
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
89
+ * values are ignored. Slug format is validated on construction but never
90
+ * throws — the backend returns 400 on invalid values.
91
+ */
92
+ projectId?: string;
86
93
  /**
87
94
  * Per-field character cap applied to event input/output BEFORE buffering
88
95
  * or serialization, so oversized payloads cost the cap — not the payload —
@@ -101,6 +108,7 @@ declare class EventShipper$1 {
101
108
  private sdkName;
102
109
  private prefix;
103
110
  private defaultEventName;
111
+ private projectId;
104
112
  private context;
105
113
  private buffers;
106
114
  private sticky;
@@ -124,6 +132,7 @@ declare class EventShipper$1 {
124
132
  constructor(opts: EventShipperOptions);
125
133
  isDebugEnabled(): boolean;
126
134
  private authHeaders;
135
+ private requestHeaders;
127
136
  /**
128
137
  * Build the retry/timeout options for one POST, honoring the shutdown
129
138
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -254,6 +263,13 @@ type TraceShipperOptions = {
254
263
  * Pass `null` to opt out of all mirroring (including auto-detect).
255
264
  */
256
265
  localDebuggerUrl?: string | null;
266
+ /**
267
+ * Optional project slug. When set, every OTLP trace export includes an
268
+ * `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
269
+ * values are ignored. Slug format is validated on construction but never
270
+ * throws — the backend returns 400 on invalid values.
271
+ */
272
+ projectId?: string;
257
273
  /**
258
274
  * Per-span hook that fires for every OTLP span right before the span is
259
275
  * shipped (both to the Raindrop API and to a local debugger). Lets callers
@@ -311,6 +327,7 @@ declare class TraceShipper$1 {
311
327
  private flushIntervalMs;
312
328
  private maxBatchSize;
313
329
  private maxQueueSize;
330
+ private projectId;
314
331
  private queue;
315
332
  private timer;
316
333
  private inFlight;
@@ -361,6 +378,7 @@ declare class TraceShipper$1 {
361
378
  private redactSpan;
362
379
  isDebugEnabled(): boolean;
363
380
  private authHeaders;
381
+ private requestHeaders;
364
382
  startSpan(args: {
365
383
  name: string;
366
384
  parent?: {
@@ -899,6 +917,12 @@ type RaindropAISDKOptions = {
899
917
  */
900
918
  writeKey?: string;
901
919
  endpoint?: string;
920
+ /**
921
+ * Optional Raindrop project slug. When set, every outbound cloud request
922
+ * carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
923
+ * resolves to `default` server-side; byte-identical to prior behavior).
924
+ */
925
+ projectId?: string;
902
926
  /**
903
927
  * Force-enable (or opt out of) Workshop / local-debugger mirroring.
904
928
  *
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- // ../core/dist/chunk-U5HUTMR5.js
3
+ // ../core/dist/chunk-SK6EJEO7.js
4
4
  function getCrypto() {
5
5
  const c = globalThis.crypto;
6
6
  return c;
@@ -397,6 +397,25 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
397
397
  ).catch(() => {
398
398
  });
399
399
  }
400
+ var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
401
+ var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
402
+ function isValidProjectIdSlug(value) {
403
+ return PROJECT_ID_SLUG_PATTERN.test(value);
404
+ }
405
+ function normalizeProjectId(raw, opts) {
406
+ if (typeof raw !== "string") return void 0;
407
+ const trimmed = raw.trim();
408
+ if (!trimmed) return void 0;
409
+ if (!isValidProjectIdSlug(trimmed) && opts.debug) {
410
+ console.warn(
411
+ `${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
412
+ );
413
+ }
414
+ return trimmed;
415
+ }
416
+ function projectIdHeaders(projectId) {
417
+ return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
418
+ }
400
419
  var SHUTDOWN_DEADLINE_MS = 1e4;
401
420
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
402
421
  function mergePatches(target, source) {
@@ -431,6 +450,10 @@ var EventShipper = class {
431
450
  if (this.debug && this.localDebuggerUrl) {
432
451
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
433
452
  }
453
+ this.projectId = normalizeProjectId(opts.projectId, {
454
+ debug: this.debug,
455
+ prefix: this.prefix
456
+ });
434
457
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
435
458
  this.context = {
436
459
  library: {
@@ -449,6 +472,9 @@ var EventShipper = class {
449
472
  authHeaders() {
450
473
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
451
474
  }
475
+ requestHeaders() {
476
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
477
+ }
452
478
  /**
453
479
  * Build the retry/timeout options for one POST, honoring the shutdown
454
480
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -578,7 +604,7 @@ var EventShipper = class {
578
604
  return;
579
605
  }
580
606
  try {
581
- await postJson(url, body, this.authHeaders(), opts);
607
+ await postJson(url, body, this.requestHeaders(), opts);
582
608
  } catch (err) {
583
609
  const msg = err instanceof Error ? err.message : String(err);
584
610
  rateLimitedLog(
@@ -614,7 +640,7 @@ var EventShipper = class {
614
640
  return;
615
641
  }
616
642
  try {
617
- await postJson(url, body, this.authHeaders(), opts);
643
+ await postJson(url, body, this.requestHeaders(), opts);
618
644
  } catch (err) {
619
645
  const msg = err instanceof Error ? err.message : String(err);
620
646
  rateLimitedLog(
@@ -710,7 +736,7 @@ var EventShipper = class {
710
736
  if (!isPending) this.sticky.delete(eventId);
711
737
  return;
712
738
  }
713
- const p = postJson(url, payload, this.authHeaders(), opts);
739
+ const p = postJson(url, payload, this.requestHeaders(), opts);
714
740
  this.inFlight.add(p);
715
741
  try {
716
742
  try {
@@ -857,6 +883,10 @@ var TraceShipper = class {
857
883
  if (this.debug && this.localDebuggerUrl) {
858
884
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
859
885
  }
886
+ this.projectId = normalizeProjectId(opts.projectId, {
887
+ debug: this.debug,
888
+ prefix: this.prefix
889
+ });
860
890
  this.transformSpanHook = opts.transformSpan;
861
891
  this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
862
892
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
@@ -933,6 +963,9 @@ var TraceShipper = class {
933
963
  authHeaders() {
934
964
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
935
965
  }
966
+ requestHeaders() {
967
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
968
+ }
936
969
  startSpan(args) {
937
970
  var _a, _b;
938
971
  const ids = createSpanIds(args.parent);
@@ -1064,7 +1097,7 @@ var TraceShipper = class {
1064
1097
  endpoint: url
1065
1098
  });
1066
1099
  }
1067
- const p = postJson(url, body, this.authHeaders(), opts);
1100
+ const p = postJson(url, body, this.requestHeaders(), opts);
1068
1101
  this.inFlight.add(p);
1069
1102
  try {
1070
1103
  try {
@@ -1250,7 +1283,7 @@ async function* asyncGeneratorWithCurrent(span, gen) {
1250
1283
  // package.json
1251
1284
  var package_default = {
1252
1285
  name: "@raindrop-ai/ai-sdk",
1253
- version: "0.0.34"};
1286
+ version: "0.0.35"};
1254
1287
 
1255
1288
  // src/internal/version.ts
1256
1289
  var libraryName = package_default.name;
@@ -5123,6 +5156,7 @@ function createRaindropAISDK(opts) {
5123
5156
  enabled: eventsEnabled,
5124
5157
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
5125
5158
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
5159
+ projectId: opts.projectId,
5126
5160
  localDebuggerUrl
5127
5161
  });
5128
5162
  const traceShipper = new TraceShipper2({
@@ -5134,6 +5168,7 @@ function createRaindropAISDK(opts) {
5134
5168
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
5135
5169
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
5136
5170
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
5171
+ projectId: opts.projectId,
5137
5172
  localDebuggerUrl,
5138
5173
  transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
5139
5174
  disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
@@ -1,4 +1,4 @@
1
- // ../core/dist/chunk-U5HUTMR5.js
1
+ // ../core/dist/chunk-SK6EJEO7.js
2
2
  function getCrypto() {
3
3
  const c = globalThis.crypto;
4
4
  return c;
@@ -395,6 +395,25 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
395
395
  ).catch(() => {
396
396
  });
397
397
  }
398
+ var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
399
+ var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
400
+ function isValidProjectIdSlug(value) {
401
+ return PROJECT_ID_SLUG_PATTERN.test(value);
402
+ }
403
+ function normalizeProjectId(raw, opts) {
404
+ if (typeof raw !== "string") return void 0;
405
+ const trimmed = raw.trim();
406
+ if (!trimmed) return void 0;
407
+ if (!isValidProjectIdSlug(trimmed) && opts.debug) {
408
+ console.warn(
409
+ `${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
410
+ );
411
+ }
412
+ return trimmed;
413
+ }
414
+ function projectIdHeaders(projectId) {
415
+ return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
416
+ }
398
417
  var SHUTDOWN_DEADLINE_MS = 1e4;
399
418
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
400
419
  function mergePatches(target, source) {
@@ -429,6 +448,10 @@ var EventShipper = class {
429
448
  if (this.debug && this.localDebuggerUrl) {
430
449
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
431
450
  }
451
+ this.projectId = normalizeProjectId(opts.projectId, {
452
+ debug: this.debug,
453
+ prefix: this.prefix
454
+ });
432
455
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
433
456
  this.context = {
434
457
  library: {
@@ -447,6 +470,9 @@ var EventShipper = class {
447
470
  authHeaders() {
448
471
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
449
472
  }
473
+ requestHeaders() {
474
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
475
+ }
450
476
  /**
451
477
  * Build the retry/timeout options for one POST, honoring the shutdown
452
478
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -576,7 +602,7 @@ var EventShipper = class {
576
602
  return;
577
603
  }
578
604
  try {
579
- await postJson(url, body, this.authHeaders(), opts);
605
+ await postJson(url, body, this.requestHeaders(), opts);
580
606
  } catch (err) {
581
607
  const msg = err instanceof Error ? err.message : String(err);
582
608
  rateLimitedLog(
@@ -612,7 +638,7 @@ var EventShipper = class {
612
638
  return;
613
639
  }
614
640
  try {
615
- await postJson(url, body, this.authHeaders(), opts);
641
+ await postJson(url, body, this.requestHeaders(), opts);
616
642
  } catch (err) {
617
643
  const msg = err instanceof Error ? err.message : String(err);
618
644
  rateLimitedLog(
@@ -708,7 +734,7 @@ var EventShipper = class {
708
734
  if (!isPending) this.sticky.delete(eventId);
709
735
  return;
710
736
  }
711
- const p = postJson(url, payload, this.authHeaders(), opts);
737
+ const p = postJson(url, payload, this.requestHeaders(), opts);
712
738
  this.inFlight.add(p);
713
739
  try {
714
740
  try {
@@ -855,6 +881,10 @@ var TraceShipper = class {
855
881
  if (this.debug && this.localDebuggerUrl) {
856
882
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
857
883
  }
884
+ this.projectId = normalizeProjectId(opts.projectId, {
885
+ debug: this.debug,
886
+ prefix: this.prefix
887
+ });
858
888
  this.transformSpanHook = opts.transformSpan;
859
889
  this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
860
890
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
@@ -931,6 +961,9 @@ var TraceShipper = class {
931
961
  authHeaders() {
932
962
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
933
963
  }
964
+ requestHeaders() {
965
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
966
+ }
934
967
  startSpan(args) {
935
968
  var _a, _b;
936
969
  const ids = createSpanIds(args.parent);
@@ -1062,7 +1095,7 @@ var TraceShipper = class {
1062
1095
  endpoint: url
1063
1096
  });
1064
1097
  }
1065
- const p = postJson(url, body, this.authHeaders(), opts);
1098
+ const p = postJson(url, body, this.requestHeaders(), opts);
1066
1099
  this.inFlight.add(p);
1067
1100
  try {
1068
1101
  try {
@@ -1248,7 +1281,7 @@ async function* asyncGeneratorWithCurrent(span, gen) {
1248
1281
  // package.json
1249
1282
  var package_default = {
1250
1283
  name: "@raindrop-ai/ai-sdk",
1251
- version: "0.0.34"};
1284
+ version: "0.0.35"};
1252
1285
 
1253
1286
  // src/internal/version.ts
1254
1287
  var libraryName = package_default.name;
@@ -5121,6 +5154,7 @@ function createRaindropAISDK(opts) {
5121
5154
  enabled: eventsEnabled,
5122
5155
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
5123
5156
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
5157
+ projectId: opts.projectId,
5124
5158
  localDebuggerUrl
5125
5159
  });
5126
5160
  const traceShipper = new TraceShipper2({
@@ -5132,6 +5166,7 @@ function createRaindropAISDK(opts) {
5132
5166
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
5133
5167
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
5134
5168
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
5169
+ projectId: opts.projectId,
5135
5170
  localDebuggerUrl,
5136
5171
  transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
5137
5172
  disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
@@ -1,4 +1,4 @@
1
- export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-HYjRP6nV.mjs';
1
+ export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-DFLIiW1D.mjs';
2
2
 
3
3
  declare global {
4
4
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => {
@@ -1,4 +1,4 @@
1
- export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-HYjRP6nV.js';
1
+ export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-DFLIiW1D.js';
2
2
 
3
3
  declare global {
4
4
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => {
@@ -4,7 +4,7 @@ var async_hooks = require('async_hooks');
4
4
 
5
5
  // src/index.node.ts
6
6
 
7
- // ../core/dist/chunk-U5HUTMR5.js
7
+ // ../core/dist/chunk-SK6EJEO7.js
8
8
  function getCrypto() {
9
9
  const c = globalThis.crypto;
10
10
  return c;
@@ -401,6 +401,25 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
401
401
  ).catch(() => {
402
402
  });
403
403
  }
404
+ var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
405
+ var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
406
+ function isValidProjectIdSlug(value) {
407
+ return PROJECT_ID_SLUG_PATTERN.test(value);
408
+ }
409
+ function normalizeProjectId(raw, opts) {
410
+ if (typeof raw !== "string") return void 0;
411
+ const trimmed = raw.trim();
412
+ if (!trimmed) return void 0;
413
+ if (!isValidProjectIdSlug(trimmed) && opts.debug) {
414
+ console.warn(
415
+ `${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
416
+ );
417
+ }
418
+ return trimmed;
419
+ }
420
+ function projectIdHeaders(projectId) {
421
+ return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
422
+ }
404
423
  var SHUTDOWN_DEADLINE_MS = 1e4;
405
424
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
406
425
  function mergePatches(target, source) {
@@ -435,6 +454,10 @@ var EventShipper = class {
435
454
  if (this.debug && this.localDebuggerUrl) {
436
455
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
437
456
  }
457
+ this.projectId = normalizeProjectId(opts.projectId, {
458
+ debug: this.debug,
459
+ prefix: this.prefix
460
+ });
438
461
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
439
462
  this.context = {
440
463
  library: {
@@ -453,6 +476,9 @@ var EventShipper = class {
453
476
  authHeaders() {
454
477
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
455
478
  }
479
+ requestHeaders() {
480
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
481
+ }
456
482
  /**
457
483
  * Build the retry/timeout options for one POST, honoring the shutdown
458
484
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -582,7 +608,7 @@ var EventShipper = class {
582
608
  return;
583
609
  }
584
610
  try {
585
- await postJson(url, body, this.authHeaders(), opts);
611
+ await postJson(url, body, this.requestHeaders(), opts);
586
612
  } catch (err) {
587
613
  const msg = err instanceof Error ? err.message : String(err);
588
614
  rateLimitedLog(
@@ -618,7 +644,7 @@ var EventShipper = class {
618
644
  return;
619
645
  }
620
646
  try {
621
- await postJson(url, body, this.authHeaders(), opts);
647
+ await postJson(url, body, this.requestHeaders(), opts);
622
648
  } catch (err) {
623
649
  const msg = err instanceof Error ? err.message : String(err);
624
650
  rateLimitedLog(
@@ -714,7 +740,7 @@ var EventShipper = class {
714
740
  if (!isPending) this.sticky.delete(eventId);
715
741
  return;
716
742
  }
717
- const p = postJson(url, payload, this.authHeaders(), opts);
743
+ const p = postJson(url, payload, this.requestHeaders(), opts);
718
744
  this.inFlight.add(p);
719
745
  try {
720
746
  try {
@@ -861,6 +887,10 @@ var TraceShipper = class {
861
887
  if (this.debug && this.localDebuggerUrl) {
862
888
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
863
889
  }
890
+ this.projectId = normalizeProjectId(opts.projectId, {
891
+ debug: this.debug,
892
+ prefix: this.prefix
893
+ });
864
894
  this.transformSpanHook = opts.transformSpan;
865
895
  this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
866
896
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
@@ -937,6 +967,9 @@ var TraceShipper = class {
937
967
  authHeaders() {
938
968
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
939
969
  }
970
+ requestHeaders() {
971
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
972
+ }
940
973
  startSpan(args) {
941
974
  var _a, _b;
942
975
  const ids = createSpanIds(args.parent);
@@ -1068,7 +1101,7 @@ var TraceShipper = class {
1068
1101
  endpoint: url
1069
1102
  });
1070
1103
  }
1071
- const p = postJson(url, body, this.authHeaders(), opts);
1104
+ const p = postJson(url, body, this.requestHeaders(), opts);
1072
1105
  this.inFlight.add(p);
1073
1106
  try {
1074
1107
  try {
@@ -1255,7 +1288,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
1255
1288
  // package.json
1256
1289
  var package_default = {
1257
1290
  name: "@raindrop-ai/ai-sdk",
1258
- version: "0.0.34"};
1291
+ version: "0.0.35"};
1259
1292
 
1260
1293
  // src/internal/version.ts
1261
1294
  var libraryName = package_default.name;
@@ -5128,6 +5161,7 @@ function createRaindropAISDK(opts) {
5128
5161
  enabled: eventsEnabled,
5129
5162
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
5130
5163
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
5164
+ projectId: opts.projectId,
5131
5165
  localDebuggerUrl
5132
5166
  });
5133
5167
  const traceShipper = new TraceShipper2({
@@ -5139,6 +5173,7 @@ function createRaindropAISDK(opts) {
5139
5173
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
5140
5174
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
5141
5175
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
5176
+ projectId: opts.projectId,
5142
5177
  localDebuggerUrl,
5143
5178
  transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
5144
5179
  disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
@@ -1,4 +1,4 @@
1
- export { DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent } from './chunk-OLOFN54C.mjs';
1
+ export { DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent } from './chunk-XPZBPNLC.mjs';
2
2
  import { AsyncLocalStorage } from 'async_hooks';
3
3
 
4
4
  globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
@@ -1,4 +1,4 @@
1
- export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-HYjRP6nV.mjs';
1
+ export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-DFLIiW1D.mjs';
2
2
 
3
3
  declare global {
4
4
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => {
@@ -1,4 +1,4 @@
1
- export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-HYjRP6nV.js';
1
+ export { A as AISDKChatRequestLike, a as AISDKChatRequestMessageLike, b as AISDKMessage, c as AgentCallMetadata, d as AgentWithMetadata, e as Attachment, B as BuildEventPatch, C as ContextManager, f as ContextSpan, g as CreateSpanArgs, D as DEFAULT_MAX_TEXT_FIELD_CHARS, h as DEFAULT_REDACT_ATTRIBUTE_KEYS, i as DEFAULT_SECRET_KEY_NAMES, E as EndSpanArgs, j as EventBuilder, k as EventMetadataOptions, I as IdentifyInput, O as OtlpAnyValue, l as OtlpSpan, P as ParentToolContext, R as REDACTED_PLACEHOLDER, m as RaindropAISDKClient, n as RaindropAISDKContext, o as RaindropAISDKOptions, p as RaindropCallMetadata, q as RaindropTelemetryIntegration, r as RaindropTelemetryIntegrationOptions, s as RaindropTelemetryOptions, S as SelfDiagnosticsOptions, t as SelfDiagnosticsSignalDefinition, u as SelfDiagnosticsSignalDefinitions, v as SelfDiagnosticsTool, w as SelfDiagnosticsToolInput, x as SelfDiagnosticsToolOptions, y as SelfDiagnosticsToolResult, z as StartSpanArgs, T as TRUNCATION_MARKER, F as TraceSpan, G as TransformSpanHook, W as WrapAISDKOptions, H as WrappedAI, J as WrappedAISDK, _ as _resetParentToolContextStorage, K as _resetRaindropCallMetadataStorage, L as _resetWarnedMissingUserId, M as boundedStringify, N as capText, Q as clearParentToolContext, U as createRaindropAISDK, V as currentSpan, X as defaultTransformSpan, Y as enterParentToolContext, Z as eventMetadata, $ as eventMetadataFromChatRequest, a0 as getContextManager, a1 as getCurrentParentToolContext, a2 as getCurrentRaindropCallMetadata, a3 as raindrop, a4 as readRaindropCallMetadataFromArgs, a5 as redactJsonAttributeValue, a6 as redactSecretsInObject, a7 as runWithParentToolContext, a8 as runWithRaindropCallMetadata, a9 as withCurrent } from './index-DFLIiW1D.js';
2
2
 
3
3
  declare global {
4
4
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => {
@@ -4,7 +4,7 @@ var async_hooks = require('async_hooks');
4
4
 
5
5
  // src/index.workers.ts
6
6
 
7
- // ../core/dist/chunk-U5HUTMR5.js
7
+ // ../core/dist/chunk-SK6EJEO7.js
8
8
  function getCrypto() {
9
9
  const c = globalThis.crypto;
10
10
  return c;
@@ -401,6 +401,25 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
401
401
  ).catch(() => {
402
402
  });
403
403
  }
404
+ var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
405
+ var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
406
+ function isValidProjectIdSlug(value) {
407
+ return PROJECT_ID_SLUG_PATTERN.test(value);
408
+ }
409
+ function normalizeProjectId(raw, opts) {
410
+ if (typeof raw !== "string") return void 0;
411
+ const trimmed = raw.trim();
412
+ if (!trimmed) return void 0;
413
+ if (!isValidProjectIdSlug(trimmed) && opts.debug) {
414
+ console.warn(
415
+ `${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
416
+ );
417
+ }
418
+ return trimmed;
419
+ }
420
+ function projectIdHeaders(projectId) {
421
+ return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
422
+ }
404
423
  var SHUTDOWN_DEADLINE_MS = 1e4;
405
424
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
406
425
  function mergePatches(target, source) {
@@ -435,6 +454,10 @@ var EventShipper = class {
435
454
  if (this.debug && this.localDebuggerUrl) {
436
455
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
437
456
  }
457
+ this.projectId = normalizeProjectId(opts.projectId, {
458
+ debug: this.debug,
459
+ prefix: this.prefix
460
+ });
438
461
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
439
462
  this.context = {
440
463
  library: {
@@ -453,6 +476,9 @@ var EventShipper = class {
453
476
  authHeaders() {
454
477
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
455
478
  }
479
+ requestHeaders() {
480
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
481
+ }
456
482
  /**
457
483
  * Build the retry/timeout options for one POST, honoring the shutdown
458
484
  * deadline. Returns `null` when the shutdown drain window is exhausted —
@@ -582,7 +608,7 @@ var EventShipper = class {
582
608
  return;
583
609
  }
584
610
  try {
585
- await postJson(url, body, this.authHeaders(), opts);
611
+ await postJson(url, body, this.requestHeaders(), opts);
586
612
  } catch (err) {
587
613
  const msg = err instanceof Error ? err.message : String(err);
588
614
  rateLimitedLog(
@@ -618,7 +644,7 @@ var EventShipper = class {
618
644
  return;
619
645
  }
620
646
  try {
621
- await postJson(url, body, this.authHeaders(), opts);
647
+ await postJson(url, body, this.requestHeaders(), opts);
622
648
  } catch (err) {
623
649
  const msg = err instanceof Error ? err.message : String(err);
624
650
  rateLimitedLog(
@@ -714,7 +740,7 @@ var EventShipper = class {
714
740
  if (!isPending) this.sticky.delete(eventId);
715
741
  return;
716
742
  }
717
- const p = postJson(url, payload, this.authHeaders(), opts);
743
+ const p = postJson(url, payload, this.requestHeaders(), opts);
718
744
  this.inFlight.add(p);
719
745
  try {
720
746
  try {
@@ -861,6 +887,10 @@ var TraceShipper = class {
861
887
  if (this.debug && this.localDebuggerUrl) {
862
888
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
863
889
  }
890
+ this.projectId = normalizeProjectId(opts.projectId, {
891
+ debug: this.debug,
892
+ prefix: this.prefix
893
+ });
864
894
  this.transformSpanHook = opts.transformSpan;
865
895
  this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
866
896
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
@@ -937,6 +967,9 @@ var TraceShipper = class {
937
967
  authHeaders() {
938
968
  return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
939
969
  }
970
+ requestHeaders() {
971
+ return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
972
+ }
940
973
  startSpan(args) {
941
974
  var _a, _b;
942
975
  const ids = createSpanIds(args.parent);
@@ -1068,7 +1101,7 @@ var TraceShipper = class {
1068
1101
  endpoint: url
1069
1102
  });
1070
1103
  }
1071
- const p = postJson(url, body, this.authHeaders(), opts);
1104
+ const p = postJson(url, body, this.requestHeaders(), opts);
1072
1105
  this.inFlight.add(p);
1073
1106
  try {
1074
1107
  try {
@@ -1255,7 +1288,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
1255
1288
  // package.json
1256
1289
  var package_default = {
1257
1290
  name: "@raindrop-ai/ai-sdk",
1258
- version: "0.0.34"};
1291
+ version: "0.0.35"};
1259
1292
 
1260
1293
  // src/internal/version.ts
1261
1294
  var libraryName = package_default.name;
@@ -5128,6 +5161,7 @@ function createRaindropAISDK(opts) {
5128
5161
  enabled: eventsEnabled,
5129
5162
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
5130
5163
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
5164
+ projectId: opts.projectId,
5131
5165
  localDebuggerUrl
5132
5166
  });
5133
5167
  const traceShipper = new TraceShipper2({
@@ -5139,6 +5173,7 @@ function createRaindropAISDK(opts) {
5139
5173
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
5140
5174
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
5141
5175
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
5176
+ projectId: opts.projectId,
5142
5177
  localDebuggerUrl,
5143
5178
  transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
5144
5179
  disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
@@ -1,4 +1,4 @@
1
- export { DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent } from './chunk-OLOFN54C.mjs';
1
+ export { DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent } from './chunk-XPZBPNLC.mjs';
2
2
  import { AsyncLocalStorage } from 'async_hooks';
3
3
 
4
4
  if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raindrop-ai/ai-sdk",
3
- "version": "0.0.34",
3
+ "version": "0.0.35",
4
4
  "description": "Standalone Vercel AI SDK integration for Raindrop (events + OTLP/HTTP JSON traces, no OTEL runtime)",
5
5
  "main": "dist/index.node.js",
6
6
  "module": "dist/index.node.mjs",
@@ -42,7 +42,7 @@
42
42
  "tsup": "^8.4.0",
43
43
  "tsx": "^4.20.3",
44
44
  "typescript": "^5.3.3",
45
- "@raindrop-ai/core": "0.0.3"
45
+ "@raindrop-ai/core": "0.0.4"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "ai": ">=4 <8"