raindrop-ai 0.9.0 → 0.9.1

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.
@@ -101,7 +101,7 @@ function evalScopeAttributes() {
101
101
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
102
102
  }
103
103
 
104
- // ../core/dist/chunk-WJOR6M7H.js
104
+ // ../core/dist/chunk-I6TVJQEC.js
105
105
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
106
106
  function state() {
107
107
  const holder = globalThis;
@@ -1215,6 +1215,178 @@ var DEFAULT_REDACT_ATTRIBUTE_KEYS = [
1215
1215
  "ai.response.providerMetadata"
1216
1216
  ];
1217
1217
  var REDACT_JSON_ATTRIBUTE_KEYS = new Set(DEFAULT_REDACT_ATTRIBUTE_KEYS);
1218
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
1219
+ function isRecord(value) {
1220
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1221
+ }
1222
+ var JSON_SCHEMA_KEYS = [
1223
+ "type",
1224
+ "properties",
1225
+ "$schema",
1226
+ "$ref",
1227
+ "anyOf",
1228
+ "oneOf",
1229
+ "allOf",
1230
+ "enum",
1231
+ "const",
1232
+ "items",
1233
+ "additionalProperties",
1234
+ "required"
1235
+ ];
1236
+ function isJsonSchema(value) {
1237
+ if (!isRecord(value)) return false;
1238
+ if (typeof value["~standard"] === "object") return false;
1239
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
1240
+ if (Object.keys(value).length === 0) return true;
1241
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
1242
+ }
1243
+ function toJsonSchema(value, options) {
1244
+ if (value === void 0 || value === null) return void 0;
1245
+ if (isJsonSchema(value)) return value;
1246
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
1247
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
1248
+ if (options == null ? void 0 : options.schema) {
1249
+ try {
1250
+ return options.schema(value);
1251
+ } catch (e) {
1252
+ return void 0;
1253
+ }
1254
+ }
1255
+ return void 0;
1256
+ }
1257
+ function pickString(value) {
1258
+ return typeof value === "string" && value.length > 0 ? value : void 0;
1259
+ }
1260
+ function functionTool(name, description, schema, options) {
1261
+ const tool = { type: "function", name };
1262
+ const desc = pickString(description);
1263
+ if (desc !== void 0) tool.description = desc;
1264
+ const inputSchema = toJsonSchema(schema, options);
1265
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
1266
+ return tool;
1267
+ }
1268
+ function normalizeToolDeclaration(tool, options, fallbackName) {
1269
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1270
+ if (!isRecord(tool)) return void 0;
1271
+ if (tool.type === "provider-defined" || tool.type === "provider") {
1272
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
1273
+ if (name2 === void 0) return void 0;
1274
+ const declaration = { type: "provider-defined", name: name2 };
1275
+ const id = pickString(tool.id);
1276
+ if (id !== void 0) declaration.id = id;
1277
+ if (isRecord(tool.args)) declaration.args = tool.args;
1278
+ return declaration;
1279
+ }
1280
+ if (isRecord(tool.toolSpec)) {
1281
+ const spec = tool.toolSpec;
1282
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
1283
+ if (name2 === void 0) return void 0;
1284
+ return functionTool(name2, spec.description, spec.inputSchema, options);
1285
+ }
1286
+ if (isRecord(tool.function)) {
1287
+ const fn = tool.function;
1288
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
1289
+ if (name2 === void 0) return void 0;
1290
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
1291
+ }
1292
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
1293
+ if (name === void 0) return void 0;
1294
+ const type = pickString(tool.type);
1295
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
1296
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
1297
+ return { type: "provider-defined", id: type, name };
1298
+ }
1299
+ }
1300
+ return functionTool(
1301
+ name,
1302
+ tool.description,
1303
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
1304
+ options
1305
+ );
1306
+ }
1307
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
1308
+ function isGeminiToolGroup(tool) {
1309
+ if (Array.isArray(tool.functionDeclarations)) return true;
1310
+ const keys = Object.keys(tool);
1311
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
1312
+ return keys.every((key) => isRecord(tool[key]));
1313
+ }
1314
+ function expandGeminiTool(tool, options) {
1315
+ const declarations = [];
1316
+ for (const [key, value] of Object.entries(tool)) {
1317
+ if (key === "functionDeclarations" && Array.isArray(value)) {
1318
+ for (const declaration of value) {
1319
+ const normalized = normalizeToolDeclaration(declaration, options);
1320
+ if (normalized) declarations.push(normalized);
1321
+ }
1322
+ } else if (isRecord(value)) {
1323
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
1324
+ }
1325
+ }
1326
+ return declarations;
1327
+ }
1328
+ function normalizeToolDeclarations(tools, options) {
1329
+ if (tools === void 0 || tools === null) return void 0;
1330
+ if (Array.isArray(tools)) {
1331
+ return tools.flatMap((tool) => {
1332
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
1333
+ return expandGeminiTool(tool, options);
1334
+ }
1335
+ const declaration = normalizeToolDeclaration(tool, options);
1336
+ return declaration ? [declaration] : [];
1337
+ });
1338
+ }
1339
+ if (!isRecord(tools)) return void 0;
1340
+ return Object.entries(tools).flatMap(([key, tool]) => {
1341
+ const declaration = normalizeToolDeclaration(tool, options, key);
1342
+ return declaration ? [declaration] : [];
1343
+ });
1344
+ }
1345
+ function promptToolsAttributeValue(tools) {
1346
+ if (tools === void 0) return void 0;
1347
+ return tools.map((tool) => {
1348
+ try {
1349
+ return JSON.stringify(tool);
1350
+ } catch (e) {
1351
+ return JSON.stringify({ type: tool.type, name: tool.name });
1352
+ }
1353
+ });
1354
+ }
1355
+ function promptToolsFromTraceloopAttributes(attributes) {
1356
+ var _a;
1357
+ const byIndex = /* @__PURE__ */ new Map();
1358
+ const prefix = "llm.request.functions.";
1359
+ for (const [key, value] of Object.entries(attributes)) {
1360
+ if (!key.startsWith(prefix)) continue;
1361
+ const rest = key.slice(prefix.length);
1362
+ const dot = rest.indexOf(".");
1363
+ if (dot <= 0) continue;
1364
+ const index = Number(rest.slice(0, dot));
1365
+ if (!Number.isInteger(index) || index < 0) continue;
1366
+ const field = rest.slice(dot + 1);
1367
+ const entry = (_a = byIndex.get(index)) != null ? _a : {};
1368
+ if (field === "name" && typeof value === "string") entry.name = value;
1369
+ else if (field === "description" && typeof value === "string") entry.description = value;
1370
+ else if (field === "parameters") entry.parameters = value;
1371
+ byIndex.set(index, entry);
1372
+ }
1373
+ if (byIndex.size === 0) return void 0;
1374
+ const tools = [];
1375
+ for (const index of [...byIndex.keys()].sort((a, b) => a - b)) {
1376
+ const entry = byIndex.get(index);
1377
+ if (!(entry == null ? void 0 : entry.name)) continue;
1378
+ let parameters = entry.parameters;
1379
+ if (typeof parameters === "string") {
1380
+ try {
1381
+ parameters = JSON.parse(parameters);
1382
+ } catch (e) {
1383
+ parameters = void 0;
1384
+ }
1385
+ }
1386
+ tools.push(functionTool(entry.name, entry.description, parameters, void 0));
1387
+ }
1388
+ return tools;
1389
+ }
1218
1390
 
1219
1391
  // ../core/dist/index.node.js
1220
1392
  var import_async_hooks = require("async_hooks");
@@ -1422,7 +1594,7 @@ function base64ToHex2(base64) {
1422
1594
  // package.json
1423
1595
  var package_default = {
1424
1596
  name: "raindrop-ai",
1425
- version: "0.9.0",
1597
+ version: "0.9.1",
1426
1598
  main: "dist/index.js",
1427
1599
  module: "dist/index.mjs",
1428
1600
  types: "dist/index.d.ts",
@@ -2472,6 +2644,34 @@ function enrichStart(span) {
2472
2644
  }
2473
2645
  }
2474
2646
  }
2647
+ var PROMPT_TOOLS_OVERRIDE_MARKER = "raindrop.prompt_tools.override";
2648
+ var MODEL_SPAN_ATTRIBUTES = ["llm.request.type", "gen_ai.request.model", "ai.model.id"];
2649
+ function isModelSpan(attributes) {
2650
+ return MODEL_SPAN_ATTRIBUTES.some((key) => attributes[key] !== void 0);
2651
+ }
2652
+ function applyPromptTools(span) {
2653
+ var _a;
2654
+ const attributes = span.attributes;
2655
+ const marker = attributes[PROMPT_TOOLS_OVERRIDE_MARKER];
2656
+ if (marker !== void 0) {
2657
+ delete attributes[PROMPT_TOOLS_OVERRIDE_MARKER];
2658
+ if (!isModelSpan(attributes) || !shouldSendTraceContent()) return;
2659
+ let parsed;
2660
+ try {
2661
+ parsed = JSON.parse(String(marker));
2662
+ } catch (e) {
2663
+ return;
2664
+ }
2665
+ const tools = (_a = normalizeToolDeclarations(parsed)) != null ? _a : [];
2666
+ attributes[PROMPT_TOOLS_ATTRIBUTE] = promptToolsAttributeValue(tools);
2667
+ return;
2668
+ }
2669
+ if (attributes[PROMPT_TOOLS_ATTRIBUTE] !== void 0) return;
2670
+ if (!shouldSendTraceContent()) return;
2671
+ const inferred = promptToolsFromTraceloopAttributes(attributes);
2672
+ if (inferred === void 0) return;
2673
+ attributes[PROMPT_TOOLS_ATTRIBUTE] = promptToolsAttributeValue(inferred);
2674
+ }
2475
2675
  function createSpanProcessor(options) {
2476
2676
  var _a, _b;
2477
2677
  const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
@@ -2497,6 +2697,7 @@ function createSpanProcessor(options) {
2497
2697
  if (allowed !== ALL_INSTRUMENTATION_LIBRARIES && ![...INSTRUMENTATION_LIBRARIES, ...allowed != null ? allowed : []].includes((_a2 = scopeName(span)) != null ? _a2 : "")) {
2498
2698
  return;
2499
2699
  }
2700
+ applyPromptTools(span);
2500
2701
  outgoing = transformAiSdkSpan(span);
2501
2702
  if (outgoing !== span) copyReplayTraceDestination(span, outgoing);
2502
2703
  } catch (e) {
@@ -3612,6 +3813,22 @@ var LiveInteraction = class {
3612
3813
  if (this.toolEventsFrame) return;
3613
3814
  this.toolEventsFrame = bindSpanAttributes(attributes, this);
3614
3815
  }
3816
+ /**
3817
+ * Carry a `begin({ tools })` override to every span started inside this
3818
+ * interaction. Frames stamp strings, so the normalized catalog rides as one
3819
+ * JSON marker attribute; the span processor turns it into `ai.prompt.tools`
3820
+ * on model spans (and drops it from every other span) when the span ends.
3821
+ * Same lifetime as the tool-events frame: removed by `finish()`.
3822
+ */
3823
+ bindPromptToolsOverride(tools) {
3824
+ var _a;
3825
+ if (tools === void 0 || this.promptToolsFrame) return;
3826
+ const declarations = (_a = normalizeToolDeclarations(tools)) != null ? _a : [];
3827
+ this.promptToolsFrame = bindSpanAttributes(
3828
+ { [PROMPT_TOOLS_OVERRIDE_MARKER]: JSON.stringify(declarations) },
3829
+ this
3830
+ );
3831
+ }
3615
3832
  subagent(options) {
3616
3833
  return recordSubagentDispatch(this, options);
3617
3834
  }
@@ -3739,6 +3956,8 @@ var LiveInteraction = class {
3739
3956
  this.boundContext = void 0;
3740
3957
  unbindSpanAttributes(this.toolEventsFrame);
3741
3958
  this.toolEventsFrame = void 0;
3959
+ unbindSpanAttributes(this.promptToolsFrame);
3960
+ this.promptToolsFrame = void 0;
3742
3961
  if (!this.traceId) {
3743
3962
  this.resolveLiveTraceId();
3744
3963
  }
@@ -4764,8 +4983,9 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
4764
4983
  } catch (e) {
4765
4984
  }
4766
4985
  }) : void 0;
4767
- const beginInteraction = (traceContext) => {
4986
+ const beginInteraction = (params) => {
4768
4987
  var _a2;
4988
+ const { tools, ...traceContext } = params;
4769
4989
  if (!traceContext.eventId) {
4770
4990
  traceContext.eventId = crypto.randomUUID();
4771
4991
  }
@@ -4779,6 +4999,7 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
4779
4999
  );
4780
5000
  const bound = bindRoutingContext({ projectId, authHint, appGit: analytics.getAppGitSnapshot(traceContext.properties, traceContext.eventId) }, interaction);
4781
5001
  interaction.setBoundContext(bound);
5002
+ interaction.bindPromptToolsOverride(tools);
4782
5003
  try {
4783
5004
  analytics._trackAiPartial({
4784
5005
  ...traceContext,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  tracing
3
- } from "../chunk-RIL2CV7Q.mjs";
3
+ } from "../chunk-WLBBPTI6.mjs";
4
4
  import "../chunk-UJCSKKID.mjs";
5
5
 
6
6
  // src/tracing/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raindrop-ai",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -48,7 +48,7 @@
48
48
  "typescript": "^5.3.3",
49
49
  "vite": "^7.3.2",
50
50
  "vitest": "^4.0.10",
51
- "@raindrop-ai/core": "0.3.0",
51
+ "@raindrop-ai/core": "0.3.1",
52
52
  "@raindrop-ai/redact-pii": "0.1.2",
53
53
  "@raindrop-ai/schemas": "0.1.0"
54
54
  },