raindrop-ai 0.0.83 → 0.0.84

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,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "raindrop-ai",
4
- version: "0.0.83",
4
+ version: "0.0.84",
5
5
  main: "dist/index.js",
6
6
  module: "dist/index.mjs",
7
7
  types: "dist/index.d.ts",
@@ -34,7 +34,15 @@ var package_default = {
34
34
  clean: "rm -rf .turbo && rm -rf dist",
35
35
  try: "tsx ./src/example/index.ts",
36
36
  test: "vitest run",
37
- smoke: "tsx ./scripts/smoke.ts"
37
+ smoke: "tsx ./scripts/smoke.ts",
38
+ "smoke:ai-sdk-self-diagnostics": "tsx ./scripts/smoke.ai-sdk-self-diagnostics.ts",
39
+ "smoke:self-diagnostics:v4": "yarn build && cd tests/v4 && yarn install && yarn smoke",
40
+ "smoke:self-diagnostics:v5": "yarn build && cd tests/v5 && yarn install && yarn smoke",
41
+ "smoke:self-diagnostics:v6": "yarn build && cd tests/v6 && yarn install && yarn smoke",
42
+ "smoke:self-diagnostics:ai-sdk:all": "yarn smoke:self-diagnostics:v4 && yarn smoke:self-diagnostics:v5 && yarn smoke:self-diagnostics:v6",
43
+ "smoke:self-diagnostics:openai-sdk": "yarn build && cd tests/openai && yarn install && yarn smoke",
44
+ "smoke:self-diagnostics:anthropic-sdk": "yarn build && cd tests/anthropic && yarn install && yarn smoke",
45
+ "smoke:self-diagnostics:all": "yarn smoke:self-diagnostics:ai-sdk:all && yarn smoke:self-diagnostics:openai-sdk && yarn smoke:self-diagnostics:anthropic-sdk"
38
46
  },
39
47
  devDependencies: {
40
48
  "@types/node": "^20.11.17",
@@ -732,6 +740,9 @@ var LiveInteraction = class {
732
740
  }
733
741
  return metadata;
734
742
  }
743
+ getEventId() {
744
+ return this.context.eventId;
745
+ }
735
746
  finish(resultEvent) {
736
747
  var _a;
737
748
  if (this.traceId) {
package/dist/index.d.mts CHANGED
@@ -58,7 +58,7 @@ type BasicSignal = {
58
58
  attachmentId?: string;
59
59
  };
60
60
  type DefaultSignal = BasicSignal & {
61
- type?: "default";
61
+ type?: "default" | "standard";
62
62
  };
63
63
  type FeedbackSignal = BasicSignal & {
64
64
  type: "feedback";
@@ -68,7 +68,84 @@ type EditSignal = BasicSignal & {
68
68
  type: "edit";
69
69
  after?: string;
70
70
  };
71
- type SignalEvent = DefaultSignal | FeedbackSignal | EditSignal;
71
+ type AgentSignal = BasicSignal & {
72
+ type: "agent" | "agent_internal";
73
+ };
74
+ type SignalEvent = DefaultSignal | FeedbackSignal | EditSignal | AgentSignal;
75
+ type SelfDiagnosticsSignalDefinition = {
76
+ description: string;
77
+ sentiment?: "POSITIVE" | "NEGATIVE";
78
+ };
79
+ type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
80
+ type SelfDiagnosticsToolInputSchema = {
81
+ type: "object";
82
+ additionalProperties: false;
83
+ properties: {
84
+ category: {
85
+ type: "string";
86
+ enum: string[];
87
+ description: string;
88
+ };
89
+ detail: {
90
+ type: "string";
91
+ description: string;
92
+ };
93
+ };
94
+ required: string[];
95
+ };
96
+ type SelfDiagnosticsExecuteContext = {
97
+ eventId?: string;
98
+ interaction?: {
99
+ getEventId(): string | undefined;
100
+ };
101
+ metadata?: Record<string, unknown>;
102
+ properties?: Record<string, unknown>;
103
+ source?: string;
104
+ };
105
+ type SelfDiagnosticsExecuteResult = {
106
+ acknowledged: boolean;
107
+ category: string;
108
+ eventId?: string;
109
+ reason?: "missing_event_id";
110
+ };
111
+ type SelfDiagnosticsToolOptions = {
112
+ eventId?: string;
113
+ getEventId?: () => string | undefined;
114
+ interaction?: {
115
+ getEventId(): string | undefined;
116
+ };
117
+ toolName?: string;
118
+ guidance?: string;
119
+ signals?: SelfDiagnosticsSignalDefinitions;
120
+ source?: string;
121
+ onMissingEventId?: "warn" | "ignore" | "throw";
122
+ };
123
+ type SelfDiagnosticsTool = {
124
+ name: string;
125
+ description: string;
126
+ inputSchema: SelfDiagnosticsToolInputSchema;
127
+ signalKeys: string[];
128
+ execute(input: unknown, context?: SelfDiagnosticsExecuteContext): Promise<SelfDiagnosticsExecuteResult>;
129
+ forVercelAI(): {
130
+ description: string;
131
+ parameters: SelfDiagnosticsToolInputSchema;
132
+ inputSchema: SelfDiagnosticsToolInputSchema;
133
+ execute: (input: unknown, context?: SelfDiagnosticsExecuteContext) => Promise<SelfDiagnosticsExecuteResult>;
134
+ };
135
+ forOpenAI(): {
136
+ type: "function";
137
+ function: {
138
+ name: string;
139
+ description: string;
140
+ parameters: SelfDiagnosticsToolInputSchema;
141
+ };
142
+ };
143
+ forAnthropic(): {
144
+ name: string;
145
+ description: string;
146
+ input_schema: SelfDiagnosticsToolInputSchema;
147
+ };
148
+ };
72
149
  /**
73
150
  * Interface for identifying events.
74
151
  *
@@ -501,6 +578,10 @@ type Interaction = {
501
578
  * ```
502
579
  */
503
580
  vercelAiSdkMetadata(): Record<string, string>;
581
+ /**
582
+ * Returns the interaction event ID used for event/signal correlation.
583
+ */
584
+ getEventId(): string | undefined;
504
585
  /**
505
586
  * Logs a tool span directly without wrapping a function.
506
587
  *
@@ -738,6 +819,14 @@ declare class Raindrop {
738
819
  * @returns The interaction object.
739
820
  */
740
821
  resumeInteraction(eventId: string): Interaction;
822
+ /**
823
+ * Creates a framework-agnostic self-diagnostics tool definition.
824
+ *
825
+ * Use this when your agent framework does not support automatic tool injection.
826
+ * The returned object includes adapters for Vercel AI SDK, OpenAI function tools,
827
+ * and Anthropic tool definitions.
828
+ */
829
+ createSelfDiagnosticsTool(options?: SelfDiagnosticsToolOptions): SelfDiagnosticsTool;
741
830
  /**
742
831
  * Track AI events. In addiiton to normal event properties, you can provide an "input", "output", or "model" parameter.
743
832
  * It takes an AiTrackEvent as input and sends it to the /track-ai endpoint of the raindrop api.
@@ -795,4 +884,4 @@ declare class Raindrop {
795
884
  close(): Promise<void>;
796
885
  }
797
886
 
798
- export { type AiTrackEvent, type Attachment, type AttachmentType, type BeginInteractionOptions, type FinishInteractionOptions, type IdentifyEvent, type Interaction, MAX_INGEST_SIZE_BYTES, type PartialAiTrackEvent, Raindrop, type RaindropSpanProcessor, type SignalEvent, type SpanParams, type ToolParams, type ToolSpan, type TraceContext, type Tracer, type TrackToolParams, type WorkflowParams, Raindrop as default };
887
+ export { type AiTrackEvent, type Attachment, type AttachmentType, type BeginInteractionOptions, type FinishInteractionOptions, type IdentifyEvent, type Interaction, MAX_INGEST_SIZE_BYTES, type PartialAiTrackEvent, Raindrop, type RaindropSpanProcessor, type SelfDiagnosticsExecuteContext, type SelfDiagnosticsExecuteResult, type SelfDiagnosticsSignalDefinition, type SelfDiagnosticsSignalDefinitions, type SelfDiagnosticsTool, type SelfDiagnosticsToolInputSchema, type SelfDiagnosticsToolOptions, type SignalEvent, type SpanParams, type ToolParams, type ToolSpan, type TraceContext, type Tracer, type TrackToolParams, type WorkflowParams, Raindrop as default };
package/dist/index.d.ts CHANGED
@@ -58,7 +58,7 @@ type BasicSignal = {
58
58
  attachmentId?: string;
59
59
  };
60
60
  type DefaultSignal = BasicSignal & {
61
- type?: "default";
61
+ type?: "default" | "standard";
62
62
  };
63
63
  type FeedbackSignal = BasicSignal & {
64
64
  type: "feedback";
@@ -68,7 +68,84 @@ type EditSignal = BasicSignal & {
68
68
  type: "edit";
69
69
  after?: string;
70
70
  };
71
- type SignalEvent = DefaultSignal | FeedbackSignal | EditSignal;
71
+ type AgentSignal = BasicSignal & {
72
+ type: "agent" | "agent_internal";
73
+ };
74
+ type SignalEvent = DefaultSignal | FeedbackSignal | EditSignal | AgentSignal;
75
+ type SelfDiagnosticsSignalDefinition = {
76
+ description: string;
77
+ sentiment?: "POSITIVE" | "NEGATIVE";
78
+ };
79
+ type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
80
+ type SelfDiagnosticsToolInputSchema = {
81
+ type: "object";
82
+ additionalProperties: false;
83
+ properties: {
84
+ category: {
85
+ type: "string";
86
+ enum: string[];
87
+ description: string;
88
+ };
89
+ detail: {
90
+ type: "string";
91
+ description: string;
92
+ };
93
+ };
94
+ required: string[];
95
+ };
96
+ type SelfDiagnosticsExecuteContext = {
97
+ eventId?: string;
98
+ interaction?: {
99
+ getEventId(): string | undefined;
100
+ };
101
+ metadata?: Record<string, unknown>;
102
+ properties?: Record<string, unknown>;
103
+ source?: string;
104
+ };
105
+ type SelfDiagnosticsExecuteResult = {
106
+ acknowledged: boolean;
107
+ category: string;
108
+ eventId?: string;
109
+ reason?: "missing_event_id";
110
+ };
111
+ type SelfDiagnosticsToolOptions = {
112
+ eventId?: string;
113
+ getEventId?: () => string | undefined;
114
+ interaction?: {
115
+ getEventId(): string | undefined;
116
+ };
117
+ toolName?: string;
118
+ guidance?: string;
119
+ signals?: SelfDiagnosticsSignalDefinitions;
120
+ source?: string;
121
+ onMissingEventId?: "warn" | "ignore" | "throw";
122
+ };
123
+ type SelfDiagnosticsTool = {
124
+ name: string;
125
+ description: string;
126
+ inputSchema: SelfDiagnosticsToolInputSchema;
127
+ signalKeys: string[];
128
+ execute(input: unknown, context?: SelfDiagnosticsExecuteContext): Promise<SelfDiagnosticsExecuteResult>;
129
+ forVercelAI(): {
130
+ description: string;
131
+ parameters: SelfDiagnosticsToolInputSchema;
132
+ inputSchema: SelfDiagnosticsToolInputSchema;
133
+ execute: (input: unknown, context?: SelfDiagnosticsExecuteContext) => Promise<SelfDiagnosticsExecuteResult>;
134
+ };
135
+ forOpenAI(): {
136
+ type: "function";
137
+ function: {
138
+ name: string;
139
+ description: string;
140
+ parameters: SelfDiagnosticsToolInputSchema;
141
+ };
142
+ };
143
+ forAnthropic(): {
144
+ name: string;
145
+ description: string;
146
+ input_schema: SelfDiagnosticsToolInputSchema;
147
+ };
148
+ };
72
149
  /**
73
150
  * Interface for identifying events.
74
151
  *
@@ -501,6 +578,10 @@ type Interaction = {
501
578
  * ```
502
579
  */
503
580
  vercelAiSdkMetadata(): Record<string, string>;
581
+ /**
582
+ * Returns the interaction event ID used for event/signal correlation.
583
+ */
584
+ getEventId(): string | undefined;
504
585
  /**
505
586
  * Logs a tool span directly without wrapping a function.
506
587
  *
@@ -738,6 +819,14 @@ declare class Raindrop {
738
819
  * @returns The interaction object.
739
820
  */
740
821
  resumeInteraction(eventId: string): Interaction;
822
+ /**
823
+ * Creates a framework-agnostic self-diagnostics tool definition.
824
+ *
825
+ * Use this when your agent framework does not support automatic tool injection.
826
+ * The returned object includes adapters for Vercel AI SDK, OpenAI function tools,
827
+ * and Anthropic tool definitions.
828
+ */
829
+ createSelfDiagnosticsTool(options?: SelfDiagnosticsToolOptions): SelfDiagnosticsTool;
741
830
  /**
742
831
  * Track AI events. In addiiton to normal event properties, you can provide an "input", "output", or "model" parameter.
743
832
  * It takes an AiTrackEvent as input and sends it to the /track-ai endpoint of the raindrop api.
@@ -795,4 +884,4 @@ declare class Raindrop {
795
884
  close(): Promise<void>;
796
885
  }
797
886
 
798
- export { type AiTrackEvent, type Attachment, type AttachmentType, type BeginInteractionOptions, type FinishInteractionOptions, type IdentifyEvent, type Interaction, MAX_INGEST_SIZE_BYTES, type PartialAiTrackEvent, Raindrop, type RaindropSpanProcessor, type SignalEvent, type SpanParams, type ToolParams, type ToolSpan, type TraceContext, type Tracer, type TrackToolParams, type WorkflowParams, Raindrop as default };
887
+ export { type AiTrackEvent, type Attachment, type AttachmentType, type BeginInteractionOptions, type FinishInteractionOptions, type IdentifyEvent, type Interaction, MAX_INGEST_SIZE_BYTES, type PartialAiTrackEvent, Raindrop, type RaindropSpanProcessor, type SelfDiagnosticsExecuteContext, type SelfDiagnosticsExecuteResult, type SelfDiagnosticsSignalDefinition, type SelfDiagnosticsSignalDefinitions, type SelfDiagnosticsTool, type SelfDiagnosticsToolInputSchema, type SelfDiagnosticsToolOptions, type SignalEvent, type SpanParams, type ToolParams, type ToolSpan, type TraceContext, type Tracer, type TrackToolParams, type WorkflowParams, Raindrop as default };
package/dist/index.js CHANGED
@@ -138,7 +138,7 @@ var CategorizationRequestSchema = import_zod.z.object({
138
138
  // package.json
139
139
  var package_default = {
140
140
  name: "raindrop-ai",
141
- version: "0.0.83",
141
+ version: "0.0.84",
142
142
  main: "dist/index.js",
143
143
  module: "dist/index.mjs",
144
144
  types: "dist/index.d.ts",
@@ -171,7 +171,15 @@ var package_default = {
171
171
  clean: "rm -rf .turbo && rm -rf dist",
172
172
  try: "tsx ./src/example/index.ts",
173
173
  test: "vitest run",
174
- smoke: "tsx ./scripts/smoke.ts"
174
+ smoke: "tsx ./scripts/smoke.ts",
175
+ "smoke:ai-sdk-self-diagnostics": "tsx ./scripts/smoke.ai-sdk-self-diagnostics.ts",
176
+ "smoke:self-diagnostics:v4": "yarn build && cd tests/v4 && yarn install && yarn smoke",
177
+ "smoke:self-diagnostics:v5": "yarn build && cd tests/v5 && yarn install && yarn smoke",
178
+ "smoke:self-diagnostics:v6": "yarn build && cd tests/v6 && yarn install && yarn smoke",
179
+ "smoke:self-diagnostics:ai-sdk:all": "yarn smoke:self-diagnostics:v4 && yarn smoke:self-diagnostics:v5 && yarn smoke:self-diagnostics:v6",
180
+ "smoke:self-diagnostics:openai-sdk": "yarn build && cd tests/openai && yarn install && yarn smoke",
181
+ "smoke:self-diagnostics:anthropic-sdk": "yarn build && cd tests/anthropic && yarn install && yarn smoke",
182
+ "smoke:self-diagnostics:all": "yarn smoke:self-diagnostics:ai-sdk:all && yarn smoke:self-diagnostics:openai-sdk && yarn smoke:self-diagnostics:anthropic-sdk"
175
183
  },
176
184
  devDependencies: {
177
185
  "@types/node": "^20.11.17",
@@ -955,6 +963,9 @@ var LiveInteraction = class {
955
963
  }
956
964
  return metadata;
957
965
  }
966
+ getEventId() {
967
+ return this.context.eventId;
968
+ }
958
969
  finish(resultEvent) {
959
970
  var _a;
960
971
  if (this.traceId) {
@@ -1405,6 +1416,111 @@ var AttachmentTypeSchema = import_zod2.z.enum(["code", "text", "image", "iframe"
1405
1416
  // src/index.ts
1406
1417
  process.env.TRACELOOP_TELEMETRY = "false";
1407
1418
  var MAX_INGEST_SIZE_BYTES = 1 * 1024 * 1024;
1419
+ var SELF_DIAGNOSTICS_TOOL_NAME_DEFAULT = "__raindrop_report";
1420
+ var SELF_DIAGNOSTICS_SOURCE_DEFAULT = "agent_reporting_tool";
1421
+ var SELF_DIAGNOSTICS_SIGNALS_DEFAULT = {
1422
+ missing_context: {
1423
+ description: "You cannot complete the task because critical information, credentials, or access is missing and the user cannot provide it. Do NOT report this for normal clarifying questions \u2014 only when you are blocked.",
1424
+ sentiment: "NEGATIVE"
1425
+ },
1426
+ repeatedly_broken_tool: {
1427
+ description: "A tool has failed on multiple distinct attempts in this conversation, preventing task completion. You are sure the tool exists, and you have tried to use it, but it has failed. A single tool error is NOT enough \u2014 the tool must be persistently broken across retries.",
1428
+ sentiment: "NEGATIVE"
1429
+ },
1430
+ capability_gap: {
1431
+ description: "The task requires a tool, permission, or capability that you do not have. For example, the user asks you to perform an action but no suitable tool exists, or you lack the necessary access. Do NOT report this if you simply need more information from the user \u2014 only when the gap is in your own capabilities.",
1432
+ sentiment: "NEGATIVE"
1433
+ },
1434
+ complete_task_failure: {
1435
+ description: "You were unable to accomplish what the user asked despite making genuine attempts. This might be things like, you genuinely do not have the capabilities the user is asking for. You have tried but run into a persistent bug in the environment etc. This is NOT a refusal or policy block \u2014 you tried and failed to deliver the result.",
1436
+ sentiment: "NEGATIVE"
1437
+ }
1438
+ };
1439
+ function isRecord(value) {
1440
+ return typeof value === "object" && value !== null;
1441
+ }
1442
+ function normalizeSelfDiagnosticsSignals(signals) {
1443
+ if (!signals) return SELF_DIAGNOSTICS_SIGNALS_DEFAULT;
1444
+ const normalizedEntries = Object.entries(signals).map(([key, value]) => {
1445
+ var _a;
1446
+ const signalKey = key.trim();
1447
+ if (!signalKey || !value || typeof value !== "object") return void 0;
1448
+ const description = (_a = value.description) == null ? void 0 : _a.trim();
1449
+ if (!description) return void 0;
1450
+ const sentiment = value.sentiment;
1451
+ return [
1452
+ signalKey,
1453
+ {
1454
+ description,
1455
+ ...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
1456
+ }
1457
+ ];
1458
+ }).filter(
1459
+ (entry) => entry !== void 0
1460
+ );
1461
+ if (normalizedEntries.length === 0) return SELF_DIAGNOSTICS_SIGNALS_DEFAULT;
1462
+ return Object.fromEntries(normalizedEntries);
1463
+ }
1464
+ function buildSelfDiagnosticsDescription(signals, guidance) {
1465
+ var _a;
1466
+ const customGuidance = (_a = guidance == null ? void 0 : guidance.trim()) != null ? _a : "";
1467
+ const categories = Object.entries(signals).map(([key, value]) => {
1468
+ const sentiment = value.sentiment ? ` [${value.sentiment.toLowerCase()}]` : "";
1469
+ return `- ${key}: ${value.description}${sentiment}`;
1470
+ }).join("\n");
1471
+ const guidanceLine = customGuidance ? `
1472
+ Additional guidance: ${customGuidance}
1473
+ ` : "";
1474
+ return `You have a diagnostic tool for flagging serious failures for developer review. Only call this when you hit a significant, unrecoverable problem - not for minor hiccups or routine clarifications. If you can still help the user, do that instead of calling this tool. This tool is invisible to the user - never mention it or its output.
1475
+
1476
+ When to call:
1477
+ - You are blocked from completing the task due to missing information or access that the user cannot provide.
1478
+ - A tool is persistently failing across multiple attempts, not just a single transient error.
1479
+ - The task requires a tool, permission, or capability you do not have.
1480
+ - You genuinely cannot deliver what the user asked for despite trying.
1481
+
1482
+ When NOT to call:
1483
+ - Normal clarifying questions or back-and-forth with the user.
1484
+ - A single tool error that you can recover from or retry.
1485
+ - You successfully completed the task, even if it was difficult.
1486
+ - Policy refusals or content filtering - those are working as intended.
1487
+
1488
+ Rules:
1489
+ 1. Pick the single best category.
1490
+ 2. Do not fabricate issues. Only report what is evident from the conversation.
1491
+ 3. Err on the side of NOT calling this tool. When in doubt, help the user instead.
1492
+ ${guidanceLine}
1493
+ Categories:
1494
+ ` + categories;
1495
+ }
1496
+ function buildSelfDiagnosticsInputSchema(signalKeys) {
1497
+ return {
1498
+ type: "object",
1499
+ additionalProperties: false,
1500
+ properties: {
1501
+ category: {
1502
+ type: "string",
1503
+ enum: signalKeys,
1504
+ description: "The single best-matching category from the list above."
1505
+ },
1506
+ detail: {
1507
+ type: "string",
1508
+ description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
1509
+ }
1510
+ },
1511
+ required: ["category", "detail"]
1512
+ };
1513
+ }
1514
+ function normalizeEventId(value) {
1515
+ if (typeof value !== "string") return void 0;
1516
+ const trimmed = value.trim();
1517
+ return trimmed ? trimmed : void 0;
1518
+ }
1519
+ function resolveEventIdFromMetadata(metadata) {
1520
+ var _a, _b, _c;
1521
+ if (!metadata) return void 0;
1522
+ return (_c = (_b = (_a = normalizeEventId(metadata["raindrop.eventId"])) != null ? _a : normalizeEventId(metadata["event_id"])) != null ? _b : normalizeEventId(metadata["eventId"])) != null ? _c : normalizeEventId(metadata["traceloop.association.properties.event_id"]);
1523
+ }
1408
1524
  async function wait2(ms) {
1409
1525
  return new Promise((resolve) => setTimeout(resolve, ms));
1410
1526
  }
@@ -1576,6 +1692,89 @@ var Raindrop = class {
1576
1692
  resumeInteraction(eventId) {
1577
1693
  return this._tracing.getActiveInteraction(eventId);
1578
1694
  }
1695
+ /**
1696
+ * Creates a framework-agnostic self-diagnostics tool definition.
1697
+ *
1698
+ * Use this when your agent framework does not support automatic tool injection.
1699
+ * The returned object includes adapters for Vercel AI SDK, OpenAI function tools,
1700
+ * and Anthropic tool definitions.
1701
+ */
1702
+ createSelfDiagnosticsTool(options = {}) {
1703
+ var _a, _b;
1704
+ const signals = normalizeSelfDiagnosticsSignals(options.signals);
1705
+ const signalKeys = Object.keys(signals);
1706
+ const signalKeySet = new Set(signalKeys);
1707
+ const toolName = ((_a = options.toolName) == null ? void 0 : _a.trim()) || SELF_DIAGNOSTICS_TOOL_NAME_DEFAULT;
1708
+ const description = buildSelfDiagnosticsDescription(signals, options.guidance);
1709
+ const inputSchema = buildSelfDiagnosticsInputSchema(signalKeys);
1710
+ const onMissingEventId = (_b = options.onMissingEventId) != null ? _b : "warn";
1711
+ const execute = async (rawInput, context3) => {
1712
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1713
+ const input = isRecord(rawInput) ? rawInput : void 0;
1714
+ const fallbackCategory = (_a2 = signalKeys[0]) != null ? _a2 : "unknown";
1715
+ const categoryCandidate = normalizeEventId(input == null ? void 0 : input["category"]);
1716
+ const category = categoryCandidate && signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
1717
+ const detail = (_b2 = normalizeEventId(input == null ? void 0 : input["detail"])) != null ? _b2 : "";
1718
+ const eventId = (_l = (_k = (_i = (_g = (_f = (_e = (_d = normalizeEventId(context3 == null ? void 0 : context3.eventId)) != null ? _d : (_c = context3 == null ? void 0 : context3.interaction) == null ? void 0 : _c.getEventId()) != null ? _e : resolveEventIdFromMetadata(context3 == null ? void 0 : context3.metadata)) != null ? _f : normalizeEventId(input == null ? void 0 : input["event_id"])) != null ? _g : normalizeEventId(input == null ? void 0 : input["eventId"])) != null ? _i : (_h = options.interaction) == null ? void 0 : _h.getEventId()) != null ? _k : (_j = options.getEventId) == null ? void 0 : _j.call(options)) != null ? _l : normalizeEventId(options.eventId);
1719
+ if (!eventId) {
1720
+ const message = "self diagnostics signal skipped: missing eventId. Pass eventId, interaction, or getEventId when creating or executing the tool.";
1721
+ if (onMissingEventId === "throw") {
1722
+ throw new Error(`[raindrop] ${message}`);
1723
+ }
1724
+ if (onMissingEventId === "warn") {
1725
+ console.warn(`[raindrop] ${message}`);
1726
+ }
1727
+ return { acknowledged: false, category, reason: "missing_event_id" };
1728
+ }
1729
+ const signalDefinition = signals[category];
1730
+ this.trackSignal({
1731
+ eventId,
1732
+ name: `self diagnostics - ${category}`,
1733
+ type: "agent",
1734
+ sentiment: signalDefinition == null ? void 0 : signalDefinition.sentiment,
1735
+ properties: {
1736
+ source: (context3 == null ? void 0 : context3.source) || options.source || SELF_DIAGNOSTICS_SOURCE_DEFAULT,
1737
+ category,
1738
+ signal_description: signalDefinition == null ? void 0 : signalDefinition.description,
1739
+ ...detail ? { detail } : {},
1740
+ ...(_m = context3 == null ? void 0 : context3.properties) != null ? _m : {}
1741
+ }
1742
+ });
1743
+ return { acknowledged: true, category, eventId };
1744
+ };
1745
+ return {
1746
+ name: toolName,
1747
+ description,
1748
+ inputSchema,
1749
+ signalKeys,
1750
+ execute,
1751
+ forVercelAI() {
1752
+ return {
1753
+ description,
1754
+ parameters: inputSchema,
1755
+ inputSchema,
1756
+ execute
1757
+ };
1758
+ },
1759
+ forOpenAI() {
1760
+ return {
1761
+ type: "function",
1762
+ function: {
1763
+ name: toolName,
1764
+ description,
1765
+ parameters: inputSchema
1766
+ }
1767
+ };
1768
+ },
1769
+ forAnthropic() {
1770
+ return {
1771
+ name: toolName,
1772
+ description,
1773
+ input_schema: inputSchema
1774
+ };
1775
+ }
1776
+ };
1777
+ }
1579
1778
  /**
1580
1779
  * Track AI events. In addiiton to normal event properties, you can provide an "input", "output", or "model" parameter.
1581
1780
  * It takes an AiTrackEvent as input and sends it to the /track-ai endpoint of the raindrop api.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  tracing
4
- } from "./chunk-CYYFVRZF.mjs";
4
+ } from "./chunk-UEKYAG7S.mjs";
5
5
 
6
6
  // ../schemas/src/ingest/index.ts
7
7
  import { z } from "zod";
@@ -215,6 +215,111 @@ var AttachmentTypeSchema = z2.enum(["code", "text", "image", "iframe"]);
215
215
  // src/index.ts
216
216
  process.env.TRACELOOP_TELEMETRY = "false";
217
217
  var MAX_INGEST_SIZE_BYTES = 1 * 1024 * 1024;
218
+ var SELF_DIAGNOSTICS_TOOL_NAME_DEFAULT = "__raindrop_report";
219
+ var SELF_DIAGNOSTICS_SOURCE_DEFAULT = "agent_reporting_tool";
220
+ var SELF_DIAGNOSTICS_SIGNALS_DEFAULT = {
221
+ missing_context: {
222
+ description: "You cannot complete the task because critical information, credentials, or access is missing and the user cannot provide it. Do NOT report this for normal clarifying questions \u2014 only when you are blocked.",
223
+ sentiment: "NEGATIVE"
224
+ },
225
+ repeatedly_broken_tool: {
226
+ description: "A tool has failed on multiple distinct attempts in this conversation, preventing task completion. You are sure the tool exists, and you have tried to use it, but it has failed. A single tool error is NOT enough \u2014 the tool must be persistently broken across retries.",
227
+ sentiment: "NEGATIVE"
228
+ },
229
+ capability_gap: {
230
+ description: "The task requires a tool, permission, or capability that you do not have. For example, the user asks you to perform an action but no suitable tool exists, or you lack the necessary access. Do NOT report this if you simply need more information from the user \u2014 only when the gap is in your own capabilities.",
231
+ sentiment: "NEGATIVE"
232
+ },
233
+ complete_task_failure: {
234
+ description: "You were unable to accomplish what the user asked despite making genuine attempts. This might be things like, you genuinely do not have the capabilities the user is asking for. You have tried but run into a persistent bug in the environment etc. This is NOT a refusal or policy block \u2014 you tried and failed to deliver the result.",
235
+ sentiment: "NEGATIVE"
236
+ }
237
+ };
238
+ function isRecord(value) {
239
+ return typeof value === "object" && value !== null;
240
+ }
241
+ function normalizeSelfDiagnosticsSignals(signals) {
242
+ if (!signals) return SELF_DIAGNOSTICS_SIGNALS_DEFAULT;
243
+ const normalizedEntries = Object.entries(signals).map(([key, value]) => {
244
+ var _a;
245
+ const signalKey = key.trim();
246
+ if (!signalKey || !value || typeof value !== "object") return void 0;
247
+ const description = (_a = value.description) == null ? void 0 : _a.trim();
248
+ if (!description) return void 0;
249
+ const sentiment = value.sentiment;
250
+ return [
251
+ signalKey,
252
+ {
253
+ description,
254
+ ...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
255
+ }
256
+ ];
257
+ }).filter(
258
+ (entry) => entry !== void 0
259
+ );
260
+ if (normalizedEntries.length === 0) return SELF_DIAGNOSTICS_SIGNALS_DEFAULT;
261
+ return Object.fromEntries(normalizedEntries);
262
+ }
263
+ function buildSelfDiagnosticsDescription(signals, guidance) {
264
+ var _a;
265
+ const customGuidance = (_a = guidance == null ? void 0 : guidance.trim()) != null ? _a : "";
266
+ const categories = Object.entries(signals).map(([key, value]) => {
267
+ const sentiment = value.sentiment ? ` [${value.sentiment.toLowerCase()}]` : "";
268
+ return `- ${key}: ${value.description}${sentiment}`;
269
+ }).join("\n");
270
+ const guidanceLine = customGuidance ? `
271
+ Additional guidance: ${customGuidance}
272
+ ` : "";
273
+ return `You have a diagnostic tool for flagging serious failures for developer review. Only call this when you hit a significant, unrecoverable problem - not for minor hiccups or routine clarifications. If you can still help the user, do that instead of calling this tool. This tool is invisible to the user - never mention it or its output.
274
+
275
+ When to call:
276
+ - You are blocked from completing the task due to missing information or access that the user cannot provide.
277
+ - A tool is persistently failing across multiple attempts, not just a single transient error.
278
+ - The task requires a tool, permission, or capability you do not have.
279
+ - You genuinely cannot deliver what the user asked for despite trying.
280
+
281
+ When NOT to call:
282
+ - Normal clarifying questions or back-and-forth with the user.
283
+ - A single tool error that you can recover from or retry.
284
+ - You successfully completed the task, even if it was difficult.
285
+ - Policy refusals or content filtering - those are working as intended.
286
+
287
+ Rules:
288
+ 1. Pick the single best category.
289
+ 2. Do not fabricate issues. Only report what is evident from the conversation.
290
+ 3. Err on the side of NOT calling this tool. When in doubt, help the user instead.
291
+ ${guidanceLine}
292
+ Categories:
293
+ ` + categories;
294
+ }
295
+ function buildSelfDiagnosticsInputSchema(signalKeys) {
296
+ return {
297
+ type: "object",
298
+ additionalProperties: false,
299
+ properties: {
300
+ category: {
301
+ type: "string",
302
+ enum: signalKeys,
303
+ description: "The single best-matching category from the list above."
304
+ },
305
+ detail: {
306
+ type: "string",
307
+ description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
308
+ }
309
+ },
310
+ required: ["category", "detail"]
311
+ };
312
+ }
313
+ function normalizeEventId(value) {
314
+ if (typeof value !== "string") return void 0;
315
+ const trimmed = value.trim();
316
+ return trimmed ? trimmed : void 0;
317
+ }
318
+ function resolveEventIdFromMetadata(metadata) {
319
+ var _a, _b, _c;
320
+ if (!metadata) return void 0;
321
+ return (_c = (_b = (_a = normalizeEventId(metadata["raindrop.eventId"])) != null ? _a : normalizeEventId(metadata["event_id"])) != null ? _b : normalizeEventId(metadata["eventId"])) != null ? _c : normalizeEventId(metadata["traceloop.association.properties.event_id"]);
322
+ }
218
323
  async function wait(ms) {
219
324
  return new Promise((resolve) => setTimeout(resolve, ms));
220
325
  }
@@ -386,6 +491,89 @@ var Raindrop = class {
386
491
  resumeInteraction(eventId) {
387
492
  return this._tracing.getActiveInteraction(eventId);
388
493
  }
494
+ /**
495
+ * Creates a framework-agnostic self-diagnostics tool definition.
496
+ *
497
+ * Use this when your agent framework does not support automatic tool injection.
498
+ * The returned object includes adapters for Vercel AI SDK, OpenAI function tools,
499
+ * and Anthropic tool definitions.
500
+ */
501
+ createSelfDiagnosticsTool(options = {}) {
502
+ var _a, _b;
503
+ const signals = normalizeSelfDiagnosticsSignals(options.signals);
504
+ const signalKeys = Object.keys(signals);
505
+ const signalKeySet = new Set(signalKeys);
506
+ const toolName = ((_a = options.toolName) == null ? void 0 : _a.trim()) || SELF_DIAGNOSTICS_TOOL_NAME_DEFAULT;
507
+ const description = buildSelfDiagnosticsDescription(signals, options.guidance);
508
+ const inputSchema = buildSelfDiagnosticsInputSchema(signalKeys);
509
+ const onMissingEventId = (_b = options.onMissingEventId) != null ? _b : "warn";
510
+ const execute = async (rawInput, context) => {
511
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
512
+ const input = isRecord(rawInput) ? rawInput : void 0;
513
+ const fallbackCategory = (_a2 = signalKeys[0]) != null ? _a2 : "unknown";
514
+ const categoryCandidate = normalizeEventId(input == null ? void 0 : input["category"]);
515
+ const category = categoryCandidate && signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
516
+ const detail = (_b2 = normalizeEventId(input == null ? void 0 : input["detail"])) != null ? _b2 : "";
517
+ const eventId = (_l = (_k = (_i = (_g = (_f = (_e = (_d = normalizeEventId(context == null ? void 0 : context.eventId)) != null ? _d : (_c = context == null ? void 0 : context.interaction) == null ? void 0 : _c.getEventId()) != null ? _e : resolveEventIdFromMetadata(context == null ? void 0 : context.metadata)) != null ? _f : normalizeEventId(input == null ? void 0 : input["event_id"])) != null ? _g : normalizeEventId(input == null ? void 0 : input["eventId"])) != null ? _i : (_h = options.interaction) == null ? void 0 : _h.getEventId()) != null ? _k : (_j = options.getEventId) == null ? void 0 : _j.call(options)) != null ? _l : normalizeEventId(options.eventId);
518
+ if (!eventId) {
519
+ const message = "self diagnostics signal skipped: missing eventId. Pass eventId, interaction, or getEventId when creating or executing the tool.";
520
+ if (onMissingEventId === "throw") {
521
+ throw new Error(`[raindrop] ${message}`);
522
+ }
523
+ if (onMissingEventId === "warn") {
524
+ console.warn(`[raindrop] ${message}`);
525
+ }
526
+ return { acknowledged: false, category, reason: "missing_event_id" };
527
+ }
528
+ const signalDefinition = signals[category];
529
+ this.trackSignal({
530
+ eventId,
531
+ name: `self diagnostics - ${category}`,
532
+ type: "agent",
533
+ sentiment: signalDefinition == null ? void 0 : signalDefinition.sentiment,
534
+ properties: {
535
+ source: (context == null ? void 0 : context.source) || options.source || SELF_DIAGNOSTICS_SOURCE_DEFAULT,
536
+ category,
537
+ signal_description: signalDefinition == null ? void 0 : signalDefinition.description,
538
+ ...detail ? { detail } : {},
539
+ ...(_m = context == null ? void 0 : context.properties) != null ? _m : {}
540
+ }
541
+ });
542
+ return { acknowledged: true, category, eventId };
543
+ };
544
+ return {
545
+ name: toolName,
546
+ description,
547
+ inputSchema,
548
+ signalKeys,
549
+ execute,
550
+ forVercelAI() {
551
+ return {
552
+ description,
553
+ parameters: inputSchema,
554
+ inputSchema,
555
+ execute
556
+ };
557
+ },
558
+ forOpenAI() {
559
+ return {
560
+ type: "function",
561
+ function: {
562
+ name: toolName,
563
+ description,
564
+ parameters: inputSchema
565
+ }
566
+ };
567
+ },
568
+ forAnthropic() {
569
+ return {
570
+ name: toolName,
571
+ description,
572
+ input_schema: inputSchema
573
+ };
574
+ }
575
+ };
576
+ }
389
577
  /**
390
578
  * Track AI events. In addiiton to normal event properties, you can provide an "input", "output", or "model" parameter.
391
579
  * It takes an AiTrackEvent as input and sends it to the /track-ai endpoint of the raindrop api.
@@ -184,7 +184,7 @@ function base64Encode(bytes) {
184
184
  // package.json
185
185
  var package_default = {
186
186
  name: "raindrop-ai",
187
- version: "0.0.83",
187
+ version: "0.0.84",
188
188
  main: "dist/index.js",
189
189
  module: "dist/index.mjs",
190
190
  types: "dist/index.d.ts",
@@ -217,7 +217,15 @@ var package_default = {
217
217
  clean: "rm -rf .turbo && rm -rf dist",
218
218
  try: "tsx ./src/example/index.ts",
219
219
  test: "vitest run",
220
- smoke: "tsx ./scripts/smoke.ts"
220
+ smoke: "tsx ./scripts/smoke.ts",
221
+ "smoke:ai-sdk-self-diagnostics": "tsx ./scripts/smoke.ai-sdk-self-diagnostics.ts",
222
+ "smoke:self-diagnostics:v4": "yarn build && cd tests/v4 && yarn install && yarn smoke",
223
+ "smoke:self-diagnostics:v5": "yarn build && cd tests/v5 && yarn install && yarn smoke",
224
+ "smoke:self-diagnostics:v6": "yarn build && cd tests/v6 && yarn install && yarn smoke",
225
+ "smoke:self-diagnostics:ai-sdk:all": "yarn smoke:self-diagnostics:v4 && yarn smoke:self-diagnostics:v5 && yarn smoke:self-diagnostics:v6",
226
+ "smoke:self-diagnostics:openai-sdk": "yarn build && cd tests/openai && yarn install && yarn smoke",
227
+ "smoke:self-diagnostics:anthropic-sdk": "yarn build && cd tests/anthropic && yarn install && yarn smoke",
228
+ "smoke:self-diagnostics:all": "yarn smoke:self-diagnostics:ai-sdk:all && yarn smoke:self-diagnostics:openai-sdk && yarn smoke:self-diagnostics:anthropic-sdk"
221
229
  },
222
230
  devDependencies: {
223
231
  "@types/node": "^20.11.17",
@@ -766,6 +774,9 @@ var LiveInteraction = class {
766
774
  }
767
775
  return metadata;
768
776
  }
777
+ getEventId() {
778
+ return this.context.eventId;
779
+ }
769
780
  finish(resultEvent) {
770
781
  var _a;
771
782
  if (this.traceId) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tracing
3
- } from "../chunk-CYYFVRZF.mjs";
3
+ } from "../chunk-UEKYAG7S.mjs";
4
4
 
5
5
  // src/tracing/index.ts
6
6
  function initTracing() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raindrop-ai",
3
- "version": "0.0.83",
3
+ "version": "0.0.84",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -33,7 +33,15 @@
33
33
  "clean": "rm -rf .turbo && rm -rf dist",
34
34
  "try": "tsx ./src/example/index.ts",
35
35
  "test": "vitest run",
36
- "smoke": "tsx ./scripts/smoke.ts"
36
+ "smoke": "tsx ./scripts/smoke.ts",
37
+ "smoke:ai-sdk-self-diagnostics": "tsx ./scripts/smoke.ai-sdk-self-diagnostics.ts",
38
+ "smoke:self-diagnostics:v4": "yarn build && cd tests/v4 && yarn install && yarn smoke",
39
+ "smoke:self-diagnostics:v5": "yarn build && cd tests/v5 && yarn install && yarn smoke",
40
+ "smoke:self-diagnostics:v6": "yarn build && cd tests/v6 && yarn install && yarn smoke",
41
+ "smoke:self-diagnostics:ai-sdk:all": "yarn smoke:self-diagnostics:v4 && yarn smoke:self-diagnostics:v5 && yarn smoke:self-diagnostics:v6",
42
+ "smoke:self-diagnostics:openai-sdk": "yarn build && cd tests/openai && yarn install && yarn smoke",
43
+ "smoke:self-diagnostics:anthropic-sdk": "yarn build && cd tests/anthropic && yarn install && yarn smoke",
44
+ "smoke:self-diagnostics:all": "yarn smoke:self-diagnostics:ai-sdk:all && yarn smoke:self-diagnostics:openai-sdk && yarn smoke:self-diagnostics:anthropic-sdk"
37
45
  },
38
46
  "devDependencies": {
39
47
  "@types/node": "^20.11.17",