@raindrop-ai/pi-agent 0.0.10 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- // ../core/dist/chunk-267IXHO5.js
1
+ // ../core/dist/chunk-QTUH3BHZ.js
2
2
  function getCrypto() {
3
3
  const c = globalThis.crypto;
4
4
  return c;
@@ -391,19 +391,52 @@ function projectIdHeaders(projectId) {
391
391
  var SHUTDOWN_DEADLINE_MS = 1e4;
392
392
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
393
393
  function mergePatches(target, source) {
394
- var _a, _b, _c, _d, _e, _f;
394
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
395
395
  const out = { ...target, ...source };
396
396
  if (target.properties || source.properties) {
397
397
  out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
398
398
  }
399
+ if (target.usage || source.usage) {
400
+ out.usage = { ...(_c = target.usage) != null ? _c : {} };
401
+ if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
402
+ out.usage.promptTokens = source.usage.promptTokens;
403
+ }
404
+ if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
405
+ out.usage.completionTokens = source.usage.completionTokens;
406
+ }
407
+ }
408
+ if (source.error === void 0) {
409
+ out.error = target.error;
410
+ }
399
411
  if (target.featureFlags || source.featureFlags) {
400
- out.featureFlags = { ...(_c = target.featureFlags) != null ? _c : {}, ...(_d = source.featureFlags) != null ? _d : {} };
412
+ out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
401
413
  }
402
414
  if (target.attachments || source.attachments) {
403
- out.attachments = [...(_e = target.attachments) != null ? _e : [], ...(_f = source.attachments) != null ? _f : []];
415
+ out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
404
416
  }
405
417
  return out;
406
418
  }
419
+ function isErrorLike(value) {
420
+ return value !== null && typeof value === "object";
421
+ }
422
+ function eventTelemetryProperties(patch) {
423
+ var _a, _b;
424
+ const properties = {};
425
+ if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
426
+ properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
427
+ }
428
+ if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
429
+ properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
430
+ }
431
+ if (patch.error !== void 0 && patch.error !== null) {
432
+ const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
433
+ const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
434
+ const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
435
+ properties["error.type"] = errorType;
436
+ properties["error.message"] = errorMessage;
437
+ }
438
+ return properties;
439
+ }
407
440
  var EventShipper = class {
408
441
  constructor(opts) {
409
442
  this.buffers = /* @__PURE__ */ new Map();
@@ -652,6 +685,11 @@ var EventShipper = class {
652
685
  return;
653
686
  }
654
687
  const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
688
+ let telemetryProperties = {};
689
+ try {
690
+ telemetryProperties = eventTelemetryProperties(accumulated);
691
+ } catch (e) {
692
+ }
655
693
  const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
656
694
  const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
657
695
  const payload = {
@@ -661,12 +699,13 @@ var EventShipper = class {
661
699
  timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
662
700
  ai_data: {
663
701
  input: accumulated.input,
664
- output: accumulated.output,
702
+ output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
665
703
  model: accumulated.model,
666
704
  convo_id: convoId
667
705
  },
668
706
  properties: {
669
707
  ...restProperties,
708
+ ...telemetryProperties,
670
709
  ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
671
710
  $context: this.context
672
711
  },
@@ -824,6 +863,13 @@ function redactJsonAttributeValue(key, value) {
824
863
  if (scrubbedJson === json) return void 0;
825
864
  return { stringValue: scrubbedJson };
826
865
  }
866
+ function identityAttrs(args) {
867
+ return [
868
+ attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
869
+ attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
870
+ attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
871
+ ];
872
+ }
827
873
  function applyOtelSpanAttributeLimit(limit) {
828
874
  var _a, _b;
829
875
  try {
@@ -948,6 +994,7 @@ var TraceShipper = class {
948
994
  const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
949
995
  const attrs = [
950
996
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
997
+ ...identityAttrs(args),
951
998
  attrString("ai.operationId", args.operationId)
952
999
  ];
953
1000
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
@@ -1003,7 +1050,8 @@ var TraceShipper = class {
1003
1050
  var _a;
1004
1051
  const ids = createSpanIds(args.parent);
1005
1052
  const attrs = [
1006
- attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
1053
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1054
+ ...identityAttrs(args)
1007
1055
  ];
1008
1056
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
1009
1057
  const otlp = buildOtlpSpan({
@@ -1171,7 +1219,7 @@ installTracingSuppressionHook();
1171
1219
  // package.json
1172
1220
  var package_default = {
1173
1221
  name: "@raindrop-ai/pi-agent",
1174
- version: "0.0.10",
1222
+ version: "0.1.0",
1175
1223
  description: "Raindrop observability for Pi Agent \u2014 automatic tracing via subscriber or pi-coding-agent extension",
1176
1224
  type: "module",
1177
1225
  license: "MIT",
@@ -25,7 +25,7 @@ __export(extension_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(extension_exports);
27
27
 
28
- // ../core/dist/chunk-267IXHO5.js
28
+ // ../core/dist/chunk-QTUH3BHZ.js
29
29
  function getCrypto() {
30
30
  const c = globalThis.crypto;
31
31
  return c;
@@ -418,19 +418,52 @@ function projectIdHeaders(projectId) {
418
418
  var SHUTDOWN_DEADLINE_MS = 1e4;
419
419
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
420
420
  function mergePatches(target, source) {
421
- var _a, _b, _c, _d, _e, _f;
421
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
422
422
  const out = { ...target, ...source };
423
423
  if (target.properties || source.properties) {
424
424
  out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
425
425
  }
426
+ if (target.usage || source.usage) {
427
+ out.usage = { ...(_c = target.usage) != null ? _c : {} };
428
+ if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
429
+ out.usage.promptTokens = source.usage.promptTokens;
430
+ }
431
+ if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
432
+ out.usage.completionTokens = source.usage.completionTokens;
433
+ }
434
+ }
435
+ if (source.error === void 0) {
436
+ out.error = target.error;
437
+ }
426
438
  if (target.featureFlags || source.featureFlags) {
427
- out.featureFlags = { ...(_c = target.featureFlags) != null ? _c : {}, ...(_d = source.featureFlags) != null ? _d : {} };
439
+ out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
428
440
  }
429
441
  if (target.attachments || source.attachments) {
430
- out.attachments = [...(_e = target.attachments) != null ? _e : [], ...(_f = source.attachments) != null ? _f : []];
442
+ out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
431
443
  }
432
444
  return out;
433
445
  }
446
+ function isErrorLike(value) {
447
+ return value !== null && typeof value === "object";
448
+ }
449
+ function eventTelemetryProperties(patch) {
450
+ var _a, _b;
451
+ const properties = {};
452
+ if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
453
+ properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
454
+ }
455
+ if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
456
+ properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
457
+ }
458
+ if (patch.error !== void 0 && patch.error !== null) {
459
+ const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
460
+ const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
461
+ const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
462
+ properties["error.type"] = errorType;
463
+ properties["error.message"] = errorMessage;
464
+ }
465
+ return properties;
466
+ }
434
467
  var EventShipper = class {
435
468
  constructor(opts) {
436
469
  this.buffers = /* @__PURE__ */ new Map();
@@ -679,6 +712,11 @@ var EventShipper = class {
679
712
  return;
680
713
  }
681
714
  const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
715
+ let telemetryProperties = {};
716
+ try {
717
+ telemetryProperties = eventTelemetryProperties(accumulated);
718
+ } catch (e) {
719
+ }
682
720
  const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
683
721
  const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
684
722
  const payload = {
@@ -688,12 +726,13 @@ var EventShipper = class {
688
726
  timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
689
727
  ai_data: {
690
728
  input: accumulated.input,
691
- output: accumulated.output,
729
+ output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
692
730
  model: accumulated.model,
693
731
  convo_id: convoId
694
732
  },
695
733
  properties: {
696
734
  ...restProperties,
735
+ ...telemetryProperties,
697
736
  ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
698
737
  $context: this.context
699
738
  },
@@ -851,6 +890,13 @@ function redactJsonAttributeValue(key, value) {
851
890
  if (scrubbedJson === json) return void 0;
852
891
  return { stringValue: scrubbedJson };
853
892
  }
893
+ function identityAttrs(args) {
894
+ return [
895
+ attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
896
+ attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
897
+ attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
898
+ ];
899
+ }
854
900
  function applyOtelSpanAttributeLimit(limit) {
855
901
  var _a, _b;
856
902
  try {
@@ -975,6 +1021,7 @@ var TraceShipper = class {
975
1021
  const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
976
1022
  const attrs = [
977
1023
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1024
+ ...identityAttrs(args),
978
1025
  attrString("ai.operationId", args.operationId)
979
1026
  ];
980
1027
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
@@ -1030,7 +1077,8 @@ var TraceShipper = class {
1030
1077
  var _a;
1031
1078
  const ids = createSpanIds(args.parent);
1032
1079
  const attrs = [
1033
- attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
1080
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1081
+ ...identityAttrs(args)
1034
1082
  ];
1035
1083
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
1036
1084
  const otlp = buildOtlpSpan({
@@ -1253,7 +1301,7 @@ function resolveLocalWorkshopUrl(fileValue) {
1253
1301
  // package.json
1254
1302
  var package_default = {
1255
1303
  name: "@raindrop-ai/pi-agent",
1256
- version: "0.0.10",
1304
+ version: "0.1.0",
1257
1305
  description: "Raindrop observability for Pi Agent \u2014 automatic tracing via subscriber or pi-coding-agent extension",
1258
1306
  type: "module",
1259
1307
  license: "MIT",
@@ -1578,7 +1626,9 @@ function getAssistantError(message) {
1578
1626
  var _a;
1579
1627
  if (message.role !== "assistant") return void 0;
1580
1628
  if (message.stopReason !== "error" && message.stopReason !== "aborted") return void 0;
1581
- return (_a = message.errorMessage) != null ? _a : `Assistant ${message.stopReason}`;
1629
+ const error = new Error((_a = message.errorMessage) != null ? _a : `Assistant ${message.stopReason}`);
1630
+ error.name = message.stopReason === "aborted" ? "AbortError" : "PiAgentError";
1631
+ return error;
1582
1632
  }
1583
1633
  function getState(stateRef, ctx) {
1584
1634
  const sessionId = ctx.sessionManager.getSessionId();
@@ -1772,13 +1822,16 @@ function registerTracing(pi, config, eventShipper, traceShipper) {
1772
1822
  await eventShipper.finish((_h = state.currentEventRequestId) != null ? _h : state.currentEventId, {
1773
1823
  userId: getUserId(state, config.eventMetadata),
1774
1824
  ...modelId ? { model: modelId } : {},
1775
- ...outputText.trim() ? { output: outputText } : {},
1825
+ ...!errorForSpan && outputText.trim() ? { output: outputText } : {},
1826
+ usage: {
1827
+ promptTokens: state.totalInputTokens > 0 ? state.totalInputTokens : void 0,
1828
+ completionTokens: state.totalOutputTokens > 0 ? state.totalOutputTokens : void 0
1829
+ },
1830
+ error: errorForSpan,
1776
1831
  properties: {
1777
1832
  sdk_version: libraryVersion,
1778
1833
  stop_reason: message.stopReason,
1779
1834
  ...provider ? { "ai.provider": provider } : {},
1780
- ...state.totalInputTokens > 0 ? { "ai.usage.prompt_tokens": state.totalInputTokens } : {},
1781
- ...state.totalOutputTokens > 0 ? { "ai.usage.completion_tokens": state.totalOutputTokens } : {},
1782
1835
  ...state.totalCacheReadTokens > 0 ? { "ai.usage.cache_read_tokens": state.totalCacheReadTokens } : {}
1783
1836
  }
1784
1837
  });
@@ -1,5 +1,5 @@
1
1
  import { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
- import { E as EventShipper$1, T as TraceShipper$1, O as OtlpSpan } from './index.d-DBLTz2Nz.cjs';
2
+ import { E as EventShipper$1, T as TraceShipper$1, O as OtlpSpan } from './index.d-DPYV95P7.cjs';
3
3
 
4
4
  interface EventMetadata {
5
5
  userId?: string;
@@ -1,5 +1,5 @@
1
1
  import { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
- import { E as EventShipper$1, T as TraceShipper$1, O as OtlpSpan } from './index.d-DBLTz2Nz.js';
2
+ import { E as EventShipper$1, T as TraceShipper$1, O as OtlpSpan } from './index.d-DPYV95P7.js';
3
3
 
4
4
  interface EventMetadata {
5
5
  userId?: string;
package/dist/extension.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  resolveLocalDebuggerBaseUrl,
15
15
  safeStringify,
16
16
  truncate
17
- } from "./chunk-GXL5WZE5.js";
17
+ } from "./chunk-XQJ6G4YA.js";
18
18
 
19
19
  // src/internal/config.ts
20
20
  import { existsSync, readFileSync } from "fs";
@@ -141,7 +141,9 @@ function getAssistantError(message) {
141
141
  var _a;
142
142
  if (message.role !== "assistant") return void 0;
143
143
  if (message.stopReason !== "error" && message.stopReason !== "aborted") return void 0;
144
- return (_a = message.errorMessage) != null ? _a : `Assistant ${message.stopReason}`;
144
+ const error = new Error((_a = message.errorMessage) != null ? _a : `Assistant ${message.stopReason}`);
145
+ error.name = message.stopReason === "aborted" ? "AbortError" : "PiAgentError";
146
+ return error;
145
147
  }
146
148
  function getState(stateRef, ctx) {
147
149
  const sessionId = ctx.sessionManager.getSessionId();
@@ -335,13 +337,16 @@ function registerTracing(pi, config, eventShipper, traceShipper) {
335
337
  await eventShipper.finish((_h = state.currentEventRequestId) != null ? _h : state.currentEventId, {
336
338
  userId: getUserId(state, config.eventMetadata),
337
339
  ...modelId ? { model: modelId } : {},
338
- ...outputText.trim() ? { output: outputText } : {},
340
+ ...!errorForSpan && outputText.trim() ? { output: outputText } : {},
341
+ usage: {
342
+ promptTokens: state.totalInputTokens > 0 ? state.totalInputTokens : void 0,
343
+ completionTokens: state.totalOutputTokens > 0 ? state.totalOutputTokens : void 0
344
+ },
345
+ error: errorForSpan,
339
346
  properties: {
340
347
  sdk_version: libraryVersion,
341
348
  stop_reason: message.stopReason,
342
349
  ...provider ? { "ai.provider": provider } : {},
343
- ...state.totalInputTokens > 0 ? { "ai.usage.prompt_tokens": state.totalInputTokens } : {},
344
- ...state.totalOutputTokens > 0 ? { "ai.usage.completion_tokens": state.totalOutputTokens } : {},
345
350
  ...state.totalCacheReadTokens > 0 ? { "ai.usage.cache_read_tokens": state.totalCacheReadTokens } : {}
346
351
  }
347
352
  });
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ __export(index_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(index_exports);
26
26
 
27
- // ../core/dist/chunk-267IXHO5.js
27
+ // ../core/dist/chunk-QTUH3BHZ.js
28
28
  function getCrypto() {
29
29
  const c = globalThis.crypto;
30
30
  return c;
@@ -414,19 +414,52 @@ function projectIdHeaders(projectId) {
414
414
  var SHUTDOWN_DEADLINE_MS = 1e4;
415
415
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
416
416
  function mergePatches(target, source) {
417
- var _a, _b, _c, _d, _e, _f;
417
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
418
418
  const out = { ...target, ...source };
419
419
  if (target.properties || source.properties) {
420
420
  out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
421
421
  }
422
+ if (target.usage || source.usage) {
423
+ out.usage = { ...(_c = target.usage) != null ? _c : {} };
424
+ if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
425
+ out.usage.promptTokens = source.usage.promptTokens;
426
+ }
427
+ if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
428
+ out.usage.completionTokens = source.usage.completionTokens;
429
+ }
430
+ }
431
+ if (source.error === void 0) {
432
+ out.error = target.error;
433
+ }
422
434
  if (target.featureFlags || source.featureFlags) {
423
- out.featureFlags = { ...(_c = target.featureFlags) != null ? _c : {}, ...(_d = source.featureFlags) != null ? _d : {} };
435
+ out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
424
436
  }
425
437
  if (target.attachments || source.attachments) {
426
- out.attachments = [...(_e = target.attachments) != null ? _e : [], ...(_f = source.attachments) != null ? _f : []];
438
+ out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
427
439
  }
428
440
  return out;
429
441
  }
442
+ function isErrorLike(value) {
443
+ return value !== null && typeof value === "object";
444
+ }
445
+ function eventTelemetryProperties(patch) {
446
+ var _a, _b;
447
+ const properties = {};
448
+ if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
449
+ properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
450
+ }
451
+ if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
452
+ properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
453
+ }
454
+ if (patch.error !== void 0 && patch.error !== null) {
455
+ const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
456
+ const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
457
+ const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
458
+ properties["error.type"] = errorType;
459
+ properties["error.message"] = errorMessage;
460
+ }
461
+ return properties;
462
+ }
430
463
  var EventShipper = class {
431
464
  constructor(opts) {
432
465
  this.buffers = /* @__PURE__ */ new Map();
@@ -675,6 +708,11 @@ var EventShipper = class {
675
708
  return;
676
709
  }
677
710
  const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
711
+ let telemetryProperties = {};
712
+ try {
713
+ telemetryProperties = eventTelemetryProperties(accumulated);
714
+ } catch (e) {
715
+ }
678
716
  const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
679
717
  const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
680
718
  const payload = {
@@ -684,12 +722,13 @@ var EventShipper = class {
684
722
  timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
685
723
  ai_data: {
686
724
  input: accumulated.input,
687
- output: accumulated.output,
725
+ output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
688
726
  model: accumulated.model,
689
727
  convo_id: convoId
690
728
  },
691
729
  properties: {
692
730
  ...restProperties,
731
+ ...telemetryProperties,
693
732
  ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
694
733
  $context: this.context
695
734
  },
@@ -847,6 +886,13 @@ function redactJsonAttributeValue(key, value) {
847
886
  if (scrubbedJson === json) return void 0;
848
887
  return { stringValue: scrubbedJson };
849
888
  }
889
+ function identityAttrs(args) {
890
+ return [
891
+ attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
892
+ attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
893
+ attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
894
+ ];
895
+ }
850
896
  function applyOtelSpanAttributeLimit(limit) {
851
897
  var _a, _b;
852
898
  try {
@@ -971,6 +1017,7 @@ var TraceShipper = class {
971
1017
  const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
972
1018
  const attrs = [
973
1019
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1020
+ ...identityAttrs(args),
974
1021
  attrString("ai.operationId", args.operationId)
975
1022
  ];
976
1023
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
@@ -1026,7 +1073,8 @@ var TraceShipper = class {
1026
1073
  var _a;
1027
1074
  const ids = createSpanIds(args.parent);
1028
1075
  const attrs = [
1029
- attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
1076
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1077
+ ...identityAttrs(args)
1030
1078
  ];
1031
1079
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
1032
1080
  const otlp = buildOtlpSpan({
@@ -1194,7 +1242,7 @@ installTracingSuppressionHook();
1194
1242
  // package.json
1195
1243
  var package_default = {
1196
1244
  name: "@raindrop-ai/pi-agent",
1197
- version: "0.0.10",
1245
+ version: "0.1.0",
1198
1246
  description: "Raindrop observability for Pi Agent \u2014 automatic tracing via subscriber or pi-coding-agent extension",
1199
1247
  type: "module",
1200
1248
  license: "MIT",
@@ -1493,14 +1541,24 @@ function getUsername() {
1493
1541
  }
1494
1542
 
1495
1543
  // src/internal/subscriber.ts
1544
+ function resolveEventId(source) {
1545
+ if (typeof source !== "function") return randomUUID();
1546
+ try {
1547
+ const id = source();
1548
+ return typeof id === "string" && id.trim() !== "" ? id : randomUUID();
1549
+ } catch (e) {
1550
+ return randomUUID();
1551
+ }
1552
+ }
1496
1553
  function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, options, debug) {
1497
- var _a, _b, _c, _d, _e;
1554
+ var _a, _b, _c, _d, _e, _f;
1498
1555
  const userId = (_a = options.userId) != null ? _a : defaultOptions.userId;
1499
1556
  const convoId = (_b = options.convoId) != null ? _b : defaultOptions.convoId;
1500
1557
  const eventName = (_c = options.eventName) != null ? _c : defaultOptions.eventName;
1558
+ const eventIdSource = (_d = options.eventId) != null ? _d : defaultOptions.eventId;
1501
1559
  const properties = {
1502
- ...(_d = defaultOptions.properties) != null ? _d : {},
1503
- ...(_e = options.properties) != null ? _e : {}
1560
+ ...(_e = defaultOptions.properties) != null ? _e : {},
1561
+ ...(_f = options.properties) != null ? _f : {}
1504
1562
  };
1505
1563
  let currentRun;
1506
1564
  function log(msg) {
@@ -1531,7 +1589,7 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
1531
1589
  }
1532
1590
  currentRun = void 0;
1533
1591
  }
1534
- const eventId = randomUUID();
1592
+ const eventId = resolveEventId(eventIdSource);
1535
1593
  const rootSpan = traceShipper ? traceShipper.startSpan({
1536
1594
  name: "ai.event",
1537
1595
  eventId,
@@ -1643,6 +1701,13 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
1643
1701
  attributes: llmAttrs
1644
1702
  });
1645
1703
  const errorForSpan = stopReason === "error" || stopReason === "aborted" ? "errorMessage" in message && typeof message.errorMessage === "string" ? message.errorMessage : `Assistant ${stopReason}` : void 0;
1704
+ if (errorForSpan) {
1705
+ const assistantError = new Error(errorForSpan);
1706
+ assistantError.name = stopReason === "aborted" ? "AbortError" : "PiAgentError";
1707
+ currentRun.error = assistantError;
1708
+ } else {
1709
+ currentRun.error = void 0;
1710
+ }
1646
1711
  traceShipper.endSpan(llmSpan, errorForSpan ? { error: errorForSpan } : void 0);
1647
1712
  const toolCallIds = extractToolCallIds(message);
1648
1713
  for (const tcId of toolCallIds) {
@@ -1787,13 +1852,16 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
1787
1852
  eventShipper.finish(run.eventId, {
1788
1853
  userId: userId != null ? userId : "anonymous",
1789
1854
  model: run.lastModel || void 0,
1790
- output: outputText || void 0,
1855
+ output: run.error ? void 0 : outputText || void 0,
1856
+ usage: {
1857
+ promptTokens: run.totalInputTokens > 0 ? run.totalInputTokens : void 0,
1858
+ completionTokens: run.totalOutputTokens > 0 ? run.totalOutputTokens : void 0
1859
+ },
1860
+ error: run.error,
1791
1861
  properties: {
1792
1862
  ...properties,
1793
1863
  sdk_version: libraryVersion,
1794
1864
  ...run.lastProvider ? { "ai.provider": run.lastProvider } : {},
1795
- ...run.totalInputTokens > 0 ? { "ai.usage.prompt_tokens": run.totalInputTokens } : {},
1796
- ...run.totalOutputTokens > 0 ? { "ai.usage.completion_tokens": run.totalOutputTokens } : {},
1797
1865
  ...run.totalCacheReadTokens > 0 ? { "ai.usage.cache_read_tokens": run.totalCacheReadTokens } : {}
1798
1866
  }
1799
1867
  }).catch(() => {
@@ -1894,6 +1962,7 @@ function createRaindropPiAgent(opts) {
1894
1962
  userId: opts.userId,
1895
1963
  convoId: opts.convoId,
1896
1964
  eventName: opts.eventName,
1965
+ eventId: opts.eventId,
1897
1966
  properties: opts.properties
1898
1967
  };
1899
1968
  return {
@@ -45,6 +45,10 @@ type IdentifyInput = {
45
45
  userId: string;
46
46
  traits?: Record<string, unknown>;
47
47
  };
48
+ type EventUsage = {
49
+ promptTokens?: number;
50
+ completionTokens?: number;
51
+ };
48
52
  type Patch = {
49
53
  eventName?: string;
50
54
  userId?: string;
@@ -52,6 +56,8 @@ type Patch = {
52
56
  input?: string;
53
57
  output?: string;
54
58
  model?: string;
59
+ usage?: EventUsage;
60
+ error?: unknown;
55
61
  properties?: Record<string, unknown>;
56
62
  featureFlags?: Record<string, string>;
57
63
  attachments?: Attachment[];
@@ -150,13 +156,7 @@ declare class EventShipper {
150
156
  */
151
157
  private requestOpts;
152
158
  patch(eventId: string, patch: Patch): Promise<void>;
153
- finish(eventId: string, patch: {
154
- output?: string;
155
- model?: string;
156
- properties?: Record<string, unknown>;
157
- featureFlags?: Record<string, string>;
158
- userId?: string;
159
- }): Promise<void>;
159
+ finish(eventId: string, patch: Pick<Patch, "output" | "model" | "usage" | "error" | "properties" | "featureFlags" | "userId">): Promise<void>;
160
160
  flush(): Promise<void>;
161
161
  shutdown(): Promise<void>;
162
162
  trackSignal(signal: SignalInput): Promise<void>;
@@ -329,6 +329,9 @@ declare class TraceShipper {
329
329
  spanIdB64: string;
330
330
  };
331
331
  eventId: string;
332
+ userId?: string;
333
+ convoId?: string;
334
+ eventName?: string;
332
335
  operationId?: string;
333
336
  attributes?: Array<OtlpKeyValue | undefined>;
334
337
  startTimeUnixNano?: string;
@@ -347,6 +350,9 @@ declare class TraceShipper {
347
350
  spanIdB64: string;
348
351
  };
349
352
  eventId: string;
353
+ userId?: string;
354
+ convoId?: string;
355
+ eventName?: string;
350
356
  startTimeUnixNano: string;
351
357
  endTimeUnixNano: string;
352
358
  attributes?: Array<OtlpKeyValue | undefined>;
@@ -45,6 +45,10 @@ type IdentifyInput = {
45
45
  userId: string;
46
46
  traits?: Record<string, unknown>;
47
47
  };
48
+ type EventUsage = {
49
+ promptTokens?: number;
50
+ completionTokens?: number;
51
+ };
48
52
  type Patch = {
49
53
  eventName?: string;
50
54
  userId?: string;
@@ -52,6 +56,8 @@ type Patch = {
52
56
  input?: string;
53
57
  output?: string;
54
58
  model?: string;
59
+ usage?: EventUsage;
60
+ error?: unknown;
55
61
  properties?: Record<string, unknown>;
56
62
  featureFlags?: Record<string, string>;
57
63
  attachments?: Attachment[];
@@ -150,13 +156,7 @@ declare class EventShipper {
150
156
  */
151
157
  private requestOpts;
152
158
  patch(eventId: string, patch: Patch): Promise<void>;
153
- finish(eventId: string, patch: {
154
- output?: string;
155
- model?: string;
156
- properties?: Record<string, unknown>;
157
- featureFlags?: Record<string, string>;
158
- userId?: string;
159
- }): Promise<void>;
159
+ finish(eventId: string, patch: Pick<Patch, "output" | "model" | "usage" | "error" | "properties" | "featureFlags" | "userId">): Promise<void>;
160
160
  flush(): Promise<void>;
161
161
  shutdown(): Promise<void>;
162
162
  trackSignal(signal: SignalInput): Promise<void>;
@@ -329,6 +329,9 @@ declare class TraceShipper {
329
329
  spanIdB64: string;
330
330
  };
331
331
  eventId: string;
332
+ userId?: string;
333
+ convoId?: string;
334
+ eventName?: string;
332
335
  operationId?: string;
333
336
  attributes?: Array<OtlpKeyValue | undefined>;
334
337
  startTimeUnixNano?: string;
@@ -347,6 +350,9 @@ declare class TraceShipper {
347
350
  spanIdB64: string;
348
351
  };
349
352
  eventId: string;
353
+ userId?: string;
354
+ convoId?: string;
355
+ eventName?: string;
350
356
  startTimeUnixNano: string;
351
357
  endTimeUnixNano: string;
352
358
  attributes?: Array<OtlpKeyValue | undefined>;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Agent } from '@earendil-works/pi-agent-core';
2
- import { A as Attachment } from './index.d-DBLTz2Nz.cjs';
2
+ import { A as Attachment } from './index.d-DPYV95P7.cjs';
3
3
 
4
4
  /**
5
5
  * Options for the Raindrop Pi Agent client.
@@ -24,6 +24,15 @@ interface RaindropPiAgentOptions {
24
24
  convoId?: string;
25
25
  /** Default event name (default: "pi_agent_prompt") */
26
26
  eventName?: string;
27
+ /**
28
+ * Per-run event id source. Invoked once per agent run to mint that run's
29
+ * event id (reused for the run's Raindrop event and every linked span). A
30
+ * static string is intentionally not accepted: a long-lived client runs many
31
+ * agent runs, and a fixed id would collide across them. Absent / throwing /
32
+ * non-string / empty results fall back to a random UUID, so a caller's id
33
+ * source never crashes telemetry.
34
+ */
35
+ eventId?: () => string;
27
36
  /** Default properties attached to every event */
28
37
  properties?: Record<string, unknown>;
29
38
  /**
@@ -69,6 +78,8 @@ interface PiAgentSubscribeOptions {
69
78
  convoId?: string;
70
79
  /** Event name override */
71
80
  eventName?: string;
81
+ /** Per-run event id source override (see RaindropPiAgentOptions.eventId) */
82
+ eventId?: () => string;
72
83
  /** Additional properties */
73
84
  properties?: Record<string, unknown>;
74
85
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Agent } from '@earendil-works/pi-agent-core';
2
- import { A as Attachment } from './index.d-DBLTz2Nz.js';
2
+ import { A as Attachment } from './index.d-DPYV95P7.js';
3
3
 
4
4
  /**
5
5
  * Options for the Raindrop Pi Agent client.
@@ -24,6 +24,15 @@ interface RaindropPiAgentOptions {
24
24
  convoId?: string;
25
25
  /** Default event name (default: "pi_agent_prompt") */
26
26
  eventName?: string;
27
+ /**
28
+ * Per-run event id source. Invoked once per agent run to mint that run's
29
+ * event id (reused for the run's Raindrop event and every linked span). A
30
+ * static string is intentionally not accepted: a long-lived client runs many
31
+ * agent runs, and a fixed id would collide across them. Absent / throwing /
32
+ * non-string / empty results fall back to a random UUID, so a caller's id
33
+ * source never crashes telemetry.
34
+ */
35
+ eventId?: () => string;
27
36
  /** Default properties attached to every event */
28
37
  properties?: Record<string, unknown>;
29
38
  /**
@@ -69,6 +78,8 @@ interface PiAgentSubscribeOptions {
69
78
  convoId?: string;
70
79
  /** Event name override */
71
80
  eventName?: string;
81
+ /** Per-run event id source override (see RaindropPiAgentOptions.eventId) */
82
+ eventId?: () => string;
72
83
  /** Additional properties */
73
84
  properties?: Record<string, unknown>;
74
85
  }
package/dist/index.js CHANGED
@@ -17,17 +17,27 @@ import {
17
17
  resolveLocalDebuggerBaseUrl,
18
18
  safeStringify,
19
19
  truncate
20
- } from "./chunk-GXL5WZE5.js";
20
+ } from "./chunk-XQJ6G4YA.js";
21
21
 
22
22
  // src/internal/subscriber.ts
23
+ function resolveEventId(source) {
24
+ if (typeof source !== "function") return randomUUID();
25
+ try {
26
+ const id = source();
27
+ return typeof id === "string" && id.trim() !== "" ? id : randomUUID();
28
+ } catch (e) {
29
+ return randomUUID();
30
+ }
31
+ }
23
32
  function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, options, debug) {
24
- var _a, _b, _c, _d, _e;
33
+ var _a, _b, _c, _d, _e, _f;
25
34
  const userId = (_a = options.userId) != null ? _a : defaultOptions.userId;
26
35
  const convoId = (_b = options.convoId) != null ? _b : defaultOptions.convoId;
27
36
  const eventName = (_c = options.eventName) != null ? _c : defaultOptions.eventName;
37
+ const eventIdSource = (_d = options.eventId) != null ? _d : defaultOptions.eventId;
28
38
  const properties = {
29
- ...(_d = defaultOptions.properties) != null ? _d : {},
30
- ...(_e = options.properties) != null ? _e : {}
39
+ ...(_e = defaultOptions.properties) != null ? _e : {},
40
+ ...(_f = options.properties) != null ? _f : {}
31
41
  };
32
42
  let currentRun;
33
43
  function log(msg) {
@@ -58,7 +68,7 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
58
68
  }
59
69
  currentRun = void 0;
60
70
  }
61
- const eventId = randomUUID();
71
+ const eventId = resolveEventId(eventIdSource);
62
72
  const rootSpan = traceShipper ? traceShipper.startSpan({
63
73
  name: "ai.event",
64
74
  eventId,
@@ -170,6 +180,13 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
170
180
  attributes: llmAttrs
171
181
  });
172
182
  const errorForSpan = stopReason === "error" || stopReason === "aborted" ? "errorMessage" in message && typeof message.errorMessage === "string" ? message.errorMessage : `Assistant ${stopReason}` : void 0;
183
+ if (errorForSpan) {
184
+ const assistantError = new Error(errorForSpan);
185
+ assistantError.name = stopReason === "aborted" ? "AbortError" : "PiAgentError";
186
+ currentRun.error = assistantError;
187
+ } else {
188
+ currentRun.error = void 0;
189
+ }
173
190
  traceShipper.endSpan(llmSpan, errorForSpan ? { error: errorForSpan } : void 0);
174
191
  const toolCallIds = extractToolCallIds(message);
175
192
  for (const tcId of toolCallIds) {
@@ -314,13 +331,16 @@ function createSubscriber(agent, eventShipper, traceShipper, defaultOptions, opt
314
331
  eventShipper.finish(run.eventId, {
315
332
  userId: userId != null ? userId : "anonymous",
316
333
  model: run.lastModel || void 0,
317
- output: outputText || void 0,
334
+ output: run.error ? void 0 : outputText || void 0,
335
+ usage: {
336
+ promptTokens: run.totalInputTokens > 0 ? run.totalInputTokens : void 0,
337
+ completionTokens: run.totalOutputTokens > 0 ? run.totalOutputTokens : void 0
338
+ },
339
+ error: run.error,
318
340
  properties: {
319
341
  ...properties,
320
342
  sdk_version: libraryVersion,
321
343
  ...run.lastProvider ? { "ai.provider": run.lastProvider } : {},
322
- ...run.totalInputTokens > 0 ? { "ai.usage.prompt_tokens": run.totalInputTokens } : {},
323
- ...run.totalOutputTokens > 0 ? { "ai.usage.completion_tokens": run.totalOutputTokens } : {},
324
344
  ...run.totalCacheReadTokens > 0 ? { "ai.usage.cache_read_tokens": run.totalCacheReadTokens } : {}
325
345
  }
326
346
  }).catch(() => {
@@ -421,6 +441,7 @@ function createRaindropPiAgent(opts) {
421
441
  userId: opts.userId,
422
442
  convoId: opts.convoId,
423
443
  eventName: opts.eventName,
444
+ eventId: opts.eventId,
424
445
  properties: opts.properties
425
446
  };
426
447
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raindrop-ai/pi-agent",
3
- "version": "0.0.10",
3
+ "version": "0.1.0",
4
4
  "description": "Raindrop observability for Pi Agent — automatic tracing via subscriber or pi-coding-agent extension",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -54,7 +54,7 @@
54
54
  "tsup": "^8.5.1",
55
55
  "typescript": "^5.7.3",
56
56
  "vitest": "^2.1.9",
57
- "@raindrop-ai/core": "0.1.2"
57
+ "@raindrop-ai/core": "0.1.3"
58
58
  },
59
59
  "tsup": {
60
60
  "entry": [